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