Annotation of sys/dev/ic/adv.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: adv.c,v 1.17 2006/11/29 01:00:47 grange Exp $ */
2: /* $NetBSD: adv.c,v 1.6 1998/10/28 20:39:45 dante Exp $ */
3:
4: /*
5: * Generic driver for the Advanced Systems Inc. Narrow SCSI controllers
6: *
7: * Copyright (c) 1998 The NetBSD Foundation, Inc.
8: * All rights reserved.
9: *
10: * Author: Baldassare Dante Profeta <dante@mclink.it>
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. All advertising materials mentioning features or use of this software
21: * must display the following acknowledgement:
22: * This product includes software developed by the NetBSD
23: * Foundation, Inc. and its contributors.
24: * 4. Neither the name of The NetBSD Foundation nor the names of its
25: * contributors may be used to endorse or promote products derived
26: * from this software without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38: * POSSIBILITY OF SUCH DAMAGE.
39: */
40:
41: #include <sys/types.h>
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/kernel.h>
45: #include <sys/errno.h>
46: #include <sys/ioctl.h>
47: #include <sys/device.h>
48: #include <sys/malloc.h>
49: #include <sys/buf.h>
50: #include <sys/proc.h>
51: #include <sys/user.h>
52:
53: #include <machine/bus.h>
54: #include <machine/intr.h>
55:
56: #include <scsi/scsi_all.h>
57: #include <scsi/scsiconf.h>
58:
59: #include <dev/ic/adv.h>
60: #include <dev/ic/advlib.h>
61:
62: #ifndef DDB
63: #define Debugger() panic("should call debugger here (adv.c)")
64: #endif /* ! DDB */
65:
66:
67: /* #define ASC_DEBUG */
68:
69: /******************************************************************************/
70:
71:
72: static void adv_enqueue(ASC_SOFTC *, struct scsi_xfer *, int);
73: static struct scsi_xfer *adv_dequeue(ASC_SOFTC *);
74:
75: static int adv_alloc_ccbs(ASC_SOFTC *);
76: static int adv_create_ccbs(ASC_SOFTC *, ADV_CCB *, int);
77: static void adv_free_ccb(ASC_SOFTC *, ADV_CCB *);
78: static void adv_reset_ccb(ADV_CCB *);
79: static int adv_init_ccb(ASC_SOFTC *, ADV_CCB *);
80: static ADV_CCB *adv_get_ccb(ASC_SOFTC *, int);
81: static void adv_queue_ccb(ASC_SOFTC *, ADV_CCB *);
82: static void adv_start_ccbs(ASC_SOFTC *);
83:
84: static u_int8_t *adv_alloc_overrunbuf(char *dvname, bus_dma_tag_t);
85:
86: static int adv_scsi_cmd(struct scsi_xfer *);
87: static void advminphys(struct buf *);
88: static void adv_narrow_isr_callback(ASC_SOFTC *, ASC_QDONE_INFO *);
89:
90: static int adv_poll(ASC_SOFTC *, struct scsi_xfer *, int);
91: static void adv_timeout(void *);
92: static void adv_watchdog(void *);
93:
94:
95: /******************************************************************************/
96:
97:
98: struct cfdriver adv_cd = {
99: NULL, "adv", DV_DULL
100: };
101:
102:
103: struct scsi_adapter adv_switch =
104: {
105: adv_scsi_cmd, /* called to start/enqueue a SCSI command */
106: advminphys, /* to limit the transfer to max device can do */
107: 0, /* IT SEEMS IT IS NOT USED YET */
108: 0, /* as above... */
109: };
110:
111:
112: /* the below structure is so we have a default dev struct for out link struct */
113: struct scsi_device adv_dev =
114: {
115: NULL, /* Use default error handler */
116: NULL, /* have a queue, served by this */
117: NULL, /* have no async handler */
118: NULL, /* Use default 'done' routine */
119: };
120:
121:
122: #define ADV_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */
123: #define ADV_WATCH_TIMEOUT 1000 /* time to wait for watchdog (mSec) */
124:
125:
126: /******************************************************************************/
127: /* scsi_xfer queue routines */
128: /******************************************************************************/
129:
130:
131: /*
132: * Insert a scsi_xfer into the software queue. We overload xs->free_list
133: * to avoid having to allocate additional resources (since we're used
134: * only during resource shortages anyhow.
135: */
136: static void
137: adv_enqueue(sc, xs, infront)
138: ASC_SOFTC *sc;
139: struct scsi_xfer *xs;
140: int infront;
141: {
142:
143: if (infront || LIST_EMPTY(&sc->sc_queue)) {
144: if (LIST_EMPTY(&sc->sc_queue))
145: sc->sc_queuelast = xs;
146: LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
147: return;
148: }
149: LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
150: sc->sc_queuelast = xs;
151: }
152:
153:
154: /*
155: * Pull a scsi_xfer off the front of the software queue.
156: */
157: static struct scsi_xfer *
158: adv_dequeue(sc)
159: ASC_SOFTC *sc;
160: {
161: struct scsi_xfer *xs;
162:
163: xs = LIST_FIRST(&sc->sc_queue);
164: LIST_REMOVE(xs, free_list);
165:
166: if (LIST_EMPTY(&sc->sc_queue))
167: sc->sc_queuelast = NULL;
168:
169: return (xs);
170: }
171:
172:
173: /******************************************************************************/
174: /* Control Blocks routines */
175: /******************************************************************************/
176:
177:
178: static int
179: adv_alloc_ccbs(sc)
180: ASC_SOFTC *sc;
181: {
182: bus_dma_segment_t seg;
183: int error, rseg;
184:
185: /*
186: * Allocate the control blocks.
187: */
188: if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adv_control),
189: NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
190: printf("%s: unable to allocate control structures,"
191: " error = %d\n", sc->sc_dev.dv_xname, error);
192: return (error);
193: }
194: if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
195: sizeof(struct adv_control), (caddr_t *) & sc->sc_control,
196: BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
197: printf("%s: unable to map control structures, error = %d\n",
198: sc->sc_dev.dv_xname, error);
199: return (error);
200: }
201: /*
202: * Create and load the DMA map used for the control blocks.
203: */
204: if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct adv_control),
205: 1, sizeof(struct adv_control), 0, BUS_DMA_NOWAIT,
206: &sc->sc_dmamap_control)) != 0) {
207: printf("%s: unable to create control DMA map, error = %d\n",
208: sc->sc_dev.dv_xname, error);
209: return (error);
210: }
211: if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
212: sc->sc_control, sizeof(struct adv_control), NULL,
213: BUS_DMA_NOWAIT)) != 0) {
214: printf("%s: unable to load control DMA map, error = %d\n",
215: sc->sc_dev.dv_xname, error);
216: return (error);
217: }
218: return (0);
219: }
220:
221:
222: /*
223: * Create a set of ccbs and add them to the free list. Called once
224: * by adv_init(). We return the number of CCBs successfully created.
225: */
226: static int
227: adv_create_ccbs(sc, ccbstore, count)
228: ASC_SOFTC *sc;
229: ADV_CCB *ccbstore;
230: int count;
231: {
232: ADV_CCB *ccb;
233: int i, error;
234:
235: bzero(ccbstore, sizeof(ADV_CCB) * count);
236: for (i = 0; i < count; i++) {
237: ccb = &ccbstore[i];
238: if ((error = adv_init_ccb(sc, ccb)) != 0) {
239: printf("%s: unable to initialize ccb, error = %d\n",
240: sc->sc_dev.dv_xname, error);
241: return (i);
242: }
243: TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
244: }
245:
246: return (i);
247: }
248:
249:
250: /*
251: * A ccb is put onto the free list.
252: */
253: static void
254: adv_free_ccb(sc, ccb)
255: ASC_SOFTC *sc;
256: ADV_CCB *ccb;
257: {
258: int s;
259:
260: s = splbio();
261:
262: adv_reset_ccb(ccb);
263: TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
264:
265: /*
266: * If there were none, wake anybody waiting for one to come free,
267: * starting with queued entries.
268: */
269: if (TAILQ_NEXT(ccb, chain) == NULL)
270: wakeup(&sc->sc_free_ccb);
271:
272: splx(s);
273: }
274:
275:
276: static void
277: adv_reset_ccb(ccb)
278: ADV_CCB *ccb;
279: {
280:
281: ccb->flags = 0;
282: }
283:
284:
285: static int
286: adv_init_ccb(sc, ccb)
287: ASC_SOFTC *sc;
288: ADV_CCB *ccb;
289: {
290: int error;
291:
292: /*
293: * Create the DMA map for this CCB.
294: */
295: error = bus_dmamap_create(sc->sc_dmat,
296: (ASC_MAX_SG_LIST - 1) * PAGE_SIZE,
297: ASC_MAX_SG_LIST, (ASC_MAX_SG_LIST - 1) * PAGE_SIZE,
298: 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
299: if (error) {
300: printf("%s: unable to create DMA map, error = %d\n",
301: sc->sc_dev.dv_xname, error);
302: return (error);
303: }
304: adv_reset_ccb(ccb);
305: return (0);
306: }
307:
308:
309: /*
310: * Get a free ccb
311: *
312: * If there are none, see if we can allocate a new one
313: */
314: static ADV_CCB *
315: adv_get_ccb(sc, flags)
316: ASC_SOFTC *sc;
317: int flags;
318: {
319: ADV_CCB *ccb = 0;
320: int s;
321:
322: s = splbio();
323:
324: /*
325: * If we can and have to, sleep waiting for one to come free
326: * but only if we can't allocate a new one.
327: */
328: for (;;) {
329: ccb = TAILQ_FIRST(&sc->sc_free_ccb);
330: if (ccb) {
331: TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
332: break;
333: }
334: if ((flags & SCSI_NOSLEEP) != 0)
335: goto out;
336:
337: tsleep(&sc->sc_free_ccb, PRIBIO, "advccb", 0);
338: }
339:
340: ccb->flags |= CCB_ALLOC;
341:
342: out:
343: splx(s);
344: return (ccb);
345: }
346:
347:
348: /*
349: * Queue a CCB to be sent to the controller, and send it if possible.
350: */
351: static void
352: adv_queue_ccb(sc, ccb)
353: ASC_SOFTC *sc;
354: ADV_CCB *ccb;
355: {
356:
357: timeout_set(&ccb->xs->stimeout, adv_timeout, ccb);
358: TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
359:
360: adv_start_ccbs(sc);
361: }
362:
363:
364: static void
365: adv_start_ccbs(sc)
366: ASC_SOFTC *sc;
367: {
368: ADV_CCB *ccb;
369: struct scsi_xfer *xs;
370:
371: while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
372:
373: xs = ccb->xs;
374: if (ccb->flags & CCB_WATCHDOG)
375: timeout_del(&xs->stimeout);
376:
377: if (AscExeScsiQueue(sc, &ccb->scsiq) == ASC_BUSY) {
378: ccb->flags |= CCB_WATCHDOG;
379: timeout_set(&xs->stimeout, adv_watchdog, ccb);
380: timeout_add(&xs->stimeout,
381: (ADV_WATCH_TIMEOUT * hz) / 1000);
382: break;
383: }
384: TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
385:
386: if ((ccb->xs->flags & SCSI_POLL) == 0) {
387: timeout_set(&xs->stimeout, adv_timeout, ccb);
388: timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
389: }
390: }
391: }
392:
393:
394: /******************************************************************************/
395: /* DMA able memory allocation routines */
396: /******************************************************************************/
397:
398:
399: /*
400: * Allocate a DMA able memory for overrun_buffer.
401: * This memory can be safely shared among all the AdvanSys boards.
402: */
403: u_int8_t *
404: adv_alloc_overrunbuf(dvname, dmat)
405: char *dvname;
406: bus_dma_tag_t dmat;
407: {
408: static u_int8_t *overrunbuf = NULL;
409:
410: bus_dmamap_t ovrbuf_dmamap;
411: bus_dma_segment_t seg;
412: int rseg, error;
413:
414:
415: /*
416: * if an overrun buffer has been already allocated don't allocate it
417: * again. Instead return the address of the allocated buffer.
418: */
419: if (overrunbuf)
420: return (overrunbuf);
421:
422:
423: if ((error = bus_dmamem_alloc(dmat, ASC_OVERRUN_BSIZE,
424: NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
425: printf("%s: unable to allocate overrun buffer, error = %d\n",
426: dvname, error);
427: return (0);
428: }
429: if ((error = bus_dmamem_map(dmat, &seg, rseg, ASC_OVERRUN_BSIZE,
430: (caddr_t *) & overrunbuf, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
431: printf("%s: unable to map overrun buffer, error = %d\n",
432: dvname, error);
433:
434: bus_dmamem_free(dmat, &seg, 1);
435: return (0);
436: }
437: if ((error = bus_dmamap_create(dmat, ASC_OVERRUN_BSIZE, 1,
438: ASC_OVERRUN_BSIZE, 0, BUS_DMA_NOWAIT, &ovrbuf_dmamap)) != 0) {
439: printf("%s: unable to create overrun buffer DMA map,"
440: " error = %d\n", dvname, error);
441:
442: bus_dmamem_unmap(dmat, overrunbuf, ASC_OVERRUN_BSIZE);
443: bus_dmamem_free(dmat, &seg, 1);
444: return (0);
445: }
446: if ((error = bus_dmamap_load(dmat, ovrbuf_dmamap, overrunbuf,
447: ASC_OVERRUN_BSIZE, NULL, BUS_DMA_NOWAIT)) != 0) {
448: printf("%s: unable to load overrun buffer DMA map,"
449: " error = %d\n", dvname, error);
450:
451: bus_dmamap_destroy(dmat, ovrbuf_dmamap);
452: bus_dmamem_unmap(dmat, overrunbuf, ASC_OVERRUN_BSIZE);
453: bus_dmamem_free(dmat, &seg, 1);
454: return (0);
455: }
456: return (overrunbuf);
457: }
458:
459:
460: /******************************************************************************/
461: /* SCSI layer interfacing routines */
462: /******************************************************************************/
463:
464:
465: int
466: adv_init(sc)
467: ASC_SOFTC *sc;
468: {
469: int warn;
470:
471: if (!AscFindSignature(sc->sc_iot, sc->sc_ioh))
472: panic("adv_init: adv_find_signature failed");
473:
474: /*
475: * Read the board configuration
476: */
477: AscInitASC_SOFTC(sc);
478: warn = AscInitFromEEP(sc);
479: if (warn) {
480: printf("%s -get: ", sc->sc_dev.dv_xname);
481: switch (warn) {
482: case -1:
483: printf("Chip is not halted\n");
484: break;
485:
486: case -2:
487: printf("Couldn't get MicroCode Start"
488: " address\n");
489: break;
490:
491: case ASC_WARN_IO_PORT_ROTATE:
492: printf("I/O port address modified\n");
493: break;
494:
495: case ASC_WARN_AUTO_CONFIG:
496: printf("I/O port increment switch enabled\n");
497: break;
498:
499: case ASC_WARN_EEPROM_CHKSUM:
500: printf("EEPROM checksum error\n");
501: break;
502:
503: case ASC_WARN_IRQ_MODIFIED:
504: printf("IRQ modified\n");
505: break;
506:
507: case ASC_WARN_CMD_QNG_CONFLICT:
508: printf("tag queuing enabled w/o disconnects\n");
509: break;
510:
511: default:
512: printf("unknown warning %d\n", warn);
513: }
514: }
515: if (sc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
516: sc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
517:
518: /*
519: * Modify the board configuration
520: */
521: warn = AscInitFromASC_SOFTC(sc);
522: if (warn) {
523: printf("%s -set: ", sc->sc_dev.dv_xname);
524: switch (warn) {
525: case ASC_WARN_CMD_QNG_CONFLICT:
526: printf("tag queuing enabled w/o disconnects\n");
527: break;
528:
529: case ASC_WARN_AUTO_CONFIG:
530: printf("I/O port increment switch enabled\n");
531: break;
532:
533: default:
534: printf("unknown warning %d\n", warn);
535: }
536: }
537: sc->isr_callback = (ulong) adv_narrow_isr_callback;
538:
539: if (!(sc->overrun_buf = adv_alloc_overrunbuf(sc->sc_dev.dv_xname,
540: sc->sc_dmat))) {
541: return (1);
542: }
543:
544: return (0);
545: }
546:
547:
548: void
549: adv_attach(sc)
550: ASC_SOFTC *sc;
551: {
552: struct scsibus_attach_args saa;
553: int i, error;
554:
555: /*
556: * Initialize board RISC chip and enable interrupts.
557: */
558: switch (AscInitDriver(sc)) {
559: case 0:
560: /* AllOK */
561: break;
562:
563: case 1:
564: panic("%s: bad signature", sc->sc_dev.dv_xname);
565: break;
566:
567: case 2:
568: panic("%s: unable to load MicroCode",
569: sc->sc_dev.dv_xname);
570: break;
571:
572: case 3:
573: panic("%s: unable to initialize MicroCode",
574: sc->sc_dev.dv_xname);
575: break;
576:
577: default:
578: panic("%s: unable to initialize board RISC chip",
579: sc->sc_dev.dv_xname);
580: }
581:
582:
583: /*
584: * fill in the prototype scsi_link.
585: */
586: sc->sc_link.adapter_softc = sc;
587: sc->sc_link.adapter_target = sc->chip_scsi_id;
588: sc->sc_link.adapter = &adv_switch;
589: sc->sc_link.device = &adv_dev;
590: sc->sc_link.openings = 4;
591: sc->sc_link.adapter_buswidth = 7;
592:
593:
594: TAILQ_INIT(&sc->sc_free_ccb);
595: TAILQ_INIT(&sc->sc_waiting_ccb);
596: LIST_INIT(&sc->sc_queue);
597:
598:
599: /*
600: * Allocate the Control Blocks.
601: */
602: error = adv_alloc_ccbs(sc);
603: if (error)
604: return; /* (error) */ ;
605:
606: /*
607: * Create and initialize the Control Blocks.
608: */
609: i = adv_create_ccbs(sc, sc->sc_control->ccbs, ADV_MAX_CCB);
610: if (i == 0) {
611: printf("%s: unable to create control blocks\n",
612: sc->sc_dev.dv_xname);
613: return; /* (ENOMEM) */ ;
614: } else if (i != ADV_MAX_CCB) {
615: printf("%s: WARNING: only %d of %d control blocks created\n",
616: sc->sc_dev.dv_xname, i, ADV_MAX_CCB);
617: }
618:
619: bzero(&saa, sizeof(saa));
620: saa.saa_sc_link = &sc->sc_link;
621: config_found(&sc->sc_dev, &saa, scsiprint);
622: }
623:
624:
625: static void
626: advminphys(bp)
627: struct buf *bp;
628: {
629:
630: if (bp->b_bcount > ((ASC_MAX_SG_LIST - 1) * PAGE_SIZE))
631: bp->b_bcount = ((ASC_MAX_SG_LIST - 1) * PAGE_SIZE);
632: minphys(bp);
633: }
634:
635:
636: /*
637: * start a scsi operation given the command and the data address. Also needs
638: * the unit, target and lu.
639: */
640: static int
641: adv_scsi_cmd(xs)
642: struct scsi_xfer *xs;
643: {
644: struct scsi_link *sc_link = xs->sc_link;
645: ASC_SOFTC *sc = sc_link->adapter_softc;
646: bus_dma_tag_t dmat = sc->sc_dmat;
647: ADV_CCB *ccb;
648: int s, flags, error, nsegs;
649: int fromqueue = 1, dontqueue = 0;
650:
651:
652: s = splbio(); /* protect the queue */
653:
654: /*
655: * If we're running the queue from adv_done(), we've been
656: * called with the first queue entry as our argument.
657: */
658: if (xs == LIST_FIRST(&sc->sc_queue)) {
659: xs = adv_dequeue(sc);
660: fromqueue = 1;
661: } else {
662:
663: /* Polled requests can't be queued for later. */
664: dontqueue = xs->flags & SCSI_POLL;
665:
666: /*
667: * If there are jobs in the queue, run them first.
668: */
669: if (!LIST_EMPTY(&sc->sc_queue)) {
670: /*
671: * If we can't queue, we have to abort, since
672: * we have to preserve order.
673: */
674: if (dontqueue) {
675: splx(s);
676: return (TRY_AGAIN_LATER);
677: }
678: /*
679: * Swap with the first queue entry.
680: */
681: adv_enqueue(sc, xs, 0);
682: xs = adv_dequeue(sc);
683: fromqueue = 1;
684: }
685: }
686:
687:
688: /*
689: * get a ccb to use. If the transfer
690: * is from a buf (possibly from interrupt time)
691: * then we can't allow it to sleep
692: */
693:
694: flags = xs->flags;
695: if ((ccb = adv_get_ccb(sc, flags)) == NULL) {
696: /*
697: * If we can't queue, we lose.
698: */
699: if (dontqueue) {
700: splx(s);
701: return (TRY_AGAIN_LATER);
702: }
703: /*
704: * Stuff ourselves into the queue, in front
705: * if we came off in the first place.
706: */
707: adv_enqueue(sc, xs, fromqueue);
708: splx(s);
709: return (SUCCESSFULLY_QUEUED);
710: }
711: splx(s); /* done playing with the queue */
712:
713: ccb->xs = xs;
714: ccb->timeout = xs->timeout;
715:
716: /*
717: * Build up the request
718: */
719: memset(&ccb->scsiq, 0, sizeof(ASC_SCSI_Q));
720:
721: ccb->scsiq.q2.ccb_ptr = (ulong) ccb;
722:
723: ccb->scsiq.cdbptr = &xs->cmd->opcode;
724: ccb->scsiq.q2.cdb_len = xs->cmdlen;
725: ccb->scsiq.q1.target_id = ASC_TID_TO_TARGET_ID(sc_link->target);
726: ccb->scsiq.q1.target_lun = sc_link->lun;
727: ccb->scsiq.q2.target_ix = ASC_TIDLUN_TO_IX(sc_link->target,
728: sc_link->lun);
729: ccb->scsiq.q1.sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
730: ADV_CCB_OFF(ccb) + offsetof(struct adv_ccb, scsi_sense);
731: ccb->scsiq.q1.sense_len = sizeof(struct scsi_sense_data);
732:
733: /*
734: * If there are any outstanding requests for the current target,
735: * then every 255th request send an ORDERED request. This heuristic
736: * tries to retain the benefit of request sorting while preventing
737: * request starvation. 255 is the max number of tags or pending commands
738: * a device may have outstanding.
739: */
740: sc->reqcnt[sc_link->target]++;
741: if ((sc->reqcnt[sc_link->target] > 0) &&
742: (sc->reqcnt[sc_link->target] % 255) == 0) {
743: ccb->scsiq.q2.tag_code = M2_QTAG_MSG_ORDERED;
744: } else {
745: ccb->scsiq.q2.tag_code = M2_QTAG_MSG_SIMPLE;
746: }
747:
748:
749: if (xs->datalen) {
750: /*
751: * Map the DMA transfer.
752: */
753: #ifdef TFS
754: if (flags & SCSI_DATA_UIO) {
755: error = bus_dmamap_load_uio(dmat,
756: ccb->dmamap_xfer, (struct uio *) xs->data,
757: (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
758: } else
759: #endif /* TFS */
760: {
761: error = bus_dmamap_load(dmat,
762: ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
763: (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
764: }
765:
766: if (error) {
767: if (error == EFBIG) {
768: printf("%s: adv_scsi_cmd, more than %d dma"
769: " segments\n",
770: sc->sc_dev.dv_xname, ASC_MAX_SG_LIST);
771: } else {
772: printf("%s: adv_scsi_cmd, error %d loading"
773: " dma map\n",
774: sc->sc_dev.dv_xname, error);
775: }
776:
777: xs->error = XS_DRIVER_STUFFUP;
778: adv_free_ccb(sc, ccb);
779: return (COMPLETE);
780: }
781: bus_dmamap_sync(dmat, ccb->dmamap_xfer,
782: 0, ccb->dmamap_xfer->dm_mapsize,
783: ((flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
784: BUS_DMASYNC_PREWRITE));
785:
786:
787: memset(&ccb->sghead, 0, sizeof(ASC_SG_HEAD));
788:
789: for (nsegs = 0; nsegs < ccb->dmamap_xfer->dm_nsegs; nsegs++) {
790:
791: ccb->sghead.sg_list[nsegs].addr =
792: ccb->dmamap_xfer->dm_segs[nsegs].ds_addr;
793: ccb->sghead.sg_list[nsegs].bytes =
794: ccb->dmamap_xfer->dm_segs[nsegs].ds_len;
795: }
796:
797: ccb->sghead.entry_cnt = ccb->scsiq.q1.sg_queue_cnt =
798: ccb->dmamap_xfer->dm_nsegs;
799:
800: ccb->scsiq.q1.cntl |= ASC_QC_SG_HEAD;
801: ccb->scsiq.sg_head = &ccb->sghead;
802: ccb->scsiq.q1.data_addr = 0;
803: ccb->scsiq.q1.data_cnt = 0;
804: } else {
805: /*
806: * No data xfer, use non S/G values.
807: */
808: ccb->scsiq.q1.data_addr = 0;
809: ccb->scsiq.q1.data_cnt = 0;
810: }
811:
812: #ifdef ASC_DEBUG
813: printf("id = %d, lun = %d, cmd = %d, ccb = 0x%lX \n",
814: sc_link->scsipi_scsi.target,
815: sc_link->scsipi_scsi.lun, xs->cmd->opcode,
816: (unsigned long)ccb);
817: #endif
818: s = splbio();
819: adv_queue_ccb(sc, ccb);
820: splx(s);
821:
822: /*
823: * Usually return SUCCESSFULLY QUEUED
824: */
825: if ((flags & SCSI_POLL) == 0)
826: return (SUCCESSFULLY_QUEUED);
827:
828: /*
829: * If we can't use interrupts, poll on completion
830: */
831: if (adv_poll(sc, xs, ccb->timeout)) {
832: adv_timeout(ccb);
833: if (adv_poll(sc, xs, ccb->timeout))
834: adv_timeout(ccb);
835: }
836: return (COMPLETE);
837: }
838:
839:
840: int
841: adv_intr(arg)
842: void *arg;
843: {
844: ASC_SOFTC *sc = arg;
845: struct scsi_xfer *xs;
846:
847: #ifdef ASC_DEBUG
848: int int_pend = FALSE;
849:
850: if(ASC_IS_INT_PENDING(sc->sc_iot, sc->sc_ioh))
851: {
852: int_pend = TRUE;
853: printf("ISR - ");
854: }
855: #endif
856: AscISR(sc);
857: #ifdef ASC_DEBUG
858: if(int_pend)
859: printf("\n");
860: #endif
861:
862: /*
863: * If there are queue entries in the software queue, try to
864: * run the first one. We should be more or less guaranteed
865: * to succeed, since we just freed a CCB.
866: *
867: * NOTE: adv_scsi_cmd() relies on our calling it with
868: * the first entry in the queue.
869: */
870: if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
871: (void) adv_scsi_cmd(xs);
872:
873: return (1);
874: }
875:
876:
877: /*
878: * Poll a particular unit, looking for a particular xs
879: */
880: static int
881: adv_poll(sc, xs, count)
882: ASC_SOFTC *sc;
883: struct scsi_xfer *xs;
884: int count;
885: {
886:
887: /* timeouts are in msec, so we loop in 1000 usec cycles */
888: while (count) {
889: adv_intr(sc);
890: if (xs->flags & ITSDONE)
891: return (0);
892: delay(1000); /* only happens in boot so ok */
893: count--;
894: }
895: return (1);
896: }
897:
898:
899: static void
900: adv_timeout(arg)
901: void *arg;
902: {
903: ADV_CCB *ccb = arg;
904: struct scsi_xfer *xs = ccb->xs;
905: struct scsi_link *sc_link = xs->sc_link;
906: ASC_SOFTC *sc = sc_link->adapter_softc;
907: int s;
908:
909: sc_print_addr(sc_link);
910: printf("timed out");
911:
912: s = splbio();
913:
914: /*
915: * If it has been through before, then a previous abort has failed,
916: * don't try abort again, reset the bus instead.
917: */
918: if (ccb->flags & CCB_ABORT) {
919: /* abort timed out */
920: printf(" AGAIN. Resetting Bus\n");
921: /* Lets try resetting the bus! */
922: if (AscResetBus(sc) == ASC_ERROR) {
923: ccb->timeout = sc->scsi_reset_wait;
924: adv_queue_ccb(sc, ccb);
925: }
926: } else {
927: /* abort the operation that has timed out */
928: printf("\n");
929: AscAbortCCB(sc, (u_int32_t) ccb);
930: ccb->xs->error = XS_TIMEOUT;
931: ccb->timeout = ADV_ABORT_TIMEOUT;
932: ccb->flags |= CCB_ABORT;
933: adv_queue_ccb(sc, ccb);
934: }
935:
936: splx(s);
937: }
938:
939:
940: static void
941: adv_watchdog(arg)
942: void *arg;
943: {
944: ADV_CCB *ccb = arg;
945: struct scsi_xfer *xs = ccb->xs;
946: struct scsi_link *sc_link = xs->sc_link;
947: ASC_SOFTC *sc = sc_link->adapter_softc;
948: int s;
949:
950: s = splbio();
951:
952: ccb->flags &= ~CCB_WATCHDOG;
953: adv_start_ccbs(sc);
954:
955: splx(s);
956: }
957:
958:
959: /******************************************************************************/
960: /* NARROW and WIDE boards Interrupt callbacks */
961: /******************************************************************************/
962:
963:
964: /*
965: * adv_narrow_isr_callback() - Second Level Interrupt Handler called by AscISR()
966: *
967: * Interrupt callback function for the Narrow SCSI Asc Library.
968: */
969: static void
970: adv_narrow_isr_callback(sc, qdonep)
971: ASC_SOFTC *sc;
972: ASC_QDONE_INFO *qdonep;
973: {
974: bus_dma_tag_t dmat = sc->sc_dmat;
975: ADV_CCB *ccb = (ADV_CCB *) qdonep->d2.ccb_ptr;
976: struct scsi_xfer *xs = ccb->xs;
977: struct scsi_sense_data *s1, *s2;
978:
979:
980: #ifdef ASC_DEBUG
981: printf(" - ccb=0x%lx, id=%d, lun=%d, cmd=%d, ",
982: (unsigned long)ccb,
983: xs->sc_link->scsipi_scsi.target,
984: xs->sc_link->scsipi_scsi.lun, xs->cmd->opcode);
985: #endif
986: timeout_del(&xs->stimeout);
987:
988: /*
989: * If we were a data transfer, unload the map that described
990: * the data buffer.
991: */
992: if (xs->datalen) {
993: bus_dmamap_sync(dmat, ccb->dmamap_xfer,
994: 0, ccb->dmamap_xfer->dm_mapsize,
995: ((xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
996: BUS_DMASYNC_POSTWRITE));
997: bus_dmamap_unload(dmat, ccb->dmamap_xfer);
998: }
999: if ((ccb->flags & CCB_ALLOC) == 0) {
1000: printf("%s: exiting ccb not allocated!\n", sc->sc_dev.dv_xname);
1001: Debugger();
1002: return;
1003: }
1004: /*
1005: * 'qdonep' contains the command's ending status.
1006: */
1007: #ifdef ASC_DEBUG
1008: printf("d_s=%d, h_s=%d", qdonep->d3.done_stat, qdonep->d3.host_stat);
1009: #endif
1010: switch (qdonep->d3.done_stat) {
1011: case ASC_QD_NO_ERROR:
1012: switch (qdonep->d3.host_stat) {
1013: case ASC_QHSTA_NO_ERROR:
1014: xs->error = XS_NOERROR;
1015: xs->resid = 0;
1016: break;
1017:
1018: default:
1019: /* QHSTA error occurred */
1020: xs->error = XS_DRIVER_STUFFUP;
1021: break;
1022: }
1023:
1024: /*
1025: * If an INQUIRY command completed successfully, then call
1026: * the AscInquiryHandling() function to patch bugged boards.
1027: */
1028: if ((xs->cmd->opcode == SCSICMD_Inquiry) &&
1029: (xs->sc_link->lun == 0) &&
1030: (xs->datalen - qdonep->remain_bytes) >= 8) {
1031: AscInquiryHandling(sc,
1032: xs->sc_link->target & 0x7,
1033: (ASC_SCSI_INQUIRY *) xs->data);
1034: }
1035: break;
1036:
1037: case ASC_QD_WITH_ERROR:
1038: switch (qdonep->d3.host_stat) {
1039: case ASC_QHSTA_NO_ERROR:
1040: if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
1041: s1 = &ccb->scsi_sense;
1042: s2 = &xs->sense;
1043: *s2 = *s1;
1044: xs->error = XS_SENSE;
1045: } else {
1046: xs->error = XS_DRIVER_STUFFUP;
1047: }
1048: break;
1049:
1050: default:
1051: /* QHSTA error occurred */
1052: xs->error = XS_DRIVER_STUFFUP;
1053: break;
1054: }
1055: break;
1056:
1057: case ASC_QD_ABORTED_BY_HOST:
1058: default:
1059: xs->error = XS_DRIVER_STUFFUP;
1060: break;
1061: }
1062:
1063:
1064: adv_free_ccb(sc, ccb);
1065: xs->flags |= ITSDONE;
1066: scsi_done(xs);
1067: }
CVSweb