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