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