aha.c revision 1.28 1 /* $NetBSD: aha.c,v 1.28 2000/03/30 12:45:28 augustss Exp $ */
2
3 #include "opt_ddb.h"
4
5 #undef AHADIAG
6 #ifdef DDB
7 #define integrate
8 #else
9 #define integrate static inline
10 #endif
11
12 /*-
13 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
14 * All rights reserved.
15 *
16 * This code is derived from software contributed to The NetBSD Foundation
17 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
18 * Simulation Facility, NASA Ames Research Center.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * 3. All advertising materials mentioning features or use of this software
29 * must display the following acknowledgement:
30 * This product includes software developed by the NetBSD
31 * Foundation, Inc. and its contributors.
32 * 4. Neither the name of The NetBSD Foundation nor the names of its
33 * contributors may be used to endorse or promote products derived
34 * from this software without specific prior written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
37 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
38 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
40 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 * POSSIBILITY OF SUCH DAMAGE.
47 */
48
49 /*
50 * Originally written by Julian Elischer (julian (at) tfs.com)
51 * for TRW Financial Systems for use under the MACH(2.5) operating system.
52 *
53 * TRW Financial Systems, in accordance with their agreement with Carnegie
54 * Mellon University, makes this software available to CMU to distribute
55 * or use in any manner that they see fit as long as this message is kept with
56 * the software. For this reason TFS also grants any other persons or
57 * organisations permission to use or modify this software.
58 *
59 * TFS supplies this software to be publicly redistributed
60 * on the understanding that TFS is not responsible for the correct
61 * functioning of this software in any circumstances.
62 */
63
64 #include <sys/types.h>
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/callout.h>
68 #include <sys/kernel.h>
69 #include <sys/errno.h>
70 #include <sys/ioctl.h>
71 #include <sys/device.h>
72 #include <sys/malloc.h>
73 #include <sys/buf.h>
74 #include <sys/proc.h>
75 #include <sys/user.h>
76
77 #include <machine/bus.h>
78 #include <machine/intr.h>
79
80 #include <dev/scsipi/scsi_all.h>
81 #include <dev/scsipi/scsipi_all.h>
82 #include <dev/scsipi/scsiconf.h>
83
84 #include <dev/ic/ahareg.h>
85 #include <dev/ic/ahavar.h>
86
87 #ifndef DDB
88 #define Debugger() panic("should call debugger here (aha1542.c)")
89 #endif /* ! DDB */
90
91 #define AHA_MAXXFER ((AHA_NSEG - 1) << PGSHIFT)
92
93 #ifdef AHADEBUG
94 int aha_debug = 1;
95 #endif /* AHADEBUG */
96
97 int aha_cmd __P((bus_space_tag_t, bus_space_handle_t, struct aha_softc *, int,
98 u_char *, int, u_char *));
99 integrate void aha_finish_ccbs __P((struct aha_softc *));
100 integrate void aha_reset_ccb __P((struct aha_softc *, struct aha_ccb *));
101 void aha_free_ccb __P((struct aha_softc *, struct aha_ccb *));
102 integrate int aha_init_ccb __P((struct aha_softc *, struct aha_ccb *));
103 struct aha_ccb *aha_get_ccb __P((struct aha_softc *, int));
104 struct aha_ccb *aha_ccb_phys_kv __P((struct aha_softc *, u_long));
105 void aha_queue_ccb __P((struct aha_softc *, struct aha_ccb *));
106 void aha_collect_mbo __P((struct aha_softc *));
107 void aha_start_ccbs __P((struct aha_softc *));
108 void aha_done __P((struct aha_softc *, struct aha_ccb *));
109 int aha_init __P((struct aha_softc *));
110 void aha_inquire_setup_information __P((struct aha_softc *));
111 void ahaminphys __P((struct buf *));
112 int aha_scsi_cmd __P((struct scsipi_xfer *));
113 int aha_poll __P((struct aha_softc *, struct scsipi_xfer *, int));
114 void aha_timeout __P((void *arg));
115 int aha_create_ccbs __P((struct aha_softc *, struct aha_ccb *, int));
116
117 /* the below structure is so we have a default dev struct for out link struct */
118 struct scsipi_device aha_dev = {
119 NULL, /* Use default error handler */
120 NULL, /* have a queue, served by this */
121 NULL, /* have no async handler */
122 NULL, /* Use default 'done' routine */
123 };
124
125 #define AHA_RESET_TIMEOUT 2000 /* time to wait for reset (mSec) */
126 #define AHA_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */
127
128 /*
129 * aha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
130 *
131 * Activate Adapter command
132 * icnt: number of args (outbound bytes including opcode)
133 * ibuf: argument buffer
134 * ocnt: number of expected returned bytes
135 * obuf: result buffer
136 * wait: number of seconds to wait for response
137 *
138 * Performs an adapter command through the ports. Not to be confused with a
139 * scsi command, which is read in via the dma; one of the adapter commands
140 * tells it to read in a scsi command.
141 */
142 int
143 aha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
144 bus_space_tag_t iot;
145 bus_space_handle_t ioh;
146 struct aha_softc *sc;
147 int icnt, ocnt;
148 u_char *ibuf, *obuf;
149 {
150 const char *name;
151 int i;
152 int wait;
153 u_char sts;
154 u_char opcode = ibuf[0];
155
156 if (sc != NULL)
157 name = sc->sc_dev.dv_xname;
158 else
159 name = "(aha probe)";
160
161 /*
162 * Calculate a reasonable timeout for the command.
163 */
164 switch (opcode) {
165 case AHA_INQUIRE_DEVICES:
166 wait = 90 * 20000;
167 break;
168 default:
169 wait = 1 * 20000;
170 break;
171 }
172
173 /*
174 * Wait for the adapter to go idle, unless it's one of
175 * the commands which don't need this
176 */
177 if (opcode != AHA_MBO_INTR_EN) {
178 for (i = 20000; i; i--) { /* 1 sec? */
179 sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
180 if (sts & AHA_STAT_IDLE)
181 break;
182 delay(50);
183 }
184 if (!i) {
185 printf("%s: aha_cmd, host not idle(0x%x)\n",
186 name, sts);
187 return (1);
188 }
189 }
190 /*
191 * Now that it is idle, if we expect output, preflush the
192 * queue feeding to us.
193 */
194 if (ocnt) {
195 while ((bus_space_read_1(iot, ioh, AHA_STAT_PORT)) & AHA_STAT_DF)
196 bus_space_read_1(iot, ioh, AHA_DATA_PORT);
197 }
198 /*
199 * Output the command and the number of arguments given
200 * for each byte, first check the port is empty.
201 */
202 while (icnt--) {
203 for (i = wait; i; i--) {
204 sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
205 if (!(sts & AHA_STAT_CDF))
206 break;
207 delay(50);
208 }
209 if (!i) {
210 if (opcode != AHA_INQUIRE_REVISION)
211 printf("%s: aha_cmd, cmd/data port full\n", name);
212 bus_space_write_1(iot, ioh, AHA_CTRL_PORT, AHA_CTRL_SRST);
213 return (1);
214 }
215 bus_space_write_1(iot, ioh, AHA_CMD_PORT, *ibuf++);
216 }
217 /*
218 * If we expect input, loop that many times, each time,
219 * looking for the data register to have valid data
220 */
221 while (ocnt--) {
222 for (i = wait; i; i--) {
223 sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
224 if (sts & AHA_STAT_DF)
225 break;
226 delay(50);
227 }
228 if (!i) {
229 if (opcode != AHA_INQUIRE_REVISION)
230 printf("%s: aha_cmd, cmd/data port empty %d\n",
231 name, ocnt);
232 bus_space_write_1(iot, ioh, AHA_CTRL_PORT, AHA_CTRL_SRST);
233 return (1);
234 }
235 *obuf++ = bus_space_read_1(iot, ioh, AHA_DATA_PORT);
236 }
237 /*
238 * Wait for the board to report a finished instruction.
239 * We may get an extra interrupt for the HACC signal, but this is
240 * unimportant.
241 */
242 if (opcode != AHA_MBO_INTR_EN) {
243 for (i = 20000; i; i--) { /* 1 sec? */
244 sts = bus_space_read_1(iot, ioh, AHA_INTR_PORT);
245 /* XXX Need to save this in the interrupt handler? */
246 if (sts & AHA_INTR_HACC)
247 break;
248 delay(50);
249 }
250 if (!i) {
251 printf("%s: aha_cmd, host not finished(0x%x)\n",
252 name, sts);
253 return (1);
254 }
255 }
256 bus_space_write_1(iot, ioh, AHA_CTRL_PORT, AHA_CTRL_IRST);
257 return (0);
258 }
259
260 void
261 aha_attach(sc, apd)
262 struct aha_softc *sc;
263 struct aha_probe_data *apd;
264 {
265
266 TAILQ_INIT(&sc->sc_free_ccb);
267 TAILQ_INIT(&sc->sc_waiting_ccb);
268 TAILQ_INIT(&sc->sc_queue);
269
270 /*
271 * Fill in the adapter.
272 */
273 sc->sc_adapter.scsipi_cmd = aha_scsi_cmd;
274 sc->sc_adapter.scsipi_minphys = ahaminphys;
275
276 /*
277 * fill in the prototype scsipi_link.
278 */
279 sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
280 sc->sc_link.adapter_softc = sc;
281 sc->sc_link.scsipi_scsi.adapter_target = apd->sc_scsi_dev;
282 sc->sc_link.adapter = &sc->sc_adapter;
283 sc->sc_link.device = &aha_dev;
284 sc->sc_link.openings = 2;
285 sc->sc_link.scsipi_scsi.max_target = 7;
286 sc->sc_link.scsipi_scsi.max_lun = 7;
287 sc->sc_link.type = BUS_SCSI;
288
289 aha_inquire_setup_information(sc);
290 if (aha_init(sc) != 0) {
291 /* Error during initialization! */
292 return;
293 }
294
295 /*
296 * ask the adapter what subunits are present
297 */
298 config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
299 }
300
301 integrate void
302 aha_finish_ccbs(sc)
303 struct aha_softc *sc;
304 {
305 struct aha_mbx_in *wmbi;
306 struct aha_ccb *ccb;
307 int i;
308
309 wmbi = wmbx->tmbi;
310
311 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
312 AHA_MBI_OFF(wmbi), sizeof(struct aha_mbx_in),
313 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
314
315 if (wmbi->stat == AHA_MBI_FREE) {
316 for (i = 0; i < AHA_MBX_SIZE; i++) {
317 if (wmbi->stat != AHA_MBI_FREE) {
318 printf("%s: mbi not in round-robin order\n",
319 sc->sc_dev.dv_xname);
320 goto AGAIN;
321 }
322 aha_nextmbx(wmbi, wmbx, mbi);
323 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
324 AHA_MBI_OFF(wmbi), sizeof(struct aha_mbx_in),
325 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
326 }
327 #ifdef AHADIAGnot
328 printf("%s: mbi interrupt with no full mailboxes\n",
329 sc->sc_dev.dv_xname);
330 #endif
331 return;
332 }
333
334 AGAIN:
335 do {
336 ccb = aha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
337 if (!ccb) {
338 printf("%s: bad mbi ccb pointer; skipping\n",
339 sc->sc_dev.dv_xname);
340 goto next;
341 }
342
343 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
344 AHA_CCB_OFF(ccb), sizeof(struct aha_ccb),
345 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
346
347 #ifdef AHADEBUG
348 if (aha_debug) {
349 u_char *cp = &ccb->scsi_cmd;
350 printf("op=%x %x %x %x %x %x\n",
351 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
352 printf("stat %x for mbi addr = 0x%08x, ",
353 wmbi->stat, wmbi);
354 printf("ccb addr = 0x%x\n", ccb);
355 }
356 #endif /* AHADEBUG */
357
358 switch (wmbi->stat) {
359 case AHA_MBI_OK:
360 case AHA_MBI_ERROR:
361 if ((ccb->flags & CCB_ABORT) != 0) {
362 /*
363 * If we already started an abort, wait for it
364 * to complete before clearing the CCB. We
365 * could instead just clear CCB_SENDING, but
366 * what if the mailbox was already received?
367 * The worst that happens here is that we clear
368 * the CCB a bit later than we need to. BFD.
369 */
370 goto next;
371 }
372 break;
373
374 case AHA_MBI_ABORT:
375 case AHA_MBI_UNKNOWN:
376 /*
377 * Even if the CCB wasn't found, we clear it anyway.
378 * See preceeding comment.
379 */
380 break;
381
382 default:
383 printf("%s: bad mbi status %02x; skipping\n",
384 sc->sc_dev.dv_xname, wmbi->stat);
385 goto next;
386 }
387
388 callout_stop(&ccb->xs->xs_callout);
389 aha_done(sc, ccb);
390
391 next:
392 wmbi->stat = AHA_MBI_FREE;
393 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
394 AHA_MBI_OFF(wmbi), sizeof(struct aha_mbx_in),
395 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
396 aha_nextmbx(wmbi, wmbx, mbi);
397 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
398 AHA_MBI_OFF(wmbi), sizeof(struct aha_mbx_in),
399 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
400 } while (wmbi->stat != AHA_MBI_FREE);
401
402 wmbx->tmbi = wmbi;
403 }
404
405 /*
406 * Catch an interrupt from the adaptor
407 */
408 int
409 aha_intr(arg)
410 void *arg;
411 {
412 struct aha_softc *sc = arg;
413 bus_space_tag_t iot = sc->sc_iot;
414 bus_space_handle_t ioh = sc->sc_ioh;
415 u_char sts;
416
417 #ifdef AHADEBUG
418 printf("%s: aha_intr ", sc->sc_dev.dv_xname);
419 #endif /*AHADEBUG */
420
421 /*
422 * First acknowlege the interrupt, Then if it's not telling about
423 * a completed operation just return.
424 */
425 sts = bus_space_read_1(iot, ioh, AHA_INTR_PORT);
426 if ((sts & AHA_INTR_ANYINTR) == 0)
427 return (0);
428 bus_space_write_1(iot, ioh, AHA_CTRL_PORT, AHA_CTRL_IRST);
429
430 #ifdef AHADIAG
431 /* Make sure we clear CCB_SENDING before finishing a CCB. */
432 aha_collect_mbo(sc);
433 #endif
434
435 /* Mail box out empty? */
436 if (sts & AHA_INTR_MBOA) {
437 struct aha_toggle toggle;
438
439 toggle.cmd.opcode = AHA_MBO_INTR_EN;
440 toggle.cmd.enable = 0;
441 aha_cmd(iot, ioh, sc,
442 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
443 0, (u_char *)0);
444 aha_start_ccbs(sc);
445 }
446
447 /* Mail box in full? */
448 if (sts & AHA_INTR_MBIF)
449 aha_finish_ccbs(sc);
450
451 return (1);
452 }
453
454 integrate void
455 aha_reset_ccb(sc, ccb)
456 struct aha_softc *sc;
457 struct aha_ccb *ccb;
458 {
459
460 ccb->flags = 0;
461 }
462
463 /*
464 * A ccb is put onto the free list.
465 */
466 void
467 aha_free_ccb(sc, ccb)
468 struct aha_softc *sc;
469 struct aha_ccb *ccb;
470 {
471 int s;
472
473 s = splbio();
474
475 aha_reset_ccb(sc, ccb);
476 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
477
478 /*
479 * If there were none, wake anybody waiting for one to come free,
480 * starting with queued entries.
481 */
482 if (ccb->chain.tqe_next == 0)
483 wakeup(&sc->sc_free_ccb);
484
485 splx(s);
486 }
487
488 integrate int
489 aha_init_ccb(sc, ccb)
490 struct aha_softc *sc;
491 struct aha_ccb *ccb;
492 {
493 bus_dma_tag_t dmat = sc->sc_dmat;
494 int hashnum, error;
495
496 /*
497 * Create the DMA map for this CCB.
498 */
499 error = bus_dmamap_create(dmat, AHA_MAXXFER, AHA_NSEG, AHA_MAXXFER,
500 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
501 if (error) {
502 printf("%s: unable to create ccb DMA map, error = %d\n",
503 sc->sc_dev.dv_xname, error);
504 return (error);
505 }
506
507 /*
508 * put in the phystokv hash table
509 * Never gets taken out.
510 */
511 ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr +
512 AHA_CCB_OFF(ccb);
513 hashnum = CCB_HASH(ccb->hashkey);
514 ccb->nexthash = sc->sc_ccbhash[hashnum];
515 sc->sc_ccbhash[hashnum] = ccb;
516 aha_reset_ccb(sc, ccb);
517 return (0);
518 }
519
520 /*
521 * Create a set of ccbs and add them to the free list. Called once
522 * by aha_init(). We return the number of CCBs successfully created.
523 */
524 int
525 aha_create_ccbs(sc, ccbstore, count)
526 struct aha_softc *sc;
527 struct aha_ccb *ccbstore;
528 int count;
529 {
530 struct aha_ccb *ccb;
531 int i, error;
532
533 bzero(ccbstore, sizeof(struct aha_ccb) * count);
534 for (i = 0; i < count; i++) {
535 ccb = &ccbstore[i];
536 if ((error = aha_init_ccb(sc, ccb)) != 0) {
537 printf("%s: unable to initialize ccb, error = %d\n",
538 sc->sc_dev.dv_xname, error);
539 goto out;
540 }
541 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
542 }
543 out:
544 return (i);
545 }
546
547 /*
548 * Get a free ccb
549 *
550 * If there are none, see if we can allocate a new one. If so, put it in
551 * the hash table too otherwise either return an error or sleep.
552 */
553 struct aha_ccb *
554 aha_get_ccb(sc, flags)
555 struct aha_softc *sc;
556 int flags;
557 {
558 struct aha_ccb *ccb;
559 int s;
560
561 s = splbio();
562
563 /*
564 * If we can and have to, sleep waiting for one to come free
565 * but only if we can't allocate a new one.
566 */
567 for (;;) {
568 ccb = sc->sc_free_ccb.tqh_first;
569 if (ccb) {
570 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
571 break;
572 }
573 if ((flags & XS_CTL_NOSLEEP) != 0)
574 goto out;
575 tsleep(&sc->sc_free_ccb, PRIBIO, "ahaccb", 0);
576 }
577
578 ccb->flags |= CCB_ALLOC;
579
580 out:
581 splx(s);
582 return (ccb);
583 }
584
585 /*
586 * Given a physical address, find the ccb that it corresponds to.
587 */
588 struct aha_ccb *
589 aha_ccb_phys_kv(sc, ccb_phys)
590 struct aha_softc *sc;
591 u_long ccb_phys;
592 {
593 int hashnum = CCB_HASH(ccb_phys);
594 struct aha_ccb *ccb = sc->sc_ccbhash[hashnum];
595
596 while (ccb) {
597 if (ccb->hashkey == ccb_phys)
598 break;
599 ccb = ccb->nexthash;
600 }
601 return (ccb);
602 }
603
604 /*
605 * Queue a CCB to be sent to the controller, and send it if possible.
606 */
607 void
608 aha_queue_ccb(sc, ccb)
609 struct aha_softc *sc;
610 struct aha_ccb *ccb;
611 {
612
613 TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
614 aha_start_ccbs(sc);
615 }
616
617 /*
618 * Garbage collect mailboxes that are no longer in use.
619 */
620 void
621 aha_collect_mbo(sc)
622 struct aha_softc *sc;
623 {
624 struct aha_mbx_out *wmbo; /* Mail Box Out pointer */
625 #ifdef AHADIAG
626 struct aha_ccb *ccb;
627 #endif
628
629 wmbo = wmbx->cmbo;
630
631 while (sc->sc_mbofull > 0) {
632 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
633 AHA_MBO_OFF(wmbo), sizeof(struct aha_mbx_out),
634 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
635 if (wmbo->cmd != AHA_MBO_FREE)
636 break;
637
638 #ifdef AHADIAG
639 ccb = aha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
640 ccb->flags &= ~CCB_SENDING;
641 #endif
642
643 --sc->sc_mbofull;
644 aha_nextmbx(wmbo, wmbx, mbo);
645 }
646
647 wmbx->cmbo = wmbo;
648 }
649
650 /*
651 * Send as many CCBs as we have empty mailboxes for.
652 */
653 void
654 aha_start_ccbs(sc)
655 struct aha_softc *sc;
656 {
657 bus_space_tag_t iot = sc->sc_iot;
658 bus_space_handle_t ioh = sc->sc_ioh;
659 struct aha_mbx_out *wmbo; /* Mail Box Out pointer */
660 struct aha_ccb *ccb;
661
662 wmbo = wmbx->tmbo;
663
664 while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) {
665 if (sc->sc_mbofull >= AHA_MBX_SIZE) {
666 aha_collect_mbo(sc);
667 if (sc->sc_mbofull >= AHA_MBX_SIZE) {
668 struct aha_toggle toggle;
669
670 toggle.cmd.opcode = AHA_MBO_INTR_EN;
671 toggle.cmd.enable = 1;
672 aha_cmd(iot, ioh, sc,
673 sizeof(toggle.cmd), (u_char *)&toggle.cmd,
674 0, (u_char *)0);
675 break;
676 }
677 }
678
679 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
680 #ifdef AHADIAG
681 ccb->flags |= CCB_SENDING;
682 #endif
683
684 /* Link ccb to mbo. */
685 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
686 AHA_CCB_OFF(ccb), wmbo->ccb_addr);
687 if (ccb->flags & CCB_ABORT)
688 wmbo->cmd = AHA_MBO_ABORT;
689 else
690 wmbo->cmd = AHA_MBO_START;
691
692 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
693 AHA_MBO_OFF(wmbo), sizeof(struct aha_mbx_out),
694 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
695
696 /* Tell the card to poll immediately. */
697 bus_space_write_1(iot, ioh, AHA_CMD_PORT, AHA_START_SCSI);
698
699 if ((ccb->xs->xs_control & XS_CTL_POLL) == 0)
700 callout_reset(&ccb->xs->xs_callout,
701 (ccb->timeout * hz) / 1000, aha_timeout, ccb);
702
703 ++sc->sc_mbofull;
704 aha_nextmbx(wmbo, wmbx, mbo);
705 }
706
707 wmbx->tmbo = wmbo;
708 }
709
710 /*
711 * We have a ccb which has been processed by the
712 * adaptor, now we look to see how the operation
713 * went. Wake up the owner if waiting
714 */
715 void
716 aha_done(sc, ccb)
717 struct aha_softc *sc;
718 struct aha_ccb *ccb;
719 {
720 bus_dma_tag_t dmat = sc->sc_dmat;
721 struct scsipi_sense_data *s1, *s2;
722 struct scsipi_xfer *xs = ccb->xs;
723
724 SC_DEBUG(xs->sc_link, SDEV_DB2, ("aha_done\n"));
725
726 /*
727 * If we were a data transfer, unload the map that described
728 * the data buffer.
729 */
730 if (xs->datalen) {
731 bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
732 ccb->dmamap_xfer->dm_mapsize,
733 (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD :
734 BUS_DMASYNC_POSTWRITE);
735 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
736 }
737
738 /*
739 * Otherwise, put the results of the operation
740 * into the xfer and call whoever started it
741 */
742 #ifdef AHADIAG
743 if (ccb->flags & CCB_SENDING) {
744 printf("%s: exiting ccb still in transit!\n", sc->sc_dev.dv_xname);
745 Debugger();
746 return;
747 }
748 #endif
749 if ((ccb->flags & CCB_ALLOC) == 0) {
750 printf("%s: exiting ccb not allocated!\n", sc->sc_dev.dv_xname);
751 Debugger();
752 return;
753 }
754 if (xs->error == XS_NOERROR) {
755 if (ccb->host_stat != AHA_OK) {
756 switch (ccb->host_stat) {
757 case AHA_SEL_TIMEOUT: /* No response */
758 xs->error = XS_SELTIMEOUT;
759 break;
760 default: /* Other scsi protocol messes */
761 printf("%s: host_stat %x\n",
762 sc->sc_dev.dv_xname, ccb->host_stat);
763 xs->error = XS_DRIVER_STUFFUP;
764 break;
765 }
766 } else if (ccb->target_stat != SCSI_OK) {
767 switch (ccb->target_stat) {
768 case SCSI_CHECK:
769 s1 = (struct scsipi_sense_data *) (((char *) (&ccb->scsi_cmd)) +
770 ccb->scsi_cmd_length);
771 s2 = &xs->sense.scsi_sense;
772 *s2 = *s1;
773 xs->error = XS_SENSE;
774 break;
775 case SCSI_BUSY:
776 xs->error = XS_BUSY;
777 break;
778 default:
779 printf("%s: target_stat %x\n",
780 sc->sc_dev.dv_xname, ccb->target_stat);
781 xs->error = XS_DRIVER_STUFFUP;
782 break;
783 }
784 } else
785 xs->resid = 0;
786 }
787 aha_free_ccb(sc, ccb);
788 xs->xs_status |= XS_STS_DONE;
789 scsipi_done(xs);
790
791 /*
792 * If there are queue entries in the software queue, try to
793 * run the first one. We should be more or less guaranteed
794 * to succeed, since we just freed a CCB.
795 *
796 * NOTE: aha_scsi_cmd() relies on our calling it with
797 * the first entry in the queue.
798 */
799 if ((xs = TAILQ_FIRST(&sc->sc_queue)) != NULL)
800 (void) aha_scsi_cmd(xs);
801 }
802
803 /*
804 * Find the board and find its irq/drq
805 */
806 int
807 aha_find(iot, ioh, sc)
808 bus_space_tag_t iot;
809 bus_space_handle_t ioh;
810 struct aha_probe_data *sc;
811 {
812 int i;
813 u_char sts;
814 struct aha_config config;
815 int irq, drq;
816
817 /*
818 * reset board, If it doesn't respond, assume
819 * that it's not there.. good for the probe
820 */
821
822 bus_space_write_1(iot, ioh, AHA_CTRL_PORT, AHA_CTRL_HRST | AHA_CTRL_SRST);
823
824 delay(100);
825 for (i = AHA_RESET_TIMEOUT; i; i--) {
826 sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
827 if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
828 break;
829 delay(1000); /* calibrated in msec */
830 }
831 if (!i) {
832 #ifdef AHADEBUG
833 if (aha_debug)
834 printf("aha_find: No answer from adaptec board\n");
835 #endif /* AHADEBUG */
836 return (0);
837 }
838
839 /*
840 * setup dma channel from jumpers and save int
841 * level
842 */
843 delay(1000); /* for Bustek 545 */
844 config.cmd.opcode = AHA_INQUIRE_CONFIG;
845 aha_cmd(iot, ioh, (struct aha_softc *)0,
846 sizeof(config.cmd), (u_char *)&config.cmd,
847 sizeof(config.reply), (u_char *)&config.reply);
848 switch (config.reply.chan) {
849 case EISADMA:
850 drq = -1;
851 break;
852 case CHAN0:
853 drq = 0;
854 break;
855 case CHAN5:
856 drq = 5;
857 break;
858 case CHAN6:
859 drq = 6;
860 break;
861 case CHAN7:
862 drq = 7;
863 break;
864 default:
865 printf("aha_find: illegal drq setting %x\n", config.reply.chan);
866 return (0);
867 }
868
869 switch (config.reply.intr) {
870 case INT9:
871 irq = 9;
872 break;
873 case INT10:
874 irq = 10;
875 break;
876 case INT11:
877 irq = 11;
878 break;
879 case INT12:
880 irq = 12;
881 break;
882 case INT14:
883 irq = 14;
884 break;
885 case INT15:
886 irq = 15;
887 break;
888 default:
889 printf("aha_find: illegal irq setting %x\n", config.reply.intr);
890 return (0);
891 }
892
893 if (sc) {
894 sc->sc_irq = irq;
895 sc->sc_drq = drq;
896 sc->sc_scsi_dev = config.reply.scsi_dev;
897 }
898
899 return (1);
900 }
901
902 /*
903 * Start the board, ready for normal operation
904 */
905 int
906 aha_init(sc)
907 struct aha_softc *sc;
908 {
909 bus_space_tag_t iot = sc->sc_iot;
910 bus_space_handle_t ioh = sc->sc_ioh;
911 bus_dma_segment_t seg;
912 struct aha_devices devices;
913 struct aha_setup setup;
914 struct aha_mailbox mailbox;
915 int error, i, j, initial_ccbs, rseg;
916
917 /*
918 * XXX
919 * If we are a 1542C or later, disable the extended BIOS so that the
920 * mailbox interface is unlocked.
921 * No need to check the extended BIOS flags as some of the
922 * extensions that cause us problems are not flagged in that byte.
923 */
924 if (!strncmp(sc->sc_model, "1542C", 5)) {
925 struct aha_extbios extbios;
926 struct aha_unlock unlock;
927
928 printf("%s: unlocking mailbox interface\n", sc->sc_dev.dv_xname);
929 extbios.cmd.opcode = AHA_EXT_BIOS;
930 aha_cmd(iot, ioh, sc,
931 sizeof(extbios.cmd), (u_char *)&extbios.cmd,
932 sizeof(extbios.reply), (u_char *)&extbios.reply);
933
934 #ifdef AHADEBUG
935 printf("%s: flags=%02x, mailboxlock=%02x\n",
936 sc->sc_dev.dv_xname,
937 extbios.reply.flags, extbios.reply.mailboxlock);
938 #endif /* AHADEBUG */
939
940 unlock.cmd.opcode = AHA_MBX_ENABLE;
941 unlock.cmd.junk = 0;
942 unlock.cmd.magic = extbios.reply.mailboxlock;
943 aha_cmd(iot, ioh, sc,
944 sizeof(unlock.cmd), (u_char *)&unlock.cmd,
945 0, (u_char *)0);
946 }
947
948 #if 0
949 /*
950 * Change the bus on/off times to not clash with other dma users.
951 */
952 aha_cmd(iot, ioh, 1, 0, 0, 0, AHA_BUS_ON_TIME_SET, 7);
953 aha_cmd(iot, ioh, 1, 0, 0, 0, AHA_BUS_OFF_TIME_SET, 4);
954 #endif
955
956 /* Inquire Installed Devices (to force synchronous negotiation). */
957 devices.cmd.opcode = AHA_INQUIRE_DEVICES;
958 aha_cmd(iot, ioh, sc,
959 sizeof(devices.cmd), (u_char *)&devices.cmd,
960 sizeof(devices.reply), (u_char *)&devices.reply);
961
962 /* Count installed units */
963 initial_ccbs = 0;
964 for (i = 0; i < 8; i++) {
965 for (j = 0; j < 8; j++) {
966 if (((devices.reply.lun_map[i] >> j) & 1) == 1)
967 initial_ccbs += 1;
968 }
969 }
970 initial_ccbs *= sc->sc_link.openings;
971 if (initial_ccbs > AHA_CCB_MAX)
972 initial_ccbs = AHA_CCB_MAX;
973 if (initial_ccbs == 0) /* yes, this can happen */
974 initial_ccbs = sc->sc_link.openings;
975
976 /* Obtain setup information from. */
977 setup.cmd.opcode = AHA_INQUIRE_SETUP;
978 setup.cmd.len = sizeof(setup.reply);
979 aha_cmd(iot, ioh, sc,
980 sizeof(setup.cmd), (u_char *)&setup.cmd,
981 sizeof(setup.reply), (u_char *)&setup.reply);
982
983 printf("%s: %s, %s\n",
984 sc->sc_dev.dv_xname,
985 setup.reply.sync_neg ? "sync" : "async",
986 setup.reply.parity ? "parity" : "no parity");
987
988 for (i = 0; i < 8; i++) {
989 if (!setup.reply.sync[i].valid ||
990 (!setup.reply.sync[i].offset && !setup.reply.sync[i].period))
991 continue;
992 printf("%s targ %d: sync, offset %d, period %dnsec\n",
993 sc->sc_dev.dv_xname, i,
994 setup.reply.sync[i].offset, setup.reply.sync[i].period * 50 + 200);
995 }
996
997 /*
998 * Allocate the mailbox and control blocks.
999 */
1000 if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct aha_control),
1001 NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
1002 printf("%s: unable to allocate control structures, "
1003 "error = %d\n", sc->sc_dev.dv_xname, error);
1004 return (error);
1005 }
1006 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
1007 sizeof(struct aha_control), (caddr_t *)&sc->sc_control,
1008 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
1009 printf("%s: unable to map control structures, error = %d\n",
1010 sc->sc_dev.dv_xname, error);
1011 return (error);
1012 }
1013
1014 /*
1015 * Create and load the DMA map used for the mailbox and
1016 * control blocks.
1017 */
1018 if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct aha_control),
1019 1, sizeof(struct aha_control), 0, BUS_DMA_NOWAIT,
1020 &sc->sc_dmamap_control)) != 0) {
1021 printf("%s: unable to create control DMA map, error = %d\n",
1022 sc->sc_dev.dv_xname, error);
1023 return (error);
1024 }
1025 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
1026 sc->sc_control, sizeof(struct aha_control), NULL,
1027 BUS_DMA_NOWAIT)) != 0) {
1028 printf("%s: unable to load control DMA map, error = %d\n",
1029 sc->sc_dev.dv_xname, error);
1030 return (error);
1031 }
1032
1033 /*
1034 * Initialize the control blocks.
1035 */
1036 i = aha_create_ccbs(sc, sc->sc_control->ac_ccbs, initial_ccbs);
1037 if (i == 0) {
1038 printf("%s: unable to create control blocks\n",
1039 sc->sc_dev.dv_xname);
1040 return (ENOMEM);
1041 } else if (i != initial_ccbs) {
1042 printf("%s: WARNING: only %d of %d control blocks created\n",
1043 sc->sc_dev.dv_xname, i, initial_ccbs);
1044 }
1045
1046 /*
1047 * Set up initial mail box for round-robin operation.
1048 */
1049 for (i = 0; i < AHA_MBX_SIZE; i++) {
1050 wmbx->mbo[i].cmd = AHA_MBO_FREE;
1051 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1052 AHA_MBO_OFF(&wmbx->mbo[i]), sizeof(struct aha_mbx_out),
1053 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1054 wmbx->mbi[i].stat = AHA_MBI_FREE;
1055 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1056 AHA_MBI_OFF(&wmbx->mbi[i]), sizeof(struct aha_mbx_in),
1057 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1058 }
1059 wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
1060 wmbx->tmbi = &wmbx->mbi[0];
1061 sc->sc_mbofull = 0;
1062
1063 /* Initialize mail box. */
1064 mailbox.cmd.opcode = AHA_MBX_INIT;
1065 mailbox.cmd.nmbx = AHA_MBX_SIZE;
1066 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1067 offsetof(struct aha_control, ac_mbx), mailbox.cmd.addr);
1068 aha_cmd(iot, ioh, sc,
1069 sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
1070 0, (u_char *)0);
1071 return (0);
1072 }
1073
1074 void
1075 aha_inquire_setup_information(sc)
1076 struct aha_softc *sc;
1077 {
1078 bus_space_tag_t iot = sc->sc_iot;
1079 bus_space_handle_t ioh = sc->sc_ioh;
1080 struct aha_revision revision;
1081 u_char sts;
1082 int i;
1083 char *p;
1084
1085 strcpy(sc->sc_model, "unknown");
1086
1087 /*
1088 * Assume we have a board at this stage, do an adapter inquire
1089 * to find out what type of controller it is. If the command
1090 * fails, we assume it's either a crusty board or an old 1542
1091 * clone, and skip the board-specific stuff.
1092 */
1093 revision.cmd.opcode = AHA_INQUIRE_REVISION;
1094 if (aha_cmd(iot, ioh, sc,
1095 sizeof(revision.cmd), (u_char *)&revision.cmd,
1096 sizeof(revision.reply), (u_char *)&revision.reply)) {
1097 /*
1098 * aha_cmd() already started the reset. It's not clear we
1099 * even need to bother here.
1100 */
1101 for (i = AHA_RESET_TIMEOUT; i; i--) {
1102 sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
1103 if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
1104 break;
1105 delay(1000);
1106 }
1107 if (!i) {
1108 #ifdef AHADEBUG
1109 printf("aha_init: soft reset failed\n");
1110 #endif /* AHADEBUG */
1111 return;
1112 }
1113 #ifdef AHADEBUG
1114 printf("aha_init: inquire command failed\n");
1115 #endif /* AHADEBUG */
1116 goto noinquire;
1117 }
1118
1119 #ifdef AHADEBUG
1120 printf("%s: inquire %x, %x, %x, %x\n",
1121 sc->sc_dev.dv_xname,
1122 revision.reply.boardid, revision.reply.spec_opts,
1123 revision.reply.revision_1, revision.reply.revision_2);
1124 #endif /* AHADEBUG */
1125
1126 switch (revision.reply.boardid) {
1127 case BOARD_1540_16HEAD_BIOS:
1128 case BOARD_1540_64HEAD_BIOS:
1129 case BOARD_1540:
1130 strcpy(sc->sc_model, "1540");
1131 break;
1132 case BOARD_1542:
1133 strcpy(sc->sc_model, "1540A/1542A/1542B");
1134 break;
1135 case BOARD_1640:
1136 strcpy(sc->sc_model, "1640");
1137 break;
1138 case BOARD_1740:
1139 strcpy(sc->sc_model, "1740");
1140 break;
1141 case BOARD_1542C:
1142 strcpy(sc->sc_model, "1542C");
1143 break;
1144 case BOARD_1542CF:
1145 strcpy(sc->sc_model, "1542CF");
1146 break;
1147 case BOARD_1542CP:
1148 strcpy(sc->sc_model, "1542CP");
1149 break;
1150 }
1151
1152 p = sc->sc_firmware;
1153 *p++ = revision.reply.revision_1;
1154 *p++ = '.';
1155 *p++ = revision.reply.revision_2;
1156 *p = '\0';
1157
1158 noinquire:
1159 printf("%s: model AHA-%s, firmware %s\n",
1160 sc->sc_dev.dv_xname,
1161 sc->sc_model, sc->sc_firmware);
1162 }
1163
1164 void
1165 ahaminphys(bp)
1166 struct buf *bp;
1167 {
1168
1169 if (bp->b_bcount > AHA_MAXXFER)
1170 bp->b_bcount = AHA_MAXXFER;
1171 minphys(bp);
1172 }
1173
1174 /*
1175 * start a scsi operation given the command and the data address. Also needs
1176 * the unit, target and lu.
1177 */
1178 int
1179 aha_scsi_cmd(xs)
1180 struct scsipi_xfer *xs;
1181 {
1182 struct scsipi_link *sc_link = xs->sc_link;
1183 struct aha_softc *sc = sc_link->adapter_softc;
1184 bus_dma_tag_t dmat = sc->sc_dmat;
1185 struct aha_ccb *ccb;
1186 int error, seg, flags, s;
1187 int fromqueue = 0, dontqueue = 0, nowait = 0;
1188
1189 SC_DEBUG(sc_link, SDEV_DB2, ("aha_scsi_cmd\n"));
1190
1191 s = splbio(); /* protect the queue */
1192
1193 /*
1194 * If we're running the queue from aha_done(), we've been
1195 * called with the first queue entry as our argument.
1196 */
1197 if (xs == TAILQ_FIRST(&sc->sc_queue)) {
1198 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
1199 fromqueue = 1;
1200 nowait = 1;
1201 goto get_ccb;
1202 }
1203
1204 /* Polled requests can't be queued for later. */
1205 dontqueue = xs->xs_control & XS_CTL_POLL;
1206
1207 /*
1208 * If there are jobs in the queue, run them first.
1209 */
1210 if (TAILQ_FIRST(&sc->sc_queue) != NULL) {
1211 /*
1212 * If we can't queue, we have to abort, since
1213 * we have to preserve order.
1214 */
1215 if (dontqueue) {
1216 splx(s);
1217 xs->error = XS_DRIVER_STUFFUP;
1218 return (TRY_AGAIN_LATER);
1219 }
1220
1221 /*
1222 * Swap with the first queue entry.
1223 */
1224 TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
1225 xs = TAILQ_FIRST(&sc->sc_queue);
1226 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
1227 fromqueue = 1;
1228 }
1229
1230 get_ccb:
1231 /*
1232 * get a ccb to use. If the transfer
1233 * is from a buf (possibly from interrupt time)
1234 * then we can't allow it to sleep
1235 */
1236 flags = xs->xs_control;
1237 if (nowait)
1238 flags |= XS_CTL_NOSLEEP;
1239 if ((ccb = aha_get_ccb(sc, flags)) == NULL) {
1240 /*
1241 * If we can't queue, we lose.
1242 */
1243 if (dontqueue) {
1244 splx(s);
1245 xs->error = XS_DRIVER_STUFFUP;
1246 return (TRY_AGAIN_LATER);
1247 }
1248
1249 /*
1250 * Stuff ourselves into the queue, in front
1251 * if we came off in the first place.
1252 */
1253 if (fromqueue)
1254 TAILQ_INSERT_HEAD(&sc->sc_queue, xs, adapter_q);
1255 else
1256 TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
1257 splx(s);
1258 return (SUCCESSFULLY_QUEUED);
1259 }
1260
1261 splx(s); /* done playing with the queue */
1262
1263 ccb->xs = xs;
1264 ccb->timeout = xs->timeout;
1265
1266 /*
1267 * Put all the arguments for the xfer in the ccb
1268 */
1269 if (flags & XS_CTL_RESET) {
1270 ccb->opcode = AHA_RESET_CCB;
1271 ccb->scsi_cmd_length = 0;
1272 } else {
1273 /* can't use S/G if zero length */
1274 ccb->opcode = (xs->datalen ? AHA_INIT_SCAT_GATH_CCB
1275 : AHA_INITIATOR_CCB);
1276 bcopy(xs->cmd, &ccb->scsi_cmd,
1277 ccb->scsi_cmd_length = xs->cmdlen);
1278 }
1279
1280 if (xs->datalen) {
1281 /*
1282 * Map the DMA transfer.
1283 */
1284 #ifdef TFS
1285 if (flags & XS_CTL_DATA_UIO) {
1286 error = bus_dmamap_load_uio(dmat,
1287 ccb->dmamap_xfer, (struct uio *)xs->data,
1288 (flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT :
1289 BUS_DMA_WAITOK);
1290 } else
1291 #endif
1292 {
1293 error = bus_dmamap_load(dmat,
1294 ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
1295 (flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT :
1296 BUS_DMA_WAITOK);
1297 }
1298
1299 if (error) {
1300 if (error == EFBIG) {
1301 printf("%s: aha_scsi_cmd, more than %d"
1302 " dma segments\n",
1303 sc->sc_dev.dv_xname, AHA_NSEG);
1304 } else {
1305 printf("%s: aha_scsi_cmd, error %d loading"
1306 " dma map\n",
1307 sc->sc_dev.dv_xname, error);
1308 }
1309 goto bad;
1310 }
1311
1312 bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
1313 ccb->dmamap_xfer->dm_mapsize,
1314 (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
1315 BUS_DMASYNC_PREWRITE);
1316
1317 /*
1318 * Load the hardware scatter/gather map with the
1319 * contents of the DMA map.
1320 */
1321 for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
1322 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
1323 ccb->scat_gath[seg].seg_addr);
1324 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
1325 ccb->scat_gath[seg].seg_len);
1326 }
1327
1328 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1329 AHA_CCB_OFF(ccb) + offsetof(struct aha_ccb, scat_gath),
1330 ccb->data_addr);
1331 ltophys(ccb->dmamap_xfer->dm_nsegs *
1332 sizeof(struct aha_scat_gath), ccb->data_length);
1333 } else {
1334 /*
1335 * No data xfer, use non S/G values.
1336 */
1337 ltophys(0, ccb->data_addr);
1338 ltophys(0, ccb->data_length);
1339 }
1340
1341 ccb->data_out = 0;
1342 ccb->data_in = 0;
1343 ccb->target = sc_link->scsipi_scsi.target;
1344 ccb->lun = sc_link->scsipi_scsi.lun;
1345 ccb->req_sense_length = sizeof(ccb->scsi_sense);
1346 ccb->host_stat = 0x00;
1347 ccb->target_stat = 0x00;
1348 ccb->link_id = 0;
1349 ltophys(0, ccb->link_addr);
1350
1351 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1352 AHA_CCB_OFF(ccb), sizeof(struct aha_ccb),
1353 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1354
1355 s = splbio();
1356 aha_queue_ccb(sc, ccb);
1357 splx(s);
1358
1359 /*
1360 * Usually return SUCCESSFULLY QUEUED
1361 */
1362 SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
1363 if ((flags & XS_CTL_POLL) == 0)
1364 return (SUCCESSFULLY_QUEUED);
1365
1366 /*
1367 * If we can't use interrupts, poll on completion
1368 */
1369 if (aha_poll(sc, xs, ccb->timeout)) {
1370 aha_timeout(ccb);
1371 if (aha_poll(sc, xs, ccb->timeout))
1372 aha_timeout(ccb);
1373 }
1374 return (COMPLETE);
1375
1376 bad:
1377 xs->error = XS_DRIVER_STUFFUP;
1378 aha_free_ccb(sc, ccb);
1379 return (COMPLETE);
1380 }
1381
1382 /*
1383 * Poll a particular unit, looking for a particular xs
1384 */
1385 int
1386 aha_poll(sc, xs, count)
1387 struct aha_softc *sc;
1388 struct scsipi_xfer *xs;
1389 int count;
1390 {
1391 bus_space_tag_t iot = sc->sc_iot;
1392 bus_space_handle_t ioh = sc->sc_ioh;
1393
1394 /* timeouts are in msec, so we loop in 1000 usec cycles */
1395 while (count) {
1396 /*
1397 * If we had interrupts enabled, would we
1398 * have got an interrupt?
1399 */
1400 if (bus_space_read_1(iot, ioh, AHA_INTR_PORT) & AHA_INTR_ANYINTR)
1401 aha_intr(sc);
1402 if (xs->xs_status & XS_STS_DONE)
1403 return (0);
1404 delay(1000); /* only happens in boot so ok */
1405 count--;
1406 }
1407 return (1);
1408 }
1409
1410 void
1411 aha_timeout(arg)
1412 void *arg;
1413 {
1414 struct aha_ccb *ccb = arg;
1415 struct scsipi_xfer *xs = ccb->xs;
1416 struct scsipi_link *sc_link = xs->sc_link;
1417 struct aha_softc *sc = sc_link->adapter_softc;
1418 int s;
1419
1420 scsi_print_addr(sc_link);
1421 printf("timed out");
1422
1423 s = splbio();
1424
1425 #ifdef AHADIAG
1426 /*
1427 * If The ccb's mbx is not free, then the board has gone south?
1428 */
1429 aha_collect_mbo(sc);
1430 if (ccb->flags & CCB_SENDING) {
1431 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
1432 Debugger();
1433 }
1434 #endif
1435
1436 /*
1437 * If it has been through before, then
1438 * a previous abort has failed, don't
1439 * try abort again
1440 */
1441 if (ccb->flags & CCB_ABORT) {
1442 /* abort timed out */
1443 printf(" AGAIN\n");
1444 /* XXX Must reset! */
1445 } else {
1446 /* abort the operation that has timed out */
1447 printf("\n");
1448 ccb->xs->error = XS_TIMEOUT;
1449 ccb->timeout = AHA_ABORT_TIMEOUT;
1450 ccb->flags |= CCB_ABORT;
1451 aha_queue_ccb(sc, ccb);
1452 }
1453
1454 splx(s);
1455 }
1456