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