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