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