|
|
1.1 root 1: /*
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Van Jacobson of Lawrence Berkeley Laboratory.
7: *
8: * Redistribution is only permitted until one year after the first shipment
9: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
10: * binary forms are permitted provided that: (1) source distributions retain
11: * this entire copyright notice and comment, and (2) distributions including
12: * binaries display the following acknowledgement: This product includes
13: * software developed by the University of California, Berkeley and its
14: * contributors'' in the documentation or other materials provided with the
15: * distribution and in all advertising materials mentioning features or use
16: * of this software. Neither the name of the University nor the names of
17: * its contributors may be used to endorse or promote products derived from
18: * this software without specific prior written permission.
19: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22: *
23: * @(#)scsi.c 7.1 (Berkeley) 5/8/90
24: */
25:
26: /*
27: * HP9000/3xx 98658 SCSI host adaptor driver.
28: */
29: #include "scsi.h"
30: #if NSCSI > 0
31:
32: #ifndef lint
33: static char rcsid[] = "$Header: scsi.c,v 1.3 90/01/06 04:56:50 van Exp $";
34: #endif
35:
36: #include "param.h"
37: #include "systm.h"
38: #include "buf.h"
39: #include "device.h"
40: #include "scsivar.h"
41: #include "scsireg.h"
42: #include "dmavar.h"
43:
44: #include "machine/cpu.h"
45: #include "machine/isr.h"
46:
47: extern void isrlink();
48: extern void printf();
49: extern void _insque();
50: extern void _remque();
51: extern void bzero();
52:
53: int scsiinit(), scsigo(), scsiintr(), scsixfer();
54: void scsistart(), scsidone(), scsifree(), scsireset();
55: struct driver scsidriver = {
56: scsiinit, "scsi", (int (*)())scsistart, scsigo, scsiintr,
57: (int (*)())scsidone,
58: };
59:
60: struct scsi_softc scsi_softc[NSCSI];
61: struct isr scsi_isr[NSCSI];
62:
63: int scsi_cmd_wait = 512; /* microsec wait per step of 'immediate' cmds */
64: int scsi_data_wait = 512; /* wait per data in/out step */
65: int scsi_nosync = 1; /* inhibit sync xfers if 1 */
66:
67: #ifdef DEBUG
68: int scsi_debug = 0;
69: #define WAITHIST
70: #endif
71:
72: #ifdef WAITHIST
73: #define MAXWAIT 2048
74: u_int ixstart_wait[MAXWAIT+2];
75: u_int ixin_wait[MAXWAIT+2];
76: u_int ixout_wait[MAXWAIT+2];
77: u_int mxin_wait[MAXWAIT+2];
78: u_int cxin_wait[MAXWAIT+2];
79: u_int fxfr_wait[MAXWAIT+2];
80: u_int sgo_wait[MAXWAIT+2];
81: #define HIST(h,w) (++h[((w)>MAXWAIT? MAXWAIT : ((w) < 0 ? -1 : (w))) + 1]);
82: #else
83: #define HIST(h,w)
84: #endif
85:
86: #define b_cylin b_resid
87:
88: static void
89: scsiabort(hs, hd, where)
90: register struct scsi_softc *hs;
91: volatile register struct scsidevice *hd;
92: char *where;
93: {
94: int len;
95: u_char junk;
96:
97: printf("scsi%d: abort from %s: phase=0x%x, ssts=0x%x, ints=0x%x\n",
98: hs->sc_hc->hp_unit, where, hd->scsi_psns, hd->scsi_ssts,
99: hd->scsi_ints);
100:
101: hd->scsi_ints = hd->scsi_ints;
102: hd->scsi_csr = 0;
103: if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0)
104: /* no longer connected to scsi target */
105: return;
106:
107: /* get the number of bytes remaining in current xfer + fudge */
108: len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl;
109:
110: /* for that many bus cycles, try to send an abort msg */
111: for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) {
112: hd->scsi_scmd = SCMD_SET_ATN;
113: while ((hd->scsi_psns & PSNS_REQ) == 0) {
114: if (! (hd->scsi_ssts & SSTS_INITIATOR))
115: goto out;
116: DELAY(1);
117: }
118: if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE)
119: hd->scsi_scmd = SCMD_RST_ATN;
120: hd->scsi_pctl = hd->scsi_psns & PHASE;
121: if (hd->scsi_psns & PHASE_IO) {
122: /* one of the input phases - read & discard a byte */
123: hd->scsi_scmd = SCMD_SET_ACK;
124: if (hd->scsi_tmod == 0)
125: while (hd->scsi_psns & PSNS_REQ)
126: DELAY(1);
127: junk = hd->scsi_temp;
128: } else {
129: /* one of the output phases - send an abort msg */
130: hd->scsi_temp = MSG_ABORT;
131: hd->scsi_scmd = SCMD_SET_ACK;
132: if (hd->scsi_tmod == 0)
133: while (hd->scsi_psns & PSNS_REQ)
134: DELAY(1);
135: }
136: hd->scsi_scmd = SCMD_RST_ACK;
137: }
138: out:
139: /*
140: * Either the abort was successful & the bus is disconnected or
141: * the device didn't listen. If the latter, announce the problem.
142: * Either way, reset the card & the SPC.
143: */
144: if (len < 0 && hs)
145: printf("scsi%d: abort failed. phase=0x%x, ssts=0x%x\n",
146: hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts);
147:
148: if (! ((junk = hd->scsi_ints) & INTS_RESEL)) {
149: hd->scsi_sctl |= SCTL_CTRLRST;
150: DELAY(1);
151: hd->scsi_sctl &=~ SCTL_CTRLRST;
152: hd->scsi_hconf = 0;
153: hd->scsi_ints = hd->scsi_ints;
154: }
155: }
156:
157: int
158: scsiinit(hc)
159: register struct hp_ctlr *hc;
160: {
161: register struct scsi_softc *hs = &scsi_softc[hc->hp_unit];
162: register struct scsidevice *hd = (struct scsidevice *)hc->hp_addr;
163:
164: if ((hd->scsi_id & ID_MASK) != SCSI_ID)
165: return(0);
166: hc->hp_ipl = SCSI_IPL(hd->scsi_csr);
167: hs->sc_hc = hc;
168: hs->sc_dq.dq_unit = hc->hp_unit;
169: hs->sc_dq.dq_driver = &scsidriver;
170: hs->sc_sq.dq_forw = hs->sc_sq.dq_back = &hs->sc_sq;
171: scsi_isr[hc->hp_unit].isr_intr = scsiintr;
172: scsi_isr[hc->hp_unit].isr_ipl = hc->hp_ipl;
173: scsi_isr[hc->hp_unit].isr_arg = hc->hp_unit;
174: isrlink(&scsi_isr[hc->hp_unit]);
175: scsireset(hc->hp_unit);
176: return(1);
177: }
178:
179: void
180: scsireset(unit)
181: register int unit;
182: {
183: register struct scsi_softc *hs = &scsi_softc[unit];
184: volatile register struct scsidevice *hd =
185: (struct scsidevice *)hs->sc_hc->hp_addr;
186: u_int i;
187:
188: if (hs->sc_flags & SCSI_ALIVE)
189: scsiabort(hs, hd, "reset");
190:
191: printf("scsi%d: ", unit);
192:
193: hd->scsi_id = 0xFF;
194: DELAY(100);
195: /*
196: * Disable interrupts then reset the FUJI chip.
197: */
198: hd->scsi_csr = 0;
199: hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST;
200: hd->scsi_scmd = 0;
201: hd->scsi_tmod = 0;
202: hd->scsi_pctl = 0;
203: hd->scsi_temp = 0;
204: hd->scsi_tch = 0;
205: hd->scsi_tcm = 0;
206: hd->scsi_tcl = 0;
207: hd->scsi_ints = 0;
208:
209: if ((hd->scsi_id & ID_WORD_DMA) == 0) {
210: hs->sc_flags |= SCSI_DMA32;
211: printf("32 bit dma, ");
212: }
213:
214: /* Determine Max Synchronous Transfer Rate */
215: if (scsi_nosync)
216: i = 3;
217: else
218: i = SCSI_SYNC_XFER(hd->scsi_hconf);
219: switch (i) {
220: case 0:
221: hs->sc_sync = TMOD_SYNC | 0x3e; /* 250 nsecs */
222: printf("250ns sync");
223: break;
224: case 1:
225: hs->sc_sync = TMOD_SYNC | 0x5e; /* 375 nsecs */
226: printf("375ns sync");
227: break;
228: case 2:
229: hs->sc_sync = TMOD_SYNC | 0x7d; /* 500 nsecs */
230: printf("500ns sync");
231: break;
232: case 3:
233: hs->sc_sync = 0;
234: printf("async");
235: break;
236: }
237:
238: /*
239: * Configure the FUJI chip with its SCSI address, all
240: * interrupts enabled & appropriate parity.
241: */
242: i = (~hd->scsi_hconf) & 0x7;
243: hs->sc_scsi_addr = 1 << i;
244: hd->scsi_bdid = i;
245: if (hd->scsi_hconf & HCONF_PARITY)
246: hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB |
247: SCTL_SEL_ENAB | SCTL_RESEL_ENAB |
248: SCTL_INTR_ENAB | SCTL_PARITY_ENAB;
249: else {
250: hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB |
251: SCTL_SEL_ENAB | SCTL_RESEL_ENAB |
252: SCTL_INTR_ENAB;
253: printf(", no parity");
254: }
255: hd->scsi_sctl &=~ SCTL_DISABLE;
256:
257: printf(", scsi id %d\n", i);
258: hs->sc_flags |= SCSI_ALIVE;
259: }
260:
261: static void
262: scsierror(hs, hd, ints)
263: register struct scsi_softc *hs;
264: volatile register struct scsidevice *hd;
265: u_char ints;
266: {
267: int unit = hs->sc_hc->hp_unit;
268: char *sep = "";
269:
270: printf("scsi%d: ", unit);
271: if (ints & INTS_RST) {
272: DELAY(100);
273: if (hd->scsi_hconf & HCONF_SD)
274: printf("spurious RST interrupt");
275: else
276: printf("hardware error - check fuse");
277: sep = ", ";
278: }
279: if ((ints & INTS_HARD_ERR) || hd->scsi_serr) {
280: if (hd->scsi_serr & SERR_SCSI_PAR) {
281: printf("%sparity err", sep);
282: sep = ", ";
283: }
284: if (hd->scsi_serr & SERR_SPC_PAR) {
285: printf("%sSPC parity err", sep);
286: sep = ", ";
287: }
288: if (hd->scsi_serr & SERR_TC_PAR) {
289: printf("%sTC parity err", sep);
290: sep = ", ";
291: }
292: if (hd->scsi_serr & SERR_PHASE_ERR) {
293: printf("%sphase err", sep);
294: sep = ", ";
295: }
296: if (hd->scsi_serr & SERR_SHORT_XFR) {
297: printf("%ssync short transfer err", sep);
298: sep = ", ";
299: }
300: if (hd->scsi_serr & SERR_OFFSET) {
301: printf("%ssync offset error", sep);
302: sep = ", ";
303: }
304: }
305: if (ints & INTS_TIMEOUT)
306: printf("%sSPC select timeout error", sep);
307: if (ints & INTS_SRV_REQ)
308: printf("%sspurious SRV_REQ interrupt", sep);
309: if (ints & INTS_CMD_DONE)
310: printf("%sspurious CMD_DONE interrupt", sep);
311: if (ints & INTS_DISCON)
312: printf("%sspurious disconnect interrupt", sep);
313: if (ints & INTS_RESEL)
314: printf("%sspurious reselect interrupt", sep);
315: if (ints & INTS_SEL)
316: printf("%sspurious select interrupt", sep);
317: printf("\n");
318: }
319:
320: static int
321: issue_select(hd, target, our_addr)
322: volatile register struct scsidevice *hd;
323: u_char target, our_addr;
324: {
325: if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY))
326: return (1);
327:
328: if (hd->scsi_ints & INTS_DISCON)
329: hd->scsi_ints = INTS_DISCON;
330:
331: hd->scsi_pctl = 0;
332: hd->scsi_temp = (1 << target) | our_addr;
333: /* select timeout is hardcoded to 2ms */
334: hd->scsi_tch = 0;
335: hd->scsi_tcm = 32;
336: hd->scsi_tcl = 4;
337:
338: hd->scsi_scmd = SCMD_SELECT;
339: return (0);
340: }
341:
342: static int
343: wait_for_select(hd)
344: volatile register struct scsidevice *hd;
345: {
346: u_char ints;
347:
348: while ((ints = hd->scsi_ints) == 0)
349: DELAY(1);
350: hd->scsi_ints = ints;
351: return (!(hd->scsi_ssts & SSTS_INITIATOR));
352: }
353:
354: static int
355: ixfer_start(hd, len, phase, wait)
356: volatile register struct scsidevice *hd;
357: int len;
358: u_char phase;
359: register int wait;
360: {
361:
362: hd->scsi_tch = len >> 16;
363: hd->scsi_tcm = len >> 8;
364: hd->scsi_tcl = len;
365: hd->scsi_pctl = phase;
366: hd->scsi_tmod = 0; /*XXX*/
367: hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
368:
369: /* wait for xfer to start or svc_req interrupt */
370: while ((hd->scsi_ssts & SSTS_BUSY) == 0) {
371: if (hd->scsi_ints || --wait < 0) {
372: #ifdef DEBUG
373: if (scsi_debug)
374: printf("ixfer_start fail: i%x, w%d\n",
375: hd->scsi_ints, wait);
376: #endif
377: HIST(ixstart_wait, wait)
378: return (0);
379: }
380: DELAY(1);
381: }
382: HIST(ixstart_wait, wait)
383: return (1);
384: }
385:
386: static int
387: ixfer_out(hd, len, buf)
388: volatile register struct scsidevice *hd;
389: int len;
390: register u_char *buf;
391: {
392: register int wait = scsi_data_wait;
393:
394: for (; len > 0; --len) {
395: while (hd->scsi_ssts & SSTS_DREG_FULL) {
396: if (hd->scsi_ints || --wait < 0) {
397: #ifdef DEBUG
398: if (scsi_debug)
399: printf("ixfer_out fail: l%d i%x w%d\n",
400: len, hd->scsi_ints, wait);
401: #endif
402: HIST(ixout_wait, wait)
403: return (len);
404: }
405: DELAY(1);
406: }
407: hd->scsi_dreg = *buf++;
408: }
409: HIST(ixout_wait, wait)
410: return (0);
411: }
412:
413: static void
414: ixfer_in(hd, len, buf)
415: volatile register struct scsidevice *hd;
416: int len;
417: register u_char *buf;
418: {
419: register int wait = scsi_data_wait;
420:
421: for (; len > 0; --len) {
422: while (hd->scsi_ssts & SSTS_DREG_EMPTY) {
423: if (hd->scsi_ints || --wait < 0) {
424: while (! (hd->scsi_ssts & SSTS_DREG_EMPTY)) {
425: *buf++ = hd->scsi_dreg;
426: --len;
427: }
428: #ifdef DEBUG
429: if (scsi_debug)
430: printf("ixfer_in fail: l%d i%x w%d\n",
431: len, hd->scsi_ints, wait);
432: #endif
433: HIST(ixin_wait, wait)
434: return;
435: }
436: DELAY(1);
437: }
438: *buf++ = hd->scsi_dreg;
439: }
440: HIST(ixin_wait, wait)
441: }
442:
443: static int
444: mxfer_in(hd, len, buf, phase)
445: volatile register struct scsidevice *hd;
446: register int len;
447: register u_char *buf;
448: register u_char phase;
449: {
450: register int wait = scsi_cmd_wait;
451: register int i;
452:
453: hd->scsi_tmod = 0;
454: for (i = 0; i < len; ++i) {
455: /*
456: * wait for the request line (which says the target
457: * wants to give us data). If the phase changes while
458: * we're waiting, we're done.
459: */
460: while ((hd->scsi_psns & PSNS_REQ) == 0) {
461: if (--wait < 0) {
462: HIST(mxin_wait, wait)
463: return (-1);
464: }
465: if ((hd->scsi_psns & PHASE) != phase ||
466: (hd->scsi_ssts & SSTS_INITIATOR) == 0)
467: goto out;
468:
469: DELAY(1);
470: }
471: /*
472: * set ack (which says we're ready for the data, wait for
473: * req to go away (target says data is available), grab the
474: * data, then reset ack (say we've got the data).
475: */
476: hd->scsi_pctl = phase;
477: hd->scsi_scmd = SCMD_SET_ACK;
478: while (hd->scsi_psns & PSNS_REQ) {
479: if (--wait < 0) {
480: HIST(mxin_wait, wait)
481: return (-2);
482: }
483: DELAY(1);
484: }
485: *buf++ = hd->scsi_temp;
486: hd->scsi_scmd = SCMD_RST_ACK;
487: if (hd->scsi_psns & PSNS_ATN)
488: hd->scsi_scmd = SCMD_RST_ATN;
489: }
490: out:
491: HIST(mxin_wait, wait)
492: return (i);
493: }
494:
495: /*
496: * SCSI 'immediate' command: issue a command to some SCSI device
497: * and get back an 'immediate' response (i.e., do programmed xfer
498: * to get the response data). 'cbuf' is a buffer containing a scsi
499: * command of length clen bytes. 'buf' is a buffer of length 'len'
500: * bytes for data. The transfer direction is determined by the device
501: * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the
502: * command must supply no data. 'xferphase' is the bus phase the
503: * caller expects to happen after the command is issued. It should
504: * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE.
505: */
506: static int
507: scsiicmd(hs, target, cbuf, clen, buf, len, xferphase)
508: struct scsi_softc *hs;
509: int target;
510: u_char *cbuf;
511: int clen;
512: u_char *buf;
513: int len;
514: u_char xferphase;
515: {
516: volatile register struct scsidevice *hd =
517: (struct scsidevice *)hs->sc_hc->hp_addr;
518: u_char phase, ints;
519: register int wait;
520:
521: /* select the SCSI bus (it's an error if bus isn't free) */
522: if (issue_select(hd, target, hs->sc_scsi_addr))
523: return (-1);
524: if (wait_for_select(hd))
525: return (-1);
526: /*
527: * Wait for a phase change (or error) then let the device
528: * sequence us through the various SCSI phases.
529: */
530: hs->sc_stat[0] = 0xff;
531: hs->sc_msg[0] = 0xff;
532: phase = CMD_PHASE;
533: while (1) {
534: wait = scsi_cmd_wait;
535: switch (phase) {
536:
537: case CMD_PHASE:
538: if (ixfer_start(hd, clen, phase, wait))
539: if (ixfer_out(hd, clen, cbuf))
540: goto abort;
541: phase = xferphase;
542: break;
543:
544: case DATA_IN_PHASE:
545: if (len <= 0)
546: goto abort;
547: wait = scsi_data_wait;
548: if (ixfer_start(hd, len, phase, wait) ||
549: !(hd->scsi_ssts & SSTS_DREG_EMPTY))
550: ixfer_in(hd, len, buf);
551: phase = STATUS_PHASE;
552: break;
553:
554: case DATA_OUT_PHASE:
555: if (len <= 0)
556: goto abort;
557: wait = scsi_data_wait;
558: if (ixfer_start(hd, len, phase, wait)) {
559: if (ixfer_out(hd, len, buf))
560: goto abort;
561: }
562: phase = STATUS_PHASE;
563: break;
564:
565: case STATUS_PHASE:
566: wait = scsi_data_wait;
567: if (ixfer_start(hd, sizeof(hs->sc_stat), phase, wait) ||
568: !(hd->scsi_ssts & SSTS_DREG_EMPTY))
569: ixfer_in(hd, sizeof(hs->sc_stat), hs->sc_stat);
570: phase = MESG_IN_PHASE;
571: break;
572:
573: case MESG_IN_PHASE:
574: if (ixfer_start(hd, sizeof(hs->sc_msg), phase, wait) ||
575: !(hd->scsi_ssts & SSTS_DREG_EMPTY)) {
576: ixfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg);
577: hd->scsi_scmd = SCMD_RST_ACK;
578: }
579: phase = BUS_FREE_PHASE;
580: break;
581:
582: case BUS_FREE_PHASE:
583: goto out;
584:
585: default:
586: printf("scsi%d: unexpected phase %d in icmd from %d\n",
587: hs->sc_hc->hp_unit, phase, target);
588: goto abort;
589: }
590: /* wait for last command to complete */
591: while ((ints = hd->scsi_ints) == 0) {
592: if (--wait < 0) {
593: HIST(cxin_wait, wait)
594: goto abort;
595: }
596: DELAY(1);
597: }
598: HIST(cxin_wait, wait)
599: hd->scsi_ints = ints;
600: if (ints & INTS_SRV_REQ)
601: phase = hd->scsi_psns & PHASE;
602: else if (ints & INTS_DISCON)
603: goto out;
604: else if ((ints & INTS_CMD_DONE) == 0) {
605: scsierror(hs, hd, ints);
606: goto abort;
607: }
608: }
609: abort:
610: scsiabort(hs, hd, "icmd");
611: out:
612: return (hs->sc_stat[0]);
613: }
614:
615: /*
616: * Finish SCSI xfer command: After the completion interrupt from
617: * a read/write operation, sequence through the final phases in
618: * programmed i/o. This routine is a lot like scsiicmd except we
619: * skip (and don't allow) the select, cmd out and data in/out phases.
620: */
621: static void
622: finishxfer(hs, hd, target)
623: struct scsi_softc *hs;
624: volatile register struct scsidevice *hd;
625: int target;
626: {
627: u_char phase, ints;
628:
629: /*
630: * We specified padding xfer so we ended with either a phase
631: * change interrupt (normal case) or an error interrupt (handled
632: * elsewhere). Reset the board dma logic then try to get the
633: * completion status & command done msg. The reset confuses
634: * the SPC REQ/ACK logic so we have to do any status/msg input
635: * operations via 'manual xfer'.
636: */
637: if (hd->scsi_ssts & SSTS_BUSY) {
638: int wait = scsi_cmd_wait;
639:
640: /* wait for dma operation to finish */
641: while (hd->scsi_ssts & SSTS_BUSY) {
642: if (--wait < 0) {
643: #ifdef DEBUG
644: if (scsi_debug)
645: printf("finishxfer fail: ssts %x\n",
646: hd->scsi_ssts);
647: #endif
648: HIST(fxfr_wait, wait)
649: goto abort;
650: }
651: }
652: HIST(fxfr_wait, wait)
653: }
654: hd->scsi_scmd |= SCMD_PROG_XFR;
655: hd->scsi_sctl |= SCTL_CTRLRST;
656: DELAY(1);
657: hd->scsi_sctl &=~ SCTL_CTRLRST;
658: hd->scsi_hconf = 0;
659: hs->sc_stat[0] = 0xff;
660: hs->sc_msg[0] = 0xff;
661: hd->scsi_csr = 0;
662: hd->scsi_ints = ints = hd->scsi_ints;
663: while (1) {
664: phase = hd->scsi_psns & PHASE;
665: switch (phase) {
666:
667: case STATUS_PHASE:
668: if (mxfer_in(hd, sizeof(hs->sc_stat), hs->sc_stat,
669: phase) <= 0)
670: goto abort;
671: break;
672:
673: case MESG_IN_PHASE:
674: if (mxfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg,
675: phase) < 0)
676: goto abort;
677: break;
678:
679: case BUS_FREE_PHASE:
680: return;
681:
682: default:
683: printf("scsi%d: unexpected phase %d in finishxfer from %d\n",
684: hs->sc_hc->hp_unit, phase, target);
685: goto abort;
686: }
687: if (ints = hd->scsi_ints) {
688: hd->scsi_ints = ints;
689: if (ints & INTS_DISCON)
690: return;
691: else if (ints & ~(INTS_SRV_REQ|INTS_CMD_DONE)) {
692: scsierror(hs, hd, ints);
693: break;
694: }
695: }
696: if ((hd->scsi_ssts & SSTS_INITIATOR) == 0)
697: return;
698: }
699: abort:
700: scsiabort(hs, hd, "finishxfer");
701: hs->sc_stat[0] = 0xfe;
702: }
703:
704: int
705: scsi_test_unit_rdy(ctlr, slave, unit)
706: int ctlr, slave, unit;
707: {
708: register struct scsi_softc *hs = &scsi_softc[ctlr];
709: static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
710:
711: cdb.lun = unit;
712: return (scsiicmd(hs, slave, &cdb, sizeof(cdb), (u_char *)0, 0,
713: STATUS_PHASE));
714: }
715:
716: int
717: scsi_request_sense(ctlr, slave, unit, buf, len)
718: int ctlr, slave, unit;
719: u_char *buf;
720: unsigned len;
721: {
722: register struct scsi_softc *hs = &scsi_softc[ctlr];
723: static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE };
724:
725: cdb.lun = unit;
726: cdb.len = len;
727: return (scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE));
728: }
729:
730: int
731: scsi_immed_command(ctlr, slave, unit, cdb, buf, len, rd)
732: int ctlr, slave, unit;
733: struct scsi_fmt_cdb *cdb;
734: u_char *buf;
735: unsigned len;
736: {
737: register struct scsi_softc *hs = &scsi_softc[ctlr];
738:
739: cdb->cdb[1] |= unit << 5;
740: return (scsiicmd(hs, slave, cdb->cdb, cdb->len, buf, len,
741: rd != 0? DATA_IN_PHASE : DATA_OUT_PHASE));
742: }
743:
744: /*
745: * The following routines are test-and-transfer i/o versions of read/write
746: * for things like reading disk labels and writing core dumps. The
747: * routine scsigo should be used for normal data transfers, NOT these
748: * routines.
749: */
750: int
751: scsi_tt_read(ctlr, slave, unit, buf, len, blk, bshift)
752: int ctlr, slave, unit;
753: u_char *buf;
754: u_int len;
755: daddr_t blk;
756: int bshift;
757: {
758: register struct scsi_softc *hs = &scsi_softc[ctlr];
759: struct scsi_cdb10 cdb;
760: int stat;
761: int old_wait = scsi_data_wait;
762:
763: scsi_data_wait = 300000;
764: bzero(&cdb, sizeof(cdb));
765: cdb.cmd = CMD_READ_EXT;
766: cdb.lun = unit;
767: blk >>= bshift;
768: cdb.lbah = blk >> 24;
769: cdb.lbahm = blk >> 16;
770: cdb.lbalm = blk >> 8;
771: cdb.lbal = blk;
772: cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
773: cdb.lenl = len >> (DEV_BSHIFT + bshift);
774: stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE);
775: scsi_data_wait = old_wait;
776: return (stat);
777: }
778:
779: int
780: scsi_tt_write(ctlr, slave, unit, buf, len, blk, bshift)
781: int ctlr, slave, unit;
782: u_char *buf;
783: u_int len;
784: daddr_t blk;
785: int bshift;
786: {
787: register struct scsi_softc *hs = &scsi_softc[ctlr];
788: struct scsi_cdb10 cdb;
789: int stat;
790: int old_wait = scsi_data_wait;
791:
792: scsi_data_wait = 300000;
793:
794: bzero(&cdb, sizeof(cdb));
795: cdb.cmd = CMD_WRITE_EXT;
796: cdb.lun = unit;
797: blk >>= bshift;
798: cdb.lbah = blk >> 24;
799: cdb.lbahm = blk >> 16;
800: cdb.lbalm = blk >> 8;
801: cdb.lbal = blk;
802: cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
803: cdb.lenl = len >> (DEV_BSHIFT + bshift);
804: stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_OUT_PHASE);
805: scsi_data_wait = old_wait;
806: return (stat);
807: }
808:
809:
810: int
811: scsireq(dq)
812: register struct devqueue *dq;
813: {
814: register struct devqueue *hq;
815:
816: hq = &scsi_softc[dq->dq_ctlr].sc_sq;
817: insque(dq, hq->dq_back);
818: if (dq->dq_back == hq)
819: return(1);
820: return(0);
821: }
822:
823: int
824: scsiustart(unit)
825: int unit;
826: {
827: register struct scsi_softc *hs = &scsi_softc[unit];
828:
829: hs->sc_dq.dq_ctlr = DMA0 | DMA1;
830: if (dmareq(&hs->sc_dq))
831: return(1);
832: return(0);
833: }
834:
835: void
836: scsistart(unit)
837: int unit;
838: {
839: register struct devqueue *dq;
840:
841: dq = scsi_softc[unit].sc_sq.dq_forw;
842: (dq->dq_driver->d_go)(dq->dq_unit);
843: }
844:
845: int
846: scsigo(ctlr, slave, unit, bp, cdb, pad)
847: int ctlr, slave, unit;
848: struct buf *bp;
849: struct scsi_fmt_cdb *cdb;
850: int pad;
851: {
852: register struct scsi_softc *hs = &scsi_softc[ctlr];
853: volatile register struct scsidevice *hd =
854: (struct scsidevice *)hs->sc_hc->hp_addr;
855: int i, dmaflags;
856: u_char phase, ints, cmd;
857:
858: cdb->cdb[1] |= unit << 5;
859:
860: /* select the SCSI bus (it's an error if bus isn't free) */
861: if (issue_select(hd, slave, hs->sc_scsi_addr) || wait_for_select(hd)) {
862: dmafree(&hs->sc_dq);
863: return (1);
864: }
865: /*
866: * Wait for a phase change (or error) then let the device
867: * sequence us through command phase (we may have to take
868: * a msg in/out before doing the command). If the disk has
869: * to do a seek, it may be a long time until we get a change
870: * to data phase so, in the absense of an explicit phase
871: * change, we assume data phase will be coming up and tell
872: * the SPC to start a transfer whenever it does. We'll get
873: * a service required interrupt later if this assumption is
874: * wrong. Otherwise we'll get a service required int when
875: * the transfer changes to status phase.
876: */
877: phase = CMD_PHASE;
878: while (1) {
879: register int wait = scsi_cmd_wait;
880:
881: switch (phase) {
882:
883: case CMD_PHASE:
884: if (ixfer_start(hd, cdb->len, phase, wait))
885: if (ixfer_out(hd, cdb->len, cdb->cdb))
886: goto abort;
887: break;
888:
889: case MESG_IN_PHASE:
890: if (ixfer_start(hd, sizeof(hs->sc_msg), phase, wait)||
891: !(hd->scsi_ssts & SSTS_DREG_EMPTY)) {
892: ixfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg);
893: hd->scsi_scmd = SCMD_RST_ACK;
894: }
895: phase = BUS_FREE_PHASE;
896: break;
897:
898: case DATA_IN_PHASE:
899: case DATA_OUT_PHASE:
900: goto out;
901:
902: default:
903: printf("scsi%d: unexpected phase %d in go from %d\n",
904: hs->sc_hc->hp_unit, phase, slave);
905: goto abort;
906: }
907: while ((ints = hd->scsi_ints) == 0) {
908: if (--wait < 0) {
909: HIST(sgo_wait, wait)
910: goto abort;
911: }
912: DELAY(1);
913: }
914: HIST(sgo_wait, wait)
915: hd->scsi_ints = ints;
916: if (ints & INTS_SRV_REQ)
917: phase = hd->scsi_psns & PHASE;
918: else if (ints & INTS_CMD_DONE)
919: goto out;
920: else {
921: scsierror(hs, hd, ints);
922: goto abort;
923: }
924: }
925: out:
926: /*
927: * Reset the card dma logic, setup the dma channel then
928: * get the dio part of the card set for a dma xfer.
929: */
930: hd->scsi_hconf = 0;
931: cmd = CSR_IE | (CSR_DE0 << hs->sc_dq.dq_ctlr);
932: dmaflags = DMAGO_NOINT;
933: if (bp->b_flags & B_READ)
934: dmaflags |= DMAGO_READ;
935: if ((hs->sc_flags & SCSI_DMA32) &&
936: ((int)bp->b_un.b_addr & 3) == 0 && (bp->b_bcount & 3) == 0) {
937: cmd |= CSR_DMA32;
938: dmaflags |= DMAGO_LWORD;
939: } else
940: dmaflags |= DMAGO_WORD;
941: dmago(hs->sc_dq.dq_ctlr, bp->b_un.b_addr, bp->b_bcount, dmaflags);
942:
943: if (bp->b_flags & B_READ) {
944: cmd |= CSR_DMAIN;
945: phase = DATA_IN_PHASE;
946: } else
947: phase = DATA_OUT_PHASE;
948: hd->scsi_csr = cmd;
949: /*
950: * Setup the SPC for the transfer. We don't want to take
951: * first a command complete then a service required interrupt
952: * at the end of the transfer so we try to disable the cmd
953: * complete by setting the transfer counter to more bytes
954: * than we expect. (XXX - This strategy may have to be
955: * modified to deal with devices that return variable length
956: * blocks, e.g., some tape drives.)
957: */
958: cmd = SCMD_XFR;
959: i = (unsigned)bp->b_bcount;
960: if (pad) {
961: cmd |= SCMD_PAD;
962: /*
963: * XXX - If we don't do this, the last 2 or 4 bytes
964: * (depending on word/lword DMA) of a read get trashed.
965: * It looks like it is necessary for the DMA to complete
966: * before the SPC goes into "pad mode"??? Note: if we
967: * also do this on a write, the request never completes.
968: */
969: if (bp->b_flags & B_READ)
970: i += 2;
971: #ifdef DEBUG
972: hs->sc_flags |= SCSI_PAD;
973: if (i & 1)
974: printf("scsi%d: odd byte count: %d bytes @ %d\n",
975: ctlr, i, bp->b_cylin);
976: #endif
977: } else
978: i += 4;
979: hd->scsi_tch = i >> 16;
980: hd->scsi_tcm = i >> 8;
981: hd->scsi_tcl = i;
982: hd->scsi_pctl = phase;
983: hd->scsi_tmod = 0;
984: hd->scsi_scmd = cmd;
985: hs->sc_flags |= SCSI_IO;
986: return (0);
987: abort:
988: scsiabort(hs, hd, "go");
989: dmafree(&hs->sc_dq);
990: return (1);
991: }
992:
993: void
994: scsidone(unit)
995: register int unit;
996: {
997: volatile register struct scsidevice *hd =
998: (struct scsidevice *)scsi_softc[unit].sc_hc->hp_addr;
999:
1000: /* dma operation is done -- turn off card dma */
1001: hd->scsi_csr &=~ (CSR_DE1|CSR_DE0);
1002: }
1003:
1004: int
1005: scsiintr(unit)
1006: register int unit;
1007: {
1008: register struct scsi_softc *hs = &scsi_softc[unit];
1009: volatile register struct scsidevice *hd =
1010: (struct scsidevice *)hs->sc_hc->hp_addr;
1011: register u_char ints;
1012: register struct devqueue *dq;
1013:
1014: if ((hd->scsi_csr & (CSR_IE|CSR_IR)) != (CSR_IE|CSR_IR))
1015: return (0);
1016:
1017: ints = hd->scsi_ints;
1018: if ((ints & INTS_SRV_REQ) && (hs->sc_flags & SCSI_IO)) {
1019: /*
1020: * this should be the normal i/o completion case.
1021: * get the status & cmd complete msg then let the
1022: * device driver look at what happened.
1023: */
1024: #ifdef DEBUG
1025: int len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) |
1026: hd->scsi_tcl;
1027: if (!(hs->sc_flags & SCSI_PAD))
1028: len -= 4;
1029: if (len)
1030: printf("scsi%d: transfer length error %d\n", unit, len);
1031: hs->sc_flags &=~ SCSI_PAD;
1032: #endif
1033: dq = hs->sc_sq.dq_forw;
1034: finishxfer(hs, hd, dq->dq_unit);
1035: hs->sc_flags &=~ SCSI_IO;
1036: dmafree(&hs->sc_dq);
1037: (dq->dq_driver->d_intr)(dq->dq_unit, hs->sc_stat[0]);
1038: } else {
1039: /* Something unexpected happened -- deal with it. */
1040: hd->scsi_ints = ints;
1041: hd->scsi_csr = 0;
1042: scsierror(hs, hd, ints);
1043: scsiabort(hs, hd, "intr");
1044: if (hs->sc_flags & SCSI_IO) {
1045: hs->sc_flags &=~ SCSI_IO;
1046: dmafree(&hs->sc_dq);
1047: dq = hs->sc_sq.dq_forw;
1048: (dq->dq_driver->d_intr)(dq->dq_unit, -1);
1049: }
1050: }
1051: return(1);
1052: }
1053:
1054: void
1055: scsifree(dq)
1056: register struct devqueue *dq;
1057: {
1058: register struct devqueue *hq;
1059:
1060: hq = &scsi_softc[dq->dq_ctlr].sc_sq;
1061: remque(dq);
1062: if ((dq = hq->dq_forw) != hq)
1063: (dq->dq_driver->d_start)(dq->dq_unit);
1064: }
1065: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.