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