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