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