This source file includes following definitions.
- bha_enqueue
- bha_dequeue
- bha_cmd
- bha_attach
- bha_finish_ccbs
- bha_intr
- bha_reset_ccb
- bha_free_ccb
- bha_init_ccb
- bha_create_ccbs
- bha_get_ccb
- bha_ccb_phys_kv
- bha_queue_ccb
- bha_collect_mbo
- bha_start_ccbs
- bha_done
- bha_find
- bha_disable_isacompat
- bha_init
- bha_inquire_setup_information
- bhaminphys
- bha_scsi_cmd
- bha_poll
- bha_timeout
1
2
3
4 #undef BHADEBUG
5 #ifdef DDB
6 #define integrate
7 #else
8 #define integrate static inline
9 #endif
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 #include <sys/types.h>
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/kernel.h>
67 #include <sys/errno.h>
68 #include <sys/ioctl.h>
69 #include <sys/device.h>
70 #include <sys/malloc.h>
71 #include <sys/buf.h>
72 #include <sys/proc.h>
73 #include <sys/user.h>
74
75 #include <machine/bus.h>
76 #include <machine/intr.h>
77
78 #include <scsi/scsi_all.h>
79 #include <scsi/scsiconf.h>
80
81 #include <dev/ic/bhareg.h>
82 #include <dev/ic/bhavar.h>
83
84 #ifndef DDB
85 #define Debugger() panic("should call debugger here (bha.c)")
86 #endif
87
88 #define BHA_MAXXFER ((BHA_NSEG - 1) << PGSHIFT)
89 #define ISWIDE(sc) ((sc)->sc_iswide)
90
91 #ifdef BHADEBUG
92 int bha_debug = 1;
93 #endif
94
95 integrate void bha_finish_ccbs(struct bha_softc *);
96 integrate void bha_reset_ccb(struct bha_softc *, struct bha_ccb *);
97 void bha_free_ccb(struct bha_softc *, struct bha_ccb *);
98 integrate int bha_init_ccb(struct bha_softc *, struct bha_ccb *);
99 struct bha_ccb *bha_get_ccb(struct bha_softc *, int);
100 struct bha_ccb *bha_ccb_phys_kv(struct bha_softc *, u_long);
101 void bha_queue_ccb(struct bha_softc *, struct bha_ccb *);
102 void bha_collect_mbo(struct bha_softc *);
103 void bha_start_ccbs(struct bha_softc *);
104 void bha_done(struct bha_softc *, struct bha_ccb *);
105 int bha_init(struct bha_softc *);
106 void bhaminphys(struct buf *);
107 int bha_scsi_cmd(struct scsi_xfer *);
108 int bha_poll(struct bha_softc *, struct scsi_xfer *, int);
109 void bha_timeout(void *arg);
110 int bha_create_ccbs(struct bha_softc *, struct bha_ccb *, int);
111 void bha_enqueue(struct bha_softc *, struct scsi_xfer *, int);
112 struct scsi_xfer *bha_dequeue(struct bha_softc *);
113
114 struct cfdriver bha_cd = {
115 NULL, "bha", DV_DULL
116 };
117
118
119 struct scsi_device bha_dev = {
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 };
125
126 #define BHA_RESET_TIMEOUT 2000
127 #define BHA_ABORT_TIMEOUT 2000
128
129
130
131
132
133
134 void
135 bha_enqueue(sc, xs, infront)
136 struct bha_softc *sc;
137 struct scsi_xfer *xs;
138 int infront;
139 {
140
141 if (infront || LIST_EMPTY(&sc->sc_queue)) {
142 if (LIST_EMPTY(&sc->sc_queue))
143 sc->sc_queuelast = xs;
144 LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
145 return;
146 }
147
148 LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
149 sc->sc_queuelast = xs;
150 }
151
152
153
154
155 struct scsi_xfer *
156 bha_dequeue(sc)
157 struct bha_softc *sc;
158 {
159 struct scsi_xfer *xs;
160
161 xs = LIST_FIRST(&sc->sc_queue);
162 LIST_REMOVE(xs, free_list);
163
164 if (LIST_EMPTY(&sc->sc_queue))
165 sc->sc_queuelast = NULL;
166
167 return (xs);
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 int
185 bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
186 bus_space_tag_t iot;
187 bus_space_handle_t ioh;
188 struct bha_softc *sc;
189 int icnt, ocnt;
190 u_char *ibuf, *obuf;
191 {
192 const char *name;
193 register int i;
194 int wait;
195 u_char sts;
196 u_char opcode = ibuf[0];
197
198 if (sc != NULL)
199 name = sc->sc_dev.dv_xname;
200 else
201 name = "(bha probe)";
202
203
204
205
206 switch (opcode) {
207 case BHA_INQUIRE_DEVICES:
208 case BHA_INQUIRE_DEVICES_2:
209 wait = 90 * 20000;
210 break;
211 default:
212 wait = 1 * 20000;
213 break;
214 }
215
216
217
218
219
220 if (opcode != BHA_MBO_INTR_EN) {
221 for (i = 20000; i; i--) {
222 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
223 if (sts & BHA_STAT_IDLE)
224 break;
225 delay(50);
226 }
227 if (!i) {
228 printf("%s: bha_cmd, host not idle(0x%x)\n",
229 name, sts);
230 return (1);
231 }
232 }
233
234
235
236
237 if (ocnt) {
238 while ((bus_space_read_1(iot, ioh, BHA_STAT_PORT)) &
239 BHA_STAT_DF)
240 bus_space_read_1(iot, ioh, BHA_DATA_PORT);
241 }
242
243
244
245
246 while (icnt--) {
247 for (i = wait; i; i--) {
248 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
249 if (!(sts & BHA_STAT_CDF))
250 break;
251 delay(50);
252 }
253 if (!i) {
254 if (opcode != BHA_INQUIRE_REVISION)
255 printf("%s: bha_cmd, cmd/data port full\n",
256 name);
257 goto bad;
258 }
259 bus_space_write_1(iot, ioh, BHA_CMD_PORT, *ibuf++);
260 }
261
262
263
264
265 while (ocnt--) {
266 for (i = wait; i; i--) {
267 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
268 if (sts & BHA_STAT_DF)
269 break;
270 delay(50);
271 }
272 if (!i) {
273 if (opcode != BHA_INQUIRE_REVISION)
274 printf("%s: bha_cmd, cmd/data port empty %d\n",
275 name, ocnt);
276 goto bad;
277 }
278 *obuf++ = bus_space_read_1(iot, ioh, BHA_DATA_PORT);
279 }
280
281
282
283
284
285 if (opcode != BHA_MBO_INTR_EN && opcode != BHA_MODIFY_IOPORT) {
286 for (i = 20000; i; i--) {
287 sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
288
289 if (sts & BHA_INTR_HACC)
290 break;
291 delay(50);
292 }
293 if (!i) {
294 printf("%s: bha_cmd, host not finished(0x%x)\n",
295 name, sts);
296 return (1);
297 }
298 }
299 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
300 return (0);
301
302 bad:
303 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_SRST);
304 return (1);
305 }
306
307
308
309
310 void
311 bha_attach(sc, bpd)
312 struct bha_softc *sc;
313 struct bha_probe_data *bpd;
314 {
315 struct scsibus_attach_args saa;
316 int s;
317
318
319
320
321 sc->sc_adapter.scsi_cmd = bha_scsi_cmd;
322 sc->sc_adapter.scsi_minphys = bhaminphys;
323
324
325
326
327 sc->sc_link.adapter_softc = sc;
328 sc->sc_link.adapter_target = bpd->sc_scsi_dev;
329 sc->sc_link.adapter = &sc->sc_adapter;
330 sc->sc_link.device = &bha_dev;
331 sc->sc_link.openings = 4;
332
333 TAILQ_INIT(&sc->sc_free_ccb);
334 TAILQ_INIT(&sc->sc_waiting_ccb);
335 LIST_INIT(&sc->sc_queue);
336
337 s = splbio();
338 bha_inquire_setup_information(sc);
339
340 printf("%s: model BT-%s, firmware %s\n", sc->sc_dev.dv_xname,
341 sc->sc_model, sc->sc_firmware);
342
343 if (bha_init(sc) != 0) {
344
345 splx(s);
346 return;
347 }
348
349 splx(s);
350
351 bzero(&saa, sizeof(saa));
352 saa.saa_sc_link = &sc->sc_link;
353
354
355
356
357 config_found(&sc->sc_dev, &saa, scsiprint);
358 }
359
360 integrate void
361 bha_finish_ccbs(sc)
362 struct bha_softc *sc;
363 {
364 struct bha_mbx_in *wmbi;
365 struct bha_ccb *ccb;
366 int i;
367
368 wmbi = wmbx->tmbi;
369
370 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
371 0, sc->sc_dmamap_control->dm_mapsize,
372 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
373
374 if (wmbi->comp_stat == BHA_MBI_FREE) {
375 for (i = 0; i < BHA_MBX_SIZE; i++) {
376 if (wmbi->comp_stat != BHA_MBI_FREE) {
377 printf("%s: mbi not in round-robin order\n",
378 sc->sc_dev.dv_xname);
379 goto AGAIN;
380 }
381 bha_nextmbx(wmbi, wmbx, mbi);
382 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
383 0, sc->sc_dmamap_control->dm_mapsize,
384 BUS_DMASYNC_POSTREAD);
385 }
386 #ifdef BHADIAGnot
387 printf("%s: mbi interrupt with no full mailboxes\n",
388 sc->sc_dev.dv_xname);
389 #endif
390 return;
391 }
392
393 AGAIN:
394 do {
395 ccb = bha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
396 if (!ccb) {
397 printf("%s: bad mbi ccb pointer; skipping\n",
398 sc->sc_dev.dv_xname);
399 goto next;
400 }
401
402 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
403 0, sc->sc_dmamap_control->dm_mapsize,
404 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
405
406 #ifdef BHADEBUG
407 if (bha_debug) {
408 u_int8_t *cp = ccb->scsi_cmd.bytes;
409 printf("op=%x %x %x %x %x %x\n",
410 ccb->scsi_cmd.opcode,
411 cp[0], cp[1], cp[2], cp[3], cp[4]);
412 printf("stat %x for mbi addr = 0x%08x, ",
413 wmbi->comp_stat, wmbi);
414 printf("ccb addr = 0x%x\n", ccb);
415 }
416 #endif
417
418 switch (wmbi->comp_stat) {
419 case BHA_MBI_OK:
420 case BHA_MBI_ERROR:
421 if ((ccb->flags & CCB_ABORT) != 0) {
422
423
424
425
426
427
428
429
430 goto next;
431 }
432 break;
433
434 case BHA_MBI_ABORT:
435 case BHA_MBI_UNKNOWN:
436
437
438
439
440 break;
441
442 default:
443 printf("%s: bad mbi status %02x; skipping\n",
444 sc->sc_dev.dv_xname, wmbi->comp_stat);
445 goto next;
446 }
447
448 timeout_del(&ccb->xs->stimeout);
449 bha_done(sc, ccb);
450
451 next:
452 wmbi->comp_stat = BHA_MBI_FREE;
453 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
454 0, sc->sc_dmamap_control->dm_mapsize,
455 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
456 bha_nextmbx(wmbi, wmbx, mbi);
457 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
458 0, sc->sc_dmamap_control->dm_mapsize,
459 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
460 } while (wmbi->comp_stat != BHA_MBI_FREE);
461
462 wmbx->tmbi = wmbi;
463 }
464
465
466
467
468 int
469 bha_intr(arg)
470 void *arg;
471 {
472 struct bha_softc *sc = arg;
473 bus_space_tag_t iot = sc->sc_iot;
474 bus_space_handle_t ioh = sc->sc_ioh;
475 u_char sts;
476
477 #ifdef BHADEBUG
478 printf("%s: bha_intr ", sc->sc_dev.dv_xname);
479 #endif
480
481
482
483
484
485 sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
486 if ((sts & BHA_INTR_ANYINTR) == 0)
487 return (0);
488 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
489
490 #ifdef BHADIAG
491
492 bha_collect_mbo(sc);
493 #endif
494
495
496 if (sts & BHA_INTR_MBOA) {
497 struct bha_toggle toggle;
498
499 toggle.cmd.opcode = BHA_MBO_INTR_EN;
500 toggle.cmd.enable = 0;
501 bha_cmd(iot, ioh, sc,
502 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
503 0, (u_char *)0);
504 bha_start_ccbs(sc);
505 }
506
507
508 if (sts & BHA_INTR_MBIF)
509 bha_finish_ccbs(sc);
510
511 return (1);
512 }
513
514 integrate void
515 bha_reset_ccb(sc, ccb)
516 struct bha_softc *sc;
517 struct bha_ccb *ccb;
518 {
519
520 ccb->flags = 0;
521 }
522
523
524
525
526 void
527 bha_free_ccb(sc, ccb)
528 struct bha_softc *sc;
529 struct bha_ccb *ccb;
530 {
531 int s;
532
533 s = splbio();
534
535 bha_reset_ccb(sc, ccb);
536 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
537
538
539
540
541
542 if (TAILQ_NEXT(ccb, chain) == NULL)
543 wakeup(&sc->sc_free_ccb);
544
545 splx(s);
546 }
547
548 integrate int
549 bha_init_ccb(sc, ccb)
550 struct bha_softc *sc;
551 struct bha_ccb *ccb;
552 {
553 bus_dma_tag_t dmat = sc->sc_dmat;
554 int hashnum, error;
555
556
557
558
559 error = bus_dmamap_create(dmat, BHA_MAXXFER, BHA_NSEG, BHA_MAXXFER,
560 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
561 &ccb->dmamap_xfer);
562 if (error) {
563 printf("%s: unable to create ccb DMA map, error = %d\n",
564 sc->sc_dev.dv_xname, error);
565 return (error);
566 }
567
568
569
570
571
572 ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr +
573 BHA_CCB_OFF(ccb);
574 hashnum = CCB_HASH(ccb->hashkey);
575 ccb->nexthash = sc->sc_ccbhash[hashnum];
576 sc->sc_ccbhash[hashnum] = ccb;
577 bha_reset_ccb(sc, ccb);
578 return (0);
579 }
580
581
582
583
584
585 int
586 bha_create_ccbs(sc, ccbstore, count)
587 struct bha_softc *sc;
588 struct bha_ccb *ccbstore;
589 int count;
590 {
591 struct bha_ccb *ccb;
592 int i, error;
593
594 bzero(ccbstore, sizeof(struct bha_ccb) * count);
595 for (i = 0; i < count; i++) {
596 ccb = &ccbstore[i];
597 if ((error = bha_init_ccb(sc, ccb)) != 0) {
598 printf("%s: unable to initialize ccb, error = %d\n",
599 sc->sc_dev.dv_xname, error);
600 goto out;
601 }
602 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
603 }
604 out:
605 return (i);
606 }
607
608
609
610
611
612
613
614 struct bha_ccb *
615 bha_get_ccb(sc, flags)
616 struct bha_softc *sc;
617 int flags;
618 {
619 struct bha_ccb *ccb;
620 int s;
621
622 s = splbio();
623
624
625
626
627
628 for (;;) {
629 ccb = TAILQ_FIRST(&sc->sc_free_ccb);
630 if (ccb) {
631 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
632 break;
633 }
634 if ((flags & SCSI_NOSLEEP) != 0)
635 goto out;
636 tsleep(&sc->sc_free_ccb, PRIBIO, "bhaccb", 0);
637 }
638
639 ccb->flags |= CCB_ALLOC;
640
641 out:
642 splx(s);
643 return (ccb);
644 }
645
646
647
648
649 struct bha_ccb *
650 bha_ccb_phys_kv(sc, ccb_phys)
651 struct bha_softc *sc;
652 u_long ccb_phys;
653 {
654 int hashnum = CCB_HASH(ccb_phys);
655 struct bha_ccb *ccb = sc->sc_ccbhash[hashnum];
656
657 while (ccb) {
658 if (ccb->hashkey == ccb_phys)
659 break;
660 ccb = ccb->nexthash;
661 }
662 return (ccb);
663 }
664
665
666
667
668 void
669 bha_queue_ccb(sc, ccb)
670 struct bha_softc *sc;
671 struct bha_ccb *ccb;
672 {
673
674 timeout_set(&ccb->xs->stimeout, bha_timeout, ccb);
675 TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
676 bha_start_ccbs(sc);
677 }
678
679
680
681
682 void
683 bha_collect_mbo(sc)
684 struct bha_softc *sc;
685 {
686 struct bha_mbx_out *wmbo;
687 #ifdef BHADIAG
688 struct bha_ccb *ccb;
689 #endif
690
691 wmbo = wmbx->cmbo;
692
693 while (sc->sc_mbofull > 0) {
694 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
695 0, sc->sc_dmamap_control->dm_mapsize,
696 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
697 if (wmbo->cmd != BHA_MBO_FREE)
698 break;
699
700 #ifdef BHADIAG
701 ccb = bha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
702 ccb->flags &= ~CCB_SENDING;
703 #endif
704
705 --sc->sc_mbofull;
706 bha_nextmbx(wmbo, wmbx, mbo);
707 }
708
709 wmbx->cmbo = wmbo;
710 }
711
712
713
714
715 void
716 bha_start_ccbs(sc)
717 struct bha_softc *sc;
718 {
719 bus_space_tag_t iot = sc->sc_iot;
720 bus_space_handle_t ioh = sc->sc_ioh;
721 struct bha_mbx_out *wmbo;
722 struct bha_ccb *ccb;
723 struct scsi_xfer *xs;
724
725 wmbo = wmbx->tmbo;
726
727 while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
728
729 xs = ccb->xs;
730 if (sc->sc_mbofull >= BHA_MBX_SIZE) {
731 bha_collect_mbo(sc);
732 if (sc->sc_mbofull >= BHA_MBX_SIZE) {
733 struct bha_toggle toggle;
734
735 toggle.cmd.opcode = BHA_MBO_INTR_EN;
736 toggle.cmd.enable = 1;
737 bha_cmd(iot, ioh, sc,
738 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
739 0, (u_char *)0);
740 break;
741 }
742 }
743
744 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
745 #ifdef BHADIAG
746 ccb->flags |= CCB_SENDING;
747 #endif
748
749
750 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
751 BHA_CCB_OFF(ccb), wmbo->ccb_addr);
752 if (ccb->flags & CCB_ABORT)
753 wmbo->cmd = BHA_MBO_ABORT;
754 else
755 wmbo->cmd = BHA_MBO_START;
756
757 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
758 0, sc->sc_dmamap_control->dm_mapsize,
759 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
760
761
762 bus_space_write_1(iot, ioh, BHA_CMD_PORT, BHA_START_SCSI);
763
764 if ((xs->flags & SCSI_POLL) == 0)
765 timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
766
767 ++sc->sc_mbofull;
768 bha_nextmbx(wmbo, wmbx, mbo);
769 }
770
771 wmbx->tmbo = wmbo;
772 }
773
774
775
776
777
778
779 void
780 bha_done(sc, ccb)
781 struct bha_softc *sc;
782 struct bha_ccb *ccb;
783 {
784 bus_dma_tag_t dmat = sc->sc_dmat;
785 struct scsi_sense_data *s1, *s2;
786 struct scsi_xfer *xs = ccb->xs;
787
788 SC_DEBUG(xs->sc_link, SDEV_DB2, ("bha_done\n"));
789
790
791
792
793
794 if (xs->datalen) {
795 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
796 0, ccb->dmamap_xfer->dm_mapsize,
797 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
798 BUS_DMASYNC_POSTWRITE);
799 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
800 }
801
802
803
804
805
806 #ifdef BHADIAG
807 if (ccb->flags & CCB_SENDING) {
808 printf("%s: exiting ccb still in transit!\n",
809 sc->sc_dev.dv_xname);
810 Debugger();
811 return;
812 }
813 #endif
814 if ((ccb->flags & CCB_ALLOC) == 0) {
815 printf("%s: exiting ccb not allocated!\n",
816 sc->sc_dev.dv_xname);
817 Debugger();
818 return;
819 }
820 if (xs->error == XS_NOERROR) {
821 if (ccb->host_stat != BHA_OK) {
822 switch (ccb->host_stat) {
823 case BHA_SEL_TIMEOUT:
824 xs->error = XS_SELTIMEOUT;
825 break;
826 default:
827 printf("%s: host_stat %x\n",
828 sc->sc_dev.dv_xname, ccb->host_stat);
829 xs->error = XS_DRIVER_STUFFUP;
830 break;
831 }
832 } else if (ccb->target_stat != SCSI_OK) {
833 switch (ccb->target_stat) {
834 case SCSI_CHECK:
835 s1 = &ccb->scsi_sense;
836 s2 = &xs->sense;
837 *s2 = *s1;
838 xs->error = XS_SENSE;
839 break;
840 case SCSI_BUSY:
841 xs->error = XS_BUSY;
842 break;
843 default:
844 printf("%s: target_stat %x\n",
845 sc->sc_dev.dv_xname, ccb->target_stat);
846 xs->error = XS_DRIVER_STUFFUP;
847 break;
848 }
849 } else
850 xs->resid = 0;
851 }
852 bha_free_ccb(sc, ccb);
853 xs->flags |= ITSDONE;
854 scsi_done(xs);
855
856
857
858
859
860
861
862
863
864 if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
865 (void) bha_scsi_cmd(xs);
866 }
867
868
869
870
871 int
872 bha_find(iot, ioh, sc)
873 bus_space_tag_t iot;
874 bus_space_handle_t ioh;
875 struct bha_probe_data *sc;
876 {
877 int i, iswide;
878 u_char sts;
879 struct bha_extended_inquire inquire;
880 struct bha_config config;
881 int irq, drq;
882
883
884 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
885 if (sts == 0xFF) {
886 #ifdef BHADEBUG
887 if (bha_debug)
888 printf("bha_find: Not present\n");
889 #endif
890 return (0);
891 }
892
893
894
895
896
897
898 bus_space_write_1(iot, ioh, BHA_CTRL_PORT,
899 BHA_CTRL_HRST | BHA_CTRL_SRST);
900
901 for (i = BHA_RESET_TIMEOUT; i--;) {
902 delay(100);
903 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
904 if (sts == (BHA_STAT_IDLE | BHA_STAT_INIT))
905 break;
906 }
907 if (i < 0) {
908 #ifdef BHADEBUG
909 if (bha_debug)
910 printf("bha_find: No answer from board a=%x sts=%b\n",
911 ioh, sts, BHA_STAT_BITS);
912 #endif
913 return (0);
914 }
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930 sts = bus_space_read_1(iot, ioh, BHA_EXTGEOM_PORT);
931 if (sts == 0xFF)
932 return (0);
933
934
935
936
937 delay(1000);
938 inquire.cmd.opcode = BHA_INQUIRE_EXTENDED;
939 inquire.cmd.len = sizeof(inquire.reply);
940 i = bha_cmd(iot, ioh, NULL,
941 sizeof(inquire.cmd), (u_char *)&inquire.cmd,
942 sizeof(inquire.reply), (u_char *)&inquire.reply);
943
944
945
946
947
948
949
950 if (i) {
951 #ifdef BHADEBUG
952 printf("bha_find: board returned %d instead of %d to %s\n",
953 i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
954 #endif
955 return (0);
956 }
957
958
959
960 switch (inquire.reply.bus_type) {
961 case BHA_BUS_TYPE_24BIT:
962 case BHA_BUS_TYPE_32BIT:
963 break;
964 case BHA_BUS_TYPE_MCA:
965
966 return (0);
967 default:
968 printf("bha_find: illegal bus type %c\n",
969 inquire.reply.bus_type);
970 return (0);
971 }
972
973
974 iswide = inquire.reply.scsi_flags & BHA_SCSI_WIDE;
975
976
977
978
979
980 delay(1000);
981 config.cmd.opcode = BHA_INQUIRE_CONFIG;
982 bha_cmd(iot, ioh, NULL,
983 sizeof(config.cmd), (u_char *)&config.cmd,
984 sizeof(config.reply), (u_char *)&config.reply);
985 switch (config.reply.chan) {
986 case EISADMA:
987 drq = -1;
988 break;
989 case CHAN0:
990 drq = 0;
991 break;
992 case CHAN5:
993 drq = 5;
994 break;
995 case CHAN6:
996 drq = 6;
997 break;
998 case CHAN7:
999 drq = 7;
1000 break;
1001 default:
1002 printf("bha_find: illegal drq setting %x\n",
1003 config.reply.chan);
1004 return (0);
1005 }
1006
1007 switch (config.reply.intr) {
1008 case INT9:
1009 irq = 9;
1010 break;
1011 case INT10:
1012 irq = 10;
1013 break;
1014 case INT11:
1015 irq = 11;
1016 break;
1017 case INT12:
1018 irq = 12;
1019 break;
1020 case INT14:
1021 irq = 14;
1022 break;
1023 case INT15:
1024 irq = 15;
1025 break;
1026 default:
1027 printf("bha_find: illegal irq setting %x\n",
1028 config.reply.intr);
1029 return (0);
1030 }
1031
1032
1033 if (sc != NULL) {
1034 sc->sc_irq = irq;
1035 sc->sc_drq = drq;
1036 sc->sc_scsi_dev = config.reply.scsi_dev;
1037 sc->sc_iswide = iswide;
1038 }
1039
1040 return (1);
1041 }
1042
1043
1044
1045
1046
1047
1048 int
1049 bha_disable_isacompat(sc)
1050 struct bha_softc *sc;
1051 {
1052 struct bha_isadisable isa_disable;
1053
1054 isa_disable.cmd.opcode = BHA_MODIFY_IOPORT;
1055 isa_disable.cmd.modifier = BHA_IOMODIFY_DISABLE1;
1056 bha_cmd(sc->sc_iot, sc->sc_ioh, sc,
1057 sizeof(isa_disable.cmd), (u_char *)&isa_disable.cmd,
1058 0, (u_char *)0);
1059 return (0);
1060 }
1061
1062
1063
1064
1065
1066 int
1067 bha_init(sc)
1068 struct bha_softc *sc;
1069 {
1070 bus_space_tag_t iot = sc->sc_iot;
1071 bus_space_handle_t ioh = sc->sc_ioh;
1072 bus_dma_segment_t seg;
1073 struct bha_devices devices;
1074 struct bha_setup setup;
1075 struct bha_mailbox mailbox;
1076 struct bha_period period;
1077 int error, i, j, initial_ccbs, rlen, rseg;
1078
1079
1080 if (strcmp(sc->sc_firmware, "3.31") >= 0) {
1081 struct bha_toggle toggle;
1082
1083 toggle.cmd.opcode = BHA_ROUND_ROBIN;
1084 toggle.cmd.enable = 1;
1085 bha_cmd(iot, ioh, sc,
1086 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
1087 0, (u_char *)0);
1088 }
1089
1090
1091
1092
1093
1094
1095
1096
1097 devices.cmd.opcode = BHA_INQUIRE_DEVICES;
1098 bha_cmd(iot, ioh, sc,
1099 sizeof(devices.cmd), (u_char *)&devices.cmd,
1100 sizeof(devices.reply), (u_char *)&devices.reply);
1101
1102
1103 initial_ccbs = 0;
1104 for (i = 0; i < 8; i++) {
1105 for (j = 0; j < 8; j++) {
1106 if (((devices.reply.lun_map[i] >> j) & 1) == 1)
1107 initial_ccbs++;
1108 }
1109 }
1110
1111
1112
1113
1114 if (ISWIDE(sc)) {
1115 devices.cmd.opcode = BHA_INQUIRE_DEVICES_2;
1116 bha_cmd(iot, ioh, sc,
1117 sizeof(devices.cmd), (u_char *)&devices.cmd,
1118 sizeof(devices.reply), (u_char *)&devices.reply);
1119
1120 for (i = 0; i < 8; i++) {
1121 for (j = 0; j < 8; j++) {
1122 if (((devices.reply.lun_map[i] >> j) & 1) == 1)
1123 initial_ccbs++;
1124 }
1125 }
1126 }
1127
1128 initial_ccbs *= sc->sc_link.openings;
1129 if (initial_ccbs > BHA_CCB_MAX)
1130 initial_ccbs = BHA_CCB_MAX;
1131 if (initial_ccbs == 0)
1132 initial_ccbs = sc->sc_link.openings;
1133
1134
1135 rlen = sizeof(setup.reply) +
1136 (ISWIDE(sc) ? sizeof(setup.reply_w) : 0);
1137 setup.cmd.opcode = BHA_INQUIRE_SETUP;
1138 setup.cmd.len = rlen;
1139 bha_cmd(iot, ioh, sc,
1140 sizeof(setup.cmd), (u_char *)&setup.cmd,
1141 rlen, (u_char *)&setup.reply);
1142
1143 printf("%s: %s, %s\n", sc->sc_dev.dv_xname,
1144 setup.reply.sync_neg ? "sync" : "async",
1145 setup.reply.parity ? "parity" : "no parity");
1146
1147 for (i = 0; i < 8; i++)
1148 period.reply.period[i] = setup.reply.sync[i].period * 5 + 20;
1149 if (ISWIDE(sc)) {
1150 for (i = 0; i < 8; i++)
1151 period.reply_w.period[i] =
1152 setup.reply_w.sync_high[i].period * 5 + 20;
1153 }
1154
1155 if (sc->sc_firmware[0] >= '3') {
1156 rlen = sizeof(period.reply) +
1157 (ISWIDE(sc) ? sizeof(period.reply_w) : 0);
1158 period.cmd.opcode = BHA_INQUIRE_PERIOD;
1159 period.cmd.len = sizeof(period.reply);
1160 bha_cmd(iot, ioh, sc,
1161 sizeof(period.cmd), (u_char *)&period.cmd,
1162 rlen, (u_char *)&period.reply);
1163 }
1164
1165 for (i = 0; i < 8; i++) {
1166 if (!setup.reply.sync[i].valid ||
1167 (!setup.reply.sync[i].offset &&
1168 !setup.reply.sync[i].period))
1169 continue;
1170 printf("%s targ %d: sync, offset %d, period %dnsec\n",
1171 sc->sc_dev.dv_xname, i,
1172 setup.reply.sync[i].offset, period.reply.period[i] * 10);
1173 }
1174 if (ISWIDE(sc)) {
1175 for (i = 0; i < 8; i++) {
1176 if (!setup.reply_w.sync_high[i].valid ||
1177 (!setup.reply_w.sync_high[i].offset &&
1178 !setup.reply_w.sync_high[i].period))
1179 continue;
1180 printf("%s targ %d: sync, offset %d, period %dnsec\n",
1181 sc->sc_dev.dv_xname, i + 8,
1182 setup.reply_w.sync_high[i].offset,
1183 period.reply_w.period[i] * 10);
1184 }
1185 }
1186
1187
1188
1189
1190 if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct bha_control),
1191 NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
1192 printf("%s: unable to allocate control structures, "
1193 "error = %d\n", sc->sc_dev.dv_xname, error);
1194 return (error);
1195 }
1196 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
1197 sizeof(struct bha_control), (caddr_t *)&sc->sc_control,
1198 BUS_DMA_NOWAIT)) != 0) {
1199 printf("%s: unable to map control structures, error = %d\n",
1200 sc->sc_dev.dv_xname, error);
1201 return (error);
1202 }
1203
1204
1205
1206
1207
1208 if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct bha_control),
1209 1, sizeof(struct bha_control), 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
1210 &sc->sc_dmamap_control)) != 0) {
1211 printf("%s: unable to create control DMA map, error = %d\n",
1212 sc->sc_dev.dv_xname, error);
1213 return (error);
1214 }
1215 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
1216 sc->sc_control, sizeof(struct bha_control), NULL,
1217 BUS_DMA_NOWAIT)) != 0) {
1218 printf("%s: unable to load control DMA map, error = %d\n",
1219 sc->sc_dev.dv_xname, error);
1220 return (error);
1221 }
1222
1223
1224
1225
1226 i = bha_create_ccbs(sc, sc->sc_control->bc_ccbs, initial_ccbs);
1227 if (i == 0) {
1228 printf("%s: unable to create control blocks\n",
1229 sc->sc_dev.dv_xname);
1230 return (ENOMEM);
1231 } else if (i != initial_ccbs) {
1232 printf("%s: WARNING: only %d of %d control blocks created\n",
1233 sc->sc_dev.dv_xname, i, initial_ccbs);
1234 }
1235
1236
1237
1238
1239 for (i = 0; i < BHA_MBX_SIZE; i++) {
1240 wmbx->mbo[i].cmd = BHA_MBO_FREE;
1241 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1242 0, sc->sc_dmamap_control->dm_mapsize,
1243 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1244 wmbx->mbi[i].comp_stat = BHA_MBI_FREE;
1245 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1246 0, sc->sc_dmamap_control->dm_mapsize,
1247 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1248 }
1249 wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
1250 wmbx->tmbi = &wmbx->mbi[0];
1251 sc->sc_mbofull = 0;
1252
1253
1254 mailbox.cmd.opcode = BHA_MBX_INIT_EXTENDED;
1255 mailbox.cmd.nmbx = BHA_MBX_SIZE;
1256 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1257 offsetof(struct bha_control, bc_mbx), mailbox.cmd.addr);
1258 bha_cmd(iot, ioh, sc,
1259 sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
1260 0, (u_char *)0);
1261 return (0);
1262 }
1263
1264 void
1265 bha_inquire_setup_information(sc)
1266 struct bha_softc *sc;
1267 {
1268 bus_space_tag_t iot = sc->sc_iot;
1269 bus_space_handle_t ioh = sc->sc_ioh;
1270 struct bha_model model;
1271 struct bha_revision revision;
1272 struct bha_digit digit;
1273 char *p;
1274
1275
1276
1277
1278 p = sc->sc_firmware;
1279 revision.cmd.opcode = BHA_INQUIRE_REVISION;
1280 bha_cmd(iot, ioh, sc,
1281 sizeof(revision.cmd), (u_char *)&revision.cmd,
1282 sizeof(revision.reply), (u_char *)&revision.reply);
1283 *p++ = revision.reply.firm_revision;
1284 *p++ = '.';
1285 *p++ = revision.reply.firm_version;
1286 digit.cmd.opcode = BHA_INQUIRE_REVISION_3;
1287 bha_cmd(iot, ioh, sc,
1288 sizeof(digit.cmd), (u_char *)&digit.cmd,
1289 sizeof(digit.reply), (u_char *)&digit.reply);
1290 *p++ = digit.reply.digit;
1291 if (revision.reply.firm_revision >= '3' ||
1292 (revision.reply.firm_revision == '3' &&
1293 revision.reply.firm_version >= '3')) {
1294 digit.cmd.opcode = BHA_INQUIRE_REVISION_4;
1295 bha_cmd(iot, ioh, sc,
1296 sizeof(digit.cmd), (u_char *)&digit.cmd,
1297 sizeof(digit.reply), (u_char *)&digit.reply);
1298 *p++ = digit.reply.digit;
1299 }
1300 while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0'))
1301 p--;
1302 *p = '\0';
1303
1304
1305
1306
1307 if (revision.reply.firm_revision >= '3') {
1308 p = sc->sc_model;
1309 model.cmd.opcode = BHA_INQUIRE_MODEL;
1310 model.cmd.len = sizeof(model.reply);
1311 bha_cmd(iot, ioh, sc,
1312 sizeof(model.cmd), (u_char *)&model.cmd,
1313 sizeof(model.reply), (u_char *)&model.reply);
1314 *p++ = model.reply.id[0];
1315 *p++ = model.reply.id[1];
1316 *p++ = model.reply.id[2];
1317 *p++ = model.reply.id[3];
1318 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
1319 p--;
1320 *p++ = model.reply.version[0];
1321 *p++ = model.reply.version[1];
1322 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
1323 p--;
1324 *p = '\0';
1325 } else
1326 strlcpy(sc->sc_model, "542B", sizeof sc->sc_model);
1327 }
1328
1329 void
1330 bhaminphys(bp)
1331 struct buf *bp;
1332 {
1333
1334 if (bp->b_bcount > BHA_MAXXFER)
1335 bp->b_bcount = BHA_MAXXFER;
1336 minphys(bp);
1337 }
1338
1339
1340
1341
1342
1343 int
1344 bha_scsi_cmd(xs)
1345 struct scsi_xfer *xs;
1346 {
1347 struct scsi_link *sc_link = xs->sc_link;
1348 struct bha_softc *sc = sc_link->adapter_softc;
1349 bus_dma_tag_t dmat = sc->sc_dmat;
1350 struct bha_ccb *ccb;
1351 int error, seg, flags, s;
1352 int fromqueue = 0, dontqueue = 0;
1353
1354 SC_DEBUG(sc_link, SDEV_DB2, ("bha_scsi_cmd\n"));
1355
1356 s = splbio();
1357
1358
1359
1360
1361
1362 if (xs == LIST_FIRST(&sc->sc_queue)) {
1363 xs = bha_dequeue(sc);
1364 fromqueue = 1;
1365 goto get_ccb;
1366 }
1367
1368
1369 dontqueue = xs->flags & SCSI_POLL;
1370
1371
1372
1373
1374 if (!LIST_EMPTY(&sc->sc_queue)) {
1375
1376
1377
1378
1379 if (dontqueue) {
1380 splx(s);
1381 return (TRY_AGAIN_LATER);
1382 }
1383
1384
1385
1386
1387 bha_enqueue(sc, xs, 0);
1388 xs = bha_dequeue(sc);
1389 fromqueue = 1;
1390 }
1391
1392 get_ccb:
1393
1394
1395
1396
1397
1398 flags = xs->flags;
1399 if ((ccb = bha_get_ccb(sc, flags)) == NULL) {
1400
1401
1402
1403 if (dontqueue) {
1404 splx(s);
1405 return (TRY_AGAIN_LATER);
1406 }
1407
1408
1409
1410
1411
1412 bha_enqueue(sc, xs, fromqueue);
1413 splx(s);
1414 return (SUCCESSFULLY_QUEUED);
1415 }
1416
1417 splx(s);
1418
1419 ccb->xs = xs;
1420 ccb->timeout = xs->timeout;
1421
1422
1423
1424
1425 if (flags & SCSI_RESET) {
1426 ccb->opcode = BHA_RESET_CCB;
1427 ccb->scsi_cmd_length = 0;
1428 } else {
1429
1430 ccb->opcode = (xs->datalen ? BHA_INIT_SCAT_GATH_CCB
1431 : BHA_INITIATOR_CCB);
1432 bcopy(xs->cmd, &ccb->scsi_cmd,
1433 ccb->scsi_cmd_length = xs->cmdlen);
1434 }
1435
1436 if (xs->datalen) {
1437
1438
1439
1440 #ifdef TFS
1441 if (flags & SCSI_DATA_UIO) {
1442 error = bus_dmamap_load_uio(dmat,
1443 ccb->dmamap_xfer, (struct uio *)xs->data,
1444 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1445 BUS_DMA_WAITOK);
1446 } else
1447 #endif
1448 {
1449 error = bus_dmamap_load(dmat,
1450 ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
1451 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1452 BUS_DMA_WAITOK);
1453 }
1454
1455 if (error) {
1456 if (error == EFBIG) {
1457 printf("%s: bha_scsi_cmd, more than %d"
1458 " dma segments\n",
1459 sc->sc_dev.dv_xname, BHA_NSEG);
1460 } else {
1461 printf("%s: bha_scsi_cmd, error %d loading"
1462 " dma map\n",
1463 sc->sc_dev.dv_xname, error);
1464 }
1465 goto bad;
1466 }
1467
1468 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
1469 0, ccb->dmamap_xfer->dm_mapsize,
1470 (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1471 BUS_DMASYNC_PREWRITE);
1472
1473
1474
1475
1476
1477 for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
1478 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
1479 ccb->scat_gath[seg].seg_addr);
1480 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
1481 ccb->scat_gath[seg].seg_len);
1482 }
1483
1484 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1485 BHA_CCB_OFF(ccb) + offsetof(struct bha_ccb, scat_gath),
1486 ccb->data_addr);
1487 ltophys(ccb->dmamap_xfer->dm_nsegs *
1488 sizeof(struct bha_scat_gath), ccb->data_length);
1489 } else {
1490
1491
1492
1493 ltophys(0, ccb->data_addr);
1494 ltophys(0, ccb->data_length);
1495 }
1496
1497 ccb->data_out = 0;
1498 ccb->data_in = 0;
1499 ccb->target = sc_link->target;
1500 ccb->lun = sc_link->lun;
1501 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1502 BHA_CCB_OFF(ccb) + offsetof(struct bha_ccb, scsi_sense),
1503 ccb->sense_ptr);
1504 ccb->req_sense_length = sizeof(ccb->scsi_sense);
1505 ccb->host_stat = 0x00;
1506 ccb->target_stat = 0x00;
1507 ccb->link_id = 0;
1508 ltophys(0, ccb->link_addr);
1509
1510 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1511 0, sc->sc_dmamap_control->dm_mapsize,
1512 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1513
1514 s = splbio();
1515 bha_queue_ccb(sc, ccb);
1516 splx(s);
1517
1518
1519
1520
1521 SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
1522 if ((flags & SCSI_POLL) == 0)
1523 return (SUCCESSFULLY_QUEUED);
1524
1525
1526
1527
1528 if (bha_poll(sc, xs, ccb->timeout)) {
1529 bha_timeout(ccb);
1530 if (bha_poll(sc, xs, ccb->timeout))
1531 bha_timeout(ccb);
1532 }
1533 return (COMPLETE);
1534
1535 bad:
1536 xs->error = XS_DRIVER_STUFFUP;
1537 bha_free_ccb(sc, ccb);
1538 return (COMPLETE);
1539 }
1540
1541
1542
1543
1544 int
1545 bha_poll(sc, xs, count)
1546 struct bha_softc *sc;
1547 struct scsi_xfer *xs;
1548 int count;
1549 {
1550 bus_space_tag_t iot = sc->sc_iot;
1551 bus_space_handle_t ioh = sc->sc_ioh;
1552
1553
1554 while (count) {
1555
1556
1557
1558
1559 if (bus_space_read_1(iot, ioh, BHA_INTR_PORT) &
1560 BHA_INTR_ANYINTR)
1561 bha_intr(sc);
1562 if (xs->flags & ITSDONE)
1563 return (0);
1564 delay(1000);
1565 count--;
1566 }
1567 return (1);
1568 }
1569
1570 void
1571 bha_timeout(arg)
1572 void *arg;
1573 {
1574 struct bha_ccb *ccb = arg;
1575 struct scsi_xfer *xs = ccb->xs;
1576 struct scsi_link *sc_link = xs->sc_link;
1577 struct bha_softc *sc = sc_link->adapter_softc;
1578 int s;
1579
1580 sc_print_addr(sc_link);
1581 printf("timed out");
1582
1583 s = splbio();
1584
1585 #ifdef BHADIAG
1586
1587
1588
1589 bha_collect_mbo(sc);
1590 if (ccb->flags & CCB_SENDING) {
1591 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
1592 Debugger();
1593 }
1594 #endif
1595
1596
1597
1598
1599
1600
1601 if (ccb->flags & CCB_ABORT) {
1602
1603 printf(" AGAIN\n");
1604
1605 } else {
1606
1607 printf("\n");
1608 ccb->xs->error = XS_TIMEOUT;
1609 ccb->timeout = BHA_ABORT_TIMEOUT;
1610 ccb->flags |= CCB_ABORT;
1611 bha_queue_ccb(sc, ccb);
1612 }
1613
1614 splx(s);
1615 }