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