FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/bs/bsfunc.c
1 /* $NecBSD: bsfunc.c,v 1.2 1997/10/31 17:43:37 honda Exp $ */
2 /* $NetBSD$ */
3 /*
4 * [NetBSD for NEC PC98 series]
5 * Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31 /*
32 * Copyright (c) 1994, 1995, 1996 Naofumi HONDA. All rights reserved.
33 */
34
35 #ifdef __NetBSD__
36 #include <i386/Cbus/dev/bs/bsif.h>
37 #endif
38 #ifdef __FreeBSD__
39 #include <i386/isa/bs/bsif.h>
40 #endif
41
42 #ifdef BS_STATICS
43 struct bs_statics bs_statics[NTARGETS];
44 u_int bs_linkcmd_count[NTARGETS];
45 u_int bs_bounce_used[NTARGETS];
46 #endif /* BS_STATICS */
47
48 #ifdef BS_DEBUG
49 int bs_debug_flag = 0;
50 #endif /* BS_DEBUG */
51
52 static void bs_print_syncmsg __P((struct targ_info *, char*));
53 static void bs_timeout_target __P((struct targ_info *));
54 static void bs_kill_msg __P((struct ccb *cb));
55
56 static int bs_start_target __P((struct targ_info *));
57 static int bs_check_target __P((struct targ_info *));
58
59 /*************************************************************
60 * CCB
61 ************************************************************/
62 GENERIC_CCB_STATIC_ALLOC(bs, ccb)
63 GENERIC_CCB(bs, ccb, ccb_chain)
64
65 /*************************************************************
66 * TIMEOUT
67 ************************************************************/
68 static void
69 bs_timeout_target(ti)
70 struct targ_info *ti;
71 {
72 struct bs_softc *bsc = ti->ti_bsc;
73
74 ti->ti_error |= BSTIMEOUT;
75 bsc->sc_flags |= BSRESET;
76
77 if (ti->ti_herrcnt ++ >= HARDRETRIES)
78 {
79 bs_printf(ti, "timeout", "async transfer!");
80 ti->ti_syncmax.period = ti->ti_syncmax.offset = 0;
81 }
82 }
83
84 void
85 bstimeout(arg)
86 void *arg;
87 {
88 struct bs_softc *bsc = (struct bs_softc *) arg;
89 struct targ_info *ti;
90 struct ccb *cb;
91 int s;
92
93 s = splbio();
94 bsc->sc_flags &= ~BSSTARTTIMEOUT;
95
96 /* check */
97 if ((ti = bsc->sc_nexus) && (cb = ti->ti_ctab.tqh_first))
98 {
99 if ((cb->tc -= BS_TIMEOUT_CHECK_INTERVAL) < 0)
100 bs_timeout_target(ti);
101 }
102 else for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
103 {
104 if (bsc->sc_dtgnum && ti->ti_phase < DISCONNECTED)
105 continue;
106
107 cb = ti->ti_ctab.tqh_first;
108 if (cb && ((cb->tc -= BS_TIMEOUT_CHECK_INTERVAL) < 0))
109 bs_timeout_target(ti);
110 }
111
112 /* try to recover */
113 if (bsc->sc_flags & BSRESET)
114 {
115 bs_debug_print_all(bsc);
116 bs_printf(ti, "timeout", "bus hang up");
117 bs_reset_nexus(bsc);
118 }
119
120 bs_start_timeout(bsc);
121 splx(s);
122 }
123
124 /**************************************************
125 * MAKE CCB & MSG CCB
126 *************************************************/
127 static u_int8_t cmd_unit_ready[6];
128
129 struct ccb *
130 bs_make_internal_ccb(ti, lun, cmd, cmdlen, data, datalen, flags, timeout)
131 struct targ_info *ti;
132 u_int lun;
133 u_int8_t *cmd;
134 u_int cmdlen;
135 u_int8_t *data;
136 u_int datalen;
137 u_int flags;
138 int timeout;
139 {
140 struct ccb *cb;
141
142 if ((cb = bs_get_ccb(XSBS_SCSI_NOSLEEP)) == NULL)
143 bs_panic(ti->ti_bsc, "can not get ccb mem");
144
145 cb->xs = NULL;
146 cb->lun = lun;
147 cb->cmd = (cmd ? cmd : cmd_unit_ready);
148 cb->cmdlen = (cmd ? cmdlen : sizeof(cmd_unit_ready));
149 cb->data = data;
150 cb->datalen = (data ? datalen : 0);
151 cb->msgoutlen = 0;
152 cb->flags = flags & BSCFLAGSMASK;
153 bs_targ_flags(ti, cb);
154 cb->rcnt = 0;
155 cb->tcmax = (timeout > BS_DEFAULT_TIMEOUT_SECOND ? timeout :
156 BS_DEFAULT_TIMEOUT_SECOND);
157
158 TAILQ_INSERT_HEAD(&ti->ti_ctab, cb, ccb_chain);
159
160 return cb;
161 }
162
163 struct ccb *
164 bs_make_msg_ccb(ti, lun, cb, msg, timex)
165 struct targ_info *ti;
166 u_int lun;
167 struct ccb *cb;
168 struct msgbase *msg;
169 u_int timex;
170 {
171 u_int flags;
172
173 flags = BSFORCEIOPOLL | msg->flag;
174 if (cb == NULL)
175 cb = bs_make_internal_ccb(ti, lun, NULL, 0, NULL, 0,
176 flags, timex);
177 else
178 cb->flags |= flags & BSCFLAGSMASK;
179
180 cb->msgoutlen = msg->msglen;
181 bcopy(msg->msg, cb->msgout, msg->msglen);
182 return cb;
183 }
184
185 int
186 bs_send_msg(ti, lun, msg, timex)
187 struct targ_info *ti;
188 u_int lun;
189 struct msgbase *msg;
190 int timex;
191 {
192 struct ccb *cb;
193
194 cb = bs_make_msg_ccb(ti, lun, NULL, msg, timex);
195 bscmdstart(ti, BSCMDSTART);
196 return bs_scsi_cmd_poll(ti, cb);
197 }
198
199 static void
200 bs_kill_msg(cb)
201 struct ccb *cb;
202 {
203 cb->msgoutlen = 0;
204 }
205
206 /**************************************************
207 * MAKE SENSE CCB
208 **************************************************/
209 struct ccb *
210 bs_request_sense(ti)
211 struct targ_info *ti;
212 {
213 struct ccb *cb;
214
215 bzero(ti->scsi_cmd, sizeof(struct scsi_sense));
216 bzero(&ti->sense, sizeof(struct scsi_sense_data));
217 ti->scsi_cmd[0] = REQUEST_SENSE;
218 ti->scsi_cmd[1] = (ti->ti_lun << 5);
219 ti->scsi_cmd[4] = sizeof(struct scsi_sense_data);
220 cb = bs_make_internal_ccb(ti, ti->ti_lun, ti->scsi_cmd,
221 sizeof(struct scsi_sense),
222 (u_int8_t *) & ti->sense,
223 sizeof(struct scsi_sense_data),
224 BSFORCEIOPOLL,
225 BS_DEFAULT_TIMEOUT_SECOND);
226 cb->flags |= BSSENSECCB;
227 return cb;
228 }
229
230 /**************************************************
231 * SYNC MSG
232 *************************************************/
233 /* sync neg */
234 int
235 bs_start_syncmsg(ti, cb, flag)
236 struct targ_info *ti;
237 struct ccb *cb;
238 int flag;
239 {
240 struct syncdata *negp, *maxp;
241 struct msgbase msg;
242 u_int lun;
243
244 negp = &ti->ti_syncnow;
245 maxp = &ti->ti_syncmax;
246
247 ti->ti_state = BS_TARG_SYNCH;
248
249 if (flag == BS_SYNCMSG_REQUESTED)
250 {
251 if (negp->offset > maxp->offset)
252 negp->offset = maxp->offset;
253 if (negp->offset != 0 && negp->period < maxp->period)
254 negp->period = maxp->period;
255
256 msg.flag = 0;
257 lun = ti->ti_lun;
258 if (cb == NULL)
259 cb = ti->ti_ctab.tqh_first;
260 }
261 else if (ti->ti_cfgflags & BS_SCSI_SYNC)
262 {
263 negp->offset = maxp->offset;
264 negp->period = maxp->period;
265
266 msg.flag = BSERROROK;
267 lun = 0;
268 }
269 else
270 {
271 ti->ti_state = BS_TARG_RDY;
272 return COMPLETE;
273 }
274
275 BS_SETUP_SYNCSTATE(flag);
276 msg.msg[0] = MSG_EXTEND;
277 msg.msg[1] = MSG_EXTEND_SYNCHLEN;
278 msg.msg[2] = MSG_EXTEND_SYNCHCODE;
279 msg.msg[3] = negp->period;
280 msg.msg[4] = negp->offset;
281 msg.msglen = MSG_EXTEND_SYNCHLEN + 2;
282
283 bs_make_msg_ccb(ti, lun, cb, &msg, BS_SYNC_TIMEOUT);
284 return COMPLETE;
285 }
286
287 static void
288 bs_print_syncmsg(ti, s)
289 struct targ_info *ti;
290 char *s;
291 {
292 struct bs_softc *bsc = ti->ti_bsc;
293 struct syncdata *negp;
294 u_int speed;
295
296 negp = &ti->ti_syncnow;
297 speed = (negp->offset && negp->period) ?
298 (2500 / ((u_int) negp->period)) : 0;
299
300 printf("%s(%d:%d): <%s> ", bsc->sc_dvname, ti->ti_id, ti->ti_lun, s);
301 printf("period 0x%x offset %d chip (0x%x)", negp->period, negp->offset,
302 ti->ti_sync);
303 if (speed)
304 printf(" %d.%d M/s", speed / 10, speed % 10);
305 printf("\n");
306 }
307
308 int
309 bs_analyze_syncmsg(ti, cb)
310 struct targ_info *ti;
311 struct ccb *cb;
312 {
313 struct bs_softc *bsc = ti->ti_bsc;
314 u_int8_t ans = ti->ti_syncnow.state;
315 struct syncdata *negp, *maxp;
316 struct syncdata bdata;
317 char *s = NULL;
318 u_int8_t period;
319
320 negp = &ti->ti_syncnow;
321 bdata = *negp;
322 maxp = &ti->ti_syncmax;
323
324 switch(ans)
325 {
326 case BS_SYNCMSG_REJECT:
327 period = 0;
328 s = "msg reject";
329 break;
330
331 case BS_SYNCMSG_ASSERT:
332 period = 0;
333 s = "no msg";
334 break;
335
336 default:
337 if (negp->offset != 0 && negp->period < maxp->period)
338 {
339 period = 0xff;
340 s = "illegal(period)";
341 }
342 else if (negp->offset > maxp->offset)
343 {
344 period = 0xff;
345 s = "illegal(offset)";
346 }
347 else
348 period = negp->offset ? negp->period : 0;
349 break;
350 }
351
352 if (s == NULL)
353 {
354 bshw_adj_syncdata(negp);
355 *maxp = *negp;
356
357 if (ans == BS_SYNCMSG_REQUESTED)
358 s = "requested";
359 else
360 s = negp->offset ? "synchronous" : "async";
361 }
362 else
363 {
364 negp->offset = maxp->offset = 0;
365 bshw_adj_syncdata(negp);
366 bshw_adj_syncdata(maxp);
367 }
368
369 /* really setup hardware */
370 bshw_set_synchronous(bsc, ti);
371 if (cb == NULL || (period >= negp->period && period <= negp->period + 2))
372 {
373 bs_print_syncmsg(ti, s);
374 BS_SETUP_TARGSTATE(BS_TARG_RDY);
375 BS_SETUP_SYNCSTATE(BS_SYNCMSG_NULL);
376 if (cb)
377 bs_kill_msg(cb);
378
379 return 0;
380 }
381 else
382 {
383 bs_printf(ti, "bs_analyze_syncmsg",
384 "sync(period) mismatch, retry neg...");
385 printf("expect(%d:0x%x) => reply(%d:0x%x)\n",
386 bdata.offset, bdata.period, negp->offset, negp->period);
387
388 bs_start_syncmsg(ti, cb, BS_SYNCMSG_ASSERT);
389 return EINVAL;
390 }
391 }
392
393 /**************************************************
394 * ABORT AND RESET MSG
395 **************************************************/
396 /* send device reset msg and wait */
397 void
398 bs_reset_device(ti)
399 struct targ_info *ti;
400 {
401 struct msgbase msg;
402
403 msg.msglen = 1;
404 msg.msg[0] = MSG_RESET;
405 msg.flag = 0;
406
407 bs_send_msg(ti, 0, &msg, 0);
408
409 delay(ti->ti_bsc->sc_RSTdelay);
410 bs_check_target(ti);
411 }
412
413 /* send abort msg */
414 struct ccb *
415 bs_force_abort(ti)
416 struct targ_info *ti;
417 {
418 struct bs_softc *bsc = ti->ti_bsc;
419 struct msgbase msg;
420 struct ccb *cb = ti->ti_ctab.tqh_first;
421 u_int lun;
422
423 if (cb)
424 {
425 lun = cb->lun;
426 cb->rcnt++;
427 }
428 else
429 lun = 0;
430
431 msg.msglen = 1;
432 msg.msg[0] = MSG_ABORT;
433 msg.flag = 0;
434
435 cb = bs_make_msg_ccb(ti, lun, NULL, &msg, 0);
436 bscmdstart(ti, BSCMDSTART);
437
438 if (bsc->sc_nexus == ti)
439 BS_LOAD_SDP
440
441 return cb;
442 }
443
444 /**************************************************
445 * COMPLETE SCSI BUS RESET
446 *************************************************/
447 /*
448 * XXX:
449 * 1) reset scsi bus (ie. all target reseted).
450 * 2) chip reset.
451 * 3) check target status.
452 * 4) sync neg with all targets.
453 * 5) setup sync reg in host.
454 * 6) recover previous nexus.
455 */
456 void
457 bs_scsibus_start(bsc)
458 struct bs_softc *bsc;
459 {
460 struct targ_info *ti, *nextti = NULL;
461 int error = HASERROR;
462 u_int querm, bits, skip = 0;
463
464 querm = (bsc->sc_hstate == BSC_BOOTUP);
465 bsc->sc_hstate = BSC_TARG_CHECK;
466
467 /* target check */
468 do
469 {
470 if (error != COMPLETE)
471 {
472 printf("%s: scsi bus reset and try to restart ...",
473 bsc->sc_dvname);
474 bshw_smitabort(bsc);
475 bshw_dmaabort(bsc, NULL);
476 bshw_chip_reset(bsc);
477 bshw_bus_reset(bsc);
478 bshw_chip_reset(bsc);
479 printf(" done. scsi bus ready.\n");
480 nextti = bsc->sc_titab.tqh_first;
481 error = COMPLETE;
482 }
483
484 if ((ti = nextti) == NULL)
485 break;
486 nextti = ti->ti_tchain.tqe_next;
487
488 bits = (1 << ti->ti_id);
489 if (skip & bits)
490 continue;
491
492 if ((error = bs_check_target(ti)) != COMPLETE)
493 {
494 if (querm)
495 {
496 TAILQ_REMOVE(&bsc->sc_titab, ti, ti_tchain);
497 bsc->sc_openf &= ~bits;
498 }
499
500 if (error == NOTARGET)
501 error = COMPLETE;
502
503 skip |= bits;
504 }
505 }
506 while (1);
507
508 /* ok now ready */
509 bsc->sc_hstate = BSC_RDY;
510
511 /* recover */
512 for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
513 {
514 ti->ti_ctab = ti->ti_bctab;
515 TAILQ_INIT(&ti->ti_bctab);
516 if (ti->ti_ctab.tqh_first)
517 bscmdstart(ti, BSCMDSTART);
518 }
519 }
520
521 void
522 bs_reset_nexus(bsc)
523 struct bs_softc *bsc;
524 {
525 struct targ_info *ti;
526 struct ccb *cb;
527
528 bsc->sc_flags &= ~(BSRESET | BSUNDERRESET);
529 if (bsc->sc_poll)
530 {
531 bsc->sc_flags |= BSUNDERRESET;
532 return;
533 }
534
535 /* host state clear */
536 BS_HOST_TERMINATE
537 BS_SETUP_MSGPHASE(FREE)
538 bsc->sc_dtgnum = 0;
539
540 /* target state clear */
541 for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
542 {
543 if (ti->ti_state == BS_TARG_SYNCH)
544 bs_analyze_syncmsg(ti, NULL);
545 if (ti->ti_state > BS_TARG_START)
546 BS_SETUP_TARGSTATE(BS_TARG_START);
547
548 BS_SETUP_PHASE(UNDEF)
549 bs_hostque_delete(bsc, ti);
550 if ((cb = ti->ti_ctab.tqh_first) != NULL)
551 {
552 if (bsc->sc_hstate == BSC_TARG_CHECK)
553 {
554 ti->ti_error |= BSFATALIO;
555 bscmddone(ti);
556 }
557 else if (cb->rcnt >= bsc->sc_retry)
558 {
559 ti->ti_error |= BSABNORMAL;
560 bscmddone(ti);
561 }
562 else if (ti->ti_error)
563 cb->rcnt++;
564 }
565
566 /* target state clear */
567 BS_SETUP_PHASE(FREE)
568 BS_SETUP_SYNCSTATE(BS_SYNCMSG_NULL);
569 ti->ti_flags &= ~BSCFLAGSMASK;
570 ti->ti_msgout = 0;
571 #ifdef BS_DIAG
572 ti->ti_flags &= ~BSNEXUS;
573 #endif /* BS_DIAG */
574
575 for ( ; cb; cb = cb->ccb_chain.tqe_next)
576 {
577 bs_kill_msg(cb);
578 cb->flags &= ~(BSITSDONE | BSCASTAT);
579 cb->error = 0;
580 }
581
582 if (bsc->sc_hstate != BSC_TARG_CHECK &&
583 ti->ti_bctab.tqh_first == NULL)
584 ti->ti_bctab = ti->ti_ctab;
585
586 TAILQ_INIT(&ti->ti_ctab);
587 }
588
589 if (bsc->sc_hstate != BSC_TARG_CHECK)
590 bs_scsibus_start(bsc);
591 }
592
593 /**************************************************
594 * CHECK TARGETS AND START TARGETS
595 *************************************************/
596 static int
597 bs_start_target(ti)
598 struct targ_info *ti;
599 {
600 struct ccb *cb;
601 struct scsi_start_stop cmd;
602
603 bzero(&cmd, sizeof(struct scsi_start_stop));
604 #ifdef __NetBSD__
605 cmd.opcode = START_STOP;
606 #else
607 cmd.op_code = START_STOP;
608 #endif
609 cmd.how = SSS_START;
610 ti->ti_lun = 0;
611 cb = bs_make_internal_ccb(ti, 0, (u_int8_t *) &cmd,
612 sizeof(struct scsi_start_stop),
613 NULL, 0, BSFORCEIOPOLL, BS_MOTOR_TIMEOUT);
614 bscmdstart(ti, BSCMDSTART);
615 return bs_scsi_cmd_poll(ti, cb);
616 }
617
618 /* test unit ready and check ATN msgout response */
619 static int
620 bs_check_target(ti)
621 struct targ_info *ti;
622 {
623 struct bs_softc *bsc = ti->ti_bsc;
624 struct scsi_inquiry scsi_cmd;
625 struct scsi_inquiry_data scsi_inquiry_data;
626 struct ccb *cb;
627 int count, retry = bsc->sc_retry;
628 int s, error = COMPLETE;
629
630 ti->ti_lun = 0;
631 bsc->sc_retry = 2;
632 s = splbio();
633
634 /* inquiry */
635 bzero(&scsi_cmd, sizeof(scsi_cmd));
636 #ifdef __NetBSD__
637 scsi_cmd.opcode = INQUIRY;
638 #else
639 scsi_cmd.op_code = INQUIRY;
640 #endif
641 scsi_cmd.length = sizeof(struct scsi_inquiry_data);
642 cb = bs_make_internal_ccb(ti, 0,
643 (u_int8_t *) &scsi_cmd, sizeof(scsi_cmd),
644 (u_int8_t *) &scsi_inquiry_data,
645 sizeof(scsi_inquiry_data),
646 BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);
647 bscmdstart(ti, BSCMDSTART);
648 error = bs_scsi_cmd_poll(ti, cb);
649 if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))
650 goto done;
651 ti->targ_type = scsi_inquiry_data.device;
652 ti->targ_support = scsi_inquiry_data.flags;
653
654 /* test unit ready twice */
655 for (count = 0; count < 2; count++)
656 {
657 cb = bs_make_internal_ccb(ti, 0, NULL, 0, NULL, 0,
658 BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);
659 bscmdstart(ti, BSCMDSTART);
660 error = bs_scsi_cmd_poll(ti, cb);
661 if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))
662 goto done;
663 }
664
665 if (cb->flags & BSCASTAT)
666 bs_printf(ti, "check", "could not clear CA state");
667 ti->ti_error = 0;
668
669 done:
670 bsc->sc_retry = retry;
671
672 if (ti->ti_error & BSSELTIMEOUT)
673 error = NOTARGET;
674
675 if (error == COMPLETE)
676 error = bs_start_target(ti);
677
678 splx(s);
679 return error;
680 }
681
682 /**************************************************
683 * TARGET CONTROL
684 **************************************************/
685 struct targ_info *
686 bs_init_target_info(bsc, target)
687 struct bs_softc *bsc;
688 int target;
689 {
690 struct targ_info *ti;
691
692 ti = malloc(sizeof(struct targ_info), M_DEVBUF, M_NOWAIT);
693 if (ti == NULL)
694 {
695 bs_printf(NULL, "bs_init_targ_info", "no target info memory");
696 return ti;
697 }
698
699 bzero(ti, sizeof(*ti));
700
701 ti->ti_bsc = bsc;
702 ti->ti_id = target;
703 ti->sm_offset = 0;
704 ti->ti_cfgflags = BS_SCSI_NOPARITY | BS_SCSI_NOSAT;
705 ti->ti_mflags = ~(BSSAT | BSDISC | BSSMIT | BSLINK);
706 BS_SETUP_TARGSTATE(BS_TARG_CTRL);
707
708 TAILQ_INIT(&ti->ti_ctab);
709
710 bs_alloc_buf(ti);
711 if (ti->bounce_addr == NULL)
712 {
713 free(ti, M_DEVBUF);
714 return NULL;
715 }
716
717 TAILQ_INSERT_TAIL(&bsc->sc_titab, ti, ti_tchain);
718 bsc->sc_ti[target] = ti;
719 bsc->sc_openf |= (1 << target);
720
721 return ti;
722 }
723
724 void
725 bs_setup_ctrl(ti, quirks, flags)
726 struct targ_info *ti;
727 u_int quirks;
728 u_int flags;
729 {
730 struct bs_softc *bsc = ti->ti_bsc;
731 u_int offset, period, maxperiod;
732
733 if (ti->ti_state == BS_TARG_CTRL)
734 {
735 ti->ti_cfgflags = BS_SCSI_POSITIVE;
736 ti->ti_syncmax.offset = BSHW_MAX_OFFSET;
737 BS_SETUP_TARGSTATE(BS_TARG_START);
738 }
739 else
740 flags |= ti->ti_cfgflags & BS_SCSI_NEGATIVE;
741
742 #ifdef BS_TARG_SAFEMODE
743 if (ti->targ_type != 0)
744 {
745 flags &= ~(BS_SCSI_DISC | BS_SCSI_SYNC);
746 flags |= BS_SCSI_NOPARITY;
747 }
748 #endif
749
750 #ifdef SDEV_NODISC
751 if (quirks & SDEV_NODISC)
752 flags &= ~BS_SCSI_DISC;
753 #endif
754 #ifdef SDEV_NOPARITY
755 if (quirks & SDEV_NOPARITY)
756 flags |= BS_SCSI_NOPARITY;
757 #endif
758 #ifdef SDEV_NOCMDLNK
759 if (quirks & SDEV_NOCMDLNK)
760 flags &= ~BS_SCSI_LINK;
761 #endif
762 #ifdef SDEV_ASYNC
763 if (quirks & SDEV_ASYNC)
764 flags &= ~BS_SCSI_SYNC;
765 #endif
766 #ifdef SDEV_AUTOSAVE
767 if (quirks & SDEV_AUTOSAVE)
768 flags |= BS_SCSI_SAVESP;
769 #endif
770 #ifdef SD_Q_NO_SYNC
771 if (quirks & SD_Q_NO_SYNC)
772 flags &= ~BS_SCSI_SYNC;
773 #endif
774
775 if ((flags & BS_SCSI_DISC) == 0 ||
776 (ti->targ_support & SID_Linked) == 0)
777 flags &= ~BS_SCSI_LINK;
778
779 ti->sm_offset = (flags & BS_SCSI_NOSMIT) ? 0 : bsc->sm_offset;
780 if (ti->sm_offset == 0)
781 flags |= BS_SCSI_NOSMIT;
782 else if (bsc->sc_cfgflags & BSC_SMITSAT_DISEN)
783 flags |= BS_SCSI_NOSAT;
784
785 flags &= (ti->ti_cfgflags & BS_SCSI_POSITIVE) | (~BS_SCSI_POSITIVE);
786 ti->ti_cfgflags = flags;
787
788 /* calculate synch setup */
789 period = BS_SCSI_PERIOD(flags);
790 offset = (flags & BS_SCSI_SYNC) ? BS_SCSI_OFFSET(flags) : 0;
791
792 maxperiod = (bsc->sc_cspeed & IDR_FS_15_20) ? 100 : 50;
793 if (period > maxperiod)
794 period = maxperiod;
795
796 if (period)
797 period = 2500 / period;
798
799 if (ti->ti_syncmax.offset > offset)
800 ti->ti_syncmax.offset = offset;
801 if (ti->ti_syncmax.period < period)
802 ti->ti_syncmax.period = period;
803
804 bshw_adj_syncdata(&ti->ti_syncmax);
805
806 /* finally report our info */
807 printf("%s(%d:%d): {%d:0x%x:0x%x:%s} flags 0x%b\n",
808 bsc->sc_dvname, ti->ti_id, ti->ti_lun,
809 (u_int) ti->targ_type,
810 (u_int) ti->targ_support,
811 (u_int) ti->bounce_size,
812 (flags & BS_SCSI_NOSMIT) ? "dma" : "pdma",
813 flags, BS_SCSI_BITS);
814
815 /* internal representation */
816 ti->ti_mflags = ~0;
817 if ((ti->ti_cfgflags & BS_SCSI_DISC) == 0)
818 ti->ti_mflags &= ~BSDISC;
819 if ((ti->ti_cfgflags & BS_SCSI_LINK) == 0)
820 ti->ti_mflags &= ~BSLINK;
821 if (ti->ti_cfgflags & BS_SCSI_NOSAT)
822 ti->ti_mflags &= ~BSSAT;
823 if (ti->ti_cfgflags & BS_SCSI_NOSMIT)
824 ti->ti_mflags &= ~BSSMIT;
825 }
826
827 /**************************************************
828 * MISC
829 **************************************************/
830 void
831 bs_printf(ti, ph, c)
832 struct targ_info *ti;
833 char *ph;
834 char *c;
835 {
836
837 if (ti)
838 printf("%s(%d:%d): <%s> %s\n",
839 ti->ti_bsc->sc_dvname, ti->ti_id, ti->ti_lun, ph, c);
840 else
841 printf("bs*(*:*): <%s> %s\n", ph, c);
842 }
843
844 void
845 bs_panic(bsc, c)
846 struct bs_softc *bsc;
847 u_char *c;
848 {
849
850 panic("%s %s\n", bsc->sc_dvname, c);
851 }
852
853 /**************************************************
854 * DEBUG FUNC
855 **************************************************/
856 #ifdef BS_DEBUG_ROUTINE
857 u_int
858 bsr(addr)
859 u_int addr;
860 {
861
862 outb(0xcc0, addr);
863 return inb(0xcc2);
864 }
865
866 u_int
867 bsw(addr, data)
868 u_int addr;
869 int data;
870 {
871
872 outb(0xcc0, addr);
873 outb(0xcc2, data);
874 return 0;
875 }
876 #endif /* BS_DEBUG_ROUTINE */
877
878 void
879 bs_debug_print_all(bsc)
880 struct bs_softc *bsc;
881 {
882 struct targ_info *ti;
883
884 for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
885 bs_debug_print(bsc, ti);
886 }
887
888 static u_char *phase[] =
889 {
890 "FREE", "HOSTQUE", "DISC", "COMPMSG", "ATN", "DISCMSG", "SELECT",
891 "SELECTED", "RESELECTED", "MSGIN", "MSGOUT", "STATIN", "CMDOUT",
892 "DATA", "SATSEL", "SATRESEL", "SATSDP", "SATCOMPSEQ", "UNDEF",
893 };
894
895 void
896 bs_debug_print(bsc, ti)
897 struct bs_softc *bsc;
898 struct targ_info *ti;
899 {
900 struct ccb *cb;
901
902 /* host stat */
903 printf("%s <DEBUG INFO> nexus %lx bs %lx bus status %lx \n",
904 bsc->sc_dvname, (u_long) ti, (u_long) bsc->sc_nexus, (u_long) bsc->sc_busstat);
905
906 /* target stat */
907 if (ti)
908 {
909 struct sc_p *sp = &bsc->sc_p;
910
911 printf("%s(%d:%d) ph<%s> ", bsc->sc_dvname, ti->ti_id,
912 ti->ti_lun, phase[(int) ti->ti_phase]);
913 printf("msgptr %x msg[0] %x status %x tqh %lx fl %x\n",
914 (u_int) (ti->ti_msginptr), (u_int) (ti->ti_msgin[0]),
915 ti->ti_status, (u_long) (cb = ti->ti_ctab.tqh_first),
916 ti->ti_flags);
917 if (cb)
918 printf("cmdlen %x cmdaddr %lx cmd[0] %x\n",
919 cb->cmdlen, (u_long) cb->cmd, (int) cb->cmd[0]);
920 printf("datalen %x dataaddr %lx seglen %x ",
921 sp->datalen, (u_long) sp->data, sp->seglen);
922 if (cb)
923 printf("odatalen %x flags %x\n",
924 cb->datalen, cb->flags);
925 else
926 printf("\n");
927 printf("error flags %b\n", ti->ti_error, BSERRORBITS);
928 }
929 }
Cache object: 8a5c33d213725f2ab2ccffae67ff5efb
|