bha.c revision 1.13 1 /* $NetBSD: bha.c,v 1.13 1997/06/06 23:31:01 thorpej Exp $ */
2
3 #undef BHADIAG
4 #ifdef DDB
5 #define integrate
6 #else
7 #define integrate static inline
8 #endif
9
10 /*-
11 * Copyright (c) 1997 The NetBSD Foundation, Inc.
12 * All rights reserved.
13 *
14 * This code is derived from software contributed to The NetBSD Foundation
15 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
16 * NASA Ames Research Center.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by the NetBSD
29 * Foundation, Inc. and its contributors.
30 * 4. Neither the name of The NetBSD Foundation nor the names of its
31 * contributors may be used to endorse or promote products derived
32 * from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
35 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
36 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
38 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
39 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
40 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
43 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44 * POSSIBILITY OF SUCH DAMAGE.
45 */
46
47 /*
48 * Copyright (c) 1994, 1996, 1997 Charles M. Hannum. All rights reserved.
49 *
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 * 1. Redistributions of source code must retain the above copyright
54 * notice, this list of conditions and the following disclaimer.
55 * 2. Redistributions in binary form must reproduce the above copyright
56 * notice, this list of conditions and the following disclaimer in the
57 * documentation and/or other materials provided with the distribution.
58 * 3. All advertising materials mentioning features or use of this software
59 * must display the following acknowledgement:
60 * This product includes software developed by Charles M. Hannum.
61 * 4. The name of the author may not be used to endorse or promote products
62 * derived from this software without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
65 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
66 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
67 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
68 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
69 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
70 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
71 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
73 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74 */
75
76 /*
77 * Originally written by Julian Elischer (julian (at) tfs.com)
78 * for TRW Financial Systems for use under the MACH(2.5) operating system.
79 *
80 * TRW Financial Systems, in accordance with their agreement with Carnegie
81 * Mellon University, makes this software available to CMU to distribute
82 * or use in any manner that they see fit as long as this message is kept with
83 * the software. For this reason TFS also grants any other persons or
84 * organisations permission to use or modify this software.
85 *
86 * TFS supplies this software to be publicly redistributed
87 * on the understanding that TFS is not responsible for the correct
88 * functioning of this software in any circumstances.
89 */
90
91 #include <sys/types.h>
92 #include <sys/param.h>
93 #include <sys/systm.h>
94 #include <sys/kernel.h>
95 #include <sys/errno.h>
96 #include <sys/ioctl.h>
97 #include <sys/device.h>
98 #include <sys/malloc.h>
99 #include <sys/buf.h>
100 #include <sys/proc.h>
101 #include <sys/user.h>
102
103 #include <machine/bus.h>
104 #include <machine/intr.h>
105
106 #include <scsi/scsi_all.h>
107 #include <scsi/scsiconf.h>
108
109 #include <dev/ic/bhareg.h>
110 #include <dev/ic/bhavar.h>
111
112 #ifndef DDB
113 #define Debugger() panic("should call debugger here (bha.c)")
114 #endif /* ! DDB */
115
116 #define BHA_MAXXFER ((BHA_NSEG - 1) << PGSHIFT)
117
118 #ifdef BHADEBUG
119 int bha_debug = 0;
120 #endif /* BHADEBUG */
121
122 int bha_cmd __P((bus_space_tag_t, bus_space_handle_t, struct bha_softc *,
123 int, u_char *, int, u_char *));
124 integrate void bha_finish_ccbs __P((struct bha_softc *));
125 integrate void bha_reset_ccb __P((struct bha_softc *, struct bha_ccb *));
126 void bha_free_ccb __P((struct bha_softc *, struct bha_ccb *));
127 integrate void bha_init_ccb __P((struct bha_softc *, struct bha_ccb *));
128 struct bha_ccb *bha_get_ccb __P((struct bha_softc *, int));
129 struct bha_ccb *bha_ccb_phys_kv __P((struct bha_softc *, u_long));
130 void bha_queue_ccb __P((struct bha_softc *, struct bha_ccb *));
131 void bha_collect_mbo __P((struct bha_softc *));
132 void bha_start_ccbs __P((struct bha_softc *));
133 void bha_done __P((struct bha_softc *, struct bha_ccb *));
134 void bha_init __P((struct bha_softc *));
135 void bhaminphys __P((struct buf *));
136 int bha_scsi_cmd __P((struct scsi_xfer *));
137 int bha_poll __P((struct bha_softc *, struct scsi_xfer *, int));
138 void bha_timeout __P((void *arg));
139 int bha_create_ccbs __P((struct bha_softc *, void *, size_t));
140
141 struct scsi_adapter bha_switch = {
142 bha_scsi_cmd,
143 bhaminphys,
144 0,
145 0,
146 };
147
148 /* the below structure is so we have a default dev struct for out link struct */
149 struct scsi_device bha_dev = {
150 NULL, /* Use default error handler */
151 NULL, /* have a queue, served by this */
152 NULL, /* have no async handler */
153 NULL, /* Use default 'done' routine */
154 };
155
156 struct cfdriver bha_cd = {
157 NULL, "bha", DV_DULL
158 };
159
160 #define BHA_RESET_TIMEOUT 2000 /* time to wait for reset (mSec) */
161 #define BHA_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */
162
163 /* XXX Should put this in a better place. */
164 #define offsetof(type, member) ((size_t)(&((type *)0)->member))
165
166 /*
167 * bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
168 *
169 * Activate Adapter command
170 * icnt: number of args (outbound bytes including opcode)
171 * ibuf: argument buffer
172 * ocnt: number of expected returned bytes
173 * obuf: result buffer
174 * wait: number of seconds to wait for response
175 *
176 * Performs an adapter command through the ports. Not to be confused with a
177 * scsi command, which is read in via the dma; one of the adapter commands
178 * tells it to read in a scsi command.
179 */
180 int
181 bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
182 bus_space_tag_t iot;
183 bus_space_handle_t ioh;
184 struct bha_softc *sc;
185 int icnt, ocnt;
186 u_char *ibuf, *obuf;
187 {
188 const char *name;
189 register int i;
190 int wait;
191 u_char sts;
192 u_char opcode = ibuf[0];
193
194 if (sc != NULL)
195 name = sc->sc_dev.dv_xname;
196 else
197 name = "(bha probe)";
198
199 /*
200 * Calculate a reasonable timeout for the command.
201 */
202 switch (opcode) {
203 case BHA_INQUIRE_DEVICES:
204 case BHA_INQUIRE_DEVICES_2:
205 wait = 90 * 20000;
206 break;
207 default:
208 wait = 1 * 20000;
209 break;
210 }
211
212 /*
213 * Wait for the adapter to go idle, unless it's one of
214 * the commands which don't need this
215 */
216 if (opcode != BHA_MBO_INTR_EN) {
217 for (i = 20000; i; i--) { /* 1 sec? */
218 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
219 if (sts & BHA_STAT_IDLE)
220 break;
221 delay(50);
222 }
223 if (!i) {
224 printf("%s: bha_cmd, host not idle(0x%x)\n",
225 name, sts);
226 return (1);
227 }
228 }
229 /*
230 * Now that it is idle, if we expect output, preflush the
231 * queue feeding to us.
232 */
233 if (ocnt) {
234 while ((bus_space_read_1(iot, ioh, BHA_STAT_PORT)) &
235 BHA_STAT_DF)
236 bus_space_read_1(iot, ioh, BHA_DATA_PORT);
237 }
238 /*
239 * Output the command and the number of arguments given
240 * for each byte, first check the port is empty.
241 */
242 while (icnt--) {
243 for (i = wait; i; i--) {
244 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
245 if (!(sts & BHA_STAT_CDF))
246 break;
247 delay(50);
248 }
249 if (!i) {
250 if (opcode != BHA_INQUIRE_REVISION)
251 printf("%s: bha_cmd, cmd/data port full\n",
252 name);
253 goto bad;
254 }
255 bus_space_write_1(iot, ioh, BHA_CMD_PORT, *ibuf++);
256 }
257 /*
258 * If we expect input, loop that many times, each time,
259 * looking for the data register to have valid data
260 */
261 while (ocnt--) {
262 for (i = wait; i; i--) {
263 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
264 if (sts & BHA_STAT_DF)
265 break;
266 delay(50);
267 }
268 if (!i) {
269 if (opcode != BHA_INQUIRE_REVISION)
270 printf("%s: bha_cmd, cmd/data port empty %d\n",
271 name, ocnt);
272 goto bad;
273 }
274 *obuf++ = bus_space_read_1(iot, ioh, BHA_DATA_PORT);
275 }
276 /*
277 * Wait for the board to report a finished instruction.
278 * We may get an extra interrupt for the HACC signal, but this is
279 * unimportant.
280 */
281 if (opcode != BHA_MBO_INTR_EN && opcode != BHA_MODIFY_IOPORT) {
282 for (i = 20000; i; i--) { /* 1 sec? */
283 sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
284 /* XXX Need to save this in the interrupt handler? */
285 if (sts & BHA_INTR_HACC)
286 break;
287 delay(50);
288 }
289 if (!i) {
290 printf("%s: bha_cmd, host not finished(0x%x)\n",
291 name, sts);
292 return (1);
293 }
294 }
295 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
296 return (0);
297
298 bad:
299 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_SRST);
300 return (1);
301 }
302
303 /*
304 * Attach all the sub-devices we can find
305 */
306 void
307 bha_attach(sc, bpd)
308 struct bha_softc *sc;
309 struct bha_probe_data *bpd;
310 {
311
312 /*
313 * fill in the prototype scsi_link.
314 */
315 sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
316 sc->sc_link.adapter_softc = sc;
317 sc->sc_link.adapter_target = bpd->sc_scsi_dev;
318 sc->sc_link.adapter = &bha_switch;
319 sc->sc_link.device = &bha_dev;
320 sc->sc_link.openings = 4;
321 sc->sc_link.max_target = bpd->sc_iswide ? 15 : 7;
322
323 TAILQ_INIT(&sc->sc_free_ccb);
324 TAILQ_INIT(&sc->sc_waiting_ccb);
325
326 bha_inquire_setup_information(sc);
327
328 printf("%s: model BT-%s, firmware %s\n", sc->sc_dev.dv_xname,
329 sc->sc_model, sc->sc_firmware);
330
331 bha_init(sc);
332
333 /*
334 * ask the adapter what subunits are present
335 */
336 config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
337 }
338
339 integrate void
340 bha_finish_ccbs(sc)
341 struct bha_softc *sc;
342 {
343 struct bha_mbx_in *wmbi;
344 struct bha_ccb *ccb;
345 int i;
346
347 wmbi = wmbx->tmbi;
348
349 if (wmbi->stat == BHA_MBI_FREE) {
350 for (i = 0; i < BHA_MBX_SIZE; i++) {
351 if (wmbi->stat != BHA_MBI_FREE) {
352 printf("%s: mbi not in round-robin order\n",
353 sc->sc_dev.dv_xname);
354 goto AGAIN;
355 }
356 bha_nextmbx(wmbi, wmbx, mbi);
357 }
358 #ifdef BHADIAGnot
359 printf("%s: mbi interrupt with no full mailboxes\n",
360 sc->sc_dev.dv_xname);
361 #endif
362 return;
363 }
364
365 AGAIN:
366 do {
367 ccb = bha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
368 if (!ccb) {
369 printf("%s: bad mbi ccb pointer; skipping\n",
370 sc->sc_dev.dv_xname);
371 goto next;
372 }
373
374 #ifdef BHADEBUG
375 if (bha_debug) {
376 u_char *cp = &ccb->scsi_cmd;
377 printf("op=%x %x %x %x %x %x\n",
378 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
379 printf("stat %x for mbi addr = 0x%08x, ",
380 wmbi->stat, wmbi);
381 printf("ccb addr = 0x%x\n", ccb);
382 }
383 #endif /* BHADEBUG */
384
385 switch (wmbi->stat) {
386 case BHA_MBI_OK:
387 case BHA_MBI_ERROR:
388 if ((ccb->flags & CCB_ABORT) != 0) {
389 /*
390 * If we already started an abort, wait for it
391 * to complete before clearing the CCB. We
392 * could instead just clear CCB_SENDING, but
393 * what if the mailbox was already received?
394 * The worst that happens here is that we clear
395 * the CCB a bit later than we need to. BFD.
396 */
397 goto next;
398 }
399 break;
400
401 case BHA_MBI_ABORT:
402 case BHA_MBI_UNKNOWN:
403 /*
404 * Even if the CCB wasn't found, we clear it anyway.
405 * See preceeding comment.
406 */
407 break;
408
409 default:
410 printf("%s: bad mbi status %02x; skipping\n",
411 sc->sc_dev.dv_xname, wmbi->stat);
412 goto next;
413 }
414
415 untimeout(bha_timeout, ccb);
416 bha_done(sc, ccb);
417
418 next:
419 wmbi->stat = BHA_MBI_FREE;
420 bha_nextmbx(wmbi, wmbx, mbi);
421 } while (wmbi->stat != BHA_MBI_FREE);
422
423 wmbx->tmbi = wmbi;
424 }
425
426 /*
427 * Catch an interrupt from the adaptor
428 */
429 int
430 bha_intr(arg)
431 void *arg;
432 {
433 struct bha_softc *sc = arg;
434 bus_space_tag_t iot = sc->sc_iot;
435 bus_space_handle_t ioh = sc->sc_ioh;
436 u_char sts;
437
438 #ifdef BHADEBUG
439 printf("%s: bha_intr ", sc->sc_dev.dv_xname);
440 #endif /* BHADEBUG */
441
442 /*
443 * First acknowlege the interrupt, Then if it's not telling about
444 * a completed operation just return.
445 */
446 sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
447 if ((sts & BHA_INTR_ANYINTR) == 0)
448 return (0);
449 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
450
451 #ifdef BHADIAG
452 /* Make sure we clear CCB_SENDING before finishing a CCB. */
453 bha_collect_mbo(sc);
454 #endif
455
456 /* Mail box out empty? */
457 if (sts & BHA_INTR_MBOA) {
458 struct bha_toggle toggle;
459
460 toggle.cmd.opcode = BHA_MBO_INTR_EN;
461 toggle.cmd.enable = 0;
462 bha_cmd(iot, ioh, sc,
463 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
464 0, (u_char *)0);
465 bha_start_ccbs(sc);
466 }
467
468 /* Mail box in full? */
469 if (sts & BHA_INTR_MBIF)
470 bha_finish_ccbs(sc);
471
472 return (1);
473 }
474
475 integrate void
476 bha_reset_ccb(sc, ccb)
477 struct bha_softc *sc;
478 struct bha_ccb *ccb;
479 {
480
481 ccb->flags = 0;
482 }
483
484 /*
485 * A ccb is put onto the free list.
486 */
487 void
488 bha_free_ccb(sc, ccb)
489 struct bha_softc *sc;
490 struct bha_ccb *ccb;
491 {
492 int s;
493
494 s = splbio();
495
496 bha_reset_ccb(sc, ccb);
497 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
498
499 /*
500 * If there were none, wake anybody waiting for one to come free,
501 * starting with queued entries.
502 */
503 if (ccb->chain.tqe_next == 0)
504 wakeup(&sc->sc_free_ccb);
505
506 splx(s);
507 }
508
509 integrate void
510 bha_init_ccb(sc, ccb)
511 struct bha_softc *sc;
512 struct bha_ccb *ccb;
513 {
514 bus_dma_tag_t dmat = sc->sc_dmat;
515 int hashnum;
516
517 /*
518 * XXX Should we put a DIAGNOSTIC check for multiple
519 * XXX CCB inits here?
520 */
521
522 bzero(ccb, sizeof(struct bha_ccb));
523
524 /*
525 * Create DMA maps for this CCB.
526 */
527 if (bus_dmamap_create(dmat, sizeof(struct bha_ccb), 1,
528 sizeof(struct bha_ccb), 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
529 &ccb->dmamap_self) ||
530
531 /* XXX What's a good value for this? */
532 bus_dmamap_create(dmat, BHA_MAXXFER, BHA_NSEG, BHA_MAXXFER,
533 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
534 &ccb->dmamap_xfer))
535 panic("bha_init_ccb: can't create DMA maps");
536
537 /*
538 * Load the permanent DMA maps.
539 */
540 if (bus_dmamap_load(dmat, ccb->dmamap_self, ccb,
541 sizeof(struct bha_ccb), NULL, BUS_DMA_NOWAIT))
542 panic("bha_init_ccb: can't load permanent maps");
543
544 /*
545 * put in the phystokv hash table
546 * Never gets taken out.
547 */
548 ccb->hashkey = ccb->dmamap_self->dm_segs[0].ds_addr;
549 hashnum = CCB_HASH(ccb->hashkey);
550 ccb->nexthash = sc->sc_ccbhash[hashnum];
551 sc->sc_ccbhash[hashnum] = ccb;
552 bha_reset_ccb(sc, ccb);
553 }
554
555 /*
556 * Create a set of ccbs and add them to the free list.
557 */
558 int
559 bha_create_ccbs(sc, mem, size)
560 struct bha_softc *sc;
561 void *mem;
562 size_t size;
563 {
564 bus_dma_segment_t seg;
565 struct bha_ccb *ccb;
566 int rseg, error;
567
568 if (sc->sc_numccbs >= BHA_CCB_MAX)
569 return (0);
570
571 if ((ccb = mem) != NULL)
572 goto have_mem;
573
574 size = NBPG;
575 error = bus_dmamem_alloc(sc->sc_dmat, size, NBPG, 0, &seg, 1, &rseg,
576 BUS_DMA_NOWAIT);
577 if (error)
578 return (error);
579
580 error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
581 (caddr_t *)&ccb, BUS_DMA_NOWAIT|BUS_DMAMEM_NOSYNC);
582 if (error) {
583 bus_dmamem_free(sc->sc_dmat, &seg, rseg);
584 return (error);
585 }
586
587 have_mem:
588 bzero(ccb, size);
589 while (size > sizeof(struct bha_ccb)) {
590 bha_init_ccb(sc, ccb);
591 sc->sc_numccbs++;
592 if (sc->sc_numccbs >= BHA_CCB_MAX)
593 break;
594 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
595 (caddr_t)ccb += ALIGN(sizeof(struct bha_ccb));
596 size -= ALIGN(sizeof(struct bha_ccb));
597 }
598
599 return (0);
600 }
601
602 /*
603 * Get a free ccb
604 *
605 * If there are none, see if we can allocate a new one. If so, put it in
606 * the hash table too otherwise either return an error or sleep.
607 */
608 struct bha_ccb *
609 bha_get_ccb(sc, flags)
610 struct bha_softc *sc;
611 int flags;
612 {
613 struct bha_ccb *ccb;
614 int s;
615
616 s = splbio();
617
618 /*
619 * If we can and have to, sleep waiting for one to come free
620 * but only if we can't allocate a new one.
621 */
622 for (;;) {
623 ccb = sc->sc_free_ccb.tqh_first;
624 if (ccb) {
625 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
626 break;
627 }
628 if (sc->sc_numccbs < BHA_CCB_MAX) {
629 if (bha_create_ccbs(sc, NULL, 0)) {
630 printf("%s: can't allocate ccbs\n",
631 sc->sc_dev.dv_xname);
632 goto out;
633 }
634 continue;
635 }
636 if ((flags & SCSI_NOSLEEP) != 0)
637 goto out;
638 tsleep(&sc->sc_free_ccb, PRIBIO, "bhaccb", 0);
639 }
640
641 ccb->flags |= CCB_ALLOC;
642
643 out:
644 splx(s);
645 return (ccb);
646 }
647
648 /*
649 * Given a physical address, find the ccb that it corresponds to.
650 */
651 struct bha_ccb *
652 bha_ccb_phys_kv(sc, ccb_phys)
653 struct bha_softc *sc;
654 u_long ccb_phys;
655 {
656 int hashnum = CCB_HASH(ccb_phys);
657 struct bha_ccb *ccb = sc->sc_ccbhash[hashnum];
658
659 while (ccb) {
660 if (ccb->hashkey == ccb_phys)
661 break;
662 ccb = ccb->nexthash;
663 }
664 return (ccb);
665 }
666
667 /*
668 * Queue a CCB to be sent to the controller, and send it if possible.
669 */
670 void
671 bha_queue_ccb(sc, ccb)
672 struct bha_softc *sc;
673 struct bha_ccb *ccb;
674 {
675
676 TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
677 bha_start_ccbs(sc);
678 }
679
680 /*
681 * Garbage collect mailboxes that are no longer in use.
682 */
683 void
684 bha_collect_mbo(sc)
685 struct bha_softc *sc;
686 {
687 struct bha_mbx_out *wmbo; /* Mail Box Out pointer */
688 #ifdef BHADIAG
689 struct bha_ccb *ccb;
690 #endif
691
692 wmbo = wmbx->cmbo;
693
694 while (sc->sc_mbofull > 0) {
695 if (wmbo->cmd != BHA_MBO_FREE)
696 break;
697
698 #ifdef BHADIAG
699 ccb = bha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
700 ccb->flags &= ~CCB_SENDING;
701 #endif
702
703 --sc->sc_mbofull;
704 bha_nextmbx(wmbo, wmbx, mbo);
705 }
706
707 wmbx->cmbo = wmbo;
708 }
709
710 /*
711 * Send as many CCBs as we have empty mailboxes for.
712 */
713 void
714 bha_start_ccbs(sc)
715 struct bha_softc *sc;
716 {
717 bus_space_tag_t iot = sc->sc_iot;
718 bus_space_handle_t ioh = sc->sc_ioh;
719 struct bha_mbx_out *wmbo; /* Mail Box Out pointer */
720 struct bha_ccb *ccb;
721
722 wmbo = wmbx->tmbo;
723
724 while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) {
725 if (sc->sc_mbofull >= BHA_MBX_SIZE) {
726 bha_collect_mbo(sc);
727 if (sc->sc_mbofull >= BHA_MBX_SIZE) {
728 struct bha_toggle toggle;
729
730 toggle.cmd.opcode = BHA_MBO_INTR_EN;
731 toggle.cmd.enable = 1;
732 bha_cmd(iot, ioh, sc,
733 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
734 0, (u_char *)0);
735 break;
736 }
737 }
738
739 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
740 #ifdef BHADIAG
741 ccb->flags |= CCB_SENDING;
742 #endif
743
744 /* Link ccb to mbo. */
745 ltophys(ccb->dmamap_self->dm_segs[0].ds_addr, wmbo->ccb_addr);
746 if (ccb->flags & CCB_ABORT)
747 wmbo->cmd = BHA_MBO_ABORT;
748 else
749 wmbo->cmd = BHA_MBO_START;
750
751 /* Tell the card to poll immediately. */
752 bus_space_write_1(iot, ioh, BHA_CMD_PORT, BHA_START_SCSI);
753
754 if ((ccb->xs->flags & SCSI_POLL) == 0)
755 timeout(bha_timeout, ccb, (ccb->timeout * hz) / 1000);
756
757 ++sc->sc_mbofull;
758 bha_nextmbx(wmbo, wmbx, mbo);
759 }
760
761 wmbx->tmbo = wmbo;
762 }
763
764 /*
765 * We have a ccb which has been processed by the
766 * adaptor, now we look to see how the operation
767 * went. Wake up the owner if waiting
768 */
769 void
770 bha_done(sc, ccb)
771 struct bha_softc *sc;
772 struct bha_ccb *ccb;
773 {
774 bus_dma_tag_t dmat = sc->sc_dmat;
775 struct scsi_sense_data *s1, *s2;
776 struct scsi_xfer *xs = ccb->xs;
777
778 SC_DEBUG(xs->sc_link, SDEV_DB2, ("bha_done\n"));
779
780 /*
781 * If we were a data transfer, unload the map that described
782 * the data buffer.
783 */
784 if (xs->datalen) {
785 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
786 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
787 BUS_DMASYNC_POSTWRITE);
788 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
789 }
790
791 /*
792 * Otherwise, put the results of the operation
793 * into the xfer and call whoever started it
794 */
795 #ifdef BHADIAG
796 if (ccb->flags & CCB_SENDING) {
797 printf("%s: exiting ccb still in transit!\n",
798 sc->sc_dev.dv_xname);
799 Debugger();
800 return;
801 }
802 #endif
803 if ((ccb->flags & CCB_ALLOC) == 0) {
804 printf("%s: exiting ccb not allocated!\n",
805 sc->sc_dev.dv_xname);
806 Debugger();
807 return;
808 }
809 if (xs->error == XS_NOERROR) {
810 if (ccb->host_stat != BHA_OK) {
811 switch (ccb->host_stat) {
812 case BHA_SEL_TIMEOUT: /* No response */
813 xs->error = XS_SELTIMEOUT;
814 break;
815 default: /* Other scsi protocol messes */
816 printf("%s: host_stat %x\n",
817 sc->sc_dev.dv_xname, ccb->host_stat);
818 xs->error = XS_DRIVER_STUFFUP;
819 break;
820 }
821 } else if (ccb->target_stat != SCSI_OK) {
822 switch (ccb->target_stat) {
823 case SCSI_CHECK:
824 s1 = &ccb->scsi_sense;
825 s2 = &xs->sense;
826 *s2 = *s1;
827 xs->error = XS_SENSE;
828 break;
829 case SCSI_BUSY:
830 xs->error = XS_BUSY;
831 break;
832 default:
833 printf("%s: target_stat %x\n",
834 sc->sc_dev.dv_xname, ccb->target_stat);
835 xs->error = XS_DRIVER_STUFFUP;
836 break;
837 }
838 } else
839 xs->resid = 0;
840 }
841 bha_free_ccb(sc, ccb);
842 xs->flags |= ITSDONE;
843 scsi_done(xs);
844 }
845
846 /*
847 * Find the board and find it's irq/drq
848 */
849 int
850 bha_find(iot, ioh, sc)
851 bus_space_tag_t iot;
852 bus_space_handle_t ioh;
853 struct bha_probe_data *sc;
854 {
855 int i, iswide;
856 u_char sts;
857 struct bha_extended_inquire inquire;
858 struct bha_config config;
859 int irq, drq;
860
861 /* Check something is at the ports we need to access */
862 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
863 if (sts == 0xFF)
864 return (0);
865
866 /*
867 * Reset board, If it doesn't respond, assume
868 * that it's not there.. good for the probe
869 */
870
871 bus_space_write_1(iot, ioh, BHA_CTRL_PORT,
872 BHA_CTRL_HRST | BHA_CTRL_SRST);
873
874 delay(100);
875 for (i = BHA_RESET_TIMEOUT; i; i--) {
876 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
877 if (sts == (BHA_STAT_IDLE | BHA_STAT_INIT))
878 break;
879 delay(1000);
880 }
881 if (!i) {
882 #ifdef BHADEBUG
883 if (bha_debug)
884 printf("bha_find: No answer from buslogic board\n");
885 #endif /* BHADEBUG */
886 return (0);
887 }
888
889 /*
890 * The BusLogic cards implement an Adaptec 1542 (aha)-compatible
891 * interface. The native bha interface is not compatible with
892 * an aha. 1542. We need to ensure that we never match an
893 * Adaptec 1542. We must also avoid sending Adaptec-compatible
894 * commands to a real bha, lest it go into 1542 emulation mode.
895 * (On an indirect bus like ISA, we should always probe for BusLogic
896 * interfaces before Adaptec interfaces).
897 */
898
899 /*
900 * Make sure we don't match an AHA-1542A or AHA-1542B, by checking
901 * for an extended-geometry register. The 1542[AB] don't have one.
902 */
903 sts = bus_space_read_1(iot, ioh, BHA_EXTGEOM_PORT);
904 if (sts == 0xFF)
905 return (0);
906
907 /*
908 * Check that we actually know how to use this board.
909 */
910 delay(1000);
911 inquire.cmd.opcode = BHA_INQUIRE_EXTENDED;
912 inquire.cmd.len = sizeof(inquire.reply);
913 i = bha_cmd(iot, ioh, (struct bha_softc *)0,
914 sizeof(inquire.cmd), (u_char *)&inquire.cmd,
915 sizeof(inquire.reply), (u_char *)&inquire.reply);
916
917 /*
918 * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev)
919 * have the extended-geometry register and also respond to
920 * BHA_INQUIRE_EXTENDED. Make sure we never match such cards,
921 * by checking the size of the reply is what a BusLogic card returns.
922 */
923 if (i) {
924 #ifdef BHADEBUG
925 printf("bha_find: board returned %d instead of %d to %s\n",
926 i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
927 #endif
928 return (0);
929 }
930
931 /* OK, we know we've found a buslogic adaptor. */
932
933 switch (inquire.reply.bus_type) {
934 case BHA_BUS_TYPE_24BIT:
935 case BHA_BUS_TYPE_32BIT:
936 break;
937 case BHA_BUS_TYPE_MCA:
938 /* We don't grok MicroChannel (yet). */
939 return (0);
940 default:
941 printf("bha_find: illegal bus type %c\n",
942 inquire.reply.bus_type);
943 return (0);
944 }
945
946 /* Note if we have a wide bus. */
947 iswide = inquire.reply.scsi_flags & BHA_SCSI_WIDE;
948
949 /*
950 * Assume we have a board at this stage setup dma channel from
951 * jumpers and save int level
952 */
953 delay(1000);
954 config.cmd.opcode = BHA_INQUIRE_CONFIG;
955 bha_cmd(iot, ioh, (struct bha_softc *)0,
956 sizeof(config.cmd), (u_char *)&config.cmd,
957 sizeof(config.reply), (u_char *)&config.reply);
958 switch (config.reply.chan) {
959 case EISADMA:
960 drq = -1;
961 break;
962 case CHAN0:
963 drq = 0;
964 break;
965 case CHAN5:
966 drq = 5;
967 break;
968 case CHAN6:
969 drq = 6;
970 break;
971 case CHAN7:
972 drq = 7;
973 break;
974 default:
975 printf("bha_find: illegal drq setting %x\n",
976 config.reply.chan);
977 return (0);
978 }
979
980 switch (config.reply.intr) {
981 case INT9:
982 irq = 9;
983 break;
984 case INT10:
985 irq = 10;
986 break;
987 case INT11:
988 irq = 11;
989 break;
990 case INT12:
991 irq = 12;
992 break;
993 case INT14:
994 irq = 14;
995 break;
996 case INT15:
997 irq = 15;
998 break;
999 default:
1000 printf("bha_find: illegal irq setting %x\n",
1001 config.reply.intr);
1002 return (0);
1003 }
1004
1005 /* if we want to fill in softc, do so now */
1006 if (sc != NULL) {
1007 sc->sc_irq = irq;
1008 sc->sc_drq = drq;
1009 sc->sc_scsi_dev = config.reply.scsi_dev;
1010 sc->sc_iswide = iswide;
1011 }
1012
1013 return (1);
1014 }
1015
1016
1017 /*
1018 * Disable the ISA-compatiblity ioports on PCI bha devices,
1019 * to ensure they're not autoconfigured a second time as an ISA bha.
1020 */
1021 int
1022 bha_disable_isacompat(sc)
1023 struct bha_softc *sc;
1024 {
1025 struct bha_isadisable isa_disable;
1026
1027 isa_disable.cmd.opcode = BHA_MODIFY_IOPORT;
1028 isa_disable.cmd.modifier = BHA_IOMODIFY_DISABLE1;
1029 bha_cmd(sc->sc_iot, sc->sc_ioh, sc,
1030 sizeof(isa_disable.cmd), (u_char*)&isa_disable.cmd,
1031 0, (u_char *)0);
1032 return (0);
1033 }
1034
1035
1036 /*
1037 * Start the board, ready for normal operation
1038 */
1039 void
1040 bha_init(sc)
1041 struct bha_softc *sc;
1042 {
1043 bus_space_tag_t iot = sc->sc_iot;
1044 bus_space_handle_t ioh = sc->sc_ioh;
1045 bus_dma_segment_t seg;
1046 struct bha_devices devices;
1047 struct bha_setup setup;
1048 struct bha_mailbox mailbox;
1049 struct bha_period period;
1050 int i, rlen, rseg;
1051
1052 /* Enable round-robin scheme - appeared at firmware rev. 3.31. */
1053 if (strcmp(sc->sc_firmware, "3.31") >= 0) {
1054 struct bha_toggle toggle;
1055
1056 toggle.cmd.opcode = BHA_ROUND_ROBIN;
1057 toggle.cmd.enable = 1;
1058 bha_cmd(iot, ioh, sc,
1059 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
1060 0, (u_char *)0);
1061 }
1062
1063 /*
1064 * Inquire installed devices (to force synchronous negotiation).
1065 */
1066
1067 /*
1068 * Poll targets 0 - 7.
1069 */
1070 devices.cmd.opcode = BHA_INQUIRE_DEVICES;
1071 bha_cmd(iot, ioh, sc,
1072 sizeof(devices.cmd), (u_char *)&devices.cmd,
1073 sizeof(devices.reply), (u_char *)&devices.reply);
1074
1075 /*
1076 * Poll targets 8 - 15 if we have a wide bus.
1077 */
1078 if (ISWIDE(sc)) {
1079 devices.cmd.opcode = BHA_INQUIRE_DEVICES_2;
1080 bha_cmd(iot, ioh, sc,
1081 sizeof(devices.cmd), (u_char *)&devices.cmd,
1082 sizeof(devices.reply), (u_char *)&devices.reply);
1083 }
1084
1085 /* Obtain setup information from. */
1086 rlen = sizeof(setup.reply) +
1087 (ISWIDE(sc) ? sizeof(setup.reply_w) : 0);
1088 setup.cmd.opcode = BHA_INQUIRE_SETUP;
1089 setup.cmd.len = rlen;
1090 bha_cmd(iot, ioh, sc,
1091 sizeof(setup.cmd), (u_char *)&setup.cmd,
1092 rlen, (u_char *)&setup.reply);
1093
1094 printf("%s: %s, %s\n",
1095 sc->sc_dev.dv_xname,
1096 setup.reply.sync_neg ? "sync" : "async",
1097 setup.reply.parity ? "parity" : "no parity");
1098
1099 for (i = 0; i < 8; i++)
1100 period.reply.period[i] = setup.reply.sync[i].period * 5 + 20;
1101 if (ISWIDE(sc)) {
1102 for (i = 0; i < 8; i++)
1103 period.reply_w.period[i] =
1104 setup.reply_w.sync[i].period * 5 + 20;
1105 }
1106
1107 if (sc->sc_firmware[0] >= '3') {
1108 rlen = sizeof(period.reply) +
1109 (ISWIDE(sc) ? sizeof(period.reply_w) : 0);
1110 period.cmd.opcode = BHA_INQUIRE_PERIOD;
1111 period.cmd.len = rlen;
1112 bha_cmd(iot, ioh, sc,
1113 sizeof(period.cmd), (u_char *)&period.cmd,
1114 rlen, (u_char *)&period.reply);
1115 }
1116
1117 for (i = 0; i < 8; i++) {
1118 if (!setup.reply.sync[i].valid ||
1119 (!setup.reply.sync[i].offset &&
1120 !setup.reply.sync[i].period))
1121 continue;
1122 printf("%s targ %d: sync, offset %d, period %dnsec\n",
1123 sc->sc_dev.dv_xname, i,
1124 setup.reply.sync[i].offset, period.reply.period[i] * 10);
1125 }
1126 if (ISWIDE(sc)) {
1127 for (i = 0; i < 8; i++) {
1128 if (!setup.reply_w.sync[i].valid ||
1129 (!setup.reply_w.sync[i].offset &&
1130 !setup.reply_w.sync[i].period))
1131 continue;
1132 printf("%s targ %d: sync, offset %d, period %dnsec\n",
1133 sc->sc_dev.dv_xname, i + 8,
1134 setup.reply_w.sync[i].offset,
1135 period.reply_w.period[i] * 10);
1136 }
1137 }
1138
1139 /*
1140 * Allocate the mailbox.
1141 */
1142 if (bus_dmamem_alloc(sc->sc_dmat, NBPG, NBPG, 0, &seg, 1,
1143 &rseg, BUS_DMA_NOWAIT) ||
1144 bus_dmamem_map(sc->sc_dmat, &seg, rseg, NBPG,
1145 (caddr_t *)&wmbx, BUS_DMA_NOWAIT|BUS_DMAMEM_NOSYNC))
1146 panic("bha_init: can't create or map mailbox");
1147
1148 /*
1149 * Since DMA memory allocation is always rounded up to a
1150 * page size, create some ccbs from the leftovers.
1151 */
1152 if (bha_create_ccbs(sc, ((caddr_t)wmbx) +
1153 ALIGN(sizeof(struct bha_mbx)),
1154 NBPG - ALIGN(sizeof(struct bha_mbx))))
1155 panic("bha_init: can't create ccbs");
1156
1157 /*
1158 * Create and load the mailbox DMA map.
1159 */
1160 if (bus_dmamap_create(sc->sc_dmat, sizeof(struct bha_mbx), 1,
1161 sizeof(struct bha_mbx), 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
1162 &sc->sc_dmamap_mbox) ||
1163 bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_mbox, wmbx,
1164 sizeof(struct bha_mbx), NULL, BUS_DMA_NOWAIT))
1165 panic("bha_init: can't create or load mailbox dma map");
1166
1167 /*
1168 * Set up initial mail box for round-robin operation.
1169 */
1170 for (i = 0; i < BHA_MBX_SIZE; i++) {
1171 wmbx->mbo[i].cmd = BHA_MBO_FREE;
1172 wmbx->mbi[i].stat = BHA_MBI_FREE;
1173 }
1174 wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
1175 wmbx->tmbi = &wmbx->mbi[0];
1176 sc->sc_mbofull = 0;
1177
1178 /* Initialize mail box. */
1179 mailbox.cmd.opcode = BHA_MBX_INIT_EXTENDED;
1180 mailbox.cmd.nmbx = BHA_MBX_SIZE;
1181 ltophys(sc->sc_dmamap_mbox->dm_segs[0].ds_addr, mailbox.cmd.addr);
1182 bha_cmd(iot, ioh, sc,
1183 sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
1184 0, (u_char *)0);
1185 }
1186
1187 void
1188 bha_inquire_setup_information(sc)
1189 struct bha_softc *sc;
1190 {
1191 bus_space_tag_t iot = sc->sc_iot;
1192 bus_space_handle_t ioh = sc->sc_ioh;
1193 struct bha_model model;
1194 struct bha_revision revision;
1195 struct bha_digit digit;
1196 char *p;
1197
1198 /*
1199 * Get the firmware revision.
1200 */
1201 p = sc->sc_firmware;
1202 revision.cmd.opcode = BHA_INQUIRE_REVISION;
1203 bha_cmd(iot, ioh, sc,
1204 sizeof(revision.cmd), (u_char *)&revision.cmd,
1205 sizeof(revision.reply), (u_char *)&revision.reply);
1206 *p++ = revision.reply.firm_revision;
1207 *p++ = '.';
1208 *p++ = revision.reply.firm_version;
1209 digit.cmd.opcode = BHA_INQUIRE_REVISION_3;
1210 bha_cmd(iot, ioh, sc,
1211 sizeof(digit.cmd), (u_char *)&digit.cmd,
1212 sizeof(digit.reply), (u_char *)&digit.reply);
1213 *p++ = digit.reply.digit;
1214 if (revision.reply.firm_revision >= '3' ||
1215 (revision.reply.firm_revision == '3' &&
1216 revision.reply.firm_version >= '3')) {
1217 digit.cmd.opcode = BHA_INQUIRE_REVISION_4;
1218 bha_cmd(iot, ioh, sc,
1219 sizeof(digit.cmd), (u_char *)&digit.cmd,
1220 sizeof(digit.reply), (u_char *)&digit.reply);
1221 *p++ = digit.reply.digit;
1222 }
1223 while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0'))
1224 p--;
1225 *p = '\0';
1226
1227 /*
1228 * Get the model number.
1229 */
1230 if (revision.reply.firm_revision >= '3') {
1231 p = sc->sc_model;
1232 model.cmd.opcode = BHA_INQUIRE_MODEL;
1233 model.cmd.len = sizeof(model.reply);
1234 bha_cmd(iot, ioh, sc,
1235 sizeof(model.cmd), (u_char *)&model.cmd,
1236 sizeof(model.reply), (u_char *)&model.reply);
1237 *p++ = model.reply.id[0];
1238 *p++ = model.reply.id[1];
1239 *p++ = model.reply.id[2];
1240 *p++ = model.reply.id[3];
1241 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
1242 p--;
1243 *p++ = model.reply.version[0];
1244 *p++ = model.reply.version[1];
1245 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
1246 p--;
1247 *p = '\0';
1248 } else
1249 strcpy(sc->sc_model, "542B");
1250 }
1251
1252 void
1253 bhaminphys(bp)
1254 struct buf *bp;
1255 {
1256
1257 if (bp->b_bcount > BHA_MAXXFER)
1258 bp->b_bcount = BHA_MAXXFER;
1259 minphys(bp);
1260 }
1261
1262 /*
1263 * start a scsi operation given the command and the data address. Also needs
1264 * the unit, target and lu.
1265 */
1266 int
1267 bha_scsi_cmd(xs)
1268 struct scsi_xfer *xs;
1269 {
1270 struct scsi_link *sc_link = xs->sc_link;
1271 struct bha_softc *sc = sc_link->adapter_softc;
1272 bus_dma_tag_t dmat = sc->sc_dmat;
1273 struct bha_ccb *ccb;
1274 int error, seg, flags, s;
1275
1276 SC_DEBUG(sc_link, SDEV_DB2, ("bha_scsi_cmd\n"));
1277 /*
1278 * get a ccb to use. If the transfer
1279 * is from a buf (possibly from interrupt time)
1280 * then we can't allow it to sleep
1281 */
1282 flags = xs->flags;
1283 if ((ccb = bha_get_ccb(sc, flags)) == NULL) {
1284 xs->error = XS_DRIVER_STUFFUP;
1285 return (TRY_AGAIN_LATER);
1286 }
1287 ccb->xs = xs;
1288 ccb->timeout = xs->timeout;
1289
1290 /*
1291 * Put all the arguments for the xfer in the ccb
1292 */
1293 if (flags & SCSI_RESET) {
1294 ccb->opcode = BHA_RESET_CCB;
1295 ccb->scsi_cmd_length = 0;
1296 } else {
1297 /* can't use S/G if zero length */
1298 ccb->opcode = (xs->datalen ? BHA_INIT_SCAT_GATH_CCB
1299 : BHA_INITIATOR_CCB);
1300 bcopy(xs->cmd, &ccb->scsi_cmd,
1301 ccb->scsi_cmd_length = xs->cmdlen);
1302 }
1303
1304 if (xs->datalen) {
1305 /*
1306 * Map the DMA transfer.
1307 */
1308 #ifdef TFS
1309 if (flags & SCSI_DATA_UIO) {
1310 error = bus_dmamap_load_uio(dmat,
1311 ccb->dmamap_xfer, (struct uio *)xs->data,
1312 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1313 BUS_DMA_WAITOK);
1314 } else
1315 #endif /* TFS */
1316 {
1317 error = bus_dmamap_load(dmat,
1318 ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
1319 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1320 BUS_DMA_WAITOK);
1321 }
1322
1323 if (error) {
1324 if (error == EFBIG) {
1325 printf("%s: bha_scsi_cmd, more than %d"
1326 " dma segments\n",
1327 sc->sc_dev.dv_xname, BHA_NSEG);
1328 } else {
1329 printf("%s: bha_scsi_cmd, error %d loading"
1330 " dma map\n",
1331 sc->sc_dev.dv_xname, error);
1332 }
1333 goto bad;
1334 }
1335
1336 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
1337 (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1338 BUS_DMASYNC_PREWRITE);
1339
1340 /*
1341 * Load the hardware scatter/gather map with the
1342 * contents of the DMA map.
1343 */
1344 for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
1345 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
1346 ccb->scat_gath[seg].seg_addr);
1347 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
1348 ccb->scat_gath[seg].seg_len);
1349 }
1350
1351 ltophys(ccb->dmamap_self->dm_segs[0].ds_addr +
1352 offsetof(struct bha_ccb, scat_gath), ccb->data_addr);
1353 ltophys(ccb->dmamap_xfer->dm_nsegs *
1354 sizeof(struct bha_scat_gath), ccb->data_length);
1355 } else {
1356 /*
1357 * No data xfer, use non S/G values.
1358 */
1359 ltophys(0, ccb->data_addr);
1360 ltophys(0, ccb->data_length);
1361 }
1362
1363 ccb->data_out = 0;
1364 ccb->data_in = 0;
1365 ccb->target = sc_link->target;
1366 ccb->lun = sc_link->lun;
1367 ltophys(ccb->dmamap_self->dm_segs[0].ds_addr +
1368 offsetof(struct bha_ccb, scsi_sense), ccb->sense_ptr);
1369 ccb->req_sense_length = sizeof(ccb->scsi_sense);
1370 ccb->host_stat = 0x00;
1371 ccb->target_stat = 0x00;
1372 ccb->link_id = 0;
1373 ltophys(0, ccb->link_addr);
1374
1375 s = splbio();
1376 bha_queue_ccb(sc, ccb);
1377 splx(s);
1378
1379 /*
1380 * Usually return SUCCESSFULLY QUEUED
1381 */
1382 SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
1383 if ((flags & SCSI_POLL) == 0)
1384 return (SUCCESSFULLY_QUEUED);
1385
1386 /*
1387 * If we can't use interrupts, poll on completion
1388 */
1389 if (bha_poll(sc, xs, ccb->timeout)) {
1390 bha_timeout(ccb);
1391 if (bha_poll(sc, xs, ccb->timeout))
1392 bha_timeout(ccb);
1393 }
1394 return (COMPLETE);
1395
1396 bad:
1397 xs->error = XS_DRIVER_STUFFUP;
1398 bha_free_ccb(sc, ccb);
1399 return (COMPLETE);
1400 }
1401
1402 /*
1403 * Poll a particular unit, looking for a particular xs
1404 */
1405 int
1406 bha_poll(sc, xs, count)
1407 struct bha_softc *sc;
1408 struct scsi_xfer *xs;
1409 int count;
1410 {
1411 bus_space_tag_t iot = sc->sc_iot;
1412 bus_space_handle_t ioh = sc->sc_ioh;
1413
1414 /* timeouts are in msec, so we loop in 1000 usec cycles */
1415 while (count) {
1416 /*
1417 * If we had interrupts enabled, would we
1418 * have got an interrupt?
1419 */
1420 if (bus_space_read_1(iot, ioh, BHA_INTR_PORT) &
1421 BHA_INTR_ANYINTR)
1422 bha_intr(sc);
1423 if (xs->flags & ITSDONE)
1424 return (0);
1425 delay(1000); /* only happens in boot so ok */
1426 count--;
1427 }
1428 return (1);
1429 }
1430
1431 void
1432 bha_timeout(arg)
1433 void *arg;
1434 {
1435 struct bha_ccb *ccb = arg;
1436 struct scsi_xfer *xs = ccb->xs;
1437 struct scsi_link *sc_link = xs->sc_link;
1438 struct bha_softc *sc = sc_link->adapter_softc;
1439 int s;
1440
1441 sc_print_addr(sc_link);
1442 printf("timed out");
1443
1444 s = splbio();
1445
1446 #ifdef BHADIAG
1447 /*
1448 * If the ccb's mbx is not free, then the board has gone Far East?
1449 */
1450 bha_collect_mbo(sc);
1451 if (ccb->flags & CCB_SENDING) {
1452 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
1453 Debugger();
1454 }
1455 #endif
1456
1457 /*
1458 * If it has been through before, then
1459 * a previous abort has failed, don't
1460 * try abort again
1461 */
1462 if (ccb->flags & CCB_ABORT) {
1463 /* abort timed out */
1464 printf(" AGAIN\n");
1465 /* XXX Must reset! */
1466 } else {
1467 /* abort the operation that has timed out */
1468 printf("\n");
1469 ccb->xs->error = XS_TIMEOUT;
1470 ccb->timeout = BHA_ABORT_TIMEOUT;
1471 ccb->flags |= CCB_ABORT;
1472 bha_queue_ccb(sc, ccb);
1473 }
1474
1475 splx(s);
1476 }
1477