bha.c revision 1.15 1 /* $NetBSD: bha.c,v 1.15 1997/10/28 19:13:36 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 void 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 void
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;
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 if (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
533 /* XXX What's a good value for this? */
534 bus_dmamap_create(dmat, BHA_MAXXFER, BHA_NSEG, BHA_MAXXFER,
535 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
536 &ccb->dmamap_xfer))
537 panic("bha_init_ccb: can't create DMA maps");
538
539 /*
540 * Load the permanent DMA maps.
541 */
542 if (bus_dmamap_load(dmat, ccb->dmamap_self, ccb,
543 sizeof(struct bha_ccb), NULL, BUS_DMA_NOWAIT))
544 panic("bha_init_ccb: can't load permanent maps");
545
546 /*
547 * put in the phystokv hash table
548 * Never gets taken out.
549 */
550 ccb->hashkey = ccb->dmamap_self->dm_segs[0].ds_addr;
551 hashnum = CCB_HASH(ccb->hashkey);
552 ccb->nexthash = sc->sc_ccbhash[hashnum];
553 sc->sc_ccbhash[hashnum] = ccb;
554 bha_reset_ccb(sc, ccb);
555 }
556
557 /*
558 * Create a set of ccbs and add them to the free list.
559 */
560 int
561 bha_create_ccbs(sc, mem, size, max_ccbs)
562 struct bha_softc *sc;
563 void *mem;
564 size_t size;
565 int max_ccbs;
566 {
567 bus_dma_segment_t seg;
568 struct bha_ccb *ccb;
569 int rseg, error;
570
571 if (sc->sc_numccbs >= BHA_CCB_MAX)
572 return (0);
573
574 if (max_ccbs > BHA_CCB_MAX)
575 max_ccbs = BHA_CCB_MAX;
576
577 if ((ccb = mem) != NULL)
578 goto have_mem;
579
580 size = NBPG;
581 error = bus_dmamem_alloc(sc->sc_dmat, size, NBPG, 0, &seg, 1, &rseg,
582 BUS_DMA_NOWAIT);
583 if (error)
584 return (error);
585
586 error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
587 (caddr_t *)&ccb, BUS_DMA_NOWAIT|BUS_DMAMEM_NOSYNC);
588 if (error) {
589 bus_dmamem_free(sc->sc_dmat, &seg, rseg);
590 return (error);
591 }
592
593 have_mem:
594 bzero(ccb, size);
595 while (size > sizeof(struct bha_ccb) && sc->sc_numccbs < max_ccbs) {
596 bha_init_ccb(sc, ccb);
597 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
598 (caddr_t)ccb += ALIGN(sizeof(struct bha_ccb));
599 size -= ALIGN(sizeof(struct bha_ccb));
600 sc->sc_numccbs++;
601 }
602
603 return (0);
604 }
605
606 /*
607 * Get a free ccb
608 *
609 * If there are none, see if we can allocate a new one. If so, put it in
610 * the hash table too otherwise either return an error or sleep.
611 */
612 struct bha_ccb *
613 bha_get_ccb(sc, flags)
614 struct bha_softc *sc;
615 int flags;
616 {
617 struct bha_ccb *ccb;
618 int s;
619
620 s = splbio();
621
622 /*
623 * If we can and have to, sleep waiting for one to come free
624 * but only if we can't allocate a new one.
625 */
626 for (;;) {
627 ccb = sc->sc_free_ccb.tqh_first;
628 if (ccb) {
629 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
630 break;
631 }
632 if (sc->sc_numccbs < BHA_CCB_MAX) {
633 if (bha_create_ccbs(sc, NULL, 0, BHA_CCB_MAX)) {
634 printf("%s: can't allocate ccbs\n",
635 sc->sc_dev.dv_xname);
636 goto out;
637 }
638 continue;
639 }
640 if ((flags & SCSI_NOSLEEP) != 0)
641 goto out;
642 tsleep(&sc->sc_free_ccb, PRIBIO, "bhaccb", 0);
643 }
644
645 ccb->flags |= CCB_ALLOC;
646
647 out:
648 splx(s);
649 return (ccb);
650 }
651
652 /*
653 * Given a physical address, find the ccb that it corresponds to.
654 */
655 struct bha_ccb *
656 bha_ccb_phys_kv(sc, ccb_phys)
657 struct bha_softc *sc;
658 u_long ccb_phys;
659 {
660 int hashnum = CCB_HASH(ccb_phys);
661 struct bha_ccb *ccb = sc->sc_ccbhash[hashnum];
662
663 while (ccb) {
664 if (ccb->hashkey == ccb_phys)
665 break;
666 ccb = ccb->nexthash;
667 }
668 return (ccb);
669 }
670
671 /*
672 * Queue a CCB to be sent to the controller, and send it if possible.
673 */
674 void
675 bha_queue_ccb(sc, ccb)
676 struct bha_softc *sc;
677 struct bha_ccb *ccb;
678 {
679
680 TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
681 bha_start_ccbs(sc);
682 }
683
684 /*
685 * Garbage collect mailboxes that are no longer in use.
686 */
687 void
688 bha_collect_mbo(sc)
689 struct bha_softc *sc;
690 {
691 struct bha_mbx_out *wmbo; /* Mail Box Out pointer */
692 #ifdef BHADIAG
693 struct bha_ccb *ccb;
694 #endif
695
696 wmbo = wmbx->cmbo;
697
698 while (sc->sc_mbofull > 0) {
699 if (wmbo->cmd != BHA_MBO_FREE)
700 break;
701
702 #ifdef BHADIAG
703 ccb = bha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
704 ccb->flags &= ~CCB_SENDING;
705 #endif
706
707 --sc->sc_mbofull;
708 bha_nextmbx(wmbo, wmbx, mbo);
709 }
710
711 wmbx->cmbo = wmbo;
712 }
713
714 /*
715 * Send as many CCBs as we have empty mailboxes for.
716 */
717 void
718 bha_start_ccbs(sc)
719 struct bha_softc *sc;
720 {
721 bus_space_tag_t iot = sc->sc_iot;
722 bus_space_handle_t ioh = sc->sc_ioh;
723 struct bha_mbx_out *wmbo; /* Mail Box Out pointer */
724 struct bha_ccb *ccb;
725
726 wmbo = wmbx->tmbo;
727
728 while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) {
729 if (sc->sc_mbofull >= BHA_MBX_SIZE) {
730 bha_collect_mbo(sc);
731 if (sc->sc_mbofull >= BHA_MBX_SIZE) {
732 struct bha_toggle toggle;
733
734 toggle.cmd.opcode = BHA_MBO_INTR_EN;
735 toggle.cmd.enable = 1;
736 bha_cmd(iot, ioh, sc,
737 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
738 0, (u_char *)0);
739 break;
740 }
741 }
742
743 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
744 #ifdef BHADIAG
745 ccb->flags |= CCB_SENDING;
746 #endif
747
748 /* Link ccb to mbo. */
749 ltophys(ccb->dmamap_self->dm_segs[0].ds_addr, wmbo->ccb_addr);
750 if (ccb->flags & CCB_ABORT)
751 wmbo->cmd = BHA_MBO_ABORT;
752 else
753 wmbo->cmd = BHA_MBO_START;
754
755 /* Tell the card to poll immediately. */
756 bus_space_write_1(iot, ioh, BHA_CMD_PORT, BHA_START_SCSI);
757
758 if ((ccb->xs->flags & SCSI_POLL) == 0)
759 timeout(bha_timeout, ccb, (ccb->timeout * hz) / 1000);
760
761 ++sc->sc_mbofull;
762 bha_nextmbx(wmbo, wmbx, mbo);
763 }
764
765 wmbx->tmbo = wmbo;
766 }
767
768 /*
769 * We have a ccb which has been processed by the
770 * adaptor, now we look to see how the operation
771 * went. Wake up the owner if waiting
772 */
773 void
774 bha_done(sc, ccb)
775 struct bha_softc *sc;
776 struct bha_ccb *ccb;
777 {
778 bus_dma_tag_t dmat = sc->sc_dmat;
779 struct scsipi_sense_data *s1, *s2;
780 struct scsipi_xfer *xs = ccb->xs;
781
782 SC_DEBUG(xs->sc_link, SDEV_DB2, ("bha_done\n"));
783
784 /*
785 * If we were a data transfer, unload the map that described
786 * the data buffer.
787 */
788 if (xs->datalen) {
789 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
790 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
791 BUS_DMASYNC_POSTWRITE);
792 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
793 }
794
795 /*
796 * Otherwise, put the results of the operation
797 * into the xfer and call whoever started it
798 */
799 #ifdef BHADIAG
800 if (ccb->flags & CCB_SENDING) {
801 printf("%s: exiting ccb still in transit!\n",
802 sc->sc_dev.dv_xname);
803 Debugger();
804 return;
805 }
806 #endif
807 if ((ccb->flags & CCB_ALLOC) == 0) {
808 printf("%s: exiting ccb not allocated!\n",
809 sc->sc_dev.dv_xname);
810 Debugger();
811 return;
812 }
813 if (xs->error == XS_NOERROR) {
814 if (ccb->host_stat != BHA_OK) {
815 switch (ccb->host_stat) {
816 case BHA_SEL_TIMEOUT: /* No response */
817 xs->error = XS_SELTIMEOUT;
818 break;
819 default: /* Other scsi protocol messes */
820 printf("%s: host_stat %x\n",
821 sc->sc_dev.dv_xname, ccb->host_stat);
822 xs->error = XS_DRIVER_STUFFUP;
823 break;
824 }
825 } else if (ccb->target_stat != SCSI_OK) {
826 switch (ccb->target_stat) {
827 case SCSI_CHECK:
828 s1 = &ccb->scsi_sense;
829 s2 = &xs->sense.scsi_sense;
830 *s2 = *s1;
831 xs->error = XS_SENSE;
832 break;
833 case SCSI_BUSY:
834 xs->error = XS_BUSY;
835 break;
836 default:
837 printf("%s: target_stat %x\n",
838 sc->sc_dev.dv_xname, ccb->target_stat);
839 xs->error = XS_DRIVER_STUFFUP;
840 break;
841 }
842 } else
843 xs->resid = 0;
844 }
845 bha_free_ccb(sc, ccb);
846 xs->flags |= ITSDONE;
847 scsipi_done(xs);
848 }
849
850 /*
851 * Find the board and find it's irq/drq
852 */
853 int
854 bha_find(iot, ioh, sc)
855 bus_space_tag_t iot;
856 bus_space_handle_t ioh;
857 struct bha_probe_data *sc;
858 {
859 int i, iswide;
860 u_char sts;
861 struct bha_extended_inquire inquire;
862 struct bha_config config;
863 int irq, drq;
864
865 /* Check something is at the ports we need to access */
866 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
867 if (sts == 0xFF)
868 return (0);
869
870 /*
871 * Reset board, If it doesn't respond, assume
872 * that it's not there.. good for the probe
873 */
874
875 bus_space_write_1(iot, ioh, BHA_CTRL_PORT,
876 BHA_CTRL_HRST | BHA_CTRL_SRST);
877
878 delay(100);
879 for (i = BHA_RESET_TIMEOUT; i; i--) {
880 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
881 if (sts == (BHA_STAT_IDLE | BHA_STAT_INIT))
882 break;
883 delay(1000);
884 }
885 if (!i) {
886 #ifdef BHADEBUG
887 if (bha_debug)
888 printf("bha_find: No answer from buslogic board\n");
889 #endif /* BHADEBUG */
890 return (0);
891 }
892
893 /*
894 * The BusLogic cards implement an Adaptec 1542 (aha)-compatible
895 * interface. The native bha interface is not compatible with
896 * an aha. 1542. We need to ensure that we never match an
897 * Adaptec 1542. We must also avoid sending Adaptec-compatible
898 * commands to a real bha, lest it go into 1542 emulation mode.
899 * (On an indirect bus like ISA, we should always probe for BusLogic
900 * interfaces before Adaptec interfaces).
901 */
902
903 /*
904 * Make sure we don't match an AHA-1542A or AHA-1542B, by checking
905 * for an extended-geometry register. The 1542[AB] don't have one.
906 */
907 sts = bus_space_read_1(iot, ioh, BHA_EXTGEOM_PORT);
908 if (sts == 0xFF)
909 return (0);
910
911 /*
912 * Check that we actually know how to use this board.
913 */
914 delay(1000);
915 inquire.cmd.opcode = BHA_INQUIRE_EXTENDED;
916 inquire.cmd.len = sizeof(inquire.reply);
917 i = bha_cmd(iot, ioh, (struct bha_softc *)0,
918 sizeof(inquire.cmd), (u_char *)&inquire.cmd,
919 sizeof(inquire.reply), (u_char *)&inquire.reply);
920
921 /*
922 * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev)
923 * have the extended-geometry register and also respond to
924 * BHA_INQUIRE_EXTENDED. Make sure we never match such cards,
925 * by checking the size of the reply is what a BusLogic card returns.
926 */
927 if (i) {
928 #ifdef BHADEBUG
929 printf("bha_find: board returned %d instead of %d to %s\n",
930 i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
931 #endif
932 return (0);
933 }
934
935 /* OK, we know we've found a buslogic adaptor. */
936
937 switch (inquire.reply.bus_type) {
938 case BHA_BUS_TYPE_24BIT:
939 case BHA_BUS_TYPE_32BIT:
940 break;
941 case BHA_BUS_TYPE_MCA:
942 /* We don't grok MicroChannel (yet). */
943 return (0);
944 default:
945 printf("bha_find: illegal bus type %c\n",
946 inquire.reply.bus_type);
947 return (0);
948 }
949
950 /* Note if we have a wide bus. */
951 iswide = inquire.reply.scsi_flags & BHA_SCSI_WIDE;
952
953 /*
954 * Assume we have a board at this stage setup dma channel from
955 * jumpers and save int level
956 */
957 delay(1000);
958 config.cmd.opcode = BHA_INQUIRE_CONFIG;
959 bha_cmd(iot, ioh, (struct bha_softc *)0,
960 sizeof(config.cmd), (u_char *)&config.cmd,
961 sizeof(config.reply), (u_char *)&config.reply);
962 switch (config.reply.chan) {
963 case EISADMA:
964 drq = -1;
965 break;
966 case CHAN0:
967 drq = 0;
968 break;
969 case CHAN5:
970 drq = 5;
971 break;
972 case CHAN6:
973 drq = 6;
974 break;
975 case CHAN7:
976 drq = 7;
977 break;
978 default:
979 printf("bha_find: illegal drq setting %x\n",
980 config.reply.chan);
981 return (0);
982 }
983
984 switch (config.reply.intr) {
985 case INT9:
986 irq = 9;
987 break;
988 case INT10:
989 irq = 10;
990 break;
991 case INT11:
992 irq = 11;
993 break;
994 case INT12:
995 irq = 12;
996 break;
997 case INT14:
998 irq = 14;
999 break;
1000 case INT15:
1001 irq = 15;
1002 break;
1003 default:
1004 printf("bha_find: illegal irq setting %x\n",
1005 config.reply.intr);
1006 return (0);
1007 }
1008
1009 /* if we want to fill in softc, do so now */
1010 if (sc != NULL) {
1011 sc->sc_irq = irq;
1012 sc->sc_drq = drq;
1013 sc->sc_scsi_dev = config.reply.scsi_dev;
1014 sc->sc_iswide = iswide;
1015 }
1016
1017 return (1);
1018 }
1019
1020
1021 /*
1022 * Disable the ISA-compatiblity ioports on PCI bha devices,
1023 * to ensure they're not autoconfigured a second time as an ISA bha.
1024 */
1025 int
1026 bha_disable_isacompat(sc)
1027 struct bha_softc *sc;
1028 {
1029 struct bha_isadisable isa_disable;
1030
1031 isa_disable.cmd.opcode = BHA_MODIFY_IOPORT;
1032 isa_disable.cmd.modifier = BHA_IOMODIFY_DISABLE1;
1033 bha_cmd(sc->sc_iot, sc->sc_ioh, sc,
1034 sizeof(isa_disable.cmd), (u_char*)&isa_disable.cmd,
1035 0, (u_char *)0);
1036 return (0);
1037 }
1038
1039
1040 /*
1041 * Start the board, ready for normal operation
1042 */
1043 void
1044 bha_init(sc)
1045 struct bha_softc *sc;
1046 {
1047 bus_space_tag_t iot = sc->sc_iot;
1048 bus_space_handle_t ioh = sc->sc_ioh;
1049 bus_dma_segment_t seg;
1050 struct bha_devices devices;
1051 struct bha_setup setup;
1052 struct bha_mailbox mailbox;
1053 struct bha_period period;
1054 int i, j, initial_ccbs, rlen, rseg;
1055
1056 /* Enable round-robin scheme - appeared at firmware rev. 3.31. */
1057 if (strcmp(sc->sc_firmware, "3.31") >= 0) {
1058 struct bha_toggle toggle;
1059
1060 toggle.cmd.opcode = BHA_ROUND_ROBIN;
1061 toggle.cmd.enable = 1;
1062 bha_cmd(iot, ioh, sc,
1063 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
1064 0, (u_char *)0);
1065 }
1066
1067 /*
1068 * Inquire installed devices (to force synchronous negotiation).
1069 */
1070
1071 /*
1072 * Poll targets 0 - 7.
1073 */
1074 devices.cmd.opcode = BHA_INQUIRE_DEVICES;
1075 bha_cmd(iot, ioh, sc,
1076 sizeof(devices.cmd), (u_char *)&devices.cmd,
1077 sizeof(devices.reply), (u_char *)&devices.reply);
1078
1079 /* Count installed units. */
1080 initial_ccbs = 0;
1081 for (i = 0; i < 8; i++) {
1082 for (j = 0; j < 8; j++) {
1083 if (((devices.reply.lun_map[i] >> j) & 1) == 1)
1084 initial_ccbs++;
1085 }
1086 }
1087
1088 /*
1089 * Poll targets 8 - 15 if we have a wide bus.
1090 */
1091 if (ISWIDE(sc)) {
1092 devices.cmd.opcode = BHA_INQUIRE_DEVICES_2;
1093 bha_cmd(iot, ioh, sc,
1094 sizeof(devices.cmd), (u_char *)&devices.cmd,
1095 sizeof(devices.reply), (u_char *)&devices.reply);
1096
1097 for (i = 0; i < 8; i++) {
1098 for (j = 0; j < 8; j++) {
1099 if (((devices.reply.lun_map[i] >> j) & 1) == 1)
1100 initial_ccbs++;
1101 }
1102 }
1103 }
1104
1105 initial_ccbs *= sc->sc_link.openings;
1106
1107 /* Obtain setup information from. */
1108 rlen = sizeof(setup.reply) +
1109 (ISWIDE(sc) ? sizeof(setup.reply_w) : 0);
1110 setup.cmd.opcode = BHA_INQUIRE_SETUP;
1111 setup.cmd.len = rlen;
1112 bha_cmd(iot, ioh, sc,
1113 sizeof(setup.cmd), (u_char *)&setup.cmd,
1114 rlen, (u_char *)&setup.reply);
1115
1116 printf("%s: %s, %s\n",
1117 sc->sc_dev.dv_xname,
1118 setup.reply.sync_neg ? "sync" : "async",
1119 setup.reply.parity ? "parity" : "no parity");
1120
1121 for (i = 0; i < 8; i++)
1122 period.reply.period[i] = setup.reply.sync[i].period * 5 + 20;
1123 if (ISWIDE(sc)) {
1124 for (i = 0; i < 8; i++)
1125 period.reply_w.period[i] =
1126 setup.reply_w.sync[i].period * 5 + 20;
1127 }
1128
1129 if (sc->sc_firmware[0] >= '3') {
1130 rlen = sizeof(period.reply) +
1131 (ISWIDE(sc) ? sizeof(period.reply_w) : 0);
1132 period.cmd.opcode = BHA_INQUIRE_PERIOD;
1133 period.cmd.len = rlen;
1134 bha_cmd(iot, ioh, sc,
1135 sizeof(period.cmd), (u_char *)&period.cmd,
1136 rlen, (u_char *)&period.reply);
1137 }
1138
1139 for (i = 0; i < 8; i++) {
1140 if (!setup.reply.sync[i].valid ||
1141 (!setup.reply.sync[i].offset &&
1142 !setup.reply.sync[i].period))
1143 continue;
1144 printf("%s targ %d: sync, offset %d, period %dnsec\n",
1145 sc->sc_dev.dv_xname, i,
1146 setup.reply.sync[i].offset, period.reply.period[i] * 10);
1147 }
1148 if (ISWIDE(sc)) {
1149 for (i = 0; i < 8; i++) {
1150 if (!setup.reply_w.sync[i].valid ||
1151 (!setup.reply_w.sync[i].offset &&
1152 !setup.reply_w.sync[i].period))
1153 continue;
1154 printf("%s targ %d: sync, offset %d, period %dnsec\n",
1155 sc->sc_dev.dv_xname, i + 8,
1156 setup.reply_w.sync[i].offset,
1157 period.reply_w.period[i] * 10);
1158 }
1159 }
1160
1161 /*
1162 * Allocate the mailbox.
1163 */
1164 if (bus_dmamem_alloc(sc->sc_dmat, NBPG, NBPG, 0, &seg, 1,
1165 &rseg, BUS_DMA_NOWAIT) ||
1166 bus_dmamem_map(sc->sc_dmat, &seg, rseg, NBPG,
1167 (caddr_t *)&wmbx, BUS_DMA_NOWAIT|BUS_DMAMEM_NOSYNC))
1168 panic("bha_init: can't create or map mailbox");
1169
1170 /*
1171 * Since DMA memory allocation is always rounded up to a
1172 * page size, create some ccbs from the leftovers.
1173 */
1174 if (bha_create_ccbs(sc, ((caddr_t)wmbx) +
1175 ALIGN(sizeof(struct bha_mbx)),
1176 NBPG - ALIGN(sizeof(struct bha_mbx)), initial_ccbs))
1177 panic("bha_init: can't create ccbs");
1178
1179 /*
1180 * Create and load the mailbox DMA map.
1181 */
1182 if (bus_dmamap_create(sc->sc_dmat, sizeof(struct bha_mbx), 1,
1183 sizeof(struct bha_mbx), 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
1184 &sc->sc_dmamap_mbox) ||
1185 bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_mbox, wmbx,
1186 sizeof(struct bha_mbx), NULL, BUS_DMA_NOWAIT))
1187 panic("bha_init: can't create or load mailbox dma map");
1188
1189 /*
1190 * Set up initial mail box for round-robin operation.
1191 */
1192 for (i = 0; i < BHA_MBX_SIZE; i++) {
1193 wmbx->mbo[i].cmd = BHA_MBO_FREE;
1194 wmbx->mbi[i].stat = BHA_MBI_FREE;
1195 }
1196 wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
1197 wmbx->tmbi = &wmbx->mbi[0];
1198 sc->sc_mbofull = 0;
1199
1200 /* Initialize mail box. */
1201 mailbox.cmd.opcode = BHA_MBX_INIT_EXTENDED;
1202 mailbox.cmd.nmbx = BHA_MBX_SIZE;
1203 ltophys(sc->sc_dmamap_mbox->dm_segs[0].ds_addr, mailbox.cmd.addr);
1204 bha_cmd(iot, ioh, sc,
1205 sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
1206 0, (u_char *)0);
1207 }
1208
1209 void
1210 bha_inquire_setup_information(sc)
1211 struct bha_softc *sc;
1212 {
1213 bus_space_tag_t iot = sc->sc_iot;
1214 bus_space_handle_t ioh = sc->sc_ioh;
1215 struct bha_model model;
1216 struct bha_revision revision;
1217 struct bha_digit digit;
1218 char *p;
1219
1220 /*
1221 * Get the firmware revision.
1222 */
1223 p = sc->sc_firmware;
1224 revision.cmd.opcode = BHA_INQUIRE_REVISION;
1225 bha_cmd(iot, ioh, sc,
1226 sizeof(revision.cmd), (u_char *)&revision.cmd,
1227 sizeof(revision.reply), (u_char *)&revision.reply);
1228 *p++ = revision.reply.firm_revision;
1229 *p++ = '.';
1230 *p++ = revision.reply.firm_version;
1231 digit.cmd.opcode = BHA_INQUIRE_REVISION_3;
1232 bha_cmd(iot, ioh, sc,
1233 sizeof(digit.cmd), (u_char *)&digit.cmd,
1234 sizeof(digit.reply), (u_char *)&digit.reply);
1235 *p++ = digit.reply.digit;
1236 if (revision.reply.firm_revision >= '3' ||
1237 (revision.reply.firm_revision == '3' &&
1238 revision.reply.firm_version >= '3')) {
1239 digit.cmd.opcode = BHA_INQUIRE_REVISION_4;
1240 bha_cmd(iot, ioh, sc,
1241 sizeof(digit.cmd), (u_char *)&digit.cmd,
1242 sizeof(digit.reply), (u_char *)&digit.reply);
1243 *p++ = digit.reply.digit;
1244 }
1245 while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0'))
1246 p--;
1247 *p = '\0';
1248
1249 /*
1250 * Get the model number.
1251 */
1252 if (revision.reply.firm_revision >= '3') {
1253 p = sc->sc_model;
1254 model.cmd.opcode = BHA_INQUIRE_MODEL;
1255 model.cmd.len = sizeof(model.reply);
1256 bha_cmd(iot, ioh, sc,
1257 sizeof(model.cmd), (u_char *)&model.cmd,
1258 sizeof(model.reply), (u_char *)&model.reply);
1259 *p++ = model.reply.id[0];
1260 *p++ = model.reply.id[1];
1261 *p++ = model.reply.id[2];
1262 *p++ = model.reply.id[3];
1263 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
1264 p--;
1265 *p++ = model.reply.version[0];
1266 *p++ = model.reply.version[1];
1267 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
1268 p--;
1269 *p = '\0';
1270 } else
1271 strcpy(sc->sc_model, "542B");
1272 }
1273
1274 void
1275 bhaminphys(bp)
1276 struct buf *bp;
1277 {
1278
1279 if (bp->b_bcount > BHA_MAXXFER)
1280 bp->b_bcount = BHA_MAXXFER;
1281 minphys(bp);
1282 }
1283
1284 /*
1285 * start a scsi operation given the command and the data address. Also needs
1286 * the unit, target and lu.
1287 */
1288 int
1289 bha_scsi_cmd(xs)
1290 struct scsipi_xfer *xs;
1291 {
1292 struct scsipi_link *sc_link = xs->sc_link;
1293 struct bha_softc *sc = sc_link->adapter_softc;
1294 bus_dma_tag_t dmat = sc->sc_dmat;
1295 struct bha_ccb *ccb;
1296 int error, seg, flags, s;
1297
1298 SC_DEBUG(sc_link, SDEV_DB2, ("bha_scsi_cmd\n"));
1299 /*
1300 * get a ccb to use. If the transfer
1301 * is from a buf (possibly from interrupt time)
1302 * then we can't allow it to sleep
1303 */
1304 flags = xs->flags;
1305 if ((ccb = bha_get_ccb(sc, flags)) == NULL) {
1306 xs->error = XS_DRIVER_STUFFUP;
1307 return (TRY_AGAIN_LATER);
1308 }
1309 ccb->xs = xs;
1310 ccb->timeout = xs->timeout;
1311
1312 /*
1313 * Put all the arguments for the xfer in the ccb
1314 */
1315 if (flags & SCSI_RESET) {
1316 ccb->opcode = BHA_RESET_CCB;
1317 ccb->scsi_cmd_length = 0;
1318 } else {
1319 /* can't use S/G if zero length */
1320 ccb->opcode = (xs->datalen ? BHA_INIT_SCAT_GATH_CCB
1321 : BHA_INITIATOR_CCB);
1322 bcopy(xs->cmd, &ccb->scsi_cmd,
1323 ccb->scsi_cmd_length = xs->cmdlen);
1324 }
1325
1326 if (xs->datalen) {
1327 /*
1328 * Map the DMA transfer.
1329 */
1330 #ifdef TFS
1331 if (flags & SCSI_DATA_UIO) {
1332 error = bus_dmamap_load_uio(dmat,
1333 ccb->dmamap_xfer, (struct uio *)xs->data,
1334 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1335 BUS_DMA_WAITOK);
1336 } else
1337 #endif /* TFS */
1338 {
1339 error = bus_dmamap_load(dmat,
1340 ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
1341 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1342 BUS_DMA_WAITOK);
1343 }
1344
1345 if (error) {
1346 if (error == EFBIG) {
1347 printf("%s: bha_scsi_cmd, more than %d"
1348 " dma segments\n",
1349 sc->sc_dev.dv_xname, BHA_NSEG);
1350 } else {
1351 printf("%s: bha_scsi_cmd, error %d loading"
1352 " dma map\n",
1353 sc->sc_dev.dv_xname, error);
1354 }
1355 goto bad;
1356 }
1357
1358 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
1359 (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1360 BUS_DMASYNC_PREWRITE);
1361
1362 /*
1363 * Load the hardware scatter/gather map with the
1364 * contents of the DMA map.
1365 */
1366 for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
1367 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
1368 ccb->scat_gath[seg].seg_addr);
1369 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
1370 ccb->scat_gath[seg].seg_len);
1371 }
1372
1373 ltophys(ccb->dmamap_self->dm_segs[0].ds_addr +
1374 offsetof(struct bha_ccb, scat_gath), ccb->data_addr);
1375 ltophys(ccb->dmamap_xfer->dm_nsegs *
1376 sizeof(struct bha_scat_gath), ccb->data_length);
1377 } else {
1378 /*
1379 * No data xfer, use non S/G values.
1380 */
1381 ltophys(0, ccb->data_addr);
1382 ltophys(0, ccb->data_length);
1383 }
1384
1385 ccb->data_out = 0;
1386 ccb->data_in = 0;
1387 ccb->target = sc_link->scsipi_scsi.target;
1388 ccb->lun = sc_link->scsipi_scsi.lun;
1389 ltophys(ccb->dmamap_self->dm_segs[0].ds_addr +
1390 offsetof(struct bha_ccb, scsi_sense), ccb->sense_ptr);
1391 ccb->req_sense_length = sizeof(ccb->scsi_sense);
1392 ccb->host_stat = 0x00;
1393 ccb->target_stat = 0x00;
1394 ccb->link_id = 0;
1395 ltophys(0, ccb->link_addr);
1396
1397 s = splbio();
1398 bha_queue_ccb(sc, ccb);
1399 splx(s);
1400
1401 /*
1402 * Usually return SUCCESSFULLY QUEUED
1403 */
1404 SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
1405 if ((flags & SCSI_POLL) == 0)
1406 return (SUCCESSFULLY_QUEUED);
1407
1408 /*
1409 * If we can't use interrupts, poll on completion
1410 */
1411 if (bha_poll(sc, xs, ccb->timeout)) {
1412 bha_timeout(ccb);
1413 if (bha_poll(sc, xs, ccb->timeout))
1414 bha_timeout(ccb);
1415 }
1416 return (COMPLETE);
1417
1418 bad:
1419 xs->error = XS_DRIVER_STUFFUP;
1420 bha_free_ccb(sc, ccb);
1421 return (COMPLETE);
1422 }
1423
1424 /*
1425 * Poll a particular unit, looking for a particular xs
1426 */
1427 int
1428 bha_poll(sc, xs, count)
1429 struct bha_softc *sc;
1430 struct scsipi_xfer *xs;
1431 int count;
1432 {
1433 bus_space_tag_t iot = sc->sc_iot;
1434 bus_space_handle_t ioh = sc->sc_ioh;
1435
1436 /* timeouts are in msec, so we loop in 1000 usec cycles */
1437 while (count) {
1438 /*
1439 * If we had interrupts enabled, would we
1440 * have got an interrupt?
1441 */
1442 if (bus_space_read_1(iot, ioh, BHA_INTR_PORT) &
1443 BHA_INTR_ANYINTR)
1444 bha_intr(sc);
1445 if (xs->flags & ITSDONE)
1446 return (0);
1447 delay(1000); /* only happens in boot so ok */
1448 count--;
1449 }
1450 return (1);
1451 }
1452
1453 void
1454 bha_timeout(arg)
1455 void *arg;
1456 {
1457 struct bha_ccb *ccb = arg;
1458 struct scsipi_xfer *xs = ccb->xs;
1459 struct scsipi_link *sc_link = xs->sc_link;
1460 struct bha_softc *sc = sc_link->adapter_softc;
1461 int s;
1462
1463 scsi_print_addr(sc_link);
1464 printf("timed out");
1465
1466 s = splbio();
1467
1468 #ifdef BHADIAG
1469 /*
1470 * If the ccb's mbx is not free, then the board has gone Far East?
1471 */
1472 bha_collect_mbo(sc);
1473 if (ccb->flags & CCB_SENDING) {
1474 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
1475 Debugger();
1476 }
1477 #endif
1478
1479 /*
1480 * If it has been through before, then
1481 * a previous abort has failed, don't
1482 * try abort again
1483 */
1484 if (ccb->flags & CCB_ABORT) {
1485 /* abort timed out */
1486 printf(" AGAIN\n");
1487 /* XXX Must reset! */
1488 } else {
1489 /* abort the operation that has timed out */
1490 printf("\n");
1491 ccb->xs->error = XS_TIMEOUT;
1492 ccb->timeout = BHA_ABORT_TIMEOUT;
1493 ccb->flags |= CCB_ABORT;
1494 bha_queue_ccb(sc, ccb);
1495 }
1496
1497 splx(s);
1498 }
1499