aha.c revision 1.15 1 /* $NetBSD: aha.c,v 1.15 1998/02/09 10:53:07 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
1042 /* Obtain setup information from. */
1043 setup.cmd.opcode = AHA_INQUIRE_SETUP;
1044 setup.cmd.len = sizeof(setup.reply);
1045 aha_cmd(iot, ioh, sc,
1046 sizeof(setup.cmd), (u_char *)&setup.cmd,
1047 sizeof(setup.reply), (u_char *)&setup.reply);
1048
1049 printf("%s: %s, %s\n",
1050 sc->sc_dev.dv_xname,
1051 setup.reply.sync_neg ? "sync" : "async",
1052 setup.reply.parity ? "parity" : "no parity");
1053
1054 for (i = 0; i < 8; i++) {
1055 if (!setup.reply.sync[i].valid ||
1056 (!setup.reply.sync[i].offset && !setup.reply.sync[i].period))
1057 continue;
1058 printf("%s targ %d: sync, offset %d, period %dnsec\n",
1059 sc->sc_dev.dv_xname, i,
1060 setup.reply.sync[i].offset, setup.reply.sync[i].period * 50 + 200);
1061 }
1062
1063 /*
1064 * Allocate the mailbox and control blocks.
1065 */
1066 if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct aha_control),
1067 NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
1068 printf("%s: unable to allocate control structures, "
1069 "error = %d\n", sc->sc_dev.dv_xname, error);
1070 return (error);
1071 }
1072 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
1073 sizeof(struct aha_control), (caddr_t *)&sc->sc_control,
1074 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
1075 printf("%s: unable to map control structures, error = %d\n",
1076 sc->sc_dev.dv_xname, error);
1077 return (error);
1078 }
1079
1080 /*
1081 * Create and load the DMA map used for the mailbox and
1082 * control blocks.
1083 */
1084 if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct aha_control),
1085 1, sizeof(struct aha_control), 0, BUS_DMA_NOWAIT,
1086 &sc->sc_dmamap_control)) != 0) {
1087 printf("%s: unable to create control DMA map, error = %d\n",
1088 sc->sc_dev.dv_xname, error);
1089 return (error);
1090 }
1091 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
1092 sc->sc_control, sizeof(struct aha_control), NULL,
1093 BUS_DMA_NOWAIT)) != 0) {
1094 printf("%s: unable to load control DMA map, error = %d\n",
1095 sc->sc_dev.dv_xname, error);
1096 return (error);
1097 }
1098
1099 /*
1100 * Initialize the control blocks.
1101 */
1102 i = aha_create_ccbs(sc, sc->sc_control->ac_ccbs, initial_ccbs);
1103 if (i == 0) {
1104 printf("%s: unable to create control blocks\n",
1105 sc->sc_dev.dv_xname);
1106 return (ENOMEM);
1107 } else if (i != initial_ccbs) {
1108 printf("%s: WARNING: only %d of %d control blocks created\n",
1109 sc->sc_dev.dv_xname, i, initial_ccbs);
1110 }
1111
1112 /*
1113 * Set up initial mail box for round-robin operation.
1114 */
1115 for (i = 0; i < AHA_MBX_SIZE; i++) {
1116 wmbx->mbo[i].cmd = AHA_MBO_FREE;
1117 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1118 AHA_MBO_OFF(&wmbx->mbo[i]), sizeof(struct aha_mbx_out),
1119 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1120 wmbx->mbi[i].stat = AHA_MBI_FREE;
1121 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1122 AHA_MBI_OFF(&wmbx->mbi[i]), sizeof(struct aha_mbx_in),
1123 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1124 }
1125 wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
1126 wmbx->tmbi = &wmbx->mbi[0];
1127 sc->sc_mbofull = 0;
1128
1129 /* Initialize mail box. */
1130 mailbox.cmd.opcode = AHA_MBX_INIT;
1131 mailbox.cmd.nmbx = AHA_MBX_SIZE;
1132 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1133 offsetof(struct aha_control, ac_mbx), mailbox.cmd.addr);
1134 aha_cmd(iot, ioh, sc,
1135 sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
1136 0, (u_char *)0);
1137 return (0);
1138 }
1139
1140 void
1141 aha_inquire_setup_information(sc)
1142 struct aha_softc *sc;
1143 {
1144 bus_space_tag_t iot = sc->sc_iot;
1145 bus_space_handle_t ioh = sc->sc_ioh;
1146 struct aha_revision revision;
1147 u_char sts;
1148 int i;
1149 char *p;
1150
1151 strcpy(sc->sc_model, "unknown");
1152
1153 /*
1154 * Assume we have a board at this stage, do an adapter inquire
1155 * to find out what type of controller it is. If the command
1156 * fails, we assume it's either a crusty board or an old 1542
1157 * clone, and skip the board-specific stuff.
1158 */
1159 revision.cmd.opcode = AHA_INQUIRE_REVISION;
1160 if (aha_cmd(iot, ioh, sc,
1161 sizeof(revision.cmd), (u_char *)&revision.cmd,
1162 sizeof(revision.reply), (u_char *)&revision.reply)) {
1163 /*
1164 * aha_cmd() already started the reset. It's not clear we
1165 * even need to bother here.
1166 */
1167 for (i = AHA_RESET_TIMEOUT; i; i--) {
1168 sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
1169 if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
1170 break;
1171 delay(1000);
1172 }
1173 if (!i) {
1174 #ifdef AHADEBUG
1175 printf("aha_init: soft reset failed\n");
1176 #endif /* AHADEBUG */
1177 return;
1178 }
1179 #ifdef AHADEBUG
1180 printf("aha_init: inquire command failed\n");
1181 #endif /* AHADEBUG */
1182 goto noinquire;
1183 }
1184
1185 #ifdef AHADEBUG
1186 printf("%s: inquire %x, %x, %x, %x\n",
1187 sc->sc_dev.dv_xname,
1188 revision.reply.boardid, revision.reply.spec_opts,
1189 revision.reply.revision_1, revision.reply.revision_2);
1190 #endif /* AHADEBUG */
1191
1192 switch (revision.reply.boardid) {
1193 case 0x31:
1194 strcpy(sc->sc_model, "1540");
1195 break;
1196 case 0x41:
1197 strcpy(sc->sc_model, "1540A/1542A/1542B");
1198 break;
1199 case 0x42:
1200 strcpy(sc->sc_model, "1640");
1201 break;
1202 case 0x43:
1203 strcpy(sc->sc_model, "1542C");
1204 break;
1205 case 0x44:
1206 case 0x45:
1207 strcpy(sc->sc_model, "1542CF");
1208 break;
1209 case 0x46:
1210 strcpy(sc->sc_model, "1542CP");
1211 break;
1212 }
1213
1214 p = sc->sc_firmware;
1215 *p++ = revision.reply.revision_1;
1216 *p++ = '.';
1217 *p++ = revision.reply.revision_2;
1218 *p = '\0';
1219
1220 noinquire:
1221 printf("%s: model AHA-%s, firmware %s\n",
1222 sc->sc_dev.dv_xname,
1223 sc->sc_model, sc->sc_firmware);
1224 }
1225
1226 void
1227 ahaminphys(bp)
1228 struct buf *bp;
1229 {
1230
1231 if (bp->b_bcount > AHA_MAXXFER)
1232 bp->b_bcount = AHA_MAXXFER;
1233 minphys(bp);
1234 }
1235
1236 /*
1237 * start a scsi operation given the command and the data address. Also needs
1238 * the unit, target and lu.
1239 */
1240 int
1241 aha_scsi_cmd(xs)
1242 struct scsipi_xfer *xs;
1243 {
1244 struct scsipi_link *sc_link = xs->sc_link;
1245 struct aha_softc *sc = sc_link->adapter_softc;
1246 bus_dma_tag_t dmat = sc->sc_dmat;
1247 struct aha_ccb *ccb;
1248 int error, seg, flags, s;
1249 int fromqueue = 0, dontqueue = 0;
1250
1251 SC_DEBUG(sc_link, SDEV_DB2, ("aha_scsi_cmd\n"));
1252
1253 s = splbio(); /* protect the queue */
1254
1255 /*
1256 * If we're running the queue from aha_done(), we've been
1257 * called with the first queue entry as our argument.
1258 */
1259 if (xs == sc->sc_queue.lh_first) {
1260 xs = aha_dequeue(sc);
1261 fromqueue = 1;
1262 goto get_ccb;
1263 }
1264
1265 /* Polled requests can't be queued for later. */
1266 dontqueue = xs->flags & SCSI_POLL;
1267
1268 /*
1269 * If there are jobs in the queue, run them first.
1270 */
1271 if (sc->sc_queue.lh_first != NULL) {
1272 /*
1273 * If we can't queue, we have to abort, since
1274 * we have to preserve order.
1275 */
1276 if (dontqueue) {
1277 splx(s);
1278 xs->error = XS_DRIVER_STUFFUP;
1279 return (TRY_AGAIN_LATER);
1280 }
1281
1282 /*
1283 * Swap with the first queue entry.
1284 */
1285 aha_enqueue(sc, xs, 0);
1286 xs = aha_dequeue(sc);
1287 fromqueue = 1;
1288 }
1289
1290 get_ccb:
1291 /*
1292 * get a ccb to use. If the transfer
1293 * is from a buf (possibly from interrupt time)
1294 * then we can't allow it to sleep
1295 */
1296 flags = xs->flags;
1297 if ((ccb = aha_get_ccb(sc, flags)) == NULL) {
1298 /*
1299 * If we can't queue, we lose.
1300 */
1301 if (dontqueue) {
1302 splx(s);
1303 xs->error = XS_DRIVER_STUFFUP;
1304 return (TRY_AGAIN_LATER);
1305 }
1306
1307 /*
1308 * Stuff ourselves into the queue, in front
1309 * if we came off in the first place.
1310 */
1311 aha_enqueue(sc, xs, fromqueue);
1312 splx(s);
1313 return (SUCCESSFULLY_QUEUED);
1314 }
1315
1316 splx(s); /* done playing with the queue */
1317
1318 ccb->xs = xs;
1319 ccb->timeout = xs->timeout;
1320
1321 /*
1322 * Put all the arguments for the xfer in the ccb
1323 */
1324 if (flags & SCSI_RESET) {
1325 ccb->opcode = AHA_RESET_CCB;
1326 ccb->scsi_cmd_length = 0;
1327 } else {
1328 /* can't use S/G if zero length */
1329 ccb->opcode = (xs->datalen ? AHA_INIT_SCAT_GATH_CCB
1330 : AHA_INITIATOR_CCB);
1331 bcopy(xs->cmd, &ccb->scsi_cmd,
1332 ccb->scsi_cmd_length = xs->cmdlen);
1333 }
1334
1335 if (xs->datalen) {
1336 /*
1337 * Map the DMA transfer.
1338 */
1339 #ifdef TFS
1340 if (flags & SCSI_DATA_UIO) {
1341 error = bus_dmamap_load_uio(dmat,
1342 ccb->dmamap_xfer, (struct uio *)xs->data,
1343 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1344 BUS_DMA_WAITOK);
1345 } else
1346 #endif
1347 {
1348 error = bus_dmamap_load(dmat,
1349 ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
1350 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1351 BUS_DMA_WAITOK);
1352 }
1353
1354 if (error) {
1355 if (error == EFBIG) {
1356 printf("%s: aha_scsi_cmd, more than %d"
1357 " dma segments\n",
1358 sc->sc_dev.dv_xname, AHA_NSEG);
1359 } else {
1360 printf("%s: aha_scsi_cmd, error %d loading"
1361 " dma map\n",
1362 sc->sc_dev.dv_xname, error);
1363 }
1364 goto bad;
1365 }
1366
1367 bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
1368 ccb->dmamap_xfer->dm_mapsize,
1369 (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1370 BUS_DMASYNC_PREWRITE);
1371
1372 /*
1373 * Load the hardware scatter/gather map with the
1374 * contents of the DMA map.
1375 */
1376 for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
1377 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
1378 ccb->scat_gath[seg].seg_addr);
1379 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
1380 ccb->scat_gath[seg].seg_len);
1381 }
1382
1383 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1384 AHA_CCB_OFF(ccb) + offsetof(struct aha_ccb, scat_gath),
1385 ccb->data_addr);
1386 ltophys(ccb->dmamap_xfer->dm_nsegs *
1387 sizeof(struct aha_scat_gath), ccb->data_length);
1388 } else {
1389 /*
1390 * No data xfer, use non S/G values.
1391 */
1392 ltophys(0, ccb->data_addr);
1393 ltophys(0, ccb->data_length);
1394 }
1395
1396 ccb->data_out = 0;
1397 ccb->data_in = 0;
1398 ccb->target = sc_link->scsipi_scsi.target;
1399 ccb->lun = sc_link->scsipi_scsi.lun;
1400 ccb->req_sense_length = sizeof(ccb->scsi_sense);
1401 ccb->host_stat = 0x00;
1402 ccb->target_stat = 0x00;
1403 ccb->link_id = 0;
1404 ltophys(0, ccb->link_addr);
1405
1406 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1407 AHA_CCB_OFF(ccb), sizeof(struct aha_ccb),
1408 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1409
1410 s = splbio();
1411 aha_queue_ccb(sc, ccb);
1412 splx(s);
1413
1414 /*
1415 * Usually return SUCCESSFULLY QUEUED
1416 */
1417 SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
1418 if ((flags & SCSI_POLL) == 0)
1419 return (SUCCESSFULLY_QUEUED);
1420
1421 /*
1422 * If we can't use interrupts, poll on completion
1423 */
1424 if (aha_poll(sc, xs, ccb->timeout)) {
1425 aha_timeout(ccb);
1426 if (aha_poll(sc, xs, ccb->timeout))
1427 aha_timeout(ccb);
1428 }
1429 return (COMPLETE);
1430
1431 bad:
1432 xs->error = XS_DRIVER_STUFFUP;
1433 aha_free_ccb(sc, ccb);
1434 return (COMPLETE);
1435 }
1436
1437 /*
1438 * Poll a particular unit, looking for a particular xs
1439 */
1440 int
1441 aha_poll(sc, xs, count)
1442 struct aha_softc *sc;
1443 struct scsipi_xfer *xs;
1444 int count;
1445 {
1446 bus_space_tag_t iot = sc->sc_iot;
1447 bus_space_handle_t ioh = sc->sc_ioh;
1448
1449 /* timeouts are in msec, so we loop in 1000 usec cycles */
1450 while (count) {
1451 /*
1452 * If we had interrupts enabled, would we
1453 * have got an interrupt?
1454 */
1455 if (bus_space_read_1(iot, ioh, AHA_INTR_PORT) & AHA_INTR_ANYINTR)
1456 aha_intr(sc);
1457 if (xs->flags & ITSDONE)
1458 return (0);
1459 delay(1000); /* only happens in boot so ok */
1460 count--;
1461 }
1462 return (1);
1463 }
1464
1465 void
1466 aha_timeout(arg)
1467 void *arg;
1468 {
1469 struct aha_ccb *ccb = arg;
1470 struct scsipi_xfer *xs = ccb->xs;
1471 struct scsipi_link *sc_link = xs->sc_link;
1472 struct aha_softc *sc = sc_link->adapter_softc;
1473 int s;
1474
1475 scsi_print_addr(sc_link);
1476 printf("timed out");
1477
1478 s = splbio();
1479
1480 #ifdef AHADIAG
1481 /*
1482 * If The ccb's mbx is not free, then the board has gone south?
1483 */
1484 aha_collect_mbo(sc);
1485 if (ccb->flags & CCB_SENDING) {
1486 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
1487 Debugger();
1488 }
1489 #endif
1490
1491 /*
1492 * If it has been through before, then
1493 * a previous abort has failed, don't
1494 * try abort again
1495 */
1496 if (ccb->flags & CCB_ABORT) {
1497 /* abort timed out */
1498 printf(" AGAIN\n");
1499 /* XXX Must reset! */
1500 } else {
1501 /* abort the operation that has timed out */
1502 printf("\n");
1503 ccb->xs->error = XS_TIMEOUT;
1504 ccb->timeout = AHA_ABORT_TIMEOUT;
1505 ccb->flags |= CCB_ABORT;
1506 aha_queue_ccb(sc, ccb);
1507 }
1508
1509 splx(s);
1510 }
1511