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