Annotation of sys/dev/ic/ncr5380sbc.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ncr5380sbc.c,v 1.19 2006/12/10 16:15:37 miod Exp $ */
2: /* $NetBSD: ncr5380sbc.c,v 1.13 1996/10/13 01:37:25 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1995 David Jones, Gordon W. Ross
6: * Copyright (c) 1994 Jarle Greipsland
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. The name of the authors may not be used to endorse or promote products
18: * derived from this software without specific prior written permission.
19: * 4. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by
22: * David Jones and Gordon Ross
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
25: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27: * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34: */
35:
36: /*
37: * This is a machine-independent driver for the NCR5380
38: * SCSI Bus Controller (SBC), also known as the Am5380.
39: *
40: * This code should work with any memory-mapped 5380,
41: * and can be shared by multiple adapters that address
42: * the 5380 with different register offset spacings.
43: * (This can happen on the atari, for example.)
44: * For porting/design info. see: ncr5380.doc
45: *
46: * Credits, history:
47: *
48: * David Jones is the author of most of the code that now
49: * appears in this file, and was the architect of the
50: * current overall structure (MI/MD code separation, etc.)
51: *
52: * Gordon Ross integrated the message phase code, added lots of
53: * comments about what happens when and why (re. SCSI spec.),
54: * debugged some reentrance problems, and added several new
55: * "hooks" needed for the Sun3 "si" adapters.
56: *
57: * The message in/out code was taken nearly verbatim from
58: * the aic6360 driver by Jarle Greipsland.
59: *
60: * Several other NCR5380 drivers were used for reference
61: * while developing this driver, including work by:
62: * The Alice Group (mac68k port) namely:
63: * Allen K. Briggs, Chris P. Caputo, Michael L. Finch,
64: * Bradley A. Grantham, and Lawrence A. Kesteloot
65: * Michael L. Hitch (amiga drivers: sci.c)
66: * Leo Weppelman (atari driver: ncr5380.c)
67: * There are others too. Thanks, everyone.
68: */
69:
70: #include <sys/types.h>
71: #include <sys/param.h>
72: #include <sys/systm.h>
73: #include <sys/kernel.h>
74: #include <sys/errno.h>
75: #include <sys/device.h>
76: #include <sys/buf.h>
77: #include <sys/proc.h>
78: #include <sys/user.h>
79:
80: #include <scsi/scsi_all.h>
81: #include <scsi/scsi_debug.h>
82: #include <scsi/scsi_message.h>
83: #include <scsi/scsiconf.h>
84:
85: #ifdef DDB
86: #include <ddb/db_output.h>
87: #endif
88:
89: #include <dev/ic/ncr5380reg.h>
90: #include <dev/ic/ncr5380var.h>
91:
92: static void ncr5380_sched(struct ncr5380_softc *);
93: static void ncr5380_done(struct ncr5380_softc *);
94:
95: static int ncr5380_select(struct ncr5380_softc *, struct sci_req *);
96: static void ncr5380_reselect(struct ncr5380_softc *);
97:
98: static int ncr5380_msg_in(struct ncr5380_softc *);
99: static int ncr5380_msg_out(struct ncr5380_softc *);
100: static int ncr5380_data_xfer(struct ncr5380_softc *, int);
101: static int ncr5380_command(struct ncr5380_softc *);
102: static int ncr5380_status(struct ncr5380_softc *);
103: static void ncr5380_machine(struct ncr5380_softc *);
104:
105: void ncr5380_abort(struct ncr5380_softc *);
106: void ncr5380_cmd_timeout(void *);
107: /*
108: * Action flags returned by the info_transfer functions:
109: * (These determine what happens next.)
110: */
111: #define ACT_CONTINUE 0x00 /* No flags: expect another phase */
112: #define ACT_DISCONNECT 0x01 /* Target is disconnecting */
113: #define ACT_CMD_DONE 0x02 /* Need to call scsi_done() */
114: #define ACT_RESET_BUS 0x04 /* Need bus reset (cmd timeout) */
115: #define ACT_WAIT_DMA 0x10 /* Wait for DMA to complete */
116:
117: /*****************************************************************
118: * Debugging stuff
119: *****************************************************************/
120:
121: #ifndef DDB
122: /* This is used only in recoverable places. */
123: #define Debugger() printf("Debug: ncr5380.c:%d\n", __LINE__)
124: #endif
125:
126: #ifdef NCR5380_DEBUG
127:
128: #define NCR_DBG_BREAK 1
129: #define NCR_DBG_CMDS 2
130: int ncr5380_debug = NCR_DBG_BREAK|NCR_DBG_CMDS;
131: struct ncr5380_softc *ncr5380_debug_sc;
132:
133: #define NCR_BREAK() \
134: do { if (ncr5380_debug & NCR_DBG_BREAK) Debugger(); } while (0)
135:
136: static void ncr5380_show_scsi_cmd(struct scsi_xfer *);
137: static void ncr5380_show_sense(struct scsi_xfer *);
138:
139: #ifdef DDB
140: void ncr5380_trace(char *, long);
141: void ncr5380_clear_trace(void);
142: void ncr5380_show_trace(void);
143: void ncr5380_show_req(struct sci_req *);
144: void ncr5380_show_req(struct sci_req *);
145: void ncr5380_show_state(void);
146: #endif /* DDB */
147: #else /* NCR5380_DEBUG */
148:
149: #define NCR_BREAK() /* nada */
150: #define ncr5380_show_scsi_cmd(xs) /* nada */
151: #define ncr5380_show_sense(xs) /* nada */
152:
153: #endif /* NCR5380_DEBUG */
154:
155: static char *
156: phase_names[8] = {
157: "DATA_OUT",
158: "DATA_IN",
159: "COMMAND",
160: "STATUS",
161: "UNSPEC1",
162: "UNSPEC2",
163: "MSG_OUT",
164: "MSG_IN",
165: };
166:
167: /*****************************************************************
168: * Actual chip control
169: *****************************************************************/
170:
171: /*
172: * XXX: These timeouts might need to be tuned...
173: */
174:
175: /* This one is used when waiting for a phase change. (X100uS.) */
176: int ncr5380_wait_phase_timo = 1000 * 10 * 300; /* 5 min. */
177:
178: /* These are used in the following inline functions. */
179: int ncr5380_wait_req_timo = 1000 * 50; /* X2 = 100 mS. */
180: int ncr5380_wait_nrq_timo = 1000 * 25; /* X2 = 50 mS. */
181:
182: static __inline int ncr5380_wait_req(struct ncr5380_softc *);
183: static __inline int ncr5380_wait_not_req(struct ncr5380_softc *);
184: static __inline void ncr_sched_msgout(struct ncr5380_softc *, int);
185:
186: /* Return zero on success. */
187: static __inline int ncr5380_wait_req(sc)
188: struct ncr5380_softc *sc;
189: {
190: register int timo = ncr5380_wait_req_timo;
191: for (;;) {
192: if (*sc->sci_bus_csr & SCI_BUS_REQ) {
193: timo = 0; /* return 0 */
194: break;
195: }
196: if (--timo < 0)
197: break; /* return -1 */
198: delay(2);
199: }
200: return (timo);
201: }
202:
203: /* Return zero on success. */
204: static __inline int ncr5380_wait_not_req(sc)
205: struct ncr5380_softc *sc;
206: {
207: register int timo = ncr5380_wait_nrq_timo;
208: for (;;) {
209: if ((*sc->sci_bus_csr & SCI_BUS_REQ) == 0) {
210: timo = 0; /* return 0 */
211: break;
212: }
213: if (--timo < 0)
214: break; /* return -1 */
215: delay(2);
216: }
217: return (timo);
218: }
219:
220: /* Ask the target for a MSG_OUT phase. */
221: static __inline void
222: ncr_sched_msgout(sc, msg_code)
223: struct ncr5380_softc *sc;
224: int msg_code;
225: {
226: /* First time, raise ATN line. */
227: if (sc->sc_msgpriq == 0) {
228: register u_char icmd;
229: icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
230: *sc->sci_icmd = icmd | SCI_ICMD_ATN;
231: delay(2);
232: }
233: sc->sc_msgpriq |= msg_code;
234: }
235:
236:
237: int
238: ncr5380_pio_out(sc, phase, count, data)
239: struct ncr5380_softc *sc;
240: int phase, count;
241: unsigned char *data;
242: {
243: register u_char icmd;
244: register int resid;
245: register int error;
246:
247: icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
248:
249: icmd |= SCI_ICMD_DATA;
250: *sc->sci_icmd = icmd;
251:
252: resid = count;
253: while (resid > 0) {
254: if (!SCI_BUSY(sc)) {
255: NCR_TRACE("pio_out: lost BSY, resid=%d\n", resid);
256: break;
257: }
258: if (ncr5380_wait_req(sc)) {
259: NCR_TRACE("pio_out: no REQ, resid=%d\n", resid);
260: break;
261: }
262: if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
263: break;
264:
265: /* Put the data on the bus. */
266: if (data)
267: *sc->sci_odata = *data++;
268: else
269: *sc->sci_odata = 0;
270:
271: /* Tell the target it's there. */
272: icmd |= SCI_ICMD_ACK;
273: *sc->sci_icmd = icmd;
274:
275: /* Wait for target to get it. */
276: error = ncr5380_wait_not_req(sc);
277:
278: /* OK, it's got it (or we gave up waiting). */
279: icmd &= ~SCI_ICMD_ACK;
280: *sc->sci_icmd = icmd;
281:
282: if (error) {
283: NCR_TRACE("pio_out: stuck REQ, resid=%d\n", resid);
284: break;
285: }
286:
287: --resid;
288: }
289:
290: /* Stop driving the data bus. */
291: icmd &= ~SCI_ICMD_DATA;
292: *sc->sci_icmd = icmd;
293:
294: return (count - resid);
295: }
296:
297:
298: int
299: ncr5380_pio_in(sc, phase, count, data)
300: struct ncr5380_softc *sc;
301: int phase, count;
302: unsigned char *data;
303: {
304: register u_char icmd;
305: register int resid;
306: register int error;
307:
308: icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
309:
310: resid = count;
311: while (resid > 0) {
312: if (!SCI_BUSY(sc)) {
313: NCR_TRACE("pio_in: lost BSY, resid=%d\n", resid);
314: break;
315: }
316: if (ncr5380_wait_req(sc)) {
317: NCR_TRACE("pio_in: no REQ, resid=%d\n", resid);
318: break;
319: }
320: /* A phase change is not valid until AFTER REQ rises! */
321: if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
322: break;
323:
324: /* Read the data bus. */
325: if (data)
326: *data++ = *sc->sci_data;
327: else
328: (void) *sc->sci_data;
329:
330: /* Tell target we got it. */
331: icmd |= SCI_ICMD_ACK;
332: *sc->sci_icmd = icmd;
333:
334: /* Wait for target to drop REQ... */
335: error = ncr5380_wait_not_req(sc);
336:
337: /* OK, we can drop ACK. */
338: icmd &= ~SCI_ICMD_ACK;
339: *sc->sci_icmd = icmd;
340:
341: if (error) {
342: NCR_TRACE("pio_in: stuck REQ, resid=%d\n", resid);
343: break;
344: }
345:
346: --resid;
347: }
348:
349: return (count - resid);
350: }
351:
352:
353: void
354: ncr5380_init(sc)
355: struct ncr5380_softc *sc;
356: {
357: int i, j;
358: struct sci_req *sr;
359:
360: #ifdef NCR5380_DEBUG
361: ncr5380_debug_sc = sc;
362: #endif
363:
364: for (i = 0; i < SCI_OPENINGS; i++) {
365: sr = &sc->sc_ring[i];
366: sr->sr_xs = NULL;
367: timeout_set(&sr->sr_timeout, ncr5380_cmd_timeout, sr);
368: }
369: for (i = 0; i < 8; i++)
370: for (j = 0; j < 8; j++)
371: sc->sc_matrix[i][j] = NULL;
372:
373: sc->sc_link.openings = 2; /* XXX - Not SCI_OPENINGS */
374: sc->sc_prevphase = PHASE_INVALID;
375: sc->sc_state = NCR_IDLE;
376:
377: *sc->sci_tcmd = PHASE_INVALID;
378: *sc->sci_icmd = 0;
379: *sc->sci_mode = 0;
380: *sc->sci_sel_enb = 0;
381: SCI_CLR_INTR(sc);
382:
383: /* XXX: Enable reselect interrupts... */
384: *sc->sci_sel_enb = 0x80;
385:
386: /* Another hack (Er.. hook!) for the sun3 si: */
387: if (sc->sc_intr_on) {
388: NCR_TRACE("init: intr ON\n", 0);
389: sc->sc_intr_on(sc);
390: }
391: }
392:
393:
394: void
395: ncr5380_reset_scsibus(sc)
396: struct ncr5380_softc *sc;
397: {
398:
399: NCR_TRACE("reset_scsibus, cur=0x%x\n",
400: (long) sc->sc_current);
401:
402: *sc->sci_icmd = SCI_ICMD_RST;
403: delay(500);
404: *sc->sci_icmd = 0;
405:
406: *sc->sci_mode = 0;
407: *sc->sci_tcmd = PHASE_INVALID;
408:
409: SCI_CLR_INTR(sc);
410: /* XXX - Need long delay here! */
411: delay(100000);
412:
413: /* XXX - Need to cancel disconnected requests. */
414: }
415:
416:
417: /*
418: * Interrupt handler for the SCSI Bus Controller (SBC)
419: * This may also called for a DMA timeout (at splbio).
420: */
421: int
422: ncr5380_intr(sc)
423: struct ncr5380_softc *sc;
424: {
425: int claimed = 0;
426:
427: /*
428: * Do not touch SBC regs here unless sc_current == NULL
429: * or it will complain about "register conflict" errors.
430: * Instead, just let ncr5380_machine() deal with it.
431: */
432: NCR_TRACE("intr: top, state=%d\n", sc->sc_state);
433:
434: if (sc->sc_state == NCR_IDLE) {
435: /*
436: * Might be reselect. ncr5380_reselect() will check,
437: * and set up the connection if so. This will verify
438: * that sc_current == NULL at the beginning...
439: */
440:
441: /* Another hack (Er.. hook!) for the sun3 si: */
442: if (sc->sc_intr_off) {
443: NCR_TRACE("intr: for reselect, intr off\n", 0);
444: sc->sc_intr_off(sc);
445: }
446:
447: ncr5380_reselect(sc);
448: }
449:
450: /*
451: * The remaining documented interrupt causes are phase mismatch and
452: * disconnect. In addition, the sunsi controller may produce a state
453: * where SCI_CSR_DONE is false, yet DMA is complete.
454: *
455: * The procedure in all these cases is to let ncr5380_machine()
456: * figure out what to do next.
457: */
458: if (sc->sc_state & NCR_WORKING) {
459: NCR_TRACE("intr: call machine, cur=0x%x\n",
460: (long) sc->sc_current);
461: /* This will usually free-up the nexus. */
462: ncr5380_machine(sc);
463: NCR_TRACE("intr: machine done, cur=0x%x\n",
464: (long) sc->sc_current);
465: claimed = 1;
466: }
467:
468: /* Maybe we can run some commands now... */
469: if (sc->sc_state == NCR_IDLE) {
470: NCR_TRACE("intr: call sched, cur=0x%x\n",
471: (long) sc->sc_current);
472: ncr5380_sched(sc);
473: NCR_TRACE("intr: sched done, cur=0x%x\n",
474: (long) sc->sc_current);
475: }
476:
477: return claimed;
478: }
479:
480:
481: /*
482: * Abort the current command (i.e. due to timeout)
483: */
484: void
485: ncr5380_abort(sc)
486: struct ncr5380_softc *sc;
487: {
488:
489: /*
490: * Finish it now. If DMA is in progress, we
491: * can not call ncr_sched_msgout() because
492: * that hits the SBC (avoid DMA conflict).
493: */
494:
495: /* Another hack (Er.. hook!) for the sun3 si: */
496: if (sc->sc_intr_off) {
497: NCR_TRACE("abort: intr off\n", 0);
498: sc->sc_intr_off(sc);
499: }
500:
501: sc->sc_state |= NCR_ABORTING;
502: if ((sc->sc_state & NCR_DOINGDMA) == 0) {
503: ncr_sched_msgout(sc, SEND_ABORT);
504: }
505: NCR_TRACE("abort: call machine, cur=0x%x\n",
506: (long) sc->sc_current);
507: ncr5380_machine(sc);
508: NCR_TRACE("abort: machine done, cur=0x%x\n",
509: (long) sc->sc_current);
510:
511: /* Another hack (Er.. hook!) for the sun3 si: */
512: if (sc->sc_intr_on) {
513: NCR_TRACE("abort: intr ON\n", 0);
514: sc->sc_intr_on(sc);
515: }
516: }
517:
518: /*
519: * Timeout handler, scheduled for each SCSI command.
520: */
521: void
522: ncr5380_cmd_timeout(arg)
523: void *arg;
524: {
525: struct sci_req *sr = arg;
526: struct scsi_xfer *xs;
527: struct scsi_link *sc_link;
528: struct ncr5380_softc *sc;
529: int s;
530:
531: s = splbio();
532:
533: /* Get all our variables... */
534: xs = sr->sr_xs;
535: if (xs == NULL) {
536: printf("ncr5380_cmd_timeout: no scsi_xfer\n");
537: goto out;
538: }
539: sc_link = xs->sc_link;
540: sc = sc_link->adapter_softc;
541:
542: printf("%s: cmd timeout, targ=%d, lun=%d\n",
543: sc->sc_dev.dv_xname,
544: sr->sr_target, sr->sr_lun);
545:
546: /*
547: * Mark the overdue job as failed, and arrange for
548: * ncr5380_machine to terminate it. If the victim
549: * is the current job, call ncr5380_machine() now.
550: * Otherwise arrange for ncr5380_sched() to do it.
551: */
552: sr->sr_flags |= SR_OVERDUE;
553: if (sc->sc_current == sr) {
554: NCR_TRACE("cmd_tmo: call abort, sr=0x%x\n", (long) sr);
555: ncr5380_abort(sc);
556: } else {
557: /*
558: * The driver may be idle, or busy with another job.
559: * Arrange for ncr5380_sched() to do the deed.
560: */
561: NCR_TRACE("cmd_tmo: clear matrix, t/l=0x%02x\n",
562: (sr->sr_target << 4) | sr->sr_lun);
563: sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
564: }
565:
566: /*
567: * We may have aborted the current job, or may have
568: * already been idle. In either case, we should now
569: * be idle, so try to start another job.
570: */
571: if (sc->sc_state == NCR_IDLE) {
572: NCR_TRACE("cmd_tmo: call sched, cur=0x%x\n",
573: (long) sc->sc_current);
574: ncr5380_sched(sc);
575: NCR_TRACE("cmd_tmo: sched done, cur=0x%x\n",
576: (long) sc->sc_current);
577: }
578:
579: out:
580: splx(s);
581: }
582:
583:
584: /*****************************************************************
585: * Interface to higher level
586: *****************************************************************/
587:
588:
589: /*
590: * Enter a new SCSI command into the "issue" queue, and
591: * if there is work to do, start it going.
592: *
593: * WARNING: This can be called recursively!
594: * (see comment in ncr5380_done)
595: */
596: int
597: ncr5380_scsi_cmd(xs)
598: struct scsi_xfer *xs;
599: {
600: struct ncr5380_softc *sc;
601: struct sci_req *sr;
602: int s, rv, i, flags;
603:
604: sc = xs->sc_link->adapter_softc;
605: flags = xs->flags;
606:
607: if (sc->sc_flags & NCR5380_FORCE_POLLING)
608: flags |= SCSI_POLL;
609:
610: if (flags & SCSI_DATA_UIO)
611: panic("ncr5380: scsi data uio requested");
612:
613: s = splbio();
614:
615: if (flags & SCSI_POLL) {
616: /* Terminate any current command. */
617: sr = sc->sc_current;
618: if (sr) {
619: printf("%s: polled request aborting %d/%d\n",
620: sc->sc_dev.dv_xname,
621: sr->sr_target, sr->sr_lun);
622: ncr5380_abort(sc);
623: }
624: if (sc->sc_state != NCR_IDLE) {
625: panic("ncr5380_scsi_cmd: polled request, abort failed");
626: }
627: }
628:
629: /*
630: * Find lowest empty slot in ring buffer.
631: * XXX: What about "fairness" and cmd order?
632: */
633: for (i = 0; i < SCI_OPENINGS; i++)
634: if (sc->sc_ring[i].sr_xs == NULL)
635: goto new;
636:
637: rv = TRY_AGAIN_LATER;
638: NCR_TRACE("scsi_cmd: no openings, rv=%d\n", rv);
639: goto out;
640:
641: new:
642: /* Create queue entry */
643: sr = &sc->sc_ring[i];
644: sr->sr_xs = xs;
645: sr->sr_target = xs->sc_link->target;
646: sr->sr_lun = xs->sc_link->lun;
647: sr->sr_dma_hand = NULL;
648: sr->sr_dataptr = xs->data;
649: sr->sr_datalen = xs->datalen;
650: sr->sr_flags = (flags & SCSI_POLL) ? SR_IMMED : 0;
651: sr->sr_status = -1; /* no value */
652: sc->sc_ncmds++;
653: rv = SUCCESSFULLY_QUEUED;
654:
655: NCR_TRACE("scsi_cmd: new sr=0x%x\n", (long)sr);
656:
657: if (flags & SCSI_POLL) {
658: /* Force this new command to be next. */
659: sc->sc_rr = i;
660: }
661:
662: /*
663: * If we were idle, run some commands...
664: */
665: if (sc->sc_state == NCR_IDLE) {
666: NCR_TRACE("scsi_cmd: call sched, cur=0x%x\n",
667: (long) sc->sc_current);
668: ncr5380_sched(sc);
669: NCR_TRACE("scsi_cmd: sched done, cur=0x%x\n",
670: (long) sc->sc_current);
671: }
672:
673: if (flags & SCSI_POLL) {
674: #ifdef DIAGNOSTIC
675: /* Make sure ncr5380_sched() finished it. */
676: if (sc->sc_state != NCR_IDLE)
677: panic("ncr5380_scsi_cmd: poll didn't finish");
678: #endif
679: rv = COMPLETE;
680: }
681:
682: out:
683: splx(s);
684: return (rv);
685: }
686:
687:
688: /*
689: * POST PROCESSING OF SCSI_CMD (usually current)
690: * Called by ncr5380_sched(), ncr5380_machine()
691: */
692: static void
693: ncr5380_done(sc)
694: struct ncr5380_softc *sc;
695: {
696: struct sci_req *sr;
697: struct scsi_xfer *xs;
698:
699: #ifdef DIAGNOSTIC
700: if (sc->sc_state == NCR_IDLE)
701: panic("ncr5380_done: state=idle");
702: if (sc->sc_current == NULL)
703: panic("ncr5380_done: current=0");
704: #endif
705:
706: sr = sc->sc_current;
707: xs = sr->sr_xs;
708:
709: NCR_TRACE("done: top, cur=0x%x\n", (long) sc->sc_current);
710:
711: /*
712: * Clean up DMA resources for this command.
713: */
714: if (sr->sr_dma_hand) {
715: NCR_TRACE("done: dma_free, dh=0x%x\n",
716: (long) sr->sr_dma_hand);
717: (*sc->sc_dma_free)(sc);
718: }
719: #ifdef DIAGNOSTIC
720: if (sr->sr_dma_hand)
721: panic("ncr5380_done: dma free did not");
722: #endif
723:
724: if (sc->sc_state & NCR_ABORTING) {
725: NCR_TRACE("done: aborting, error=%d\n", xs->error);
726: if (xs->error == XS_NOERROR)
727: xs->error = XS_TIMEOUT;
728: }
729:
730: NCR_TRACE("done: check error=%d\n", (long) xs->error);
731:
732: /* If error is already set, ignore sr_status value. */
733: if (xs->error != XS_NOERROR)
734: goto finish;
735:
736: NCR_TRACE("done: check status=%d\n", sr->sr_status);
737:
738: switch (sr->sr_status) {
739: case SCSI_OK: /* 0 */
740: if (sr->sr_flags & SR_SENSE) {
741: #ifdef NCR5380_DEBUG
742: if (ncr5380_debug & NCR_DBG_CMDS) {
743: ncr5380_show_sense(xs);
744: }
745: #endif
746: xs->error = XS_SENSE;
747: }
748: break;
749:
750: case SCSI_CHECK:
751: if (sr->sr_flags & SR_SENSE) {
752: /* Sense command also asked for sense? */
753: printf("ncr5380_done: sense asked for sense\n");
754: NCR_BREAK();
755: xs->error = XS_DRIVER_STUFFUP;
756: break;
757: }
758: sr->sr_flags |= SR_SENSE;
759: NCR_TRACE("done: get sense, sr=0x%x\n", (long) sr);
760: /*
761: * Leave queued, but clear sc_current so we start over
762: * with selection. Guaranteed to get the same request.
763: */
764: sc->sc_state = NCR_IDLE;
765: sc->sc_current = NULL;
766: sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
767: return; /* XXX */
768:
769: case SCSI_BUSY:
770: xs->error = XS_BUSY;
771: break;
772:
773: case -1:
774: /* This is our "impossible" initial value. */
775: /* fallthrough */
776: default:
777: printf("%s: target %d, bad status=%d\n",
778: sc->sc_dev.dv_xname, sr->sr_target, sr->sr_status);
779: xs->error = XS_DRIVER_STUFFUP;
780: break;
781: }
782:
783: finish:
784:
785: NCR_TRACE("done: finish, error=%d\n", xs->error);
786:
787: /*
788: * Dequeue the finished command, but don't clear sc_state until
789: * after the call to scsi_done(), because that may call back to
790: * ncr5380_scsi_cmd() - unwanted recursion!
791: *
792: * Keeping sc->sc_state != idle terminates the recursion.
793: */
794: #ifdef DIAGNOSTIC
795: if ((sc->sc_state & NCR_WORKING) == 0)
796: panic("ncr5380_done: bad state");
797: #endif
798:
799: /* Clear our pointers to the request. */
800: sc->sc_current = NULL;
801: sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
802: timeout_del(&sr->sr_timeout);
803:
804: /* Make the request free. */
805: sr->sr_xs = NULL;
806: sc->sc_ncmds--;
807:
808: /* Tell common SCSI code it is done. */
809: xs->flags |= ITSDONE;
810: scsi_done(xs);
811:
812: sc->sc_state = NCR_IDLE;
813: /* Now ncr5380_sched() may be called again. */
814: }
815:
816:
817: /*
818: * Schedule a SCSI operation. This routine should return
819: * only after it achieves one of the following conditions:
820: * Busy (sc->sc_state != NCR_IDLE)
821: * No more work can be started.
822: */
823: static void
824: ncr5380_sched(sc)
825: struct ncr5380_softc *sc;
826: {
827: struct sci_req *sr;
828: struct scsi_xfer *xs;
829: int target = 0, lun = 0;
830: int error, i;
831:
832: /* Another hack (Er.. hook!) for the sun3 si: */
833: if (sc->sc_intr_off) {
834: NCR_TRACE("sched: top, intr off\n", 0);
835: sc->sc_intr_off(sc);
836: }
837:
838: next_job:
839: /*
840: * Grab the next job from queue. Must be idle.
841: */
842: #ifdef DIAGNOSTIC
843: if (sc->sc_state != NCR_IDLE)
844: panic("ncr5380_sched: not idle");
845: if (sc->sc_current)
846: panic("ncr5380_sched: current set");
847: #endif
848:
849: /*
850: * Always start the search where we last looked.
851: * The REQUEST_SENSE logic depends on this to
852: * choose the same job as was last picked, so it
853: * can just clear sc_current and reschedule.
854: * (Avoids loss of "contingent allegiance".)
855: */
856: i = sc->sc_rr;
857: sr = NULL;
858: do {
859: if (sc->sc_ring[i].sr_xs) {
860: target = sc->sc_ring[i].sr_target;
861: lun = sc->sc_ring[i].sr_lun;
862: if (sc->sc_matrix[target][lun] == NULL) {
863: /*
864: * Do not mark the target/LUN busy yet,
865: * because reselect may cause some other
866: * job to become the current one, so we
867: * might not actually start this job.
868: * Instead, set sc_matrix later on.
869: */
870: sc->sc_rr = i;
871: sr = &sc->sc_ring[i];
872: break;
873: }
874: }
875: i++;
876: if (i == SCI_OPENINGS)
877: i = 0;
878: } while (i != sc->sc_rr);
879:
880: if (sr == NULL) {
881: NCR_TRACE("sched: no work, cur=0x%x\n",
882: (long) sc->sc_current);
883:
884: /* Another hack (Er.. hook!) for the sun3 si: */
885: if (sc->sc_intr_on) {
886: NCR_TRACE("sched: ret, intr ON\n", 0);
887: sc->sc_intr_on(sc);
888: }
889:
890: return; /* No more work to do. */
891: }
892:
893: NCR_TRACE("sched: select for t/l=0x%02x\n",
894: (sr->sr_target << 4) | sr->sr_lun);
895:
896: sc->sc_state = NCR_WORKING;
897: error = ncr5380_select(sc, sr);
898: if (sc->sc_current) {
899: /* Lost the race! reselected out from under us! */
900: /* Work with the reselected job. */
901: if (sr->sr_flags & SR_IMMED) {
902: printf("%s: reselected while polling (abort)\n",
903: sc->sc_dev.dv_xname);
904: /* Abort the reselected job. */
905: sc->sc_state |= NCR_ABORTING;
906: sc->sc_msgpriq |= SEND_ABORT;
907: }
908: sr = sc->sc_current;
909: xs = sr->sr_xs;
910: NCR_TRACE("sched: reselect, new sr=0x%x\n", (long)sr);
911: goto have_nexus;
912: }
913:
914: /* Normal selection result. Target/LUN is now busy. */
915: sc->sc_matrix[target][lun] = sr;
916: sc->sc_current = sr; /* connected */
917: xs = sr->sr_xs;
918:
919: /*
920: * Initialize pointers, etc. for this job
921: */
922: sc->sc_dataptr = sr->sr_dataptr;
923: sc->sc_datalen = sr->sr_datalen;
924: sc->sc_prevphase = PHASE_INVALID;
925: sc->sc_msgpriq = SEND_IDENTIFY;
926: sc->sc_msgoutq = 0;
927: sc->sc_msgout = 0;
928:
929: NCR_TRACE("sched: select rv=%d\n", error);
930:
931: switch (error) {
932: case XS_NOERROR:
933: break;
934:
935: case XS_BUSY:
936: /* XXX - Reset and try again. */
937: printf("%s: select found SCSI bus busy, resetting...\n",
938: sc->sc_dev.dv_xname);
939: ncr5380_reset_scsibus(sc);
940: /* fallthrough */
941: case XS_SELTIMEOUT:
942: default:
943: xs->error = error; /* from select */
944: NCR_TRACE("sched: call done, sr=0x%x\n", (long)sr);
945: ncr5380_done(sc);
946:
947: /* Paranoia: clear everything. */
948: sc->sc_dataptr = NULL;
949: sc->sc_datalen = 0;
950: sc->sc_prevphase = PHASE_INVALID;
951: sc->sc_msgpriq = 0;
952: sc->sc_msgoutq = 0;
953: sc->sc_msgout = 0;
954:
955: goto next_job;
956: }
957:
958: /*
959: * Selection was successful. Normally, this means
960: * we are starting a new command. However, this
961: * might be the termination of an overdue job.
962: */
963: if (sr->sr_flags & SR_OVERDUE) {
964: NCR_TRACE("sched: overdue, sr=0x%x\n", (long)sr);
965: sc->sc_state |= NCR_ABORTING;
966: sc->sc_msgpriq |= SEND_ABORT;
967: goto have_nexus;
968: }
969:
970: /*
971: * This may be the continuation of some job that
972: * completed with a "check condition" code.
973: */
974: if (sr->sr_flags & SR_SENSE) {
975: NCR_TRACE("sched: get sense, sr=0x%x\n", (long)sr);
976: /* Do not allocate DMA, nor set timeout. */
977: goto have_nexus;
978: }
979:
980: /*
981: * OK, we are starting a new command.
982: * Initialize and allocate resources for the new command.
983: * Device reset is special (only uses MSG_OUT phase).
984: * Normal commands start in MSG_OUT phase where we will
985: * send and IDENDIFY message, and then expect CMD phase.
986: */
987: #ifdef NCR5380_DEBUG
988: if (ncr5380_debug & NCR_DBG_CMDS) {
989: printf("ncr5380_sched: begin, target=%d, LUN=%d\n",
990: xs->sc_link->target, xs->sc_link->lun);
991: ncr5380_show_scsi_cmd(xs);
992: }
993: #endif
994: if (xs->flags & SCSI_RESET) {
995: NCR_TRACE("sched: cmd=reset, sr=0x%x\n", (long)sr);
996: /* Not an error, so do not set NCR_ABORTING */
997: sc->sc_msgpriq |= SEND_DEV_RESET;
998: goto have_nexus;
999: }
1000:
1001: #ifdef DIAGNOSTIC
1002: if ((xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) == 0) {
1003: if (sc->sc_dataptr) {
1004: printf("%s: ptr but no data in/out flags?\n",
1005: sc->sc_dev.dv_xname);
1006: NCR_BREAK();
1007: sc->sc_dataptr = NULL;
1008: }
1009: }
1010: #endif
1011:
1012: /* Allocate DMA space (maybe) */
1013: if (sc->sc_dataptr && sc->sc_dma_alloc &&
1014: (sc->sc_datalen >= sc->sc_min_dma_len))
1015: {
1016: NCR_TRACE("sched: dma_alloc, len=%d\n", sc->sc_datalen);
1017: (*sc->sc_dma_alloc)(sc);
1018: }
1019:
1020: /*
1021: * Initialization hook called just after select,
1022: * at the beginning of COMMAND phase.
1023: * (but AFTER the DMA allocation is done)
1024: *
1025: * The evil Sun "si" adapter (OBIO variant) needs some
1026: * setup done to the DMA engine BEFORE the target puts
1027: * the SCSI bus into any DATA phase.
1028: */
1029: if (sr->sr_dma_hand && sc->sc_dma_setup) {
1030: NCR_TRACE("sched: dma_setup, dh=0x%x\n",
1031: (long) sr->sr_dma_hand);
1032: sc->sc_dma_setup(sc);
1033: }
1034:
1035: /*
1036: * Schedule a timeout for the job we are starting.
1037: */
1038: if ((sr->sr_flags & SR_IMMED) == 0) {
1039: i = (xs->timeout * hz) / 1000;
1040: NCR_TRACE("sched: set timeout=%d\n", i);
1041: timeout_add(&sr->sr_timeout, i);
1042: }
1043:
1044: have_nexus:
1045: NCR_TRACE("sched: call machine, cur=0x%x\n",
1046: (long) sc->sc_current);
1047: ncr5380_machine(sc);
1048: NCR_TRACE("sched: machine done, cur=0x%x\n",
1049: (long) sc->sc_current);
1050:
1051: /*
1052: * What state did ncr5380_machine() leave us in?
1053: * Hopefully it sometimes completes a job...
1054: */
1055: if (sc->sc_state == NCR_IDLE)
1056: goto next_job;
1057:
1058: return; /* Have work in progress. */
1059: }
1060:
1061:
1062: /*
1063: * Reselect handler: checks for reselection, and if we are being
1064: * reselected, it sets up sc->sc_current.
1065: *
1066: * We are reselected when:
1067: * SEL is TRUE
1068: * IO is TRUE
1069: * BSY is FALSE
1070: */
1071: void
1072: ncr5380_reselect(sc)
1073: struct ncr5380_softc *sc;
1074: {
1075: struct sci_req *sr;
1076: int target, lun, phase, timo;
1077: int target_mask;
1078: u_char bus, data, icmd, msg;
1079:
1080: #ifdef DIAGNOSTIC
1081: /*
1082: * Note: sc_state will be "idle" when ncr5380_intr()
1083: * calls, or "working" when ncr5380_select() calls.
1084: * (So don't test that in this DIAGNOSTIC)
1085: */
1086: if (sc->sc_current)
1087: panic("ncr5380_reselect: current set");
1088: #endif
1089:
1090: /*
1091: * First, check the select line.
1092: * (That has to be set first.)
1093: */
1094: bus = *(sc->sci_bus_csr);
1095: if ((bus & SCI_BUS_SEL) == 0) {
1096: /* Not a selection or reselection. */
1097: return;
1098: }
1099:
1100: /*
1101: * The target will assert BSY first (for bus arbitration),
1102: * then raise SEL, and finally drop BSY. Only then is the
1103: * data bus required to have valid selection ID bits set.
1104: * Wait for: SEL==1, BSY==0 before reading the data bus.
1105: * While this theoretically can happen, we are apparently
1106: * never fast enough to get here before BSY drops.
1107: */
1108: timo = ncr5380_wait_nrq_timo;
1109: for (;;) {
1110: if ((bus & SCI_BUS_BSY) == 0)
1111: break;
1112: /* Probably never get here... */
1113: if (--timo <= 0) {
1114: printf("%s: reselect, BSY stuck, bus=0x%x\n",
1115: sc->sc_dev.dv_xname, bus);
1116: /* Not much we can do. Reset the bus. */
1117: ncr5380_reset_scsibus(sc);
1118: return;
1119: }
1120: delay(2);
1121: bus = *(sc->sci_bus_csr);
1122: /* If SEL went away, forget it. */
1123: if ((bus & SCI_BUS_SEL) == 0)
1124: return;
1125: /* Still have SEL, check BSY. */
1126: }
1127: NCR_TRACE("reselect, valid data after %d loops\n",
1128: ncr5380_wait_nrq_timo - timo);
1129:
1130: /*
1131: * Good. We have SEL=1 and BSY=0. Now wait for a
1132: * "bus settle delay" before we sample the data bus
1133: */
1134: delay(2);
1135: data = *(sc->sci_data) & 0xFF;
1136: /* Parity check is implicit in data validation below. */
1137:
1138: /*
1139: * Is this a reselect (I/O == 1) or have we been
1140: * selected as a target? (I/O == 0)
1141: */
1142: if ((bus & SCI_BUS_IO) == 0) {
1143: printf("%s: selected as target, data=0x%x\n",
1144: sc->sc_dev.dv_xname, data);
1145: /* Not much we can do. Reset the bus. */
1146: /* XXX: send some sort of message? */
1147: ncr5380_reset_scsibus(sc);
1148: return;
1149: }
1150:
1151: /*
1152: * OK, this is a reselection.
1153: */
1154: for (target = 0; target < 7; target++) {
1155: target_mask = (1 << target);
1156: if (data & target_mask)
1157: break;
1158: }
1159: if ((data & 0x7F) != target_mask) {
1160: /* No selecting ID? or >2 IDs on bus? */
1161: printf("%s: bad reselect, data=0x%x\n",
1162: sc->sc_dev.dv_xname, data);
1163: return;
1164: }
1165:
1166: NCR_TRACE("reselect: target=0x%x\n", target);
1167:
1168: /* Raise BSY to acknowledge target reselection. */
1169: *(sc->sci_icmd) = SCI_ICMD_BSY;
1170:
1171: /* Wait for target to drop SEL. */
1172: timo = ncr5380_wait_nrq_timo;
1173: for (;;) {
1174: bus = *(sc->sci_bus_csr);
1175: if ((bus & SCI_BUS_SEL) == 0)
1176: break; /* success */
1177: if (--timo <= 0) {
1178: printf("%s: reselect, SEL stuck, bus=0x%x\n",
1179: sc->sc_dev.dv_xname, bus);
1180: NCR_BREAK();
1181: /* assume connected (fail later if not) */
1182: break;
1183: }
1184: delay(2);
1185: }
1186:
1187: /* Now we drop BSY, and we are connected. */
1188: *(sc->sci_icmd) = 0;
1189: *sc->sci_sel_enb = 0;
1190: SCI_CLR_INTR(sc);
1191:
1192: /*
1193: * At this point the target should send an IDENTIFY message,
1194: * which will permit us to determine the reselecting LUN.
1195: * If not, we assume LUN 0.
1196: */
1197: lun = 0;
1198: /* Wait for REQ before reading bus phase. */
1199: if (ncr5380_wait_req(sc)) {
1200: printf("%s: reselect, no REQ\n",
1201: sc->sc_dev.dv_xname);
1202: /* Try to send an ABORT message. */
1203: goto abort;
1204: }
1205: phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
1206: if (phase != PHASE_MSG_IN) {
1207: printf("%s: reselect, phase=%d\n",
1208: sc->sc_dev.dv_xname, phase);
1209: goto abort;
1210: }
1211:
1212: /* Ack. the change to PHASE_MSG_IN */
1213: *(sc->sci_tcmd) = PHASE_MSG_IN;
1214:
1215: /* Peek at the message byte without consuming it! */
1216: msg = *(sc->sci_data);
1217: if ((msg & 0x80) == 0) {
1218: printf("%s: reselect, not identify, msg=%d\n",
1219: sc->sc_dev.dv_xname, msg);
1220: goto abort;
1221: }
1222: lun = msg & 7;
1223:
1224: /* We now know target/LUN. Do we have the request? */
1225: sr = sc->sc_matrix[target][lun];
1226: if (sr) {
1227: /* We now have a nexus. */
1228: sc->sc_state |= NCR_WORKING;
1229: sc->sc_current = sr;
1230: NCR_TRACE("reselect: resume sr=0x%x\n", (long)sr);
1231:
1232: /* Implicit restore pointers message */
1233: sc->sc_dataptr = sr->sr_dataptr;
1234: sc->sc_datalen = sr->sr_datalen;
1235:
1236: sc->sc_prevphase = PHASE_INVALID;
1237: sc->sc_msgpriq = 0;
1238: sc->sc_msgoutq = 0;
1239: sc->sc_msgout = 0;
1240:
1241: /* XXX: Restore the normal mode register. */
1242: /* If this target's bit is set, do NOT check parity. */
1243: if (sc->sc_parity_disable & target_mask)
1244: *sc->sci_mode = (SCI_MODE_MONBSY);
1245: else
1246: *sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
1247:
1248: /*
1249: * Another hack for the Sun3 "si", which needs
1250: * some setup done to its DMA engine before the
1251: * target puts the SCSI bus into any DATA phase.
1252: */
1253: if (sr->sr_dma_hand && sc->sc_dma_setup) {
1254: NCR_TRACE("reselect: call DMA setup, dh=0x%x\n",
1255: (long) sr->sr_dma_hand);
1256: sc->sc_dma_setup(sc);
1257: }
1258:
1259: /* Now consume the IDENTIFY message. */
1260: ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
1261: return;
1262: }
1263:
1264: printf("%s: phantom reselect: target=%d, LUN=%d\n",
1265: sc->sc_dev.dv_xname, target, lun);
1266: abort:
1267: /*
1268: * Try to send an ABORT message. This makes us
1269: * temporarily busy, but no current command...
1270: */
1271: sc->sc_state |= NCR_ABORTING;
1272:
1273: /* Raise ATN, delay, raise ACK... */
1274: icmd = SCI_ICMD_ATN;
1275: *sc->sci_icmd = icmd;
1276: delay(2);
1277:
1278: /* Now consume the IDENTIFY message. */
1279: ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
1280:
1281: /* Finally try to send the ABORT. */
1282: sc->sc_prevphase = PHASE_INVALID;
1283: sc->sc_msgpriq = SEND_ABORT;
1284: ncr5380_msg_out(sc);
1285:
1286: *(sc->sci_tcmd) = PHASE_INVALID;
1287: *sc->sci_sel_enb = 0;
1288: SCI_CLR_INTR(sc);
1289: *sc->sci_sel_enb = 0x80;
1290:
1291: sc->sc_state &= ~NCR_ABORTING;
1292: }
1293:
1294:
1295: /*
1296: * Select target: xs is the transfer that we are selecting for.
1297: * sc->sc_current should be NULL.
1298: *
1299: * Returns:
1300: * sc->sc_current != NULL ==> we were reselected (race!)
1301: * XS_NOERROR ==> selection worked
1302: * XS_BUSY ==> lost arbitration
1303: * XS_SELTIMEOUT ==> no response to selection
1304: */
1305: static int
1306: ncr5380_select(sc, sr)
1307: struct ncr5380_softc *sc;
1308: struct sci_req *sr;
1309: {
1310: int timo, s, target_mask;
1311: u_char data, icmd;
1312:
1313: /* Check for reselect */
1314: ncr5380_reselect(sc);
1315: if (sc->sc_current) {
1316: NCR_TRACE("select: reselect, cur=0x%x\n",
1317: (long) sc->sc_current);
1318: return XS_BUSY; /* reselected */
1319: }
1320:
1321: /*
1322: * Set phase bits to 0, otherwise the 5380 won't drive the bus during
1323: * selection.
1324: */
1325: *sc->sci_tcmd = PHASE_DATA_OUT;
1326: *sc->sci_icmd = icmd = 0;
1327: *sc->sci_mode = 0;
1328:
1329: /*
1330: * Arbitrate for the bus. The 5380 takes care of the
1331: * time-critical bus interactions. We set our ID bit
1332: * in the output data register and set MODE_ARB. The
1333: * 5380 watches for the required "bus free" period.
1334: * If and when the "bus free" period is detected, the
1335: * 5380 drives BSY, drives the data bus, and sets the
1336: * "arbitration in progress" (AIP) bit to let us know
1337: * arbitration has started (and that it asserts BSY).
1338: * We then wait for one arbitration delay (2.2uS) and
1339: * check the ICMD_LST bit, which will be set if some
1340: * other target drives SEL during arbitration.
1341: *
1342: * There is a time-critical section during the period
1343: * after we enter arbitration up until we assert SEL.
1344: * Avoid long interrupts during this period.
1345: */
1346: s = splvm(); /* XXX: Begin time-critical section */
1347:
1348: *(sc->sci_odata) = 0x80; /* OUR_ID */
1349: *(sc->sci_mode) = SCI_MODE_ARB;
1350:
1351: #define WAIT_AIP_USEC 20 /* pleanty of time */
1352: /* Wait for the AIP bit to turn on. */
1353: timo = WAIT_AIP_USEC;
1354: for (;;) {
1355: if (*(sc->sci_icmd) & SCI_ICMD_AIP)
1356: break;
1357: if (timo <= 0) {
1358: /*
1359: * Did not see any "bus free" period.
1360: * The usual reason is a reselection,
1361: * so treat this as arbitration loss.
1362: */
1363: NCR_TRACE("select: bus busy, rc=%d\n", XS_BUSY);
1364: goto lost_arb;
1365: }
1366: timo -= 2;
1367: delay(2);
1368: }
1369: NCR_TRACE("select: have AIP after %d uSec.\n",
1370: WAIT_AIP_USEC - timo);
1371:
1372: /* Got AIP. Wait one arbitration delay (2.2 uS.) */
1373: delay(3);
1374:
1375: /* Check for ICMD_LST */
1376: if (*(sc->sci_icmd) & SCI_ICMD_LST) {
1377: /* Some other target asserted SEL. */
1378: NCR_TRACE("select: lost one, rc=%d\n", XS_BUSY);
1379: goto lost_arb;
1380: }
1381:
1382: /*
1383: * No other device has declared itself the winner.
1384: * The spec. says to check for higher IDs, but we
1385: * are always the highest (ID=7) so don't bother.
1386: * We can now declare victory by asserting SEL.
1387: *
1388: * Note that the 5380 is asserting BSY because we
1389: * have entered arbitration mode. We will now hold
1390: * BSY directly so we can turn off ARB mode.
1391: */
1392: icmd = (SCI_ICMD_BSY | SCI_ICMD_SEL);
1393: *sc->sci_icmd = icmd;
1394:
1395: /*
1396: * "The SCSI device that wins arbitration shall wait
1397: * at least a bus clear delay plus a bus settle delay
1398: * after asserting the SEL signal before changing
1399: * any [other] signal." (1.2uS. total)
1400: */
1401: delay(2);
1402:
1403: /*
1404: * Check one last time to see if we really did
1405: * win arbitration. This might only happen if
1406: * there can be a higher selection ID than ours.
1407: * Keep this code for reference anyway...
1408: */
1409: if (*(sc->sci_icmd) & SCI_ICMD_LST) {
1410: /* Some other target asserted SEL. */
1411: NCR_TRACE("select: lost two, rc=%d\n", XS_BUSY);
1412:
1413: lost_arb:
1414: *sc->sci_icmd = 0;
1415: *sc->sci_mode = 0;
1416:
1417: splx(s); /* XXX: End of time-critical section. */
1418:
1419: /*
1420: * When we lose arbitration, it usually means
1421: * there is a target trying to reselect us.
1422: */
1423: ncr5380_reselect(sc);
1424: return XS_BUSY;
1425: }
1426:
1427: /* Leave ARB mode Now that we drive BSY+SEL */
1428: *sc->sci_mode = 0;
1429: *sc->sci_sel_enb = 0;
1430:
1431: splx(s); /* XXX: End of time-critical section. */
1432:
1433: /*
1434: * Arbitration is complete. Now do selection:
1435: * Drive the data bus with the ID bits for both
1436: * the host and target. Also set ATN now, to
1437: * ask the target for a message out phase.
1438: */
1439: target_mask = (1 << sr->sr_target);
1440: data = 0x80 | target_mask;
1441: *(sc->sci_odata) = data;
1442: icmd |= (SCI_ICMD_DATA | SCI_ICMD_ATN);
1443: *(sc->sci_icmd) = icmd;
1444: delay(2); /* two deskew delays. */
1445:
1446: /* De-assert BSY (targets sample the data now). */
1447: icmd &= ~SCI_ICMD_BSY;
1448: *(sc->sci_icmd) = icmd;
1449: delay(3); /* Bus settle delay. */
1450:
1451: /*
1452: * Wait for the target to assert BSY.
1453: * SCSI spec. says wait for 250 mS.
1454: */
1455: for (timo = 25000;;) {
1456: if (*sc->sci_bus_csr & SCI_BUS_BSY)
1457: goto success;
1458: if (--timo <= 0)
1459: break;
1460: delay(10);
1461: }
1462:
1463: /*
1464: * There is no reaction from the target. Start the selection
1465: * timeout procedure. We release the databus but keep SEL+ATN
1466: * asserted. After that we wait a 'selection abort time' (200
1467: * usecs) and 2 deskew delays (90 ns) and check BSY again.
1468: * When BSY is asserted, we assume the selection succeeded,
1469: * otherwise we release the bus.
1470: */
1471: icmd &= ~SCI_ICMD_DATA;
1472: *(sc->sci_icmd) = icmd;
1473: delay(201);
1474: if ((*sc->sci_bus_csr & SCI_BUS_BSY) == 0) {
1475: /* Really no device on bus */
1476: *sc->sci_tcmd = PHASE_INVALID;
1477: *sc->sci_icmd = 0;
1478: *sc->sci_mode = 0;
1479: *sc->sci_sel_enb = 0;
1480: SCI_CLR_INTR(sc);
1481: *sc->sci_sel_enb = 0x80;
1482: NCR_TRACE("select: device down, rc=%d\n", XS_SELTIMEOUT);
1483: return XS_SELTIMEOUT;
1484: }
1485:
1486: success:
1487: /*
1488: * The target is now driving BSY, so we can stop
1489: * driving SEL and the data bus (keep ATN true).
1490: * Configure the ncr5380 to monitor BSY, parity.
1491: */
1492: icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_SEL);
1493: *sc->sci_icmd = icmd;
1494:
1495: /* If this target's bit is set, do NOT check parity. */
1496: if (sc->sc_parity_disable & target_mask)
1497: *sc->sci_mode = (SCI_MODE_MONBSY);
1498: else
1499: *sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
1500:
1501: return XS_NOERROR;
1502: }
1503:
1504:
1505: /*****************************************************************
1506: * Functions to handle each info. transfer phase:
1507: *****************************************************************/
1508:
1509: /*
1510: * The message system:
1511: *
1512: * This is a revamped message system that now should easier accommodate
1513: * new messages, if necessary.
1514: *
1515: * Currently we accept these messages:
1516: * IDENTIFY (when reselecting)
1517: * COMMAND COMPLETE # (expect bus free after messages marked #)
1518: * NOOP
1519: * MESSAGE REJECT
1520: * SYNCHRONOUS DATA TRANSFER REQUEST
1521: * SAVE DATA POINTER
1522: * RESTORE POINTERS
1523: * DISCONNECT #
1524: *
1525: * We may send these messages in prioritized order:
1526: * BUS DEVICE RESET # if SCSI_RESET & xs->flags (or in weird sits.)
1527: * MESSAGE PARITY ERROR par. err. during MSGI
1528: * MESSAGE REJECT If we get a message we don't know how to handle
1529: * ABORT # send on errors
1530: * INITIATOR DETECTED ERROR also on errors (SCSI2) (during info xfer)
1531: * IDENTIFY At the start of each transfer
1532: * SYNCHRONOUS DATA TRANSFER REQUEST if appropriate
1533: * NOOP if nothing else fits the bill ...
1534: */
1535:
1536: #define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
1537: #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
1538: #define ISEXTMSG(m) ((m) == 0x01)
1539:
1540: /*
1541: * Precondition:
1542: * The SCSI bus is already in the MSGI phase and there is a message byte
1543: * on the bus, along with an asserted REQ signal.
1544: *
1545: * Our return value determines whether our caller, ncr5380_machine()
1546: * will expect to see another REQ (and possibly phase change).
1547: */
1548: static int
1549: ncr5380_msg_in(sc)
1550: register struct ncr5380_softc *sc;
1551: {
1552: struct sci_req *sr = sc->sc_current;
1553: struct scsi_xfer *xs = sr->sr_xs;
1554: int n, phase;
1555: int act_flags;
1556: register u_char icmd;
1557:
1558: /* acknowledge phase change */
1559: *sc->sci_tcmd = PHASE_MSG_IN;
1560:
1561: act_flags = ACT_CONTINUE;
1562: icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
1563:
1564: if (sc->sc_prevphase == PHASE_MSG_IN) {
1565: /* This is a continuation of the previous message. */
1566: n = sc->sc_imp - sc->sc_imess;
1567: NCR_TRACE("msg_in: continuation, n=%d\n", n);
1568: goto nextbyte;
1569: }
1570:
1571: /* This is a new MESSAGE IN phase. Clean up our state. */
1572: sc->sc_state &= ~NCR_DROP_MSGIN;
1573:
1574: nextmsg:
1575: n = 0;
1576: sc->sc_imp = &sc->sc_imess[n];
1577:
1578: nextbyte:
1579: /*
1580: * Read a whole message, but don't ack the last byte. If we reject the
1581: * message, we have to assert ATN during the message transfer phase
1582: * itself.
1583: */
1584: for (;;) {
1585: /*
1586: * Read a message byte.
1587: * First, check BSY, REQ, phase...
1588: */
1589: if (!SCI_BUSY(sc)) {
1590: NCR_TRACE("msg_in: lost BSY, n=%d\n", n);
1591: /* XXX - Assume the command completed? */
1592: act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
1593: return (act_flags);
1594: }
1595: if (ncr5380_wait_req(sc)) {
1596: NCR_TRACE("msg_in: BSY but no REQ, n=%d\n", n);
1597: /* Just let ncr5380_machine() handle it... */
1598: return (act_flags);
1599: }
1600: phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
1601: if (phase != PHASE_MSG_IN) {
1602: /*
1603: * Target left MESSAGE IN, probably because it
1604: * a) noticed our ATN signal, or
1605: * b) ran out of messages.
1606: */
1607: return (act_flags);
1608: }
1609: /* Still in MESSAGE IN phase, and REQ is asserted. */
1610: if (*sc->sci_csr & SCI_CSR_PERR) {
1611: ncr_sched_msgout(sc, SEND_PARITY_ERROR);
1612: sc->sc_state |= NCR_DROP_MSGIN;
1613: }
1614:
1615: /* Gather incoming message bytes if needed. */
1616: if ((sc->sc_state & NCR_DROP_MSGIN) == 0) {
1617: if (n >= NCR_MAX_MSG_LEN) {
1618: ncr_sched_msgout(sc, SEND_REJECT);
1619: sc->sc_state |= NCR_DROP_MSGIN;
1620: } else {
1621: *sc->sc_imp++ = *sc->sci_data;
1622: n++;
1623: /*
1624: * This testing is suboptimal, but most
1625: * messages will be of the one byte variety, so
1626: * it should not affect performance
1627: * significantly.
1628: */
1629: if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
1630: goto have_msg;
1631: if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
1632: goto have_msg;
1633: if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
1634: n == sc->sc_imess[1] + 2)
1635: goto have_msg;
1636: }
1637: }
1638:
1639: /*
1640: * If we reach this spot we're either:
1641: * a) in the middle of a multi-byte message, or
1642: * b) dropping bytes.
1643: */
1644:
1645: /* Ack the last byte read. */
1646: icmd |= SCI_ICMD_ACK;
1647: *sc->sci_icmd = icmd;
1648:
1649: if (ncr5380_wait_not_req(sc)) {
1650: NCR_TRACE("msg_in: drop, stuck REQ, n=%d\n", n);
1651: act_flags |= ACT_RESET_BUS;
1652: }
1653:
1654: icmd &= ~SCI_ICMD_ACK;
1655: *sc->sci_icmd = icmd;
1656:
1657: if (act_flags != ACT_CONTINUE)
1658: return (act_flags);
1659:
1660: /* back to nextbyte */
1661: }
1662:
1663: have_msg:
1664: /* We now have a complete message. Parse it. */
1665:
1666: switch (sc->sc_imess[0]) {
1667: case MSG_CMDCOMPLETE:
1668: NCR_TRACE("msg_in: CMDCOMPLETE\n", 0);
1669: /* Target is about to disconnect. */
1670: act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
1671: break;
1672:
1673: case MSG_PARITY_ERROR:
1674: NCR_TRACE("msg_in: PARITY_ERROR\n", 0);
1675: /* Resend the last message. */
1676: ncr_sched_msgout(sc, sc->sc_msgout);
1677: /* Reset icmd after scheduling the REJECT cmd - jwg */
1678: icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
1679: break;
1680:
1681: case MSG_MESSAGE_REJECT:
1682: /* The target rejects the last message we sent. */
1683: NCR_TRACE("msg_in: got reject for 0x%x\n", sc->sc_msgout);
1684: switch (sc->sc_msgout) {
1685: case SEND_IDENTIFY:
1686: /* Really old target controller? */
1687: /* XXX ... */
1688: break;
1689: case SEND_INIT_DET_ERR:
1690: goto abort;
1691: }
1692: break;
1693:
1694: case MSG_NOOP:
1695: NCR_TRACE("msg_in: NOOP\n", 0);
1696: break;
1697:
1698: case MSG_DISCONNECT:
1699: NCR_TRACE("msg_in: DISCONNECT\n", 0);
1700: /* Target is about to disconnect. */
1701: act_flags |= ACT_DISCONNECT;
1702: if ((xs->sc_link->quirks & SDEV_AUTOSAVE) == 0)
1703: break;
1704: /*FALLTHROUGH*/
1705:
1706: case MSG_SAVEDATAPOINTER:
1707: NCR_TRACE("msg_in: SAVE_PTRS\n", 0);
1708: sr->sr_dataptr = sc->sc_dataptr;
1709: sr->sr_datalen = sc->sc_datalen;
1710: break;
1711:
1712: case MSG_RESTOREPOINTERS:
1713: NCR_TRACE("msg_in: RESTORE_PTRS\n", 0);
1714: sc->sc_dataptr = sr->sr_dataptr;
1715: sc->sc_datalen = sr->sr_datalen;
1716: break;
1717:
1718: case MSG_EXTENDED:
1719: switch (sc->sc_imess[2]) {
1720: case MSG_EXT_SDTR:
1721: case MSG_EXT_WDTR:
1722: /* The ncr5380 can not do synchronous mode. */
1723: goto reject;
1724: default:
1725: printf("%s: unrecognized MESSAGE EXTENDED; sending REJECT\n",
1726: sc->sc_dev.dv_xname);
1727: NCR_BREAK();
1728: goto reject;
1729: }
1730: break;
1731:
1732: default:
1733: NCR_TRACE("msg_in: eh? imsg=0x%x\n", sc->sc_imess[0]);
1734: printf("%s: unrecognized MESSAGE; sending REJECT\n",
1735: sc->sc_dev.dv_xname);
1736: NCR_BREAK();
1737: /* fallthrough */
1738: reject:
1739: ncr_sched_msgout(sc, SEND_REJECT);
1740: /* Reset icmd after scheduling the REJECT cmd - jwg */
1741: icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
1742: break;
1743:
1744: abort:
1745: sc->sc_state |= NCR_ABORTING;
1746: ncr_sched_msgout(sc, SEND_ABORT);
1747: break;
1748: }
1749:
1750: /* Ack the last byte read. */
1751: icmd |= SCI_ICMD_ACK;
1752: *sc->sci_icmd = icmd;
1753:
1754: if (ncr5380_wait_not_req(sc)) {
1755: NCR_TRACE("msg_in: last, stuck REQ, n=%d\n", n);
1756: act_flags |= ACT_RESET_BUS;
1757: }
1758:
1759: icmd &= ~SCI_ICMD_ACK;
1760: *sc->sci_icmd = icmd;
1761:
1762: /* Go get the next message, if any. */
1763: if (act_flags == ACT_CONTINUE)
1764: goto nextmsg;
1765:
1766: return (act_flags);
1767: }
1768:
1769:
1770: /*
1771: * The message out (and in) stuff is a bit complicated:
1772: * If the target requests another message (sequence) without
1773: * having changed phase in between it really asks for a
1774: * retransmit, probably due to parity error(s).
1775: * The following messages can be sent:
1776: * IDENTIFY @ These 4 stem from SCSI command activity
1777: * SDTR @
1778: * WDTR @
1779: * DEV_RESET @
1780: * REJECT if MSGI doesn't make sense
1781: * PARITY_ERROR if parity error while in MSGI
1782: * INIT_DET_ERR if parity error while not in MSGI
1783: * ABORT if INIT_DET_ERR rejected
1784: * NOOP if asked for a message and there's nothing to send
1785: *
1786: * Note that we call this one with (sc_current == NULL)
1787: * when sending ABORT for unwanted reselections.
1788: */
1789: static int
1790: ncr5380_msg_out(sc)
1791: register struct ncr5380_softc *sc;
1792: {
1793: struct sci_req *sr = sc->sc_current;
1794: int act_flags, n, phase, progress;
1795: register u_char icmd, msg;
1796:
1797: /* acknowledge phase change */
1798: *sc->sci_tcmd = PHASE_MSG_OUT;
1799:
1800: progress = 0; /* did we send any messages? */
1801: act_flags = ACT_CONTINUE;
1802:
1803: /*
1804: * Set ATN. If we're just sending a trivial 1-byte message,
1805: * we'll clear ATN later on anyway. Also drive the data bus.
1806: */
1807: icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
1808: icmd |= (SCI_ICMD_ATN | SCI_ICMD_DATA);
1809: *sc->sci_icmd = icmd;
1810:
1811: if (sc->sc_prevphase == PHASE_MSG_OUT) {
1812: if (sc->sc_omp == sc->sc_omess) {
1813: /*
1814: * This is a retransmission.
1815: *
1816: * We get here if the target stayed in MESSAGE OUT
1817: * phase. Section 5.1.9.2 of the SCSI 2 spec indicates
1818: * that all of the previously transmitted messages must
1819: * be sent again, in the same order. Therefore, we
1820: * requeue all the previously transmitted messages, and
1821: * start again from the top. Our simple priority
1822: * scheme keeps the messages in the right order.
1823: */
1824: sc->sc_msgpriq |= sc->sc_msgoutq;
1825: NCR_TRACE("msg_out: retrans priq=0x%x\n", sc->sc_msgpriq);
1826: } else {
1827: /* This is a continuation of the previous message. */
1828: n = sc->sc_omp - sc->sc_omess;
1829: NCR_TRACE("msg_out: continuation, n=%d\n", n);
1830: goto nextbyte;
1831: }
1832: }
1833:
1834: /* No messages transmitted so far. */
1835: sc->sc_msgoutq = 0;
1836:
1837: nextmsg:
1838: /* Pick up highest priority message. */
1839: sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
1840: sc->sc_msgpriq &= ~sc->sc_msgout;
1841: sc->sc_msgoutq |= sc->sc_msgout;
1842:
1843: /* Build the outgoing message data. */
1844: switch (sc->sc_msgout) {
1845: case SEND_IDENTIFY:
1846: NCR_TRACE("msg_out: SEND_IDENTIFY\n", 0);
1847: if (sr == NULL) {
1848: printf("%s: SEND_IDENTIFY while not connected; sending NOOP\n",
1849: sc->sc_dev.dv_xname);
1850: NCR_BREAK();
1851: goto noop;
1852: }
1853: /*
1854: * The identify message we send determines whether
1855: * disconnect/reselect is allowed for this command.
1856: * 0xC0+LUN: allows it, 0x80+LUN disallows it.
1857: */
1858: msg = 0xc0; /* MSG_IDENTIFY(0,1) */
1859: if (sc->sc_no_disconnect & (1 << sr->sr_target))
1860: msg = 0x80;
1861: if (sr->sr_flags & (SR_IMMED | SR_SENSE))
1862: msg = 0x80;
1863: sc->sc_omess[0] = msg | sr->sr_lun;
1864: n = 1;
1865: break;
1866:
1867: case SEND_DEV_RESET:
1868: NCR_TRACE("msg_out: SEND_DEV_RESET\n", 0);
1869: /* Expect disconnect after this! */
1870: /* XXX: Kill jobs for this target? */
1871: act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
1872: sc->sc_omess[0] = MSG_BUS_DEV_RESET;
1873: n = 1;
1874: break;
1875:
1876: case SEND_REJECT:
1877: NCR_TRACE("msg_out: SEND_REJECT\n", 0);
1878: sc->sc_omess[0] = MSG_MESSAGE_REJECT;
1879: n = 1;
1880: break;
1881:
1882: case SEND_PARITY_ERROR:
1883: NCR_TRACE("msg_out: SEND_PARITY_ERROR\n", 0);
1884: sc->sc_omess[0] = MSG_PARITY_ERROR;
1885: n = 1;
1886: break;
1887:
1888: case SEND_INIT_DET_ERR:
1889: NCR_TRACE("msg_out: SEND_INIT_DET_ERR\n", 0);
1890: sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
1891: n = 1;
1892: break;
1893:
1894: case SEND_ABORT:
1895: NCR_TRACE("msg_out: SEND_ABORT\n", 0);
1896: /* Expect disconnect after this! */
1897: /* XXX: Set error flag? */
1898: act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
1899: sc->sc_omess[0] = MSG_ABORT;
1900: n = 1;
1901: break;
1902:
1903: case 0:
1904: printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
1905: sc->sc_dev.dv_xname);
1906: NCR_BREAK();
1907: noop:
1908: NCR_TRACE("msg_out: send NOOP\n", 0);
1909: sc->sc_omess[0] = MSG_NOOP;
1910: n = 1;
1911: break;
1912:
1913: default:
1914: printf("%s: weird MESSAGE OUT; sending NOOP\n",
1915: sc->sc_dev.dv_xname);
1916: NCR_BREAK();
1917: goto noop;
1918: }
1919: sc->sc_omp = &sc->sc_omess[n];
1920:
1921: nextbyte:
1922: /* Send message bytes. */
1923: while (n > 0) {
1924: /*
1925: * Send a message byte.
1926: * First check BSY, REQ, phase...
1927: */
1928: if (!SCI_BUSY(sc)) {
1929: NCR_TRACE("msg_out: lost BSY, n=%d\n", n);
1930: goto out;
1931: }
1932: if (ncr5380_wait_req(sc)) {
1933: NCR_TRACE("msg_out: no REQ, n=%d\n", n);
1934: goto out;
1935: }
1936: phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
1937: if (phase != PHASE_MSG_OUT) {
1938: /*
1939: * Target left MESSAGE OUT, possibly to reject
1940: * our message.
1941: */
1942: NCR_TRACE("msg_out: new phase=%d\n", phase);
1943: goto out;
1944: }
1945:
1946: /* Yes, we can send this message byte. */
1947: --n;
1948:
1949: /* Clear ATN before last byte if this is the last message. */
1950: if (n == 0 && sc->sc_msgpriq == 0) {
1951: icmd &= ~SCI_ICMD_ATN;
1952: *sc->sci_icmd = icmd;
1953: /* 2 deskew delays */
1954: delay(2); /* XXX */
1955: }
1956:
1957: /* Put data on the bus. */
1958: *sc->sci_odata = *--sc->sc_omp;
1959:
1960: /* Raise ACK to tell target data is on the bus. */
1961: icmd |= SCI_ICMD_ACK;
1962: *sc->sci_icmd = icmd;
1963:
1964: /* Wait for REQ to be negated. */
1965: if (ncr5380_wait_not_req(sc)) {
1966: NCR_TRACE("msg_out: stuck REQ, n=%d\n", n);
1967: act_flags |= ACT_RESET_BUS;
1968: }
1969:
1970: /* Finally, drop ACK. */
1971: icmd &= ~SCI_ICMD_ACK;
1972: *sc->sci_icmd = icmd;
1973:
1974: /* Stuck bus or something... */
1975: if (act_flags & ACT_RESET_BUS)
1976: goto out;
1977:
1978: }
1979: progress++;
1980:
1981: /* We get here only if the entire message has been transmitted. */
1982: if (sc->sc_msgpriq != 0) {
1983: /* There are more outgoing messages. */
1984: goto nextmsg;
1985: }
1986:
1987: /*
1988: * The last message has been transmitted. We need to remember the last
1989: * message transmitted (in case the target switches to MESSAGE IN phase
1990: * and sends a MESSAGE REJECT), and the list of messages transmitted
1991: * this time around (in case the target stays in MESSAGE OUT phase to
1992: * request a retransmit).
1993: */
1994:
1995: out:
1996: /* Stop driving the data bus. */
1997: icmd &= ~SCI_ICMD_DATA;
1998: *sc->sci_icmd = icmd;
1999:
2000: if (!progress)
2001: act_flags |= ACT_RESET_BUS;
2002:
2003: return (act_flags);
2004: }
2005:
2006:
2007: /*
2008: * Handle command phase.
2009: */
2010: static int
2011: ncr5380_command(sc)
2012: struct ncr5380_softc *sc;
2013: {
2014: struct sci_req *sr = sc->sc_current;
2015: struct scsi_xfer *xs = sr->sr_xs;
2016: struct scsi_sense rqs;
2017: int len;
2018:
2019: /* acknowledge phase change */
2020: *sc->sci_tcmd = PHASE_COMMAND;
2021:
2022: if (sr->sr_flags & SR_SENSE) {
2023: rqs.opcode = REQUEST_SENSE;
2024: rqs.byte2 = xs->sc_link->lun << 5;
2025: rqs.length = sizeof(xs->sense);
2026:
2027: rqs.unused[0] = rqs.unused[1] = rqs.control = 0;
2028: len = ncr5380_pio_out(sc, PHASE_COMMAND, sizeof(rqs),
2029: (u_char *)&rqs);
2030: }
2031: else {
2032: /* Assume command can be sent in one go. */
2033: /* XXX: Do this using DMA, and get a phase change intr? */
2034: len = ncr5380_pio_out(sc, PHASE_COMMAND, xs->cmdlen,
2035: (u_char *)xs->cmd);
2036: }
2037:
2038: if (len != xs->cmdlen) {
2039: #ifdef NCR5380_DEBUG
2040: printf("ncr5380_command: short transfer: wanted %d got %d.\n",
2041: xs->cmdlen, len);
2042: ncr5380_show_scsi_cmd(xs);
2043: NCR_BREAK();
2044: #endif
2045: if (len < 6) {
2046: xs->error = XS_DRIVER_STUFFUP;
2047: sc->sc_state |= NCR_ABORTING;
2048: ncr_sched_msgout(sc, SEND_ABORT);
2049: }
2050:
2051: }
2052:
2053: return ACT_CONTINUE;
2054: }
2055:
2056:
2057: /*
2058: * Handle either data_in or data_out
2059: */
2060: static int
2061: ncr5380_data_xfer(sc, phase)
2062: struct ncr5380_softc *sc;
2063: int phase;
2064: {
2065: struct sci_req *sr = sc->sc_current;
2066: struct scsi_xfer *xs = sr->sr_xs;
2067: int expected_phase;
2068: int len;
2069:
2070: if (sr->sr_flags & SR_SENSE) {
2071: NCR_TRACE("data_xfer: get sense, sr=0x%x\n", (long)sr);
2072: if (phase != PHASE_DATA_IN) {
2073: printf("%s: sense phase error\n", sc->sc_dev.dv_xname);
2074: goto abort;
2075: }
2076: /* acknowledge phase change */
2077: *sc->sci_tcmd = PHASE_DATA_IN;
2078: len = ncr5380_pio_in(sc, phase, sizeof(xs->sense),
2079: (u_char *)&xs->sense);
2080: return ACT_CONTINUE;
2081: }
2082:
2083: /*
2084: * When aborting a command, disallow any data phase.
2085: */
2086: if (sc->sc_state & NCR_ABORTING) {
2087: printf("%s: aborting, but phase=%s (reset)\n",
2088: sc->sc_dev.dv_xname, phase_names[phase & 7]);
2089: return ACT_RESET_BUS; /* XXX */
2090: }
2091:
2092: /* Validate expected phase (data_in or data_out) */
2093: expected_phase = (xs->flags & SCSI_DATA_OUT) ?
2094: PHASE_DATA_OUT : PHASE_DATA_IN;
2095: if (phase != expected_phase) {
2096: printf("%s: data phase error\n", sc->sc_dev.dv_xname);
2097: goto abort;
2098: }
2099:
2100: /* Make sure we have some data to move. */
2101: if (sc->sc_datalen <= 0) {
2102: /* Device needs padding. */
2103: if (phase == PHASE_DATA_IN)
2104: ncr5380_pio_in(sc, phase, 4096, NULL);
2105: else
2106: ncr5380_pio_out(sc, phase, 4096, NULL);
2107: /* Make sure that caused a phase change. */
2108: if (SCI_BUS_PHASE(*sc->sci_bus_csr) == phase) {
2109: /* More than 4k is just too much! */
2110: printf("%s: too much data padding\n",
2111: sc->sc_dev.dv_xname);
2112: goto abort;
2113: }
2114: return ACT_CONTINUE;
2115: }
2116:
2117: /*
2118: * Attempt DMA only if dma_alloc gave us a DMA handle AND
2119: * there is enough left to transfer so DMA is worth while.
2120: */
2121: if (sr->sr_dma_hand &&
2122: (sc->sc_datalen >= sc->sc_min_dma_len))
2123: {
2124: /*
2125: * OK, really start DMA. Note, the MD start function
2126: * is responsible for setting the TCMD register, etc.
2127: * (Acknowledge the phase change there, not here.)
2128: */
2129: NCR_TRACE("data_xfer: dma_start, dh=0x%x\n",
2130: (long) sr->sr_dma_hand);
2131: (*sc->sc_dma_start)(sc);
2132: return ACT_WAIT_DMA;
2133: }
2134:
2135: /*
2136: * Doing PIO for data transfer. (Possibly "Pseudo DMA")
2137: * XXX: Do PDMA functions need to set tcmd later?
2138: */
2139: NCR_TRACE("data_xfer: doing PIO, len=%d\n", sc->sc_datalen);
2140: /* acknowledge phase change */
2141: *sc->sci_tcmd = phase; /* XXX: OK for PDMA? */
2142: if (phase == PHASE_DATA_OUT) {
2143: len = (*sc->sc_pio_out)(sc, phase, sc->sc_datalen, sc->sc_dataptr);
2144: } else {
2145: len = (*sc->sc_pio_in) (sc, phase, sc->sc_datalen, sc->sc_dataptr);
2146: }
2147: sc->sc_dataptr += len;
2148: sc->sc_datalen -= len;
2149:
2150: NCR_TRACE("data_xfer: did PIO, resid=%d\n", sc->sc_datalen);
2151: return (ACT_CONTINUE);
2152:
2153: abort:
2154: sc->sc_state |= NCR_ABORTING;
2155: ncr_sched_msgout(sc, SEND_ABORT);
2156: return (ACT_CONTINUE);
2157: }
2158:
2159:
2160: static int
2161: ncr5380_status(sc)
2162: struct ncr5380_softc *sc;
2163: {
2164: int len;
2165: u_char status;
2166: struct sci_req *sr = sc->sc_current;
2167:
2168: /* acknowledge phase change */
2169: *sc->sci_tcmd = PHASE_STATUS;
2170:
2171: len = ncr5380_pio_in(sc, PHASE_STATUS, 1, &status);
2172: if (len) {
2173: sr->sr_status = status;
2174: } else {
2175: printf("ncr5380_status: none?\n");
2176: }
2177:
2178: return ACT_CONTINUE;
2179: }
2180:
2181:
2182: /*
2183: * This is the big state machine that follows SCSI phase changes.
2184: * This is somewhat like a co-routine. It will do a SCSI command,
2185: * and exit if the command is complete, or if it must wait, i.e.
2186: * for DMA to complete or for reselect to resume the job.
2187: *
2188: * The bus must be selected, and we need to know which command is
2189: * being undertaken.
2190: */
2191: static void
2192: ncr5380_machine(sc)
2193: struct ncr5380_softc *sc;
2194: {
2195: struct sci_req *sr;
2196: struct scsi_xfer *xs;
2197: int act_flags, phase, timo;
2198:
2199: #ifdef DIAGNOSTIC
2200: if (sc->sc_state == NCR_IDLE)
2201: panic("ncr5380_machine: state=idle");
2202: if (sc->sc_current == NULL)
2203: panic("ncr5380_machine: no current cmd");
2204: #endif
2205:
2206: sr = sc->sc_current;
2207: xs = sr->sr_xs;
2208: act_flags = ACT_CONTINUE;
2209:
2210: /*
2211: * This will be called by ncr5380_intr() when DMA is
2212: * complete. Must stop DMA before touching the 5380 or
2213: * there will be "register conflict" errors.
2214: */
2215: if (sc->sc_state & NCR_DOINGDMA) {
2216: /* Pick-up where where we left off... */
2217: goto dma_done;
2218: }
2219:
2220: next_phase:
2221:
2222: if (!SCI_BUSY(sc)) {
2223: /* Unexpected disconnect */
2224: printf("ncr5380_machine: unexpected disconnect.\n");
2225: xs->error = XS_DRIVER_STUFFUP;
2226: act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
2227: goto do_actions;
2228: }
2229:
2230: /*
2231: * Wait for REQ before reading the phase.
2232: * Need to wait longer than usual here, because
2233: * some devices are just plain slow...
2234: */
2235: timo = ncr5380_wait_phase_timo;
2236: for (;;) {
2237: if (*sc->sci_bus_csr & SCI_BUS_REQ)
2238: break;
2239: if (--timo <= 0) {
2240: if (sc->sc_state & NCR_ABORTING) {
2241: printf("%s: no REQ while aborting, reset\n",
2242: sc->sc_dev.dv_xname);
2243: act_flags |= ACT_RESET_BUS;
2244: goto do_actions;
2245: }
2246: printf("%s: no REQ for next phase, abort\n",
2247: sc->sc_dev.dv_xname);
2248: sc->sc_state |= NCR_ABORTING;
2249: ncr_sched_msgout(sc, SEND_ABORT);
2250: goto next_phase;
2251: }
2252: delay(100);
2253: }
2254:
2255: phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
2256: NCR_TRACE("machine: phase=%s\n",
2257: (long) phase_names[phase & 7]);
2258:
2259: /*
2260: * We assume that the device knows what it's doing,
2261: * so any phase is good.
2262: */
2263:
2264: #if 0
2265: /*
2266: * XXX: Do not ACK the phase yet! do it later...
2267: * XXX: ... each phase routine does that itself.
2268: * In particular, DMA needs it done LATER.
2269: */
2270: *sc->sci_tcmd = phase; /* acknowledge phase change */
2271: #endif
2272:
2273: switch (phase) {
2274:
2275: case PHASE_DATA_OUT:
2276: case PHASE_DATA_IN:
2277: act_flags = ncr5380_data_xfer(sc, phase);
2278: break;
2279:
2280: case PHASE_COMMAND:
2281: act_flags = ncr5380_command(sc);
2282: break;
2283:
2284: case PHASE_STATUS:
2285: act_flags = ncr5380_status(sc);
2286: break;
2287:
2288: case PHASE_MSG_OUT:
2289: act_flags = ncr5380_msg_out(sc);
2290: break;
2291:
2292: case PHASE_MSG_IN:
2293: act_flags = ncr5380_msg_in(sc);
2294: break;
2295:
2296: default:
2297: printf("ncr5380_machine: Unexpected phase 0x%x\n", phase);
2298: sc->sc_state |= NCR_ABORTING;
2299: ncr_sched_msgout(sc, SEND_ABORT);
2300: goto next_phase;
2301:
2302: } /* switch */
2303: sc->sc_prevphase = phase;
2304:
2305: do_actions:
2306: __asm("_ncr5380_actions:");
2307:
2308: if (act_flags & ACT_WAIT_DMA) {
2309: act_flags &= ~ACT_WAIT_DMA;
2310: /* Wait for DMA to complete (polling, or interrupt). */
2311: if ((sr->sr_flags & SR_IMMED) == 0) {
2312: NCR_TRACE("machine: wait for DMA intr.\n", 0);
2313: return; /* will resume at dma_done */
2314: }
2315: /* Busy-wait for it to finish. */
2316: NCR_TRACE("machine: dma_poll, dh=0x%x\n",
2317: (long) sr->sr_dma_hand);
2318: (*sc->sc_dma_poll)(sc);
2319: dma_done:
2320: /* Return here after interrupt. */
2321: if (sr->sr_flags & SR_OVERDUE)
2322: sc->sc_state |= NCR_ABORTING;
2323: NCR_TRACE("machine: dma_stop, dh=0x%x\n",
2324: (long) sr->sr_dma_hand);
2325: (*sc->sc_dma_stop)(sc);
2326: SCI_CLR_INTR(sc); /* XXX */
2327: /*
2328: * While DMA is running we can not touch the SBC,
2329: * so various places just set NCR_ABORTING and
2330: * expect us the "kick it" when DMA is done.
2331: */
2332: if (sc->sc_state & NCR_ABORTING) {
2333: ncr_sched_msgout(sc, SEND_ABORT);
2334: }
2335: }
2336:
2337: /*
2338: * Check for parity error.
2339: * XXX - better place to check?
2340: */
2341: if (*(sc->sci_csr) & SCI_CSR_PERR) {
2342: printf("%s: parity error!\n", sc->sc_dev.dv_xname);
2343: /* XXX: sc->sc_state |= NCR_ABORTING; */
2344: ncr_sched_msgout(sc, SEND_PARITY_ERROR);
2345: }
2346:
2347: if (act_flags == ACT_CONTINUE)
2348: goto next_phase;
2349: /* All other actions "break" from the loop. */
2350:
2351: NCR_TRACE("machine: act_flags=0x%x\n", act_flags);
2352:
2353: if (act_flags & ACT_RESET_BUS) {
2354: act_flags |= ACT_CMD_DONE;
2355: /*
2356: * Reset the SCSI bus, usually due to a timeout.
2357: * The error code XS_TIMEOUT allows retries.
2358: */
2359: sc->sc_state |= NCR_ABORTING;
2360: printf("%s: reset SCSI bus for TID=%d LUN=%d\n",
2361: sc->sc_dev.dv_xname, sr->sr_target, sr->sr_lun);
2362: ncr5380_reset_scsibus(sc);
2363: }
2364:
2365: if (act_flags & ACT_CMD_DONE) {
2366: act_flags |= ACT_DISCONNECT;
2367: /* Need to call scsi_done() */
2368: /* XXX: from the aic6360 driver, but why? */
2369: if (sc->sc_datalen < 0) {
2370: printf("%s: %d extra bytes from %d:%d\n",
2371: sc->sc_dev.dv_xname, -sc->sc_datalen,
2372: sr->sr_target, sr->sr_lun);
2373: sc->sc_datalen = 0;
2374: }
2375: xs->resid = sc->sc_datalen;
2376: /* Note: this will clear sc_current */
2377: NCR_TRACE("machine: call done, cur=0x%x\n", (long)sr);
2378: ncr5380_done(sc);
2379: }
2380:
2381: if (act_flags & ACT_DISCONNECT) {
2382: /*
2383: * The device has dropped BSY (or will soon).
2384: * We have to wait here for BSY to drop, otherwise
2385: * the next command may decide we need a bus reset.
2386: */
2387: timo = ncr5380_wait_req_timo; /* XXX */
2388: for (;;) {
2389: if (!SCI_BUSY(sc))
2390: goto busfree;
2391: if (--timo <= 0)
2392: break;
2393: delay(2);
2394: }
2395: /* Device is sitting on the bus! */
2396: printf("%s: Target %d LUN %d stuck busy, resetting...\n",
2397: sc->sc_dev.dv_xname, sr->sr_target, sr->sr_lun);
2398: ncr5380_reset_scsibus(sc);
2399: busfree:
2400: NCR_TRACE("machine: discon, waited %d\n",
2401: ncr5380_wait_req_timo - timo);
2402:
2403: *sc->sci_icmd = 0;
2404: *sc->sci_mode = 0;
2405: *sc->sci_tcmd = PHASE_INVALID;
2406: *sc->sci_sel_enb = 0;
2407: SCI_CLR_INTR(sc);
2408: *sc->sci_sel_enb = 0x80;
2409:
2410: if ((act_flags & ACT_CMD_DONE) == 0) {
2411: __asm("_ncr5380_disconnected:");
2412: NCR_TRACE("machine: discon, cur=0x%x\n", (long)sr);
2413: }
2414:
2415: /*
2416: * We may be here due to a disconnect message,
2417: * in which case we did NOT call ncr5380_done,
2418: * and we need to clear sc_current.
2419: */
2420: sc->sc_state = NCR_IDLE;
2421: sc->sc_current = NULL;
2422:
2423: /* Paranoia: clear everything. */
2424: sc->sc_dataptr = NULL;
2425: sc->sc_datalen = 0;
2426: sc->sc_prevphase = PHASE_INVALID;
2427: sc->sc_msgpriq = 0;
2428: sc->sc_msgoutq = 0;
2429: sc->sc_msgout = 0;
2430:
2431: /* Our caller will re-enable interrupts. */
2432: }
2433: }
2434:
2435:
2436: #ifdef NCR5380_DEBUG
2437:
2438: static void
2439: ncr5380_show_scsi_cmd(xs)
2440: struct scsi_xfer *xs;
2441: {
2442: u_char *b = (u_char *) xs->cmd;
2443: int i = 0;
2444:
2445: if ( ! ( xs->flags & SCSI_RESET ) ) {
2446: printf("si(%d:%d:%d)-",
2447: xs->sc_link->scsibus, xs->sc_link->target,
2448: xs->sc_link->lun);
2449: while (i < xs->cmdlen) {
2450: if (i) printf(",");
2451: printf("%x",b[i++]);
2452: }
2453: printf("-\n");
2454: } else {
2455: printf("si(%d:%d:%d)-RESET-\n",
2456: xs->sc_link->scsibus, xs->sc_link->target,
2457: xs->sc_link->lun);
2458: }
2459: }
2460:
2461:
2462: static void
2463: ncr5380_show_sense(xs)
2464: struct scsi_xfer *xs;
2465: {
2466: u_char *b = (u_char *)&xs->sense;
2467: int i;
2468:
2469: printf("sense:");
2470: for (i = 0; i < sizeof(xs->sense); i++)
2471: printf(" %02x", b[i]);
2472: printf("\n");
2473: }
2474:
2475: int ncr5380_traceidx = 0;
2476:
2477: #define TRACE_MAX 1024
2478: struct trace_ent {
2479: char *msg;
2480: long val;
2481: } ncr5380_tracebuf[TRACE_MAX];
2482:
2483: void
2484: ncr5380_trace(msg, val)
2485: char *msg;
2486: long val;
2487: {
2488: register struct trace_ent *tr;
2489: register int s;
2490:
2491: s = splbio();
2492:
2493: tr = &ncr5380_tracebuf[ncr5380_traceidx];
2494:
2495: ncr5380_traceidx++;
2496: if (ncr5380_traceidx >= TRACE_MAX)
2497: ncr5380_traceidx = 0;
2498:
2499: tr->msg = msg;
2500: tr->val = val;
2501:
2502: splx(s);
2503: }
2504:
2505: #ifdef DDB
2506: void
2507: ncr5380_clear_trace()
2508: {
2509: ncr5380_traceidx = 0;
2510: bzero((char *) ncr5380_tracebuf, sizeof(ncr5380_tracebuf));
2511: }
2512:
2513: void
2514: ncr5380_show_trace()
2515: {
2516: struct trace_ent *tr;
2517: int idx;
2518:
2519: idx = ncr5380_traceidx;
2520: do {
2521: tr = &ncr5380_tracebuf[idx];
2522: idx++;
2523: if (idx >= TRACE_MAX)
2524: idx = 0;
2525: if (tr->msg)
2526: db_printf(tr->msg, tr->val);
2527: } while (idx != ncr5380_traceidx);
2528: }
2529:
2530: void
2531: ncr5380_show_req(sr)
2532: struct sci_req *sr;
2533: {
2534: struct scsi_xfer *xs = sr->sr_xs;
2535:
2536: db_printf("TID=%d ", sr->sr_target);
2537: db_printf("LUN=%d ", sr->sr_lun);
2538: db_printf("dh=%p ", sr->sr_dma_hand);
2539: db_printf("dptr=%p ", sr->sr_dataptr);
2540: db_printf("dlen=0x%x ", sr->sr_datalen);
2541: db_printf("flags=%d ", sr->sr_flags);
2542: db_printf("stat=%d ", sr->sr_status);
2543:
2544: if (xs == NULL) {
2545: db_printf("(xs=NULL)\n");
2546: return;
2547: }
2548: db_printf("\n");
2549: #ifdef SCSIDEBUG
2550: show_scsi_xs(xs);
2551: #else
2552: db_printf("xs=%p\n", xs);
2553: #endif
2554: }
2555:
2556: void
2557: ncr5380_show_state()
2558: {
2559: struct ncr5380_softc *sc;
2560: struct sci_req *sr;
2561: int i, j, k;
2562:
2563: sc = ncr5380_debug_sc;
2564:
2565: if (sc == NULL) {
2566: db_printf("ncr5380_debug_sc == NULL\n");
2567: return;
2568: }
2569:
2570: db_printf("sc_ncmds=%d\n", sc->sc_ncmds);
2571: k = -1; /* which is current? */
2572: for (i = 0; i < SCI_OPENINGS; i++) {
2573: sr = &sc->sc_ring[i];
2574: if (sr->sr_xs) {
2575: if (sr == sc->sc_current)
2576: k = i;
2577: db_printf("req %d: (sr=%p)", i, (long)sr);
2578: ncr5380_show_req(sr);
2579: }
2580: }
2581: db_printf("sc_rr=%d, current=%d\n", sc->sc_rr, k);
2582:
2583: db_printf("Active request matrix:\n");
2584: for(i = 0; i < 8; i++) { /* targets */
2585: for (j = 0; j < 8; j++) { /* LUN */
2586: sr = sc->sc_matrix[i][j];
2587: if (sr) {
2588: db_printf("TID=%d LUN=%d sr=0x%x\n", i, j, (long)sr);
2589: }
2590: }
2591: }
2592:
2593: db_printf("sc_state=0x%x\n", sc->sc_state);
2594: db_printf("sc_current=%p\n", sc->sc_current);
2595: db_printf("sc_dataptr=%p\n", sc->sc_dataptr);
2596: db_printf("sc_datalen=0x%x\n", sc->sc_datalen);
2597:
2598: db_printf("sc_prevphase=%d\n", sc->sc_prevphase);
2599: db_printf("sc_msgpriq=0x%x\n", sc->sc_msgpriq);
2600: }
2601:
2602: #endif /* DDB */
2603: #endif /* NCR5380_DEBUG */
CVSweb