Annotation of sys/dev/ic/aic6360.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: aic6360.c,v 1.15 2007/08/09 00:03:16 ray Exp $ */
2: /* $NetBSD: aic6360.c,v 1.52 1996/12/10 21:27:51 thorpej Exp $ */
3:
4: #ifdef DDB
5: #define integrate
6: #else
7: #define integrate static inline
8: #endif
9:
10: /*
11: * Copyright (c) 1994, 1995, 1996 Charles Hannum. All rights reserved.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. All advertising materials mentioning features or use of this software
22: * must display the following acknowledgement:
23: * This product includes software developed by Charles M. Hannum.
24: * 4. The name of the author may not be used to endorse or promote products
25: * derived from this software without specific prior written permission.
26: *
27: * Copyright (c) 1994 Jarle Greipsland
28: * All rights reserved.
29: *
30: * Redistribution and use in source and binary forms, with or without
31: * modification, are permitted provided that the following conditions
32: * are met:
33: * 1. Redistributions of source code must retain the above copyright
34: * notice, this list of conditions and the following disclaimer.
35: * 2. Redistributions in binary form must reproduce the above copyright
36: * notice, this list of conditions and the following disclaimer in the
37: * documentation and/or other materials provided with the distribution.
38: * 3. The name of the author may not be used to endorse or promote products
39: * derived from this software without specific prior written permission.
40: *
41: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
42: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
45: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
47: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
50: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
51: * POSSIBILITY OF SUCH DAMAGE.
52: */
53:
54: /*
55: * Acknowledgements: Many of the algorithms used in this driver are
56: * inspired by the work of Julian Elischer (julian@tfs.com) and
57: * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
58: */
59:
60: /* TODO list:
61: * 1) Get the DMA stuff working.
62: * 2) Get the iov/uio stuff working. Is this a good thing ???
63: * 3) Get the synch stuff working.
64: * 4) Rewrite it to use malloc for the acb structs instead of static alloc.?
65: */
66:
67: /*
68: * A few customizable items:
69: */
70:
71: /* Use doubleword transfers to/from SCSI chip. Note: This requires
72: * motherboard support. Basicly, some motherboard chipsets are able to
73: * split a 32 bit I/O operation into two 16 bit I/O operations,
74: * transparently to the processor. This speeds up some things, notably long
75: * data transfers.
76: */
77: #define AIC_USE_DWORDS 0
78:
79: /* Synchronous data transfers? */
80: #define AIC_USE_SYNCHRONOUS 0
81: #define AIC_SYNC_REQ_ACK_OFS 8
82:
83: /* Wide data transfers? */
84: #define AIC_USE_WIDE 0
85: #define AIC_MAX_WIDTH 0
86:
87: /* Max attempts made to transmit a message */
88: #define AIC_MSG_MAX_ATTEMPT 3 /* Not used now XXX */
89:
90: /* Use DMA (else we do programmed I/O using string instructions) (not yet!)*/
91: #define AIC_USE_EISA_DMA 0
92: #define AIC_USE_ISA_DMA 0
93:
94: /* How to behave on the (E)ISA bus when/if DMAing (on<<4) + off in us */
95: #define EISA_BRST_TIM ((15<<4) + 1) /* 15us on, 1us off */
96:
97: /* Some spin loop parameters (essentially how long to wait some places)
98: * The problem(?) is that sometimes we expect either to be able to transmit a
99: * byte or to get a new one from the SCSI bus pretty soon. In order to avoid
100: * returning from the interrupt just to get yanked back for the next byte we
101: * may spin in the interrupt routine waiting for this byte to come. How long?
102: * This is really (SCSI) device and processor dependent. Tuneable, I guess.
103: */
104: #define AIC_MSGIN_SPIN 1 /* Spin upto ?ms for a new msg byte */
105: #define AIC_MSGOUT_SPIN 1
106:
107: /* Include debug functions? At the end of this file there are a bunch of
108: * functions that will print out various information regarding queued SCSI
109: * commands, driver state and chip contents. You can call them from the
110: * kernel debugger. If you set AIC_DEBUG to 0 they are not included (the
111: * kernel uses less memory) but you lose the debugging facilities.
112: */
113: #ifndef SMALL_KERNEL
114: #define AIC_DEBUG 1
115: #endif
116:
117: #define AIC_ABORT_TIMEOUT 2000 /* time to wait for abort */
118:
119: /* End of customizable parameters */
120:
121: #if AIC_USE_EISA_DMA || AIC_USE_ISA_DMA
122: #error "I said not yet! Start paying attention... grumble"
123: #endif
124:
125: #include <sys/types.h>
126: #include <sys/param.h>
127: #include <sys/systm.h>
128: #include <sys/kernel.h>
129: #include <sys/errno.h>
130: #include <sys/ioctl.h>
131: #include <sys/device.h>
132: #include <sys/buf.h>
133: #include <sys/proc.h>
134: #include <sys/user.h>
135: #include <sys/queue.h>
136:
137: #include <machine/bus.h>
138: #include <machine/intr.h>
139:
140: #include <scsi/scsi_all.h>
141: #include <scsi/scsi_message.h>
142: #include <scsi/scsiconf.h>
143:
144: #include <dev/isa/isavar.h>
145:
146: #include <dev/ic/aic6360reg.h>
147: #include <dev/ic/aic6360var.h>
148:
149: #ifndef DDB
150: #define Debugger() panic("should call debugger here (aic6360.c)")
151: #endif /* ! DDB */
152:
153: #ifdef AIC_DEBUG
154: int aic_debug = 0x00; /* AIC_SHOWSTART|AIC_SHOWMISC|AIC_SHOWTRACE; */
155: #endif
156:
157: void aic_minphys(struct buf *);
158: void aic_init(struct aic_softc *);
159: void aic_done(struct aic_softc *, struct aic_acb *);
160: void aic_dequeue(struct aic_softc *, struct aic_acb *);
161: int aic_scsi_cmd(struct scsi_xfer *);
162: int aic_poll(struct aic_softc *, struct scsi_xfer *, int);
163: integrate void aic_sched_msgout(struct aic_softc *, u_char);
164: integrate void aic_setsync(struct aic_softc *, struct aic_tinfo *);
165: void aic_select(struct aic_softc *, struct aic_acb *);
166: void aic_timeout(void *);
167: void aic_sched(struct aic_softc *);
168: void aic_scsi_reset(struct aic_softc *);
169: void aic_reset(struct aic_softc *);
170: void aic_free_acb(struct aic_softc *, struct aic_acb *, int);
171: struct aic_acb* aic_get_acb(struct aic_softc *, int);
172: int aic_reselect(struct aic_softc *, int);
173: void aic_sense(struct aic_softc *, struct aic_acb *);
174: void aic_msgin(struct aic_softc *);
175: void aic_abort(struct aic_softc *, struct aic_acb *);
176: void aic_msgout(struct aic_softc *);
177: int aic_dataout_pio(struct aic_softc *, u_char *, int);
178: int aic_datain_pio(struct aic_softc *, u_char *, int);
179: #ifdef AIC_DEBUG
180: void aic_print_acb(struct aic_acb *);
181: void aic_dump_driver(struct aic_softc *);
182: void aic_dump6360(struct aic_softc *);
183: void aic_show_scsi_cmd(struct aic_acb *);
184: void aic_print_active_acb(void);
185: #endif
186:
187: struct cfdriver aic_cd = {
188: NULL, "aic", DV_DULL
189: };
190:
191: struct scsi_adapter aic_switch = {
192: aic_scsi_cmd,
193: #ifdef notyet
194: aic_minphys,
195: #else
196: minphys,
197: #endif
198: 0,
199: 0,
200: };
201:
202: struct scsi_device aic_dev = {
203: NULL, /* Use default error handler */
204: NULL, /* have a queue, served by this */
205: NULL, /* have no async handler */
206: NULL, /* Use default 'done' routine */
207: };
208:
209:
210: /*
211: * Do the real search-for-device.
212: */
213: int
214: aic_find(bus_space_tag_t iot, bus_space_handle_t ioh)
215: {
216: char chip_id[sizeof(IDSTRING)]; /* For chips that support it */
217: int i;
218:
219: /* Remove aic6360 from possible powerdown mode */
220: bus_space_write_1(iot, ioh, DMACNTRL0, 0);
221:
222: /* Thanks to mark@aggregate.com for the new method for detecting
223: * whether the chip is present or not. Bonus: may also work for
224: * the AIC-6260!
225: */
226: AIC_TRACE(("aic: probing for aic-chip\n"));
227: /*
228: * Linux also init's the stack to 1-16 and then clears it,
229: * 6260's don't appear to have an ID reg - mpg
230: */
231: /* Push the sequence 0,1,..,15 on the stack */
232: #define STSIZE 16
233: bus_space_write_1(iot, ioh, DMACNTRL1, 0); /* Reset stack pointer */
234: for (i = 0; i < STSIZE; i++)
235: bus_space_write_1(iot, ioh, STACK, i);
236:
237: /* See if we can pull out the same sequence */
238: bus_space_write_1(iot, ioh, DMACNTRL1, 0);
239: for (i = 0; i < STSIZE && bus_space_read_1(iot, ioh, STACK) == i; i++)
240: ;
241: if (i != STSIZE) {
242: AIC_START(("STACK futzed at %d.\n", i));
243: return (0);
244: }
245:
246: /* See if we can pull the id string out of the ID register,
247: * now only used for informational purposes.
248: */
249: bzero(chip_id, sizeof(chip_id));
250: bus_space_read_multi_1(iot, ioh, ID, chip_id, sizeof(IDSTRING) - 1);
251: AIC_START(("AIC ID: %s ", chip_id));
252: AIC_START(("chip revision %d\n",
253: (int)bus_space_read_1(iot, ioh, REV)));
254:
255: return (1);
256: }
257:
258: /*
259: * Attach the AIC6360, fill out some high and low level data structures
260: */
261: void
262: aicattach(struct aic_softc *sc)
263: {
264: struct scsibus_attach_args saa;
265: AIC_TRACE(("aicattach "));
266: sc->sc_state = AIC_INIT;
267:
268: sc->sc_initiator = 7;
269: sc->sc_freq = 20; /* XXXX assume 20 MHz. */
270:
271: /*
272: * These are the bounds of the sync period, based on the frequency of
273: * the chip's clock input and the size and offset of the sync period
274: * register.
275: *
276: * For a 20MHz clock, this gives us 25, or 100nS, or 10MB/s, as a
277: * maximum transfer rate, and 112.5, or 450nS, or 2.22MB/s, as a
278: * minimum transfer rate.
279: */
280: sc->sc_minsync = (2 * 250) / sc->sc_freq;
281: sc->sc_maxsync = (9 * 250) / sc->sc_freq;
282:
283: aic_init(sc); /* init chip and driver */
284:
285: /*
286: * Fill in the prototype scsi_link
287: */
288: sc->sc_link.adapter_softc = sc;
289: sc->sc_link.adapter_target = sc->sc_initiator;
290: sc->sc_link.adapter = &aic_switch;
291: sc->sc_link.device = &aic_dev;
292: sc->sc_link.openings = 2;
293:
294: bzero(&saa, sizeof(saa));
295: saa.saa_sc_link = &sc->sc_link;
296:
297: config_found(&sc->sc_dev, &saa, scsiprint);
298: }
299:
300: int
301: aic_detach(struct device *self, int flags)
302: {
303: struct aic_softc *sc = (struct aic_softc *) self;
304: int rv = 0;
305:
306: rv = config_detach_children(&sc->sc_dev, flags);
307:
308: return (rv);
309: }
310:
311: /* Initialize AIC6360 chip itself
312: * The following conditions should hold:
313: * aicprobe should have succeeded, i.e. the ioh handle in aic_softc must
314: * be valid.
315: */
316: void
317: aic_reset(struct aic_softc *sc)
318: {
319: bus_space_tag_t iot = sc->sc_iot;
320: bus_space_handle_t ioh = sc->sc_ioh;
321:
322: /*
323: * Doc. recommends to clear these two registers before operations
324: * commence
325: */
326: bus_space_write_1(iot, ioh, SCSITEST, 0);
327: bus_space_write_1(iot, ioh, TEST, 0);
328:
329: /* Reset SCSI-FIFO and abort any transfers */
330: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRCH | CLRSTCNT);
331:
332: /* Reset DMA-FIFO */
333: bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
334: bus_space_write_1(iot, ioh, DMACNTRL1, 0);
335:
336: /* Disable all selection features */
337: bus_space_write_1(iot, ioh, SCSISEQ, 0);
338: bus_space_write_1(iot, ioh, SXFRCTL1, 0);
339:
340: /* Disable some interrupts */
341: bus_space_write_1(iot, ioh, SIMODE0, 0x00);
342: /* Clear a slew of interrupts */
343: bus_space_write_1(iot, ioh, CLRSINT0, 0x7f);
344:
345: /* Disable some more interrupts */
346: bus_space_write_1(iot, ioh, SIMODE1, 0x00);
347: /* Clear another slew of interrupts */
348: bus_space_write_1(iot, ioh, CLRSINT1, 0xef);
349:
350: /* Disable synchronous transfers */
351: bus_space_write_1(iot, ioh, SCSIRATE, 0);
352:
353: /* Haven't seen ant errors (yet) */
354: bus_space_write_1(iot, ioh, CLRSERR, 0x07);
355:
356: /* Set our SCSI-ID */
357: bus_space_write_1(iot, ioh, SCSIID, sc->sc_initiator << OID_S);
358: bus_space_write_1(iot, ioh, BRSTCNTRL, EISA_BRST_TIM);
359: }
360:
361: /* Pull the SCSI RST line for 500 us */
362: void
363: aic_scsi_reset(struct aic_softc *sc)
364: {
365: bus_space_tag_t iot = sc->sc_iot;
366: bus_space_handle_t ioh = sc->sc_ioh;
367:
368: bus_space_write_1(iot, ioh, SCSISEQ, SCSIRSTO);
369: delay(500);
370: bus_space_write_1(iot, ioh, SCSISEQ, 0);
371: delay(50);
372: }
373:
374: /*
375: * Initialize aic SCSI driver.
376: */
377: void
378: aic_init(struct aic_softc *sc)
379: {
380: bus_space_tag_t iot = sc->sc_iot;
381: bus_space_handle_t ioh = sc->sc_ioh;
382: struct aic_acb *acb;
383: int r;
384:
385: aic_reset(sc);
386: aic_scsi_reset(sc);
387: aic_reset(sc);
388:
389: if (sc->sc_state == AIC_INIT) {
390: /* First time through; initialize. */
391: TAILQ_INIT(&sc->ready_list);
392: TAILQ_INIT(&sc->nexus_list);
393: TAILQ_INIT(&sc->free_list);
394: sc->sc_nexus = NULL;
395: acb = sc->sc_acb;
396: bzero(acb, sizeof(sc->sc_acb));
397: for (r = 0; r < sizeof(sc->sc_acb) / sizeof(*acb); r++) {
398: TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
399: acb++;
400: }
401: bzero(&sc->sc_tinfo, sizeof(sc->sc_tinfo));
402: } else {
403: /* Cancel any active commands. */
404: sc->sc_state = AIC_CLEANING;
405: if ((acb = sc->sc_nexus) != NULL) {
406: acb->xs->error = XS_DRIVER_STUFFUP;
407: timeout_del(&acb->xs->stimeout);
408: aic_done(sc, acb);
409: }
410: while ((acb = TAILQ_FIRST(&sc->nexus_list)) != NULL) {
411: acb->xs->error = XS_DRIVER_STUFFUP;
412: timeout_del(&acb->xs->stimeout);
413: aic_done(sc, acb);
414: }
415: }
416:
417: sc->sc_prevphase = PH_INVALID;
418: for (r = 0; r < 8; r++) {
419: struct aic_tinfo *ti = &sc->sc_tinfo[r];
420:
421: ti->flags = 0;
422: #if AIC_USE_SYNCHRONOUS
423: ti->flags |= DO_SYNC;
424: ti->period = sc->sc_minsync;
425: ti->offset = AIC_SYNC_REQ_ACK_OFS;
426: #else
427: ti->period = ti->offset = 0;
428: #endif
429: #if AIC_USE_WIDE
430: ti->flags |= DO_WIDE;
431: ti->width = AIC_MAX_WIDTH;
432: #else
433: ti->width = 0;
434: #endif
435: }
436:
437: sc->sc_state = AIC_IDLE;
438: bus_space_write_1(iot, ioh, DMACNTRL0, INTEN);
439: }
440:
441: void
442: aic_free_acb(struct aic_softc *sc, struct aic_acb *acb, int flags)
443: {
444: int s;
445:
446: s = splbio();
447:
448: acb->flags = 0;
449: TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
450:
451: /*
452: * If there were none, wake anybody waiting for one to come free,
453: * starting with queued entries.
454: */
455: if (TAILQ_NEXT(acb, chain) == NULL)
456: wakeup(&sc->free_list);
457:
458: splx(s);
459: }
460:
461: struct aic_acb *
462: aic_get_acb(struct aic_softc *sc, int flags)
463: {
464: struct aic_acb *acb;
465: int s;
466:
467: s = splbio();
468:
469: while ((acb = TAILQ_FIRST(&sc->free_list)) == NULL &&
470: (flags & SCSI_NOSLEEP) == 0)
471: tsleep(&sc->free_list, PRIBIO, "aicacb", 0);
472: if (acb) {
473: TAILQ_REMOVE(&sc->free_list, acb, chain);
474: acb->flags |= ACB_ALLOC;
475: }
476:
477: splx(s);
478: return acb;
479: }
480:
481: /*
482: * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
483: */
484:
485: /*
486: * Expected sequence:
487: * 1) Command inserted into ready list
488: * 2) Command selected for execution
489: * 3) Command won arbitration and has selected target device
490: * 4) Send message out (identify message, eventually also sync.negotiations)
491: * 5) Send command
492: * 5a) Receive disconnect message, disconnect.
493: * 5b) Reselected by target
494: * 5c) Receive identify message from target.
495: * 6) Send or receive data
496: * 7) Receive status
497: * 8) Receive message (command complete etc.)
498: * 9) If status == SCSI_CHECK construct a synthetic request sense SCSI cmd.
499: * Repeat 2-8 (no disconnects please...)
500: */
501:
502: /*
503: * Start a SCSI-command
504: * This function is called by the higher level SCSI-driver to queue/run
505: * SCSI-commands.
506: */
507: int
508: aic_scsi_cmd(struct scsi_xfer *xs)
509: {
510: struct scsi_link *sc_link = xs->sc_link;
511: struct aic_softc *sc = sc_link->adapter_softc;
512: struct aic_acb *acb;
513: int s, flags;
514:
515: AIC_TRACE(("aic_scsi_cmd "));
516: AIC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
517: sc_link->target));
518:
519: flags = xs->flags;
520: if ((acb = aic_get_acb(sc, flags)) == NULL) {
521: return TRY_AGAIN_LATER;
522: }
523:
524: /* Initialize acb */
525: acb->xs = xs;
526: acb->timeout = xs->timeout;
527: timeout_set(&xs->stimeout, aic_timeout, acb);
528:
529: if (xs->flags & SCSI_RESET) {
530: acb->flags |= ACB_RESET;
531: acb->scsi_cmd_length = 0;
532: acb->data_length = 0;
533: } else {
534: bcopy(xs->cmd, &acb->scsi_cmd, xs->cmdlen);
535: acb->scsi_cmd_length = xs->cmdlen;
536: acb->data_addr = xs->data;
537: acb->data_length = xs->datalen;
538: }
539: acb->target_stat = 0;
540:
541: s = splbio();
542:
543: TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
544: if (sc->sc_state == AIC_IDLE)
545: aic_sched(sc);
546:
547: splx(s);
548:
549: if ((flags & SCSI_POLL) == 0)
550: return SUCCESSFULLY_QUEUED;
551:
552: /* Not allowed to use interrupts, use polling instead */
553: if (aic_poll(sc, xs, acb->timeout)) {
554: aic_timeout(acb);
555: if (aic_poll(sc, xs, acb->timeout))
556: aic_timeout(acb);
557: }
558: return COMPLETE;
559: }
560:
561: #ifdef notyet
562: /*
563: * Adjust transfer size in buffer structure
564: */
565: void
566: aic_minphys(struct buf *bp)
567: {
568:
569: AIC_TRACE(("aic_minphys "));
570: if (bp->b_bcount > (AIC_NSEG << PGSHIFT))
571: bp->b_bcount = (AIC_NSEG << PGSHIFT);
572: minphys(bp);
573: }
574: #endif
575:
576: /*
577: * Used when interrupt driven I/O isn't allowed, e.g. during boot.
578: */
579: int
580: aic_poll(struct aic_softc *sc, struct scsi_xfer *xs, int count)
581: {
582: bus_space_tag_t iot = sc->sc_iot;
583: bus_space_handle_t ioh = sc->sc_ioh;
584:
585: AIC_TRACE(("aic_poll "));
586: while (count) {
587: /*
588: * If we had interrupts enabled, would we
589: * have got an interrupt?
590: */
591: if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) != 0)
592: aicintr(sc);
593: if ((xs->flags & ITSDONE) != 0)
594: return 0;
595: delay(1000);
596: count--;
597: }
598: return 1;
599: }
600:
601: /*
602: * LOW LEVEL SCSI UTILITIES
603: */
604:
605: integrate void
606: aic_sched_msgout(struct aic_softc *sc, u_char m)
607: {
608: bus_space_tag_t iot = sc->sc_iot;
609: bus_space_handle_t ioh = sc->sc_ioh;
610:
611: if (sc->sc_msgpriq == 0)
612: bus_space_write_1(iot, ioh, SCSISIG, sc->sc_phase | ATNO);
613: sc->sc_msgpriq |= m;
614: }
615:
616: /*
617: * Set synchronous transfer offset and period.
618: */
619: integrate void
620: aic_setsync(struct aic_softc *sc, struct aic_tinfo *ti)
621: {
622: #if AIC_USE_SYNCHRONOUS
623: bus_space_tag_t iot = sc->sc_iot;
624: bus_space_handle_t ioh = sc->sc_ioh;
625:
626: if (ti->offset != 0)
627: bus_space_write_1(iot, ioh, SCSIRATE,
628: ((ti->period * sc->sc_freq) / 250 - 2) << 4 | ti->offset);
629: else
630: bus_space_write_1(iot, ioh, SCSIRATE, 0);
631: #endif
632: }
633:
634: /*
635: * Start a selection. This is used by aic_sched() to select an idle target,
636: * and by aic_done() to immediately reselect a target to get sense information.
637: */
638: void
639: aic_select(struct aic_softc *sc, struct aic_acb *acb)
640: {
641: bus_space_tag_t iot = sc->sc_iot;
642: bus_space_handle_t ioh = sc->sc_ioh;
643: struct scsi_link *sc_link = acb->xs->sc_link;
644: int target = sc_link->target;
645: struct aic_tinfo *ti = &sc->sc_tinfo[target];
646:
647: bus_space_write_1(iot, ioh, SCSIID,
648: sc->sc_initiator << OID_S | target);
649: aic_setsync(sc, ti);
650: bus_space_write_1(iot, ioh, SXFRCTL1, STIMO_256ms | ENSTIMER);
651:
652: /* Always enable reselections. */
653: bus_space_write_1(iot, ioh, SIMODE0, ENSELDI | ENSELDO);
654: bus_space_write_1(iot, ioh, SIMODE1, ENSCSIRST | ENSELTIMO);
655: bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI | ENSELO | ENAUTOATNO);
656:
657: sc->sc_state = AIC_SELECTING;
658: }
659:
660: int
661: aic_reselect(struct aic_softc *sc, int message)
662: {
663: u_char selid, target, lun;
664: struct aic_acb *acb;
665: struct scsi_link *sc_link;
666: struct aic_tinfo *ti;
667:
668: /*
669: * The SCSI chip made a snapshot of the data bus while the reselection
670: * was being negotiated. This enables us to determine which target did
671: * the reselect.
672: */
673: selid = sc->sc_selid & ~(1 << sc->sc_initiator);
674: if (selid & (selid - 1)) {
675: printf("%s: reselect with invalid selid %02x; ",
676: sc->sc_dev.dv_xname, selid);
677: printf("sending DEVICE RESET\n");
678: AIC_BREAK();
679: goto reset;
680: }
681:
682: /* Search wait queue for disconnected cmd
683: * The list should be short, so I haven't bothered with
684: * any more sophisticated structures than a simple
685: * singly linked list.
686: */
687: target = ffs(selid) - 1;
688: lun = message & 0x07;
689: TAILQ_FOREACH(acb, &sc->nexus_list, chain) {
690: sc_link = acb->xs->sc_link;
691: if (sc_link->target == target && sc_link->lun == lun)
692: break;
693: }
694: if (acb == NULL) {
695: printf("%s: reselect from target %d lun %d with no nexus; ",
696: sc->sc_dev.dv_xname, target, lun);
697: printf("sending ABORT\n");
698: AIC_BREAK();
699: goto abort;
700: }
701:
702: /* Make this nexus active again. */
703: TAILQ_REMOVE(&sc->nexus_list, acb, chain);
704: sc->sc_state = AIC_CONNECTED;
705: sc->sc_nexus = acb;
706: ti = &sc->sc_tinfo[target];
707: ti->lubusy |= (1 << lun);
708: aic_setsync(sc, ti);
709:
710: if (acb->flags & ACB_RESET)
711: aic_sched_msgout(sc, SEND_DEV_RESET);
712: else if (acb->flags & ACB_ABORT)
713: aic_sched_msgout(sc, SEND_ABORT);
714:
715: /* Do an implicit RESTORE POINTERS. */
716: sc->sc_dp = acb->data_addr;
717: sc->sc_dleft = acb->data_length;
718: sc->sc_cp = (u_char *)&acb->scsi_cmd;
719: sc->sc_cleft = acb->scsi_cmd_length;
720:
721: return (0);
722:
723: reset:
724: aic_sched_msgout(sc, SEND_DEV_RESET);
725: return (1);
726:
727: abort:
728: aic_sched_msgout(sc, SEND_ABORT);
729: return (1);
730: }
731:
732: /*
733: * Schedule a SCSI operation. This has now been pulled out of the interrupt
734: * handler so that we may call it from aic_scsi_cmd and aic_done. This may
735: * save us an unnecessary interrupt just to get things going. Should only be
736: * called when state == AIC_IDLE and at bio pl.
737: */
738: void
739: aic_sched(struct aic_softc *sc)
740: {
741: bus_space_tag_t iot = sc->sc_iot;
742: bus_space_handle_t ioh = sc->sc_ioh;
743: struct aic_acb *acb;
744: struct scsi_link *sc_link;
745: struct aic_tinfo *ti;
746:
747: /*
748: * Find first acb in ready queue that is for a target/lunit pair that
749: * is not busy.
750: */
751: bus_space_write_1(iot, ioh, CLRSINT1,
752: CLRSELTIMO | CLRBUSFREE | CLRSCSIPERR);
753: TAILQ_FOREACH(acb, &sc->ready_list, chain) {
754: sc_link = acb->xs->sc_link;
755: ti = &sc->sc_tinfo[sc_link->target];
756: if ((ti->lubusy & (1 << sc_link->lun)) == 0) {
757: AIC_MISC(("selecting %d:%d ",
758: sc_link->target, sc_link->lun));
759: TAILQ_REMOVE(&sc->ready_list, acb, chain);
760: sc->sc_nexus = acb;
761: aic_select(sc, acb);
762: return;
763: } else
764: AIC_MISC(("%d:%d busy\n",
765: sc_link->target, sc_link->lun));
766: }
767: AIC_MISC(("idle "));
768: /* Nothing to start; just enable reselections and wait. */
769: bus_space_write_1(iot, ioh, SIMODE0, ENSELDI);
770: bus_space_write_1(iot, ioh, SIMODE1, ENSCSIRST);
771: bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI);
772: }
773:
774: void
775: aic_sense(struct aic_softc *sc, struct aic_acb *acb)
776: {
777: struct scsi_xfer *xs = acb->xs;
778: struct scsi_link *sc_link = xs->sc_link;
779: struct aic_tinfo *ti = &sc->sc_tinfo[sc_link->target];
780: struct scsi_sense *ss = (void *)&acb->scsi_cmd;
781:
782: AIC_MISC(("requesting sense "));
783: /* Next, setup a request sense command block */
784: bzero(ss, sizeof(*ss));
785: ss->opcode = REQUEST_SENSE;
786: ss->byte2 = sc_link->lun << 5;
787: ss->length = sizeof(struct scsi_sense_data);
788: acb->scsi_cmd_length = sizeof(*ss);
789: acb->data_addr = (char *)&xs->sense;
790: acb->data_length = sizeof(struct scsi_sense_data);
791: acb->flags |= ACB_SENSE;
792: ti->senses++;
793: if (acb->flags & ACB_NEXUS)
794: ti->lubusy &= ~(1 << sc_link->lun);
795: if (acb == sc->sc_nexus) {
796: aic_select(sc, acb);
797: } else {
798: aic_dequeue(sc, acb);
799: TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
800: if (sc->sc_state == AIC_IDLE)
801: aic_sched(sc);
802: }
803: }
804:
805: /*
806: * POST PROCESSING OF SCSI_CMD (usually current)
807: */
808: void
809: aic_done(struct aic_softc *sc, struct aic_acb *acb)
810: {
811: struct scsi_xfer *xs = acb->xs;
812: struct scsi_link *sc_link = xs->sc_link;
813: struct aic_tinfo *ti = &sc->sc_tinfo[sc_link->target];
814:
815: AIC_TRACE(("aic_done "));
816:
817: /*
818: * Now, if we've come here with no error code, i.e. we've kept the
819: * initial XS_NOERROR, and the status code signals that we should
820: * check sense, we'll need to set up a request sense cmd block and
821: * push the command back into the ready queue *before* any other
822: * commands for this target/lunit, else we lose the sense info.
823: * We don't support chk sense conditions for the request sense cmd.
824: */
825: if (xs->error == XS_NOERROR) {
826: if (acb->flags & ACB_ABORT) {
827: xs->error = XS_DRIVER_STUFFUP;
828: } else if (acb->flags & ACB_SENSE) {
829: xs->error = XS_SENSE;
830: } else if (acb->target_stat == SCSI_CHECK) {
831: /* First, save the return values */
832: xs->resid = acb->data_length;
833: xs->status = acb->target_stat;
834: aic_sense(sc, acb);
835: return;
836: } else {
837: xs->resid = acb->data_length;
838: }
839: }
840:
841: xs->flags |= ITSDONE;
842:
843: #ifdef AIC_DEBUG
844: if ((aic_debug & AIC_SHOWMISC) != 0) {
845: if (xs->resid != 0)
846: printf("resid=%lu ", (u_long)xs->resid);
847: if (xs->error == XS_SENSE)
848: printf("sense=0x%02x\n", xs->sense.error_code);
849: else
850: printf("error=%d\n", xs->error);
851: }
852: #endif
853:
854: /*
855: * Remove the ACB from whatever queue it happens to be on.
856: */
857: if (acb->flags & ACB_NEXUS)
858: ti->lubusy &= ~(1 << sc_link->lun);
859: if (acb == sc->sc_nexus) {
860: sc->sc_nexus = NULL;
861: sc->sc_state = AIC_IDLE;
862: aic_sched(sc);
863: } else
864: aic_dequeue(sc, acb);
865:
866: aic_free_acb(sc, acb, xs->flags);
867: ti->cmds++;
868: scsi_done(xs);
869: }
870:
871: void
872: aic_dequeue(struct aic_softc *sc, struct aic_acb *acb)
873: {
874:
875: if (acb->flags & ACB_NEXUS) {
876: TAILQ_REMOVE(&sc->nexus_list, acb, chain);
877: } else {
878: TAILQ_REMOVE(&sc->ready_list, acb, chain);
879: }
880: }
881:
882: /*
883: * INTERRUPT/PROTOCOL ENGINE
884: */
885:
886: #define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
887: #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
888: #define ISEXTMSG(m) ((m) == 0x01)
889:
890: /*
891: * Precondition:
892: * The SCSI bus is already in the MSGI phase and there is a message byte
893: * on the bus, along with an asserted REQ signal.
894: */
895: void
896: aic_msgin(struct aic_softc *sc)
897: {
898: bus_space_tag_t iot = sc->sc_iot;
899: bus_space_handle_t ioh = sc->sc_ioh;
900: u_char sstat1;
901: int n;
902:
903: AIC_TRACE(("aic_msgin "));
904:
905: if (sc->sc_prevphase == PH_MSGIN) {
906: /* This is a continuation of the previous message. */
907: n = sc->sc_imp - sc->sc_imess;
908: goto nextbyte;
909: }
910:
911: /* This is a new MESSAGE IN phase. Clean up our state. */
912: sc->sc_flags &= ~AIC_DROP_MSGIN;
913:
914: nextmsg:
915: n = 0;
916: sc->sc_imp = &sc->sc_imess[n];
917:
918: nextbyte:
919: /*
920: * Read a whole message, but don't ack the last byte. If we reject the
921: * message, we have to assert ATN during the message transfer phase
922: * itself.
923: */
924: for (;;) {
925: for (;;) {
926: sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
927: if ((sstat1 & (REQINIT | PHASECHG | BUSFREE)) != 0)
928: break;
929: /* Wait for REQINIT. XXX Need timeout. */
930: }
931: if ((sstat1 & (PHASECHG | BUSFREE)) != 0) {
932: /*
933: * Target left MESSAGE IN, probably because it
934: * a) noticed our ATN signal, or
935: * b) ran out of messages.
936: */
937: goto out;
938: }
939:
940: /* If parity error, just dump everything on the floor. */
941: if ((sstat1 & SCSIPERR) != 0) {
942: sc->sc_flags |= AIC_DROP_MSGIN;
943: aic_sched_msgout(sc, SEND_PARITY_ERROR);
944: }
945:
946: /* Gather incoming message bytes if needed. */
947: if ((sc->sc_flags & AIC_DROP_MSGIN) == 0) {
948: if (n >= AIC_MAX_MSG_LEN) {
949: (void) bus_space_read_1(iot, ioh, SCSIDAT);
950: sc->sc_flags |= AIC_DROP_MSGIN;
951: aic_sched_msgout(sc, SEND_REJECT);
952: } else {
953: *sc->sc_imp++ = bus_space_read_1(iot, ioh,
954: SCSIDAT);
955: n++;
956: /*
957: * This testing is suboptimal, but most
958: * messages will be of the one byte variety, so
959: * it should not affect performance
960: * significantly.
961: */
962: if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
963: break;
964: if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
965: break;
966: if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
967: n == sc->sc_imess[1] + 2)
968: break;
969: }
970: } else
971: (void) bus_space_read_1(iot, ioh, SCSIDAT);
972:
973: /*
974: * If we reach this spot we're either:
975: * a) in the middle of a multi-byte message, or
976: * b) dropping bytes.
977: */
978: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
979: /* Ack the last byte read. */
980: (void) bus_space_read_1(iot, ioh, SCSIDAT);
981: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
982: while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
983: ;
984: }
985:
986: AIC_MISC(("n=%d imess=0x%02x ", n, sc->sc_imess[0]));
987:
988: /* We now have a complete message. Parse it. */
989: switch (sc->sc_state) {
990: struct aic_acb *acb;
991: struct scsi_link *sc_link;
992: struct aic_tinfo *ti;
993:
994: case AIC_CONNECTED:
995: AIC_ASSERT(sc->sc_nexus != NULL);
996: acb = sc->sc_nexus;
997: ti = &sc->sc_tinfo[acb->xs->sc_link->target];
998:
999: switch (sc->sc_imess[0]) {
1000: case MSG_CMDCOMPLETE:
1001: if ((long)sc->sc_dleft < 0) {
1002: sc_link = acb->xs->sc_link;
1003: printf("%s: %lu extra bytes from %d:%d\n",
1004: sc->sc_dev.dv_xname, (u_long)-sc->sc_dleft,
1005: sc_link->target, sc_link->lun);
1006: acb->data_length = 0;
1007: }
1008: acb->xs->resid = acb->data_length = sc->sc_dleft;
1009: sc->sc_state = AIC_CMDCOMPLETE;
1010: break;
1011:
1012: case MSG_PARITY_ERROR:
1013: /* Resend the last message. */
1014: aic_sched_msgout(sc, sc->sc_lastmsg);
1015: break;
1016:
1017: case MSG_MESSAGE_REJECT:
1018: AIC_MISC(("message rejected %02x ", sc->sc_lastmsg));
1019: switch (sc->sc_lastmsg) {
1020: #if AIC_USE_SYNCHRONOUS + AIC_USE_WIDE
1021: case SEND_IDENTIFY:
1022: ti->flags &= ~(DO_SYNC | DO_WIDE);
1023: ti->period = ti->offset = 0;
1024: aic_setsync(sc, ti);
1025: ti->width = 0;
1026: break;
1027: #endif
1028: #if AIC_USE_SYNCHRONOUS
1029: case SEND_SDTR:
1030: ti->flags &= ~DO_SYNC;
1031: ti->period = ti->offset = 0;
1032: aic_setsync(sc, ti);
1033: break;
1034: #endif
1035: #if AIC_USE_WIDE
1036: case SEND_WDTR:
1037: ti->flags &= ~DO_WIDE;
1038: ti->width = 0;
1039: break;
1040: #endif
1041: case SEND_INIT_DET_ERR:
1042: aic_sched_msgout(sc, SEND_ABORT);
1043: break;
1044: }
1045: break;
1046:
1047: case MSG_NOOP:
1048: break;
1049:
1050: case MSG_DISCONNECT:
1051: ti->dconns++;
1052: sc->sc_state = AIC_DISCONNECT;
1053: break;
1054:
1055: case MSG_SAVEDATAPOINTER:
1056: acb->data_addr = sc->sc_dp;
1057: acb->data_length = sc->sc_dleft;
1058: break;
1059:
1060: case MSG_RESTOREPOINTERS:
1061: sc->sc_dp = acb->data_addr;
1062: sc->sc_dleft = acb->data_length;
1063: sc->sc_cp = (u_char *)&acb->scsi_cmd;
1064: sc->sc_cleft = acb->scsi_cmd_length;
1065: break;
1066:
1067: case MSG_EXTENDED:
1068: switch (sc->sc_imess[2]) {
1069: #if AIC_USE_SYNCHRONOUS
1070: case MSG_EXT_SDTR:
1071: if (sc->sc_imess[1] != 3)
1072: goto reject;
1073: ti->period = sc->sc_imess[3];
1074: ti->offset = sc->sc_imess[4];
1075: ti->flags &= ~DO_SYNC;
1076: if (ti->offset == 0) {
1077: } else if (ti->period < sc->sc_minsync ||
1078: ti->period > sc->sc_maxsync ||
1079: ti->offset > 8) {
1080: ti->period = ti->offset = 0;
1081: aic_sched_msgout(sc, SEND_SDTR);
1082: } else {
1083: sc_print_addr(acb->xs->sc_link);
1084: printf("sync, offset %d, ",
1085: ti->offset);
1086: printf("period %dnsec\n",
1087: ti->period * 4);
1088: }
1089: aic_setsync(sc, ti);
1090: break;
1091: #endif
1092:
1093: #if AIC_USE_WIDE
1094: case MSG_EXT_WDTR:
1095: if (sc->sc_imess[1] != 2)
1096: goto reject;
1097: ti->width = sc->sc_imess[3];
1098: ti->flags &= ~DO_WIDE;
1099: if (ti->width == 0) {
1100: } else if (ti->width > AIC_MAX_WIDTH) {
1101: ti->width = 0;
1102: aic_sched_msgout(sc, SEND_WDTR);
1103: } else {
1104: sc_print_addr(acb->xs->sc_link);
1105: printf("wide, width %d\n",
1106: 1 << (3 + ti->width));
1107: }
1108: break;
1109: #endif
1110:
1111: default:
1112: printf("%s: unrecognized MESSAGE EXTENDED; ",
1113: sc->sc_dev.dv_xname);
1114: printf("sending REJECT\n");
1115: AIC_BREAK();
1116: goto reject;
1117: }
1118: break;
1119:
1120: default:
1121: printf("%s: unrecognized MESSAGE; sending REJECT\n",
1122: sc->sc_dev.dv_xname);
1123: AIC_BREAK();
1124: reject:
1125: aic_sched_msgout(sc, SEND_REJECT);
1126: break;
1127: }
1128: break;
1129:
1130: case AIC_RESELECTED:
1131: if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
1132: printf("%s: reselect without IDENTIFY; ",
1133: sc->sc_dev.dv_xname);
1134: printf("sending DEVICE RESET\n");
1135: AIC_BREAK();
1136: goto reset;
1137: }
1138:
1139: (void) aic_reselect(sc, sc->sc_imess[0]);
1140: break;
1141:
1142: default:
1143: printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
1144: sc->sc_dev.dv_xname);
1145: AIC_BREAK();
1146: reset:
1147: aic_sched_msgout(sc, SEND_DEV_RESET);
1148: break;
1149:
1150: #ifdef notdef
1151: abort:
1152: aic_sched_msgout(sc, SEND_ABORT);
1153: break;
1154: #endif
1155: }
1156:
1157: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1158: /* Ack the last message byte. */
1159: (void) bus_space_read_1(iot, ioh, SCSIDAT);
1160: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1161: while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
1162: ;
1163:
1164: /* Go get the next message, if any. */
1165: goto nextmsg;
1166:
1167: out:
1168: AIC_MISC(("n=%d imess=0x%02x ", n, sc->sc_imess[0]));
1169: }
1170:
1171: /*
1172: * Send the highest priority, scheduled message.
1173: */
1174: void
1175: aic_msgout(struct aic_softc *sc)
1176: {
1177: bus_space_tag_t iot = sc->sc_iot;
1178: bus_space_handle_t ioh = sc->sc_ioh;
1179: #if AIC_USE_SYNCHRONOUS
1180: struct aic_tinfo *ti;
1181: #endif
1182: u_char sstat1;
1183: int n;
1184:
1185: AIC_TRACE(("aic_msgout "));
1186:
1187: /* Reset the FIFO. */
1188: bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
1189: /* Enable REQ/ACK protocol. */
1190: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1191:
1192: if (sc->sc_prevphase == PH_MSGOUT) {
1193: if (sc->sc_omp == sc->sc_omess) {
1194: /*
1195: * This is a retransmission.
1196: *
1197: * We get here if the target stayed in MESSAGE OUT
1198: * phase. Section 5.1.9.2 of the SCSI 2 spec indicates
1199: * that all of the previously transmitted messages must
1200: * be sent again, in the same order. Therefore, we
1201: * requeue all the previously transmitted messages, and
1202: * start again from the top. Our simple priority
1203: * scheme keeps the messages in the right order.
1204: */
1205: AIC_MISC(("retransmitting "));
1206: sc->sc_msgpriq |= sc->sc_msgoutq;
1207: /*
1208: * Set ATN. If we're just sending a trivial 1-byte
1209: * message, we'll clear ATN later on anyway.
1210: */
1211: bus_space_write_1(iot, ioh, SCSISIG, PH_MSGOUT | ATNO);
1212: } else {
1213: /* This is a continuation of the previous message. */
1214: n = sc->sc_omp - sc->sc_omess;
1215: goto nextbyte;
1216: }
1217: }
1218:
1219: /* No messages transmitted so far. */
1220: sc->sc_msgoutq = 0;
1221: sc->sc_lastmsg = 0;
1222:
1223: nextmsg:
1224: /* Pick up highest priority message. */
1225: sc->sc_currmsg = sc->sc_msgpriq & -sc->sc_msgpriq;
1226: sc->sc_msgpriq &= ~sc->sc_currmsg;
1227: sc->sc_msgoutq |= sc->sc_currmsg;
1228:
1229: /* Build the outgoing message data. */
1230: switch (sc->sc_currmsg) {
1231: case SEND_IDENTIFY:
1232: AIC_ASSERT(sc->sc_nexus != NULL);
1233: sc->sc_omess[0] =
1234: MSG_IDENTIFY(sc->sc_nexus->xs->sc_link->lun, 1);
1235: n = 1;
1236: break;
1237:
1238: #if AIC_USE_SYNCHRONOUS
1239: case SEND_SDTR:
1240: AIC_ASSERT(sc->sc_nexus != NULL);
1241: ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
1242: sc->sc_omess[4] = MSG_EXTENDED;
1243: sc->sc_omess[3] = 3;
1244: sc->sc_omess[2] = MSG_EXT_SDTR;
1245: sc->sc_omess[1] = ti->period >> 2;
1246: sc->sc_omess[0] = ti->offset;
1247: n = 5;
1248: break;
1249: #endif
1250:
1251: #if AIC_USE_WIDE
1252: case SEND_WDTR:
1253: AIC_ASSERT(sc->sc_nexus != NULL);
1254: ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
1255: sc->sc_omess[3] = MSG_EXTENDED;
1256: sc->sc_omess[2] = 2;
1257: sc->sc_omess[1] = MSG_EXT_WDTR;
1258: sc->sc_omess[0] = ti->width;
1259: n = 4;
1260: break;
1261: #endif
1262:
1263: case SEND_DEV_RESET:
1264: sc->sc_flags |= AIC_ABORTING;
1265: sc->sc_omess[0] = MSG_BUS_DEV_RESET;
1266: n = 1;
1267: break;
1268:
1269: case SEND_REJECT:
1270: sc->sc_omess[0] = MSG_MESSAGE_REJECT;
1271: n = 1;
1272: break;
1273:
1274: case SEND_PARITY_ERROR:
1275: sc->sc_omess[0] = MSG_PARITY_ERROR;
1276: n = 1;
1277: break;
1278:
1279: case SEND_INIT_DET_ERR:
1280: sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
1281: n = 1;
1282: break;
1283:
1284: case SEND_ABORT:
1285: sc->sc_flags |= AIC_ABORTING;
1286: sc->sc_omess[0] = MSG_ABORT;
1287: n = 1;
1288: break;
1289:
1290: default:
1291: printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
1292: sc->sc_dev.dv_xname);
1293: AIC_BREAK();
1294: sc->sc_omess[0] = MSG_NOOP;
1295: n = 1;
1296: break;
1297: }
1298: sc->sc_omp = &sc->sc_omess[n];
1299:
1300: nextbyte:
1301: /* Send message bytes. */
1302: for (;;) {
1303: for (;;) {
1304: sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
1305: if ((sstat1 & (REQINIT | PHASECHG | BUSFREE)) != 0)
1306: break;
1307: /* Wait for REQINIT. XXX Need timeout. */
1308: }
1309: if ((sstat1 & (PHASECHG | BUSFREE)) != 0) {
1310: /*
1311: * Target left MESSAGE OUT, possibly to reject
1312: * our message.
1313: *
1314: * If this is the last message being sent, then we
1315: * deassert ATN, since either the target is going to
1316: * ignore this message, or it's going to ask for a
1317: * retransmission via MESSAGE PARITY ERROR (in which
1318: * case we reassert ATN anyway).
1319: */
1320: if (sc->sc_msgpriq == 0)
1321: bus_space_write_1(iot, ioh, CLRSINT1, CLRATNO);
1322: goto out;
1323: }
1324:
1325: /* Clear ATN before last byte if this is the last message. */
1326: if (n == 1 && sc->sc_msgpriq == 0)
1327: bus_space_write_1(iot, ioh, CLRSINT1, CLRATNO);
1328: /* Send message byte. */
1329: bus_space_write_1(iot, ioh, SCSIDAT, *--sc->sc_omp);
1330: --n;
1331: /* Keep track of the last message we've sent any bytes of. */
1332: sc->sc_lastmsg = sc->sc_currmsg;
1333: /* Wait for ACK to be negated. XXX Need timeout. */
1334: while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
1335: ;
1336:
1337: if (n == 0)
1338: break;
1339: }
1340:
1341: /* We get here only if the entire message has been transmitted. */
1342: if (sc->sc_msgpriq != 0) {
1343: /* There are more outgoing messages. */
1344: goto nextmsg;
1345: }
1346:
1347: /*
1348: * The last message has been transmitted. We need to remember the last
1349: * message transmitted (in case the target switches to MESSAGE IN phase
1350: * and sends a MESSAGE REJECT), and the list of messages transmitted
1351: * this time around (in case the target stays in MESSAGE OUT phase to
1352: * request a retransmit).
1353: */
1354:
1355: out:
1356: /* Disable REQ/ACK protocol. */
1357: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1358: }
1359:
1360: /* aic_dataout_pio: perform a data transfer using the FIFO datapath in the aic6360
1361: * Precondition: The SCSI bus should be in the DOUT phase, with REQ asserted
1362: * and ACK deasserted (i.e. waiting for a data byte).
1363: * This new revision has been optimized (I tried) to make the common case fast,
1364: * and the rarer cases (as a result) somewhat more complex.
1365: */
1366: int
1367: aic_dataout_pio(struct aic_softc *sc, u_char *p, int n)
1368: {
1369: bus_space_tag_t iot = sc->sc_iot;
1370: bus_space_handle_t ioh = sc->sc_ioh;
1371: u_char dmastat = 0;
1372: int out = 0;
1373: #define DOUTAMOUNT 128 /* Full FIFO */
1374:
1375: AIC_MISC(("%02x%02x ", bus_space_read_1(iot, ioh, FIFOSTAT),
1376: bus_space_read_1(iot, ioh, SSTAT2)));
1377:
1378: /* Clear host FIFO and counter. */
1379: bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO | WRITE);
1380: /* Enable FIFOs. */
1381: bus_space_write_1(iot, ioh, DMACNTRL0, ENDMA | DWORDPIO | WRITE);
1382: bus_space_write_1(iot, ioh, SXFRCTL0, SCSIEN | DMAEN | CHEN);
1383:
1384: /* Turn off ENREQINIT for now. */
1385: bus_space_write_1(iot, ioh, SIMODE1,
1386: ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENPHASECHG);
1387:
1388: /* I have tried to make the main loop as tight as possible. This
1389: * means that some of the code following the loop is a bit more
1390: * complex than otherwise.
1391: */
1392: while (n > 0) {
1393: for (;;) {
1394: dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1395: if ((dmastat & (DFIFOEMP | INTSTAT)) != 0)
1396: break;
1397: }
1398:
1399: if ((dmastat & INTSTAT) != 0)
1400: goto phasechange;
1401:
1402: if (n >= DOUTAMOUNT) {
1403: n -= DOUTAMOUNT;
1404: out += DOUTAMOUNT;
1405:
1406: #if AIC_USE_DWORDS
1407: bus_space_write_multi_4(iot, ioh, DMADATALONG,
1408: (u_int32_t *)p, DOUTAMOUNT >> 2);
1409: #else
1410: bus_space_write_multi_2(iot, ioh, DMADATA,
1411: (u_int16_t *)p, DOUTAMOUNT >> 1);
1412: #endif
1413:
1414: p += DOUTAMOUNT;
1415: } else {
1416: int xfer;
1417:
1418: xfer = n;
1419: AIC_MISC(("%d> ", xfer));
1420:
1421: n -= xfer;
1422: out += xfer;
1423:
1424: #if AIC_USE_DWORDS
1425: if (xfer >= 12) {
1426: bus_space_write_multi_4(iot, ioh, DMADATALONG,
1427: (u_int32_t *)p, xfer >> 2);
1428: p += xfer & ~3;
1429: xfer &= 3;
1430: }
1431: #else
1432: if (xfer >= 8) {
1433: bus_space_write_multi_2(iot, ioh, DMADATA,
1434: (u_int16_t *)p, xfer >> 1);
1435: p += xfer & ~1;
1436: xfer &= 1;
1437: }
1438: #endif
1439:
1440: if (xfer > 0) {
1441: bus_space_write_1(iot, ioh, DMACNTRL0,
1442: ENDMA | B8MODE | WRITE);
1443: bus_space_write_multi_1(iot, ioh, DMADATA, p,
1444: xfer);
1445: p += xfer;
1446: bus_space_write_1(iot, ioh, DMACNTRL0,
1447: ENDMA | DWORDPIO | WRITE);
1448: }
1449: }
1450: }
1451:
1452: if (out == 0) {
1453: bus_space_write_1(iot, ioh, SXFRCTL1, BITBUCKET);
1454: for (;;) {
1455: if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) !=
1456: 0)
1457: break;
1458: }
1459: bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1460: AIC_MISC(("extra data "));
1461: } else {
1462: /* See the bytes off chip */
1463: for (;;) {
1464: dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1465: if ((dmastat & INTSTAT) != 0)
1466: goto phasechange;
1467: if ((dmastat & DFIFOEMP) != 0 &&
1468: (bus_space_read_1(iot, ioh, SSTAT2) & SEMPTY) != 0)
1469: break;
1470: }
1471: }
1472:
1473: phasechange:
1474: if ((dmastat & INTSTAT) != 0) {
1475: /* Some sort of phase change. */
1476: int amount;
1477:
1478: /* Stop transfers, do some accounting */
1479: amount = bus_space_read_1(iot, ioh, FIFOSTAT) +
1480: (bus_space_read_1(iot, ioh, SSTAT2) & 15);
1481: if (amount > 0) {
1482: out -= amount;
1483: bus_space_write_1(iot, ioh, DMACNTRL0,
1484: RSTFIFO | WRITE);
1485: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRCH);
1486: AIC_MISC(("+%d ", amount));
1487: }
1488: }
1489:
1490: /* Turn on ENREQINIT again. */
1491: bus_space_write_1(iot, ioh, SIMODE1,
1492: ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT | ENPHASECHG);
1493:
1494: /* Stop the FIFO data path. */
1495: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1496: bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1497:
1498: return out;
1499: }
1500:
1501: /* aic_datain_pio: perform data transfers using the FIFO datapath in the aic6360
1502: * Precondition: The SCSI bus should be in the DIN phase, with REQ asserted
1503: * and ACK deasserted (i.e. at least one byte is ready).
1504: * For now, uses a pretty dumb algorithm, hangs around until all data has been
1505: * transferred. This, is OK for fast targets, but not so smart for slow
1506: * targets which don't disconnect or for huge transfers.
1507: */
1508: int
1509: aic_datain_pio(struct aic_softc *sc, u_char *p, int n)
1510: {
1511: bus_space_tag_t iot = sc->sc_iot;
1512: bus_space_handle_t ioh = sc->sc_ioh;
1513: u_char dmastat;
1514: int in = 0;
1515: #define DINAMOUNT 128 /* Full FIFO */
1516:
1517: AIC_MISC(("%02x%02x ", bus_space_read_1(iot, ioh, FIFOSTAT),
1518: bus_space_read_1(iot, ioh, SSTAT2)));
1519:
1520: /* Clear host FIFO and counter. */
1521: bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
1522: /* Enable FIFOs. */
1523: bus_space_write_1(iot, ioh, DMACNTRL0, ENDMA | DWORDPIO);
1524: bus_space_write_1(iot, ioh, SXFRCTL0, SCSIEN | DMAEN | CHEN);
1525:
1526: /* Turn off ENREQINIT for now. */
1527: bus_space_write_1(iot, ioh, SIMODE1,
1528: ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENPHASECHG);
1529:
1530: /* We leave this loop if one or more of the following is true:
1531: * a) phase != PH_DATAIN && FIFOs are empty
1532: * b) SCSIRSTI is set (a reset has occurred) or busfree is detected.
1533: */
1534: while (n > 0) {
1535: /* Wait for fifo half full or phase mismatch */
1536: for (;;) {
1537: dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1538: if ((dmastat & (DFIFOFULL | INTSTAT)) != 0)
1539: break;
1540: }
1541:
1542: if ((dmastat & DFIFOFULL) != 0) {
1543: n -= DINAMOUNT;
1544: in += DINAMOUNT;
1545:
1546: #if AIC_USE_DWORDS
1547: bus_space_read_multi_4(iot, ioh, DMADATALONG,
1548: (u_int32_t *)p, DINAMOUNT >> 2);
1549: #else
1550: bus_space_read_multi_2(iot, ioh, DMADATA,
1551: (u_int16_t *)p, DINAMOUNT >> 1);
1552: #endif
1553:
1554: p += DINAMOUNT;
1555: } else {
1556: int xfer;
1557:
1558: xfer = min(bus_space_read_1(iot, ioh, FIFOSTAT), n);
1559: AIC_MISC((">%d ", xfer));
1560:
1561: n -= xfer;
1562: in += xfer;
1563:
1564: #if AIC_USE_DWORDS
1565: if (xfer >= 12) {
1566: bus_space_read_multi_4(iot, ioh, DMADATALONG,
1567: (u_int32_t *)p, xfer >> 2);
1568: p += xfer & ~3;
1569: xfer &= 3;
1570: }
1571: #else
1572: if (xfer >= 8) {
1573: bus_space_read_multi_2(iot, ioh, DMADATA,
1574: (u_int16_t *)p, xfer >> 1);
1575: p += xfer & ~1;
1576: xfer &= 1;
1577: }
1578: #endif
1579:
1580: if (xfer > 0) {
1581: bus_space_write_1(iot, ioh, DMACNTRL0,
1582: ENDMA | B8MODE);
1583: bus_space_read_multi_1(iot, ioh, DMADATA, p,
1584: xfer);
1585: p += xfer;
1586: bus_space_write_1(iot, ioh, DMACNTRL0,
1587: ENDMA | DWORDPIO);
1588: }
1589: }
1590:
1591: if ((dmastat & INTSTAT) != 0)
1592: goto phasechange;
1593: }
1594:
1595: /* Some SCSI-devices are rude enough to transfer more data than what
1596: * was requested, e.g. 2048 bytes from a CD-ROM instead of the
1597: * requested 512. Test for progress, i.e. real transfers. If no real
1598: * transfers have been performed (n is probably already zero) and the
1599: * FIFO is not empty, waste some bytes....
1600: */
1601: if (in == 0) {
1602: bus_space_write_1(iot, ioh, SXFRCTL1, BITBUCKET);
1603: for (;;) {
1604: if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) !=
1605: 0)
1606: break;
1607: }
1608: bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1609: AIC_MISC(("extra data "));
1610: }
1611:
1612: phasechange:
1613: /* Turn on ENREQINIT again. */
1614: bus_space_write_1(iot, ioh, SIMODE1,
1615: ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT | ENPHASECHG);
1616:
1617: /* Stop the FIFO data path. */
1618: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1619: bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1620:
1621: return in;
1622: }
1623:
1624: /*
1625: * This is the workhorse routine of the driver.
1626: * Deficiencies (for now):
1627: * 1) always uses programmed I/O
1628: */
1629: int
1630: aicintr(void *arg)
1631: {
1632: struct aic_softc *sc = arg;
1633: bus_space_tag_t iot = sc->sc_iot;
1634: bus_space_handle_t ioh = sc->sc_ioh;
1635: u_char sstat0, sstat1;
1636: struct aic_acb *acb;
1637: struct scsi_link *sc_link;
1638: struct aic_tinfo *ti;
1639: int n;
1640:
1641: /*
1642: * Clear INTEN. We enable it again before returning. This makes the
1643: * interrupt esssentially level-triggered.
1644: */
1645: bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1646:
1647: AIC_TRACE(("aicintr "));
1648:
1649: loop:
1650: /*
1651: * First check for abnormal conditions, such as reset.
1652: */
1653: sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
1654: AIC_MISC(("sstat1:0x%02x ", sstat1));
1655:
1656: if ((sstat1 & SCSIRSTI) != 0) {
1657: printf("%s: SCSI bus reset\n", sc->sc_dev.dv_xname);
1658: goto reset;
1659: }
1660:
1661: /*
1662: * Check for less serious errors.
1663: */
1664: if ((sstat1 & SCSIPERR) != 0) {
1665: printf("%s: SCSI bus parity error\n", sc->sc_dev.dv_xname);
1666: bus_space_write_1(iot, ioh, CLRSINT1, CLRSCSIPERR);
1667: if (sc->sc_prevphase == PH_MSGIN) {
1668: sc->sc_flags |= AIC_DROP_MSGIN;
1669: aic_sched_msgout(sc, SEND_PARITY_ERROR);
1670: } else
1671: aic_sched_msgout(sc, SEND_INIT_DET_ERR);
1672: }
1673:
1674: /*
1675: * If we're not already busy doing something test for the following
1676: * conditions:
1677: * 1) We have been reselected by something
1678: * 2) We have selected something successfully
1679: * 3) Our selection process has timed out
1680: * 4) This is really a bus free interrupt just to get a new command
1681: * going?
1682: * 5) Spurious interrupt?
1683: */
1684: switch (sc->sc_state) {
1685: case AIC_IDLE:
1686: case AIC_SELECTING:
1687: sstat0 = bus_space_read_1(iot, ioh, SSTAT0);
1688: AIC_MISC(("sstat0:0x%02x ", sstat0));
1689:
1690: if ((sstat0 & TARGET) != 0) {
1691: /*
1692: * We don't currently support target mode.
1693: */
1694: printf("%s: target mode selected; going to BUS FREE\n",
1695: sc->sc_dev.dv_xname);
1696: bus_space_write_1(iot, ioh, SCSISIG, 0);
1697:
1698: goto sched;
1699: } else if ((sstat0 & SELDI) != 0) {
1700: AIC_MISC(("reselected "));
1701:
1702: /*
1703: * If we're trying to select a target ourselves,
1704: * push our command back into the ready list.
1705: */
1706: if (sc->sc_state == AIC_SELECTING) {
1707: AIC_MISC(("backoff selector "));
1708: AIC_ASSERT(sc->sc_nexus != NULL);
1709: acb = sc->sc_nexus;
1710: sc->sc_nexus = NULL;
1711: TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
1712: }
1713:
1714: /* Save reselection ID. */
1715: sc->sc_selid = bus_space_read_1(iot, ioh, SELID);
1716:
1717: sc->sc_state = AIC_RESELECTED;
1718: } else if ((sstat0 & SELDO) != 0) {
1719: AIC_MISC(("selected "));
1720:
1721: /* We have selected a target. Things to do:
1722: * a) Determine what message(s) to send.
1723: * b) Verify that we're still selecting the target.
1724: * c) Mark device as busy.
1725: */
1726: if (sc->sc_state != AIC_SELECTING) {
1727: printf("%s: selection out while idle; ",
1728: sc->sc_dev.dv_xname);
1729: printf("resetting\n");
1730: AIC_BREAK();
1731: goto reset;
1732: }
1733: AIC_ASSERT(sc->sc_nexus != NULL);
1734: acb = sc->sc_nexus;
1735: sc_link = acb->xs->sc_link;
1736: ti = &sc->sc_tinfo[sc_link->target];
1737:
1738: sc->sc_msgpriq = SEND_IDENTIFY;
1739: if (acb->flags & ACB_RESET)
1740: sc->sc_msgpriq |= SEND_DEV_RESET;
1741: else if (acb->flags & ACB_ABORT)
1742: sc->sc_msgpriq |= SEND_ABORT;
1743: else {
1744: #if AIC_USE_SYNCHRONOUS
1745: if ((ti->flags & DO_SYNC) != 0)
1746: sc->sc_msgpriq |= SEND_SDTR;
1747: #endif
1748: #if AIC_USE_WIDE
1749: if ((ti->flags & DO_WIDE) != 0)
1750: sc->sc_msgpriq |= SEND_WDTR;
1751: #endif
1752: }
1753:
1754: acb->flags |= ACB_NEXUS;
1755: ti->lubusy |= (1 << sc_link->lun);
1756:
1757: /* Do an implicit RESTORE POINTERS. */
1758: sc->sc_dp = acb->data_addr;
1759: sc->sc_dleft = acb->data_length;
1760: sc->sc_cp = (u_char *)&acb->scsi_cmd;
1761: sc->sc_cleft = acb->scsi_cmd_length;
1762:
1763: /* On our first connection, schedule a timeout. */
1764: if ((acb->xs->flags & SCSI_POLL) == 0)
1765: timeout_add(&acb->xs->stimeout,
1766: (acb->timeout * hz) / 1000);
1767:
1768: sc->sc_state = AIC_CONNECTED;
1769: } else if ((sstat1 & SELTO) != 0) {
1770: AIC_MISC(("selection timeout "));
1771:
1772: if (sc->sc_state != AIC_SELECTING) {
1773: printf("%s: selection timeout while idle; ",
1774: sc->sc_dev.dv_xname);
1775: printf("resetting\n");
1776: AIC_BREAK();
1777: goto reset;
1778: }
1779: AIC_ASSERT(sc->sc_nexus != NULL);
1780: acb = sc->sc_nexus;
1781:
1782: bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1783: bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI);
1784: bus_space_write_1(iot, ioh, CLRSINT1, CLRSELTIMO);
1785: delay(250);
1786:
1787: acb->xs->error = XS_SELTIMEOUT;
1788: goto finish;
1789: } else {
1790: if (sc->sc_state != AIC_IDLE) {
1791: printf("%s: BUS FREE while not idle; ",
1792: sc->sc_dev.dv_xname);
1793: printf("state=%d\n", sc->sc_state);
1794: AIC_BREAK();
1795: goto out;
1796: }
1797:
1798: goto sched;
1799: }
1800:
1801: /*
1802: * Turn off selection stuff, and prepare to catch bus free
1803: * interrupts, parity errors, and phase changes.
1804: */
1805: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRSTCNT | CLRCH);
1806: bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1807: bus_space_write_1(iot, ioh, SCSISEQ, ENAUTOATNP);
1808: bus_space_write_1(iot, ioh, CLRSINT0, CLRSELDI | CLRSELDO);
1809: bus_space_write_1(iot, ioh, CLRSINT1,
1810: CLRBUSFREE | CLRPHASECHG);
1811: bus_space_write_1(iot, ioh, SIMODE0, 0);
1812: bus_space_write_1(iot, ioh, SIMODE1,
1813: ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT |
1814: ENPHASECHG);
1815:
1816: sc->sc_flags = 0;
1817: sc->sc_prevphase = PH_INVALID;
1818: goto dophase;
1819: }
1820:
1821: if ((sstat1 & BUSFREE) != 0) {
1822: /* We've gone to BUS FREE phase. */
1823: bus_space_write_1(iot, ioh, CLRSINT1,
1824: CLRBUSFREE | CLRPHASECHG);
1825:
1826: switch (sc->sc_state) {
1827: case AIC_RESELECTED:
1828: goto sched;
1829:
1830: case AIC_CONNECTED:
1831: AIC_ASSERT(sc->sc_nexus != NULL);
1832: acb = sc->sc_nexus;
1833:
1834: #if AIC_USE_SYNCHRONOUS + AIC_USE_WIDE
1835: if (sc->sc_prevphase == PH_MSGOUT) {
1836: /*
1837: * If the target went to BUS FREE phase during
1838: * or immediately after sending a SDTR or WDTR
1839: * message, disable negotiation.
1840: */
1841: sc_link = acb->xs->sc_link;
1842: ti = &sc->sc_tinfo[sc_link->target];
1843: switch (sc->sc_lastmsg) {
1844: #if AIC_USE_SYNCHRONOUS
1845: case SEND_SDTR:
1846: ti->flags &= ~DO_SYNC;
1847: ti->period = ti->offset = 0;
1848: break;
1849: #endif
1850: #if AIC_USE_WIDE
1851: case SEND_WDTR:
1852: ti->flags &= ~DO_WIDE;
1853: ti->width = 0;
1854: break;
1855: #endif
1856: }
1857: }
1858: #endif
1859:
1860: if ((sc->sc_flags & AIC_ABORTING) == 0) {
1861: /*
1862: * Section 5.1.1 of the SCSI 2 spec suggests
1863: * issuing a REQUEST SENSE following an
1864: * unexpected disconnect. Some devices go into
1865: * a contingent allegiance condition when
1866: * disconnecting, and this is necessary to
1867: * clean up their state.
1868: */
1869: printf("%s: unexpected disconnect; ",
1870: sc->sc_dev.dv_xname);
1871: printf("sending REQUEST SENSE\n");
1872: AIC_BREAK();
1873: aic_sense(sc, acb);
1874: goto out;
1875: }
1876:
1877: acb->xs->error = XS_DRIVER_STUFFUP;
1878: goto finish;
1879:
1880: case AIC_DISCONNECT:
1881: AIC_ASSERT(sc->sc_nexus != NULL);
1882: acb = sc->sc_nexus;
1883: #if 1 /* XXXX */
1884: acb->data_addr = sc->sc_dp;
1885: acb->data_length = sc->sc_dleft;
1886: #endif
1887: TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
1888: sc->sc_nexus = NULL;
1889: goto sched;
1890:
1891: case AIC_CMDCOMPLETE:
1892: AIC_ASSERT(sc->sc_nexus != NULL);
1893: acb = sc->sc_nexus;
1894: goto finish;
1895: }
1896: }
1897:
1898: bus_space_write_1(iot, ioh, CLRSINT1, CLRPHASECHG);
1899:
1900: dophase:
1901: if ((sstat1 & REQINIT) == 0) {
1902: /* Wait for REQINIT. */
1903: goto out;
1904: }
1905:
1906: sc->sc_phase = bus_space_read_1(iot, ioh, SCSISIG) & PH_MASK;
1907: bus_space_write_1(iot, ioh, SCSISIG, sc->sc_phase);
1908:
1909: switch (sc->sc_phase) {
1910: case PH_MSGOUT:
1911: if (sc->sc_state != AIC_CONNECTED &&
1912: sc->sc_state != AIC_RESELECTED)
1913: break;
1914: aic_msgout(sc);
1915: sc->sc_prevphase = PH_MSGOUT;
1916: goto loop;
1917:
1918: case PH_MSGIN:
1919: if (sc->sc_state != AIC_CONNECTED &&
1920: sc->sc_state != AIC_RESELECTED)
1921: break;
1922: aic_msgin(sc);
1923: sc->sc_prevphase = PH_MSGIN;
1924: goto loop;
1925:
1926: case PH_CMD:
1927: if (sc->sc_state != AIC_CONNECTED)
1928: break;
1929: #ifdef AIC_DEBUG
1930: if ((aic_debug & AIC_SHOWMISC) != 0) {
1931: AIC_ASSERT(sc->sc_nexus != NULL);
1932: acb = sc->sc_nexus;
1933: printf("cmd=0x%02x+%d ",
1934: acb->scsi_cmd.opcode, acb->scsi_cmd_length-1);
1935: }
1936: #endif
1937: n = aic_dataout_pio(sc, sc->sc_cp, sc->sc_cleft);
1938: sc->sc_cp += n;
1939: sc->sc_cleft -= n;
1940: sc->sc_prevphase = PH_CMD;
1941: goto loop;
1942:
1943: case PH_DATAOUT:
1944: if (sc->sc_state != AIC_CONNECTED)
1945: break;
1946: AIC_MISC(("dataout dleft=%lu ", (u_long)sc->sc_dleft));
1947: n = aic_dataout_pio(sc, sc->sc_dp, sc->sc_dleft);
1948: sc->sc_dp += n;
1949: sc->sc_dleft -= n;
1950: sc->sc_prevphase = PH_DATAOUT;
1951: goto loop;
1952:
1953: case PH_DATAIN:
1954: if (sc->sc_state != AIC_CONNECTED)
1955: break;
1956: AIC_MISC(("datain %lu ", (u_long)sc->sc_dleft));
1957: n = aic_datain_pio(sc, sc->sc_dp, sc->sc_dleft);
1958: sc->sc_dp += n;
1959: sc->sc_dleft -= n;
1960: sc->sc_prevphase = PH_DATAIN;
1961: goto loop;
1962:
1963: case PH_STAT:
1964: if (sc->sc_state != AIC_CONNECTED)
1965: break;
1966: AIC_ASSERT(sc->sc_nexus != NULL);
1967: acb = sc->sc_nexus;
1968: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1969: acb->target_stat = bus_space_read_1(iot, ioh, SCSIDAT);
1970: bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1971: AIC_MISC(("target_stat=0x%02x ", acb->target_stat));
1972: sc->sc_prevphase = PH_STAT;
1973: goto loop;
1974: }
1975:
1976: printf("%s: unexpected bus phase; resetting\n", sc->sc_dev.dv_xname);
1977: AIC_BREAK();
1978: reset:
1979: aic_init(sc);
1980: return 1;
1981:
1982: finish:
1983: timeout_del(&acb->xs->stimeout);
1984: aic_done(sc, acb);
1985: goto out;
1986:
1987: sched:
1988: sc->sc_state = AIC_IDLE;
1989: aic_sched(sc);
1990: goto out;
1991:
1992: out:
1993: bus_space_write_1(iot, ioh, DMACNTRL0, INTEN);
1994: return 1;
1995: }
1996:
1997: void
1998: aic_abort(struct aic_softc *sc, struct aic_acb *acb)
1999: {
2000:
2001: /* 2 secs for the abort */
2002: acb->timeout = AIC_ABORT_TIMEOUT;
2003: acb->flags |= ACB_ABORT;
2004:
2005: if (acb == sc->sc_nexus) {
2006: /*
2007: * If we're still selecting, the message will be scheduled
2008: * after selection is complete.
2009: */
2010: if (sc->sc_state == AIC_CONNECTED)
2011: aic_sched_msgout(sc, SEND_ABORT);
2012: } else {
2013: aic_dequeue(sc, acb);
2014: TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
2015: if (sc->sc_state == AIC_IDLE)
2016: aic_sched(sc);
2017: }
2018: }
2019:
2020: void
2021: aic_timeout(void *arg)
2022: {
2023: struct aic_acb *acb = arg;
2024: struct scsi_xfer *xs = acb->xs;
2025: struct scsi_link *sc_link = xs->sc_link;
2026: struct aic_softc *sc = sc_link->adapter_softc;
2027: int s;
2028:
2029: sc_print_addr(sc_link);
2030: printf("timed out");
2031:
2032: s = splbio();
2033:
2034: if (acb->flags & ACB_ABORT) {
2035: /* abort timed out */
2036: printf(" AGAIN\n");
2037: /* XXX Must reset! */
2038: } else {
2039: /* abort the operation that has timed out */
2040: printf("\n");
2041: acb->xs->error = XS_TIMEOUT;
2042: aic_abort(sc, acb);
2043: }
2044:
2045: splx(s);
2046: }
2047:
2048: #ifdef AIC_DEBUG
2049: /*
2050: * The following functions are mostly used for debugging purposes, either
2051: * directly called from the driver or from the kernel debugger.
2052: */
2053:
2054: void
2055: aic_show_scsi_cmd(struct aic_acb *acb)
2056: {
2057: u_char *b = (u_char *)&acb->scsi_cmd;
2058: struct scsi_link *sc_link = acb->xs->sc_link;
2059: int i;
2060:
2061: sc_print_addr(sc_link);
2062: if ((acb->xs->flags & SCSI_RESET) == 0) {
2063: for (i = 0; i < acb->scsi_cmd_length; i++) {
2064: if (i)
2065: printf(",");
2066: printf("%x", b[i]);
2067: }
2068: printf("\n");
2069: } else
2070: printf("RESET\n");
2071: }
2072:
2073: void
2074: aic_print_acb(struct aic_acb *acb)
2075: {
2076:
2077: printf("acb@%p xs=%p flags=%x", acb, acb->xs, acb->flags);
2078: printf(" dp=%p dleft=%d target_stat=%x\n",
2079: acb->data_addr, acb->data_length, acb->target_stat);
2080: aic_show_scsi_cmd(acb);
2081: }
2082:
2083: void
2084: aic_print_active_acb(void)
2085: {
2086: struct aic_acb *acb;
2087: struct aic_softc *sc = aic_cd.cd_devs[0];
2088:
2089: printf("ready list:\n");
2090: TAILQ_FOREACH(acb, &sc->ready_list, chain)
2091: aic_print_acb(acb);
2092: printf("nexus:\n");
2093: if (sc->sc_nexus != NULL)
2094: aic_print_acb(sc->sc_nexus);
2095: printf("nexus list:\n");
2096: TAILQ_FOREACH(acb, &sc->nexus_list, chain)
2097: aic_print_acb(acb);
2098: }
2099:
2100: void
2101: aic_dump6360(struct aic_softc *sc)
2102: {
2103: bus_space_tag_t iot = sc->sc_iot;
2104: bus_space_handle_t ioh = sc->sc_ioh;
2105:
2106: printf("aic6360: SCSISEQ=%x SXFRCTL0=%x SXFRCTL1=%x SCSISIG=%x\n",
2107: bus_space_read_1(iot, ioh, SCSISEQ),
2108: bus_space_read_1(iot, ioh, SXFRCTL0),
2109: bus_space_read_1(iot, ioh, SXFRCTL1),
2110: bus_space_read_1(iot, ioh, SCSISIG));
2111: printf(" SSTAT0=%x SSTAT1=%x SSTAT2=%x SSTAT3=%x SSTAT4=%x\n",
2112: bus_space_read_1(iot, ioh, SSTAT0),
2113: bus_space_read_1(iot, ioh, SSTAT1),
2114: bus_space_read_1(iot, ioh, SSTAT2),
2115: bus_space_read_1(iot, ioh, SSTAT3),
2116: bus_space_read_1(iot, ioh, SSTAT4));
2117: printf(" SIMODE0=%x SIMODE1=%x ",
2118: bus_space_read_1(iot, ioh, SIMODE0),
2119: bus_space_read_1(iot, ioh, SIMODE1));
2120: printf("DMACNTRL0=%x DMACNTRL1=%x DMASTAT=%x\n",
2121: bus_space_read_1(iot, ioh, DMACNTRL0),
2122: bus_space_read_1(iot, ioh, DMACNTRL1),
2123: bus_space_read_1(iot, ioh, DMASTAT));
2124: printf(" FIFOSTAT=%d SCSIBUS=0x%x\n",
2125: bus_space_read_1(iot, ioh, FIFOSTAT),
2126: bus_space_read_1(iot, ioh, SCSIBUS));
2127: }
2128:
2129: void
2130: aic_dump_driver(struct aic_softc *sc)
2131: {
2132: struct aic_tinfo *ti;
2133: int i;
2134:
2135: printf("nexus=%p prevphase=%x\n", sc->sc_nexus, sc->sc_prevphase);
2136: printf("state=%x msgin=%x ", sc->sc_state, sc->sc_imess[0]);
2137: printf("msgpriq=%x msgoutq=%x lastmsg=%x currmsg=%x\n", sc->sc_msgpriq,
2138: sc->sc_msgoutq, sc->sc_lastmsg, sc->sc_currmsg);
2139: for (i = 0; i < 7; i++) {
2140: ti = &sc->sc_tinfo[i];
2141: printf("tinfo%d: %d cmds %d disconnects %d timeouts",
2142: i, ti->cmds, ti->dconns, ti->touts);
2143: printf(" %d senses flags=%x\n", ti->senses, ti->flags);
2144: }
2145: }
2146: #endif
CVSweb