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