FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/bs/bs.c
1 /* $NecBSD: bs.c,v 1.1 1997/07/18 09:18:59 kmatsuda 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 /*****************************************************************
43 * Inline phase funcs
44 *****************************************************************/
45 /* static inline declare */
46 static BS_INLINE struct targ_info *bs_reselect __P((struct bs_softc *));
47 static BS_INLINE void bs_sat_continue __P((struct bs_softc *, struct targ_info *, struct ccb *));
48 static BS_INLINE struct targ_info *bs_selected __P((struct bs_softc *, struct targ_info *, struct ccb *));
49 static BS_INLINE u_int8_t bs_read_1byte __P((struct bs_softc *));
50 static BS_INLINE void bs_write_1byte __P((struct bs_softc *, u_int8_t));
51 static BS_INLINE void bs_commandout __P((struct bs_softc *, struct targ_info *, struct ccb *));
52 static BS_INLINE void bs_status_check __P((struct bs_softc *, struct targ_info *));
53 static BS_INLINE void bs_msgin __P((struct bs_softc *, struct targ_info *));
54 static BS_INLINE void bs_msgout __P((struct bs_softc *, struct targ_info *, struct ccb *));
55 static BS_INLINE void bs_disconnect_phase __P((struct bs_softc *, struct targ_info *, struct ccb *));
56 static void bs_phase_error __P((struct targ_info *, struct ccb *));
57 static int bs_scsi_cmd_poll_internal __P((struct targ_info *));
58 static int bs_xfer __P((struct bs_softc *, char *, int));
59 static void bs_io_xfer __P((struct targ_info *));
60 static void bs_quick_abort __P((struct targ_info *, u_int));
61 static void bs_msgin_error __P((struct targ_info *, u_int));
62 static void bs_msgin_ext __P((struct targ_info *));
63 static void bs_msg_reject __P((struct targ_info *));
64 static void bshoststart __P((struct bs_softc *, struct targ_info *));
65
66 /*****************************************************************
67 * Julian scsi interface
68 *****************************************************************/
69 XSBS_INT32T
70 bs_scsi_cmd(xs)
71 struct scsi_xfer *xs;
72 {
73 struct bs_softc *bsc = (struct bs_softc *) xs->sc_link->adapter_softc;
74 int s, target = (u_int) (xs->sc_link->target);
75 struct targ_info *ti;
76 struct ccb *cb;
77 u_int flags = xs->flags;
78
79 if (xs->bp == NULL && (bsc->sc_openf & (1 << target)) == 0)
80 {
81 s = splbio();
82 xs->error = XS_DRIVER_STUFFUP;
83 xs->flags |= XSBS_ITSDONE;
84 scsi_done(xs);
85 splx(s);
86 return COMPLETE;
87 }
88
89 ti = bsc->sc_ti[target];
90 if ((cb = bs_get_ccb(flags & XSBS_SCSI_NOSLEEP)) == NULL)
91 return TRY_AGAIN_LATER;
92
93 /* make up ccb! */
94 cb->xs = xs;
95 cb->lun = xs->sc_link->lun;
96 cb->cmd = (u_int8_t *) xs->cmd;
97 cb->cmdlen = (int) xs->cmdlen;
98 cb->data = (u_int8_t *) xs->data;
99 cb->datalen = (int) xs->datalen;
100 cb->rcnt = 0;
101 cb->msgoutlen = 0;
102 cb->flags = (flags & XSBS_SCSI_POLL) ? BSFORCEIOPOLL : 0;
103 bs_targ_flags(ti, cb);
104 cb->tcmax = (xs->timeout >> 10);
105 if (cb->tcmax < BS_DEFAULT_TIMEOUT_SECOND)
106 cb->tcmax = BS_DEFAULT_TIMEOUT_SECOND;
107
108 #ifdef BS_ADDRESS_CHECK
109 /* XXX:
110 * Sanity check, however this is critical!
111 * NetBSD 1.0: WRONG
112 * NetBSD 1.1: OK
113 * FreeBSD: WRONG
114 */
115 if ((caddr_t) cb->data < (caddr_t) KERNBASE)
116 {
117 u_int8_t *altbp;
118
119 altbp = (u_int8_t *) malloc(cb->datalen, M_DEVBUF, M_NOWAIT);
120 if (altbp == NULL)
121 {
122 bs_free_ccb(cb);
123 return TRY_AGAIN_LATER;
124 }
125
126 if (flags & SCSI_DATA_OUT)
127 bcopy(cb->data, altbp, cb->datalen);
128 else
129 bzero(altbp, cb->datalen);
130
131 cb->data = (u_int8_t *) altbp;
132 cb->flags |= BSALTBUF;
133 }
134 #endif /* BS_ADDRESS_CHECK */
135
136 s = splbio();
137
138 TAILQ_INSERT_TAIL(&ti->ti_ctab, cb, ccb_chain);
139
140 if (ti->ti_phase == FREE)
141 {
142 if (ti->ti_state == BS_TARG_START)
143 {
144 if ((flags & XSBS_SCSI_POLL) == 0)
145 bs_start_syncmsg(ti, NULL, BS_SYNCMSG_ASSERT);
146 }
147 bscmdstart(ti, BSCMDSTART);
148 }
149
150 if ((flags & XSBS_SCSI_POLL) == 0)
151 {
152 splx(s);
153 return SUCCESSFULLY_QUEUED;
154 }
155
156 bs_scsi_cmd_poll(ti, cb);
157 splx(s);
158
159 return COMPLETE;
160 }
161
162 /**************************************************
163 * ### NEXUS START and TERMINATE ###
164 **************************************************/
165 /*
166 * FLAGS : BSCMDRESTART restart in case of error.
167 */
168 int
169 bscmdstart(ti, flags)
170 struct targ_info *ti;
171 int flags;
172 {
173 struct ccb *cb;
174 struct bs_softc *bsc = ti->ti_bsc;
175
176 if ((cb = ti->ti_ctab.tqh_first) == NULL)
177 {
178 if (bsc->sc_nexus == NULL)
179 bshoststart(bsc, NULL);
180 return 0;
181 }
182
183 ti->ti_lun = cb->lun;
184 ti->ti_error = 0;
185 ti->ti_scsp.data = cb->data;
186 ti->ti_scsp.datalen = cb->datalen;
187 ti->ti_scsp.seglen = 0;
188 if (cb->rcnt)
189 cb->flags &= ~(BSSAT | BSLINK);
190 ti->ti_flags &= ~BSCFLAGSMASK;
191 ti->ti_flags |= cb->flags & BSCFLAGSMASK;
192 cb->tc = cb->tcmax;
193
194 /* GO GO */
195 if (ti->ti_phase == FREE)
196 {
197 if (bsc->sc_nexus == NULL)
198 bshoststart(bsc, ti);
199 else
200 {
201 if (flags & BSCMDRESTART)
202 bs_hostque_head(bsc, ti);
203 else
204 bs_hostque_tail(bsc, ti);
205 BS_SETUP_PHASE(HOSTQUEUE)
206 }
207 }
208 else if (bsc->sc_nexus == NULL)
209 bshoststart(bsc, NULL);
210
211 return 1;
212 }
213
214 struct ccb *
215 bscmddone(ti)
216 struct targ_info *ti;
217 {
218 struct bs_softc *bsc = ti->ti_bsc;
219 struct ccb *cb = ti->ti_ctab.tqh_first;
220 struct scsi_xfer *xs;
221 int error;
222
223 if (ti->ti_state == BS_TARG_SYNCH)
224 {
225 if (bs_analyze_syncmsg(ti, cb))
226 return cb;
227 }
228
229 if (bsc->sc_p.datalen != 0)
230 ti->ti_error |= BSDMAABNORMAL;
231
232 cb->error = ti->ti_error;
233
234 do
235 {
236 xs = cb->xs;
237 error = XS_NOERROR;
238
239 if (cb->flags & (BSITSDONE | BSSENSECCB | BSCASTAT))
240 {
241 if (cb->flags & BSSENSECCB)
242 {
243 cb->error &= ~BSDMAABNORMAL;
244 if (cb->error == 0)
245 ti->ti_flags |= BSCASTAT;
246
247 ti->ti_flags |= BSERROROK;
248 }
249 else if (cb->flags & BSCASTAT)
250 {
251 if (ti->ti_flags & BSCASTAT)
252 {
253 ti->ti_flags &= ~BSCASTAT;
254 error = XS_SENSE;
255 if (xs)
256 xs->sense = ti->sense;
257 }
258 else
259 error = XS_DRIVER_STUFFUP;
260
261 ti->ti_flags |= BSERROROK;
262 } else
263 bs_panic(bsc, "internal error");
264 }
265
266 while (cb->error)
267 {
268 if (ti->ti_flags & BSERROROK)
269 break;
270
271 if (cb->rcnt >= bsc->sc_retry || (cb->error & BSFATALIO))
272 {
273 if (cb->error & (BSSELTIMEOUT | BSTIMEOUT))
274 error = XS_TIMEOUT;
275 else if (cb->error & BSTARGETBUSY)
276 error = XS_BUSY;
277 else
278 error = XS_DRIVER_STUFFUP;
279 break;
280 }
281
282 if (cb->error & BSREQSENSE)
283 {
284 /* must clear the target's sense state */
285 cb->rcnt++;
286 cb->flags |= (BSITSDONE | BSCASTAT);
287 cb->error &= ~BSREQSENSE;
288 return bs_request_sense(ti);
289 }
290
291 /* XXX: compat with upper driver */
292 if ((cb->error & BSDMAABNORMAL) &&
293 BSHW_CMD_CHECK(cb, BSERROROK))
294 {
295 cb->error &= ~BSDMAABNORMAL;
296 continue;
297 }
298
299 if ((xs && xs->bp) || (cb->error & BSSELTIMEOUT) == 0)
300 bs_debug_print(bsc, ti);
301
302 cb->rcnt++;
303 return cb;
304 }
305
306 #ifdef BS_DIAG
307 cb->flags |= BSITSDONE;
308 #endif /* BS_DIAG */
309 if (bsc->sc_poll)
310 {
311 bsc->sc_flags |= BSJOBDONE;
312 if (bsc->sc_outccb == cb)
313 bsc->sc_flags |= BSPOLLDONE;
314 }
315
316 TAILQ_REMOVE(&ti->ti_ctab, cb, ccb_chain);
317
318 if (xs)
319 {
320 #ifdef BS_ADDRESS_CHECK
321 if (cb->flags & BSALTBUF)
322 {
323 if (xs->flags & SCSI_DATA_IN)
324 bcopy(cb->data, xs->data, cb->datalen);
325 free(cb->data, M_DEVBUF);
326 }
327 #endif /* BS_ADDRESS_CHECK */
328
329 if ((xs->error = error) == XS_NOERROR)
330 xs->resid = 0;
331 xs->flags |= XSBS_ITSDONE;
332 scsi_done(xs);
333 }
334
335 bs_free_ccb(cb);
336 cb = ti->ti_ctab.tqh_first;
337
338 }
339 while (cb != NULL && (cb->flags & BSITSDONE) != 0);
340
341 /* complete */
342 return NULL;
343 }
344
345 /**************************************************
346 * ### PHASE FUNCTIONS ###
347 **************************************************/
348 /**************************************************
349 * <SELECTION PHASE>
350 **************************************************/
351 static void
352 bshoststart(bsc, ti)
353 struct bs_softc *bsc;
354 struct targ_info *ti;
355 {
356 struct ccb *cb;
357 int s;
358
359 if (bsc->sc_flags & BSINACTIVE)
360 return;
361
362 again:
363 if (ti == NULL)
364 {
365 if ((ti = bsc->sc_sttab.tqh_first) == NULL)
366 return;
367 bs_hostque_delete(bsc, ti);
368 }
369
370 if ((cb = ti->ti_ctab.tqh_first) == NULL)
371 {
372 bs_printf(ti, "bshoststart", "Warning: No ccb");
373 BS_SETUP_PHASE(FREE);
374 ti = NULL;
375 goto again;
376 }
377
378 #ifdef BS_DIAG
379 if (cb->flags & BSITSDONE)
380 bs_panic(bsc, "bshoststart: already done");
381
382 if (bsc->sc_nexus || (ti->ti_flags & BSNEXUS))
383 {
384 char *s = ((ti->ti_flags & BSNEXUS) ?
385 "nexus already established" : "scsi board busy");
386
387 bs_debug_print(bsc, ti);
388 bs_printf(ti, "bshoststart", s);
389 }
390 #endif /* BS_DIAG */
391
392 #ifdef BS_STATICS
393 bs_statics[ti->ti_id].select++;
394 #endif /* BS_STATICS */
395
396 if (ti->ti_cfgflags & BS_SCSI_WAIT)
397 {
398 struct targ_info *tmpti;
399
400 for (tmpti = bsc->sc_titab.tqh_first; tmpti;
401 tmpti = tmpti->ti_tchain.tqe_next)
402 if (tmpti->ti_phase >= DISCONNECTED)
403 goto retry;
404 }
405
406 /* start selection */
407 ti->ti_status = ST_UNK;
408 if (bs_check_sat(ti))
409 {
410 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
411 {
412 BS_LOAD_SDP
413 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
414 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
415 bshw_cmd_pass(bsc, 0);
416 bshw_set_sync_reg(bsc, ti->ti_sync);
417 bshw_issue_satcmd(bsc, cb, bs_check_link(ti, cb));
418 if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
419 bshw_set_count(bsc, 0);
420 else
421 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
422
423 s = splhigh();
424 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
425 {
426 /* XXX:
427 * Reload a lun again here.
428 */
429 bshw_set_lun(bsc, ti->ti_lun);
430 bshw_start_sat(bsc, bs_check_disc(ti));
431 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
432 {
433 splx(s);
434 BS_HOST_START
435 BS_SELECTION_START
436 BS_SETUP_PHASE(SATSEL);
437 ti->ti_omsgoutlen = 0;
438 ti->ti_msgout = bs_identify_msg(ti);
439 #ifdef BS_DIAG
440 ti->ti_flags |= BSNEXUS;
441 #endif /* BS_DIAG */
442 #ifdef BS_STATICS
443 bs_statics[ti->ti_id].select_win++;
444 #endif /* BS_STATICS */
445 return;
446 }
447 }
448 splx(s);
449
450 if (bs_check_smit(ti) == 0)
451 bshw_dmaabort(bsc, ti);
452 #ifdef BS_STATICS
453 bs_statics[ti->ti_id].select_miss_in_assert++;
454 #endif /* BS_STATICS */
455 }
456 }
457 else
458 {
459 s = splhigh();
460 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
461 {
462 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
463 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
464 bshw_set_sync_reg(bsc, ti->ti_sync);
465 bshw_assert_select(bsc);
466
467 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
468 {
469 splx(s);
470 BS_HOST_START
471 BS_SELECTION_START
472 BS_SETUP_PHASE(SELECTASSERT);
473 #ifdef BS_STATICS
474 bs_statics[ti->ti_id].select_win++;
475 #endif /* BS_STATICS */
476 return;
477 }
478 #ifdef BS_STATICS
479 bs_statics[ti->ti_id].select_miss_in_assert++;
480 #endif /* BS_STATICS */
481 }
482 splx(s);
483 }
484
485 /* RETRY LATER */
486 retry:
487 #ifdef BS_STATICS
488 bs_statics[ti->ti_id].select_miss++;
489 #endif /* BS_STATICS */
490 bs_hostque_head(bsc, ti);
491 BS_SETUP_PHASE(HOSTQUEUE)
492 }
493
494 static BS_INLINE struct targ_info *
495 bs_selected(bsc, ti, cb)
496 struct bs_softc *bsc;
497 struct targ_info *ti;
498 struct ccb *cb;
499 {
500
501 if (bsc->sc_busstat != BSR_SELECTED)
502 {
503 bs_phase_error(ti, cb);
504 return NULL;
505 }
506
507 #ifdef BS_DIAG
508 if (bsc->sc_selwait != ti)
509 panic("%s selection internal error\n", bsc->sc_dvname);
510
511 ti->ti_flags |= BSNEXUS;
512 #endif /* BS_DIAG */
513
514 /* clear select wait state */
515 BS_SETUP_PHASE(SELECTED);
516 BS_SELECTION_TERMINATE;
517 BS_LOAD_SDP
518 return ti;
519 }
520
521 /**************************************************
522 * <RESELECTION>
523 **************************************************/
524 static BS_INLINE struct targ_info *
525 bs_reselect(bsc)
526 struct bs_softc *bsc;
527 {
528 u_int target;
529 struct targ_info *ti;
530
531 /* check collision */
532 if ((ti = bsc->sc_selwait) != NULL)
533 {
534 if (ti->ti_phase == SATSEL)
535 {
536 #ifdef BS_DIAG
537 ti->ti_flags &= ~BSNEXUS;
538 #endif /* BS_DIAG */
539 ti->ti_msgout = 0;
540 if (bs_check_smit(ti) == 0)
541 bshw_dmaabort(bsc, ti);
542 }
543 bs_hostque_head(bsc, ti);
544 BS_SELECTION_TERMINATE
545 BS_SETUP_PHASE(HOSTQUEUE)
546 #ifdef BS_STATICS
547 bs_statics[ti->ti_id].select_miss_by_reselect++;
548 bs_statics[ti->ti_id].select_miss++;
549 #endif /* BS_STATICS */
550 }
551
552 /* who are you ? */
553 target = bshw_get_src_id(bsc);
554 if ((ti = bsc->sc_ti[target]) == NULL)
555 {
556 bs_debug_print_all(bsc);
557 printf("reselect: miss reselect. target(%d)\n", target);
558 bs_reset_nexus(bsc);
559 return NULL;
560 }
561
562 /* confirm nexus */
563 BS_HOST_START
564 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
565 if (ti->ti_ctab.tqh_first == NULL || ti->ti_phase != DISCONNECTED)
566 {
567 bs_printf(ti, "reselect", "phase mismatch");
568 BS_SETUP_PHASE(UNDEF)
569 bs_force_abort(ti);
570 bs_hostque_delete(bsc, ti);
571 }
572 else
573 bsc->sc_dtgnum --;
574
575 /* recover host */
576 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
577 bshw_set_sync_reg(bsc, ti->ti_sync);
578 BS_RESTORE_SDP
579 BS_SETUP_PHASE(RESELECTED)
580 #ifdef BS_STATICS
581 bs_statics[ti->ti_id].reselect++;
582 #endif /* BS_STATICS */
583 return ti;
584 }
585
586 static BS_INLINE void
587 bs_sat_continue(bsc, ti, cb)
588 struct bs_softc *bsc;
589 struct targ_info *ti;
590 struct ccb *cb;
591 {
592
593 BS_SETUP_PHASE(SATRESEL);
594 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
595 bshw_cmd_pass(bsc, 0x44);
596 bshw_set_sync_reg(bsc, ti->ti_sync);
597 bshw_issue_satcmd(bsc, cb, 0);
598 if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
599 bshw_set_count(bsc, 0);
600 else
601 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
602 bshw_set_lun(bsc, ti->ti_lun); /* XXX */
603 bshw_start_sat(bsc, 0);
604 }
605
606 /*************************************************
607 * <DATA PHASE>
608 *************************************************/
609 #define DR (STR_BSY | STR_DBR)
610
611 void
612 bs_poll_timeout(bsc, s)
613 struct bs_softc *bsc;
614 char *s;
615 {
616 struct targ_info *ti;
617
618 bs_printf(NULL, s, "timeout");
619 bsc->sc_flags |= BSRESET;
620 if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)
621 ti->ti_error |= BSTIMEOUT;
622 }
623
624 static BS_INLINE u_int8_t
625 bs_read_1byte(bsc)
626 struct bs_softc *bsc;
627 {
628 register u_int wc;
629
630 bshw_start_sxfer(bsc);
631 for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
632 if (wc)
633 return bshw_read_data(bsc);
634 else
635 bs_poll_timeout(bsc, "read_1byte");
636
637 return 0;
638 }
639
640 static BS_INLINE void
641 bs_write_1byte(bsc, data)
642 struct bs_softc *bsc;
643 u_int8_t data;
644 {
645 register u_int wc;
646
647 bshw_start_sxfer(bsc);
648 for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
649 if (wc)
650 bshw_write_data(bsc, data);
651 else
652 bs_poll_timeout(bsc, "write_1byte");
653 }
654
655 static int
656 bs_xfer(bsc, data, len)
657 struct bs_softc *bsc;
658 char *data;
659 int len;
660 {
661 u_int8_t aux;
662 u_int count, wc;
663
664 bshw_set_count(bsc, len);
665 bshw_start_xfer(bsc);
666
667 for (count = 0, wc = bsc->sc_wc; count < len && --wc; )
668 {
669 if (((aux = bshw_get_auxstat(bsc)) & DR) == DR)
670 {
671 if (bsc->sc_busstat & BSHW_READ)
672 *(data++) = bshw_read_data(bsc);
673 else
674 bshw_write_data(bsc, *(data++));
675 count++;
676 wc = bsc->sc_wc;
677 }
678
679 if (aux & STR_INT)
680 break;
681 }
682
683 if (wc == 0)
684 bs_poll_timeout(bsc, "bs_xfer");
685
686 return count;
687 }
688 #undef DR
689
690 static void
691 bs_io_xfer(ti)
692 struct targ_info *ti;
693 {
694 struct bs_softc *bsc = ti->ti_bsc;
695 struct sc_p *sp = &bsc->sc_p;
696 u_int count, dummy;
697
698 /* switch dma trasnfr mode */
699 bshw_set_poll_trans(bsc, ti->ti_cfgflags);
700 sp->seglen = 0;
701 sp->bufp = NULL;
702
703 if (sp->datalen <= 0)
704 {
705 ti->ti_error |= BSDMAABNORMAL;
706 dummy = 0;
707 count = bs_xfer(bsc, (u_int8_t *) &dummy, 1);
708 }
709 else
710 count = bs_xfer(bsc, sp->data, sp->datalen);
711
712 sp->data += count;
713 sp->datalen -= count;
714 }
715
716 /************************************************
717 * <COMMAND PHASE>
718 ************************************************/
719 static BS_INLINE void
720 bs_commandout(bsc, ti, cb)
721 struct bs_softc *bsc;
722 struct targ_info *ti;
723 struct ccb *cb;
724 {
725 u_int8_t scsi_cmd[16];
726 int len;
727
728 BS_SETUP_PHASE(CMDPHASE);
729
730 if (bs_check_link(ti, cb))
731 {
732 bcopy(cb->cmd, scsi_cmd, cb->cmdlen);
733 scsi_cmd[cb->cmdlen - 1] |= 0x01;
734 len = bs_xfer(bsc, scsi_cmd, cb->cmdlen);
735 }
736 else
737 len = bs_xfer(bsc, cb->cmd, cb->cmdlen);
738
739 if (len != cb->cmdlen)
740 ti->ti_error |= BSCMDABNORMAL;
741 }
742
743 /************************************************
744 * <STATUS IN>
745 ************************************************/
746 static BS_INLINE void
747 bs_status_check(bsc, ti)
748 struct bs_softc *bsc;
749 struct targ_info *ti;
750 {
751
752 if (ti->ti_status == ST_GOOD || ti->ti_status == ST_INTERGOOD)
753 return;
754
755 switch (ti->ti_status)
756 {
757 case ST_MET:
758 case ST_INTERMET:
759 case ST_CHKCOND:
760 ti->ti_error |= BSREQSENSE;
761 break;
762
763 case ST_BUSY:
764 ti->ti_error |= BSTARGETBUSY;
765 break;
766
767 default:
768 ti->ti_error |= BSSTATUSERROR;
769 break;
770 }
771 }
772
773 /************************************************
774 * <MSG IN>
775 ************************************************/
776 #define MSGWAIT(cnt) { if (ti->ti_msginptr < (cnt)) return; }
777
778 static void
779 bs_quick_abort(ti, msg)
780 struct targ_info *ti;
781 u_int msg;
782 {
783 struct ccb *cb;
784
785 if ((cb = ti->ti_ctab.tqh_first) == NULL)
786 return;
787
788 cb->msgoutlen = 1;
789 cb->msgout[0] = msg;
790 cb->rcnt++;
791
792 ti->ti_error |= BSMSGERROR;
793 }
794
795 static void
796 bs_msgin_error(ti, count)
797 struct targ_info *ti;
798 u_int count;
799 {
800 int n;
801
802 MSGWAIT(count);
803
804 bs_printf(ti, "msgin", "illegal msg");
805
806 for (n = 0; n < ti->ti_msginptr; n ++)
807 printf("[0x%x] ", (u_int) ti->ti_msgin[n]);
808 printf("\n");
809
810 bs_quick_abort(ti, MSG_REJECT);
811 ti->ti_msginptr = 0;
812 }
813
814 static void
815 bs_msgin_ext(ti)
816 struct targ_info *ti;
817 {
818 struct bs_softc *bsc = ti->ti_bsc;
819 struct ccb *cb = ti->ti_ctab.tqh_first;
820 int count;
821 u_int reqlen;
822 u_int32_t *ptr;
823 struct msgbase msg;
824
825 MSGWAIT(2);
826
827 reqlen = ti->ti_msgin[1];
828 if (reqlen == 0)
829 reqlen = 256;
830
831 if (ti->ti_msginptr >= MAXMSGLEN)
832 ti->ti_msginptr = 3; /* XXX */
833
834 MSGWAIT(reqlen + 2);
835
836 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
837 {
838 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
839 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
840 count = (int) htonl((long) (*ptr));
841
842 bsc->sc_p.seglen = ti->ti_scsp.seglen = 0;
843 if (bsc->sc_p.datalen - count >= 0 &&
844 bsc->sc_p.datalen - count <= cb->datalen)
845 {
846 bsc->sc_p.datalen -= count;
847 bsc->sc_p.data += count;
848 }
849 else
850 bs_msgin_error(ti, 7);
851 break;
852
853 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
854 ti->ti_syncnow.period = ti->ti_msgin[3];
855 ti->ti_syncnow.offset = ti->ti_msgin[4];
856 if (ti->ti_syncnow.offset == 0)
857 ti->ti_syncnow.period = 0;
858
859 if (ti->ti_syncnow.state != BS_SYNCMSG_ASSERT)
860 {
861 bs_start_syncmsg(ti, NULL, BS_SYNCMSG_REQUESTED);
862 bscmdstart(ti, BSCMDSTART);
863 }
864 else
865 BS_SETUP_SYNCSTATE(BS_SYNCMSG_ACCEPT)
866 break;
867
868 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
869 msg.msglen = MSG_EXTEND_WIDELEN + 2;
870 msg.msg[0] = MSG_EXTEND;
871 msg.msg[1] = MSG_EXTEND_WIDELEN;
872 msg.msg[2] = MSG_EXTEND_WIDECODE;
873 msg.msg[3] = 0;
874 msg.flag = 0;
875 bs_make_msg_ccb(ti, cb->lun, cb, &msg, 0);
876 break;
877
878 default:
879 bs_msgin_error(ti, 0);
880 return;
881 }
882
883 ti->ti_msginptr = 0;
884 return;
885 }
886
887 static void
888 bs_msg_reject(ti)
889 struct targ_info *ti;
890 {
891 struct bs_softc *bsc = ti->ti_bsc;
892 struct ccb *cb = ti->ti_ctab.tqh_first;
893 char *s = "unexpected msg reject";
894
895 switch (ti->ti_ophase)
896 {
897 case CMDPHASE:
898 s = "cmd rejected";
899 cb->flags &= ~BSLINK;
900 BS_SETUP_MSGPHASE(IOCOMPLETED);
901 break;
902
903 case MSGOUT:
904 if (ti->ti_msgout & 0x80)
905 {
906 s = "identify msg rejected";
907 cb->flags &= ~BSDISC;
908 BS_SETUP_MSGPHASE(IOCOMPLETED);
909 }
910 else if (ti->ti_msgout == MSG_EXTEND)
911 {
912 switch (ti->ti_emsgout)
913 {
914 case MSG_EXTEND_SYNCHCODE:
915 BS_SETUP_SYNCSTATE(BS_SYNCMSG_REJECT);
916 return;
917
918 default:
919 break;
920 }
921 }
922 break;
923
924 default:
925 break;
926 }
927
928 bs_debug_print(bsc, ti);
929 bs_printf(ti, "msgin", s);
930 ti->ti_error |= BSMSGERROR;
931 }
932
933 static BS_INLINE void
934 bs_msgin(bsc, ti)
935 struct bs_softc *bsc;
936 struct targ_info *ti;
937 {
938
939 BS_SETUP_PHASE(MSGIN);
940
941 switch (ti->ti_msgin[0])
942 {
943 case MSG_SAVESP:
944 BS_SAVE_SDP
945 break;
946
947 case MSG_RESTORESP:
948 BS_RESTORE_SDP
949 bs_printf(ti, "msgin", "restore scsi pointer");
950 break;
951
952 case MSG_REJECT:
953 bs_msg_reject(ti);
954 break;
955
956 case 0xf:
957 break;
958
959 case MSG_I_ERROR:/* all I -> T : nothing to do*/
960 case MSG_ABORT:
961 case MSG_PARITY:
962 case MSG_RESET:
963 case 0xe:
964 bs_msgin_error(ti, 1);
965 goto resume;
966
967 case MSG_NOOP:
968 break;
969
970 case MSG_EXTEND:
971 bs_msgin_ext(ti);
972 goto resume;
973
974 case 0xd:
975 bs_msgin_error(ti, 2);
976 goto resume;
977
978 case MSG_DISCON:
979 BS_SETUP_MSGPHASE(DISCONNECTASSERT);
980 break;
981
982 case MSG_COMP:
983 BS_SETUP_MSGPHASE(IOCOMPLETED);
984 break;
985
986 case MSG_LCOMP:
987 case MSG_LCOMP_F:
988 bs_status_check(bsc, ti);
989 if (bscmddone(ti) == NULL)
990 {
991 if (bscmdstart(ti, BSCMDSTART) == 0)
992 {
993 bs_printf(ti, "msgin", "cmd line miss");
994 bs_force_abort(ti);
995 }
996 }
997 else
998 bscmdstart(ti, BSCMDRESTART);
999 #ifdef BS_STATICS
1000 bs_linkcmd_count[ti->ti_id]++;
1001 #endif /* BS_STATICS */
1002 BS_LOAD_SDP
1003 ti->ti_status = ST_UNK;
1004 break;
1005
1006 default:
1007 if (ti->ti_msgin[0] & 0x80)
1008 {
1009 if ((ti->ti_msgin[0] & 0x07) != ti->ti_lun)
1010 {
1011 ti->ti_lun = (ti->ti_msgin[0] & 0x07);
1012 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
1013 bshw_set_sync_reg(bsc, ti->ti_sync);
1014
1015 bs_printf(ti, "msgin", "lun error");
1016 bs_quick_abort(ti, MSG_ABORT);
1017 }
1018 break;
1019 }
1020 else if (ti->ti_msgin[0] < 0x20)
1021 bs_msgin_error(ti, 1);
1022 else if (ti->ti_msgin[0] < 0x30)
1023 bs_msgin_error(ti, 2);
1024 else
1025 bs_msgin_error(ti, 1);
1026 goto resume;
1027 }
1028
1029 ti->ti_msginptr = 0;
1030
1031 resume:
1032 return;
1033 }
1034
1035 /************************************************
1036 * <MSG OUT>
1037 ************************************************/
1038 static BS_INLINE void
1039 bs_msgout(bsc, ti, cb)
1040 struct bs_softc *bsc;
1041 struct targ_info *ti;
1042 struct ccb *cb;
1043 {
1044 u_int8_t msg[MAXMSGLEN + 1];
1045
1046 if (ti->ti_phase == MSGOUT)
1047 {
1048 if (cb->rcnt ++ < bsc->sc_retry)
1049 cb->msgoutlen = ti->ti_omsgoutlen;
1050 }
1051 else
1052 BS_SETUP_PHASE(MSGOUT);
1053
1054 if (ti->ti_ophase == SELECTED)
1055 {
1056 identify:
1057 if (cb->msgoutlen == 0)
1058 {
1059 ti->ti_msgout = bs_identify_msg(ti);
1060 ti->ti_omsgoutlen = 0;
1061 bs_write_1byte(bsc, ti->ti_msgout);
1062 }
1063 else
1064 {
1065 if (cb->msgout[0] != MSG_RESET &&
1066 cb->msgout[0] != MSG_ABORT)
1067 {
1068 msg[0] = bs_identify_msg(ti);
1069 bcopy(cb->msgout, &msg[1], cb->msgoutlen);
1070 bs_xfer(bsc, msg, cb->msgoutlen + 1);
1071 }
1072 else
1073 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
1074
1075 ti->ti_msgout = cb->msgout[0];
1076 ti->ti_emsgout = cb->msgout[2];
1077 ti->ti_omsgoutlen = cb->msgoutlen;
1078 cb->msgoutlen = 0;
1079 }
1080 return;
1081 }
1082
1083 if (ti->ti_ophase == SATSEL)
1084 {
1085 /* XXX:
1086 * Maybe identify msg rejected due to
1087 * a parity error in target side.
1088 */
1089
1090 bs_printf(ti, "msgout", "msg identify retry (SAT)");
1091 goto identify;
1092 }
1093
1094 if (cb->msgoutlen == 0)
1095 {
1096 ti->ti_msgout = MSG_REJECT;
1097 ti->ti_omsgoutlen = 0;
1098 bs_write_1byte(bsc, ti->ti_msgout);
1099 }
1100 else
1101 {
1102 ti->ti_msgout = cb->msgout[0];
1103 ti->ti_emsgout = cb->msgout[2];
1104 ti->ti_omsgoutlen = cb->msgoutlen;
1105 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
1106 cb->msgoutlen = 0;
1107 }
1108 }
1109
1110 /************************************************
1111 * <DISCONNECT>
1112 ************************************************/
1113 static BS_INLINE void
1114 bs_disconnect_phase(bsc, ti, cb)
1115 struct bs_softc *bsc;
1116 struct targ_info *ti;
1117 struct ccb *cb;
1118 {
1119
1120 switch (bsc->sc_msgphase)
1121 {
1122 default:
1123 panic("%s unknown msg phase\n", bsc->sc_dvname);
1124 break;
1125
1126 case DISCONNECTASSERT:
1127 case FREE:
1128 #ifdef BS_STATICS
1129 bs_statics[ti->ti_id].disconnected++;
1130 #endif /* BS_STATICS */
1131 if (ti->ti_cfgflags & BS_SCSI_SAVESP)
1132 BS_SAVE_SDP;
1133 BS_HOST_TERMINATE;
1134 BS_SETUP_PHASE(DISCONNECTED);
1135 bsc->sc_dtgnum ++;
1136 bshoststart(bsc, NULL);
1137 break;
1138
1139 case IOCOMPLETED:
1140 bs_status_check(bsc, ti);
1141 cb = bscmddone(ti);
1142 #ifdef BS_DIAG
1143 ti->ti_flags &= ~BSNEXUS;
1144 #endif /* BS_DIAG */
1145 BS_SETUP_PHASE(FREE);
1146 if (cb || bsc->sc_sttab.tqh_first == NULL)
1147 {
1148 BS_HOST_TERMINATE;
1149 bscmdstart(ti, BSCMDSTART);
1150 }
1151 else
1152 {
1153 /* give a chance to other target */
1154 bscmdstart(ti, BSCMDSTART);
1155 BS_HOST_TERMINATE;
1156 bshoststart(bsc, NULL);
1157 }
1158 break;
1159 }
1160
1161 BS_SETUP_MSGPHASE(FREE);
1162 }
1163
1164 /**************************************************
1165 * <PHASE ERROR>
1166 **************************************************/
1167 #define scsi_status (bsc->sc_busstat)
1168
1169 struct bs_err {
1170 u_char *pe_msg;
1171 u_int pe_err;
1172 u_int pe_ph;
1173 };
1174
1175 struct bs_err bs_cmderr[] = {
1176 /**/ { "illegal cmd", BSABNORMAL, UNDEF },
1177 /*1*/ { "unexpected bus free", BSABNORMAL, FREE },
1178 /*2*/ { NULL, BSSELTIMEOUT, FREE},
1179 /*3*/ { "scsi bus parity error", BSPARITY, UNDEF },
1180 /*4*/ { "scsi bus parity error", BSPARITY, UNDEF },
1181 /*5*/ { "unknown" , BSFATALIO, UNDEF },
1182 /*6*/ { "miss reselection (target mode)", BSFATALIO, UNDEF },
1183 /*7*/ { "wrong status byte", BSPARITY, STATUSIN },
1184 };
1185
1186 static void
1187 bs_phase_error(ti, cb)
1188 struct targ_info *ti;
1189 struct ccb *cb;
1190 {
1191 struct bs_softc *bsc = ti->ti_bsc;
1192 struct bs_err *pep;
1193
1194 if ((scsi_status & BSR_CM) == BSR_CMDERR &&
1195 (scsi_status & BSR_PHVALID) == 0)
1196 {
1197 pep = &bs_cmderr[scsi_status & BSR_PM];
1198 ti->ti_error |= pep->pe_err;
1199 if (pep->pe_msg)
1200 {
1201 bs_debug_print(bsc, ti);
1202 bs_printf(ti, "bsintr", pep->pe_msg);
1203 }
1204 BS_SETUP_PHASE(pep->pe_ph);
1205 }
1206 else
1207 {
1208 ti->ti_error |= BSABNORMAL;
1209 bs_debug_print(bsc, ti);
1210 bs_printf(ti, "bsintr", "phase error");
1211 BS_SETUP_PHASE(UNDEF);
1212 }
1213
1214 BS_SETUP_MSGPHASE(FREE);
1215 switch (ti->ti_phase)
1216 {
1217 case FREE:
1218 BS_SETUP_PHASE(UNDEF);
1219 cb = bscmddone(ti);
1220 #ifdef BS_DIAG
1221 ti->ti_flags &= ~BSNEXUS;
1222 #endif /* BS_DIAG */
1223 BS_HOST_TERMINATE;
1224 BS_SETUP_PHASE(FREE);
1225 bscmdstart(ti, ((cb == NULL) ? BSCMDSTART : BSCMDRESTART));
1226 break;
1227
1228 case STATUSIN:
1229 ti->ti_error |= BSSTATUSERROR;
1230 ti->ti_status = bshw_get_status_insat(bsc); /* XXX SAT */
1231 bs_debug_print(bsc, ti);
1232 break;
1233
1234 case UNDEF:
1235 default:
1236 ti->ti_error |= BSABNORMAL;
1237 bs_reset_nexus(bsc);
1238 break;
1239 }
1240 }
1241
1242 /**************************************************
1243 * ### SCSI PHASE SEQUENCER ###
1244 **************************************************/
1245 static inline void bs_ack_wait __P((struct bs_softc *, struct targ_info *, struct ccb *));
1246
1247 static inline void
1248 bs_ack_wait(bsc, ti, cb)
1249 struct bs_softc *bsc;
1250 struct targ_info *ti;
1251 struct ccb *cb;
1252 {
1253 int wc = bsc->sc_wc;
1254
1255 for (wc = bsc->sc_wc; bshw_get_busstat(bsc) != BSR_ACKREQ && wc > 0; )
1256 wc --;
1257
1258 if (wc <= 0)
1259 {
1260 bs_printf(ti, "bs_ack_wait", "timeout I");
1261 return;
1262 }
1263
1264 bshw_get_auxstat(bsc);
1265 scsi_status = bshw_get_busstat(bsc);
1266
1267 if (cb->msgoutlen > 0)
1268 {
1269 bshw_assert_atn(bsc);
1270 delay(800);
1271 BS_SETUP_PHASE(ATTENTIONASSERT);
1272 }
1273
1274 bshw_negate_ack(bsc);
1275
1276 #ifdef WAITNEXTP
1277 for (wc = bsc->sc_wc; bshw_get_busstat(bsc) == BSR_ACKREQ && wc > 0; )
1278 wc --;
1279
1280 if (wc <= 0)
1281 bs_printf(ti, "bs_ack_wait", "timeout II");
1282 #endif /* WAITNEXTP */
1283 }
1284
1285 int
1286 bs_sequencer(bsc)
1287 struct bs_softc *bsc;
1288 {
1289 register struct targ_info *ti;
1290 struct ccb *cb;
1291
1292 /**************************************************
1293 * Check reset
1294 **************************************************/
1295 if (bsc->sc_flags & (BSRESET | BSINACTIVE))
1296 {
1297 if (bsc->sc_flags & BSRESET)
1298 bs_reset_nexus(bsc);
1299 return 1;
1300 }
1301
1302 /**************************************************
1303 * Get status & bus phase
1304 **************************************************/
1305 if ((bshw_get_auxstat(bsc) & STR_INT) == 0)
1306 return 0;
1307
1308 scsi_status = bshw_get_busstat(bsc);
1309 if (scsi_status == ((u_int8_t) -1))
1310 {
1311 bs_debug_print_all(bsc);
1312 return 1;
1313 }
1314 /**************************************************
1315 * Check reselection, or nexus
1316 **************************************************/
1317 if (scsi_status == BSR_RESEL)
1318 {
1319 bs_reselect(bsc);
1320 return 1;
1321 }
1322
1323 ti = bsc->sc_nexus;
1324 if (ti == NULL || (cb = ti->ti_ctab.tqh_first) == NULL)
1325 {
1326 bs_debug_print_all(bsc);
1327 bs_printf(ti, "bsintr", "no nexus");
1328 bs_reset_nexus(bsc);
1329 return 1;
1330 }
1331
1332 /**************************************************
1333 * Debug section
1334 **************************************************/
1335 #ifdef BS_DEBUG
1336 if (bs_debug_flag)
1337 {
1338 bs_debug_print(bsc, ti);
1339 if (bs_debug_flag > 1)
1340 Debugger();
1341 }
1342 #endif /* BS_DEBUG */
1343
1344 /**************************************************
1345 * internal scsi phase
1346 **************************************************/
1347 switch (ti->ti_phase)
1348 {
1349 case SELECTASSERT:
1350 bs_selected(bsc, ti, cb);
1351 return 1;
1352
1353 case SATSEL:
1354 BS_SELECTION_TERMINATE;
1355
1356 case SATRESEL:
1357 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
1358 {
1359 if (bsc->sc_flags & BSSMITSTART)
1360 {
1361 bs_debug_print_all(bsc);
1362 bs_reset_nexus(bsc);
1363 bs_printf(ti, "bsintr", "smit transfer");
1364 return 1;
1365 }
1366
1367 BS_SETUP_PHASE(DATAPHASE); /* XXX */
1368 bs_dma_xfer_end(ti);
1369 ti->ti_phase = ti->ti_ophase; /* XXX */
1370 }
1371 break;
1372
1373 default:
1374 /* XXX:
1375 * check check check for safty !!
1376 */
1377 if (bsc->sc_selwait)
1378 {
1379 /* Ghaaa! phase error! retry! */
1380 bs_phase_error(ti, cb);
1381 return 1;
1382 }
1383
1384 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
1385 {
1386 if (bsc->sc_flags & BSDMASTART)
1387 bs_dma_xfer_end(ti);
1388 else
1389 bs_smit_xfer_end(ti);
1390 }
1391 break;
1392 }
1393
1394 /**************************************************
1395 * hw scsi phase
1396 **************************************************/
1397 if (scsi_status & BSR_PHVALID)
1398 {
1399 /**************************************************
1400 * Normal SCSI phase.
1401 **************************************************/
1402 if ((scsi_status & BSR_CM) == BSR_CMDABT)
1403 {
1404 bs_phase_error(ti, cb);
1405 return 1;
1406 }
1407
1408 switch (scsi_status & BSR_PM)
1409 {
1410 case BSR_DATAOUT:
1411 case BSR_DATAIN:
1412 BS_SETUP_PHASE(DATAPHASE);
1413
1414 if (bsc->sc_p.datalen <= 0 ||
1415 (ti->ti_flags & BSFORCEIOPOLL))
1416 {
1417 bs_io_xfer(ti);
1418 return 1;
1419 }
1420
1421 if (bs_check_smit(ti) &&
1422 (bsc->sc_p.datalen % sizeof(u_int32_t)) == 0)
1423 {
1424 bs_lc_smit_xfer(ti, scsi_status & BSR_IOR);
1425 return 1;
1426 }
1427
1428 bs_dma_xfer(ti, scsi_status & BSR_IOR);
1429 bshw_start_xfer(bsc);
1430 return 1;
1431
1432 case BSR_CMDOUT:
1433 bs_commandout(bsc, ti, cb);
1434 return 1;
1435
1436 case BSR_STATIN:
1437 if (bs_check_sat(ti))
1438 {
1439 BS_SETUP_PHASE(SATCOMPSEQ);
1440 bshw_set_count(bsc, 0);
1441 bshw_cmd_pass(bsc, 0x41);
1442 bshw_start_sat(bsc, 0);
1443 }
1444 else
1445 {
1446 BS_SETUP_PHASE(STATUSIN);
1447 ti->ti_status = bs_read_1byte(bsc);
1448 }
1449 return 1;
1450
1451 case BSR_UNSPINFO0:
1452 case BSR_UNSPINFO1:
1453 bs_debug_print(bsc, ti);
1454 bs_printf(ti, "bsintr", "illegal bus phase");
1455 return 1;
1456
1457 case BSR_MSGOUT:
1458 bs_msgout(bsc, ti, cb);
1459 return 1;
1460
1461 case BSR_MSGIN:/* msg in */
1462 if (bs_check_sat(ti))
1463 {
1464 if (ti->ti_phase == RESELECTED)
1465 {
1466 bs_sat_continue(bsc, ti, cb);
1467 return 1;
1468 }
1469 /* XXX */
1470 if (ti->ti_status == ST_UNK)
1471 ti->ti_status = bshw_get_status_insat(bsc);
1472 }
1473
1474 ti->ti_msgin[ti->ti_msginptr ++] = bs_read_1byte(bsc);
1475 bs_msgin(bsc, ti);
1476 if (bsc->sc_cfgflags & BSC_FASTACK)
1477 bs_ack_wait(bsc, ti, cb);
1478
1479 return 1;
1480 }
1481 }
1482 else
1483 {
1484 /**************************************************
1485 * Special SCSI phase
1486 **************************************************/
1487 switch (scsi_status)
1488 {
1489 case BSR_SATSDP:/* SAT with save data pointer */
1490 BS_SAVE_SDP
1491 bshw_cmd_pass(bsc, 0x41);
1492 bshw_start_sat(bsc, 0);
1493 BS_SETUP_PHASE(SATSDP)
1494 return 1;
1495
1496 case BSR_SATFIN:/* SAT COMPLETE */
1497 ti->ti_status = bshw_get_status_insat(bsc);
1498 BS_SETUP_MSGPHASE(IOCOMPLETED);
1499 bs_disconnect_phase(bsc, ti, cb);
1500 return 1;
1501
1502 case BSR_ACKREQ:/* negate ACK */
1503 if (cb->msgoutlen > 0)
1504 {
1505 bshw_assert_atn(bsc);
1506 delay(800);
1507 BS_SETUP_PHASE(ATTENTIONASSERT);
1508 }
1509 bshw_negate_ack(bsc);
1510 return 1;
1511
1512 case BSR_DISC:/* disconnect */
1513 bs_disconnect_phase(bsc, ti, cb);
1514 return 1;
1515
1516 default:
1517 break;
1518 }
1519 }
1520
1521 bs_phase_error(ti, cb);
1522 return 1;
1523 }
1524
1525 /*****************************************************************
1526 * INTERNAL POLLING FUNCTIONS
1527 *****************************************************************/
1528 static int
1529 bs_scsi_cmd_poll_internal(cti)
1530 struct targ_info *cti;
1531 {
1532 struct bs_softc *bsc = cti->ti_bsc;
1533 struct targ_info *ti;
1534 struct ccb *cb;
1535 int i, waits, delay_count;
1536
1537 bsc->sc_poll++;
1538
1539 /* setup timeout count */
1540 if ((ti = bsc->sc_nexus) == NULL ||
1541 (cb = ti->ti_ctab.tqh_first) == NULL)
1542 waits = BS_DEFAULT_TIMEOUT_SECOND * 1000000;
1543 else
1544 waits = cb->tcmax * 1000000;
1545
1546 /* force all current jobs into the polling state. */
1547 for (i = 0; i < NTARGETS; i++)
1548 {
1549 if ((ti = bsc->sc_ti[i]) != NULL)
1550 {
1551 ti->ti_flags |= BSFORCEIOPOLL;
1552 if ((cb = ti->ti_ctab.tqh_first) != NULL)
1553 cb->flags |= BSFORCEIOPOLL;
1554 }
1555 }
1556
1557 /* do io */
1558 bsc->sc_flags &= ~BSJOBDONE;
1559 do
1560 {
1561 delay_count = ((bsc->sc_flags & BSDMASTART) ? 1000000 : 100);
1562 delay(delay_count);
1563 waits -= delay_count;
1564 bs_sequencer(bsc);
1565 }
1566 while (waits >= 0 && (bsc->sc_flags & (BSUNDERRESET | BSJOBDONE)) == 0);
1567
1568 /* done */
1569 bsc->sc_poll--;
1570 if (waits < 0 || (bsc->sc_flags & BSUNDERRESET))
1571 {
1572 bs_printf(NULL, "cmd_poll", "timeout or fatal");
1573 return HASERROR;
1574 }
1575
1576 return COMPLETE;
1577 }
1578
1579 int
1580 bs_scsi_cmd_poll(cti, targetcb)
1581 struct targ_info *cti;
1582 struct ccb *targetcb;
1583 {
1584 struct bs_softc *bsc = cti->ti_bsc;
1585 struct targ_info *ti;
1586 int s, error = COMPLETE;
1587
1588 s = splbio();
1589 bs_terminate_timeout(bsc);
1590
1591 if (bsc->sc_hstate == BSC_TARG_CHECK)
1592 {
1593 if ((error = bs_scsi_cmd_poll_internal(cti)) != COMPLETE)
1594 bs_reset_nexus(bsc);
1595 }
1596 else
1597 {
1598 if (bsc->sc_outccb)
1599 bs_panic(bsc, "bs_cmd_poll: internal error");
1600
1601 bsc->sc_flags &= ~BSPOLLDONE;
1602 bsc->sc_outccb = targetcb;
1603
1604 while ((bsc->sc_flags & BSPOLLDONE) == 0)
1605 {
1606 if (bs_scsi_cmd_poll_internal(cti) != COMPLETE)
1607 {
1608 if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)
1609 ti->ti_error |= (BSTIMEOUT | BSABNORMAL);
1610 bs_reset_nexus(bsc);
1611 }
1612 }
1613
1614 bsc->sc_outccb = NULL;
1615 }
1616
1617 bs_start_timeout(bsc);
1618 softintr(bsc->sc_irq);
1619 splx(s);
1620 return error;
1621 }
Cache object: daa30d6369be69ab91bb4cf5700ab5f5
|