|
|
1.1 root 1: /*
2: * io.386/ss.c
3: *
4: * Device driver for Seagate ST01/ST02 scsi host adapters.
5: *
6: * Revised: Wed May 26 16:57:51 1993 CDT
7: */
8:
9: /*
10: * To do:
11: * nonzero LUN's
12: * start new command during disconnect
13: * rewrite as single state machine, instead of 7 of them
14: * separate SCSI layer from host-dependent stuff
15: */
16:
17: /*
18: * Debug levels.
19: * DEBUG = 0 No debug output.
20: * DEBUG = 1 Debug output on error only.
21: * DEBUG = 2 Debug output on error and at other selected places.
22: * DEBUG = 3 Print state machine trace.
23: * DEBUG = 4 Print info xfer phases and msg_in values.
24: */
25: #if (DEBUG >= 1)
26: static int s_id;
27: #define PR1(str) printf("%s%d ", str, s_id)
28: #else
29: #define PR1(str)
30: #endif
31: #if (DEBUG >= 2)
32: #define PR2(str) printf(str)
33: #else
34: #define PR2(str)
35: #endif
36: #if (DEBUG >= 3)
37: #define PR3(str) printf("%s%d ", str, s_id)
38: #else
39: #define PR3(str)
40: #endif
41: #if (DEBUG >= 4)
42: #define PR4(str) printf("%s%d ", str, s_id)
43: #else
44: #define PR4(str)
45: #endif
46:
47: /*
48: * Includes.
49: */
50: #include <sys/coherent.h>
51:
52: #ifdef _I386
53: #include <sys/fakeff.h>
54: #include <sys/dmac.h>
55: #endif
56: #include <sys/io.h>
57: #include <sys/sched.h>
58: #include <sys/uproc.h>
59: #include <sys/proc.h>
60: #include <sys/con.h>
61: #include <sys/stat.h>
62: #include <sys/devices.h> /* SCSI_MAJOR */
63: #include <errno.h>
64: #include <sys/fdisk.h>
65: #include <sys/hdioctl.h>
66: #include <sys/buf.h>
67: #include <sys/scsiwork.h>
68: #include <sys/typed.h>
69:
70: /*
71: * Definitions.
72: * Constants.
73: * Macros with argument lists.
74: * Typedefs.
75: * Enums.
76: */
77: #define SS_RAM 0x1800 /* Offset of parameter RAM */
78:
79: /* Future Domain */
80: #define FD_CSR 0x1C00 /* Offset of control/status register */
81: #define FD_DAT 0x1E00 /* Offset of data port */
82:
83: /* Seagate */
84: #define SS_CSR 0x1A00 /* Offset of control/status register */
85: #define SS_DAT 0x1C00 /* Offset of data port */
86:
87: #define SS_RAM_LEN 128 /* ST0x has 128 bytes of RAM */
88: #define SS_DAT_LEN 0x400 /* Byte range mapped to data port */
89: #define SS_SEL_LEN 0x2000 /* Total size of memory-mapped area */
90:
91: #define WC_ENABLE_SCSI 0x80 /* Write Control (WC) register bits */
92: #define WC_ENABLE_IRPT 0x40
93: #define WC_ENABLE_PRTY 0x20
94: #define WC_ARBITRATE 0x10
95: #define WC_ATTENTION 0x08
96: #define WC_BUSY 0x04
97: #define WC_SELECT 0x02
98: #define WC_SCSI_RESET 0x01
99:
100: #define RS_ARBIT_COMPL 0x80 /* Read STATUS (RS) register bits */
101: #define RS_PRTY_ERROR 0x40
102: #define RS_SELECT 0x20
103: #define RS_REQUEST 0x10
104: #define RS_CTRL_DATA 0x08
105: #define RS_I_O 0x04
106: #define RS_MESSAGE 0x02
107: #define RS_BUSY 0x01
108:
109: #define DEV_SCSI_ID(dev) ((dev >> 4) & 0x0007)
110: #define DEV_LUN(dev) ((dev >> 2) & 0x0003)
111: #define DEV_DRIVE(dev) ((dev >> 2) & 0x001F)
112: #define DEV_PARTN(dev) (dev & 0x0003)
113: #define DEV_SPECIAL(dev) (dev & 0x0080)
114:
115: #define HIPRI_RETRIES 5000 /* # of times to retry while hogging CPU */
116: #define LOPRI_RETRIES 5 /* # of retries with sleep between tries */
117: #define WHOLE_DRIVE NPARTN
118: #define RESET_TICKS 50 /* # of clock ticks for reset settling */
119: #define LOAD_DELAY 30000 /* Loop counter during ssload() only */
120:
121: #define BUS_FREE ((ffbyte(ss_csr) & (RS_BUSY | RS_SELECT)) == 0)
122: #define TGT_RSEL \
123: ( (ffbyte(ss_csr) & (RS_SELECT | RS_I_O )) \
124: && (ffbyte(ss_dat) & (host_id | (1<<s_id) )) )
125:
126: #define DELAY_ARB 10 /* delays units are 10 msec (clock ticks) */
127: #define DELAY_BDR 30
128: #define DELAY_BSY 20
129: #define DELAY_RES 50
130: #define DELAY_RST 40
131:
132: #define MAX_AVL_COUNT 100
133: #define MAX_BDR_COUNT 3
134: #define MAX_BSY_COUNT 3
135: #define MAX_TRY_COUNT 10
136: #define INL_MAX_REQ_POLL 800000L
137: #define WKG_MAX_REQ_POLL 20000L
138:
139: typedef enum { /* values for current driver state */
140: SST_DEQUEUE =0,
141: SST_BUS_DEV_RESET,
142: SST_HIPRI_RESET,
143: SST_LOPRI_RESET,
144: SST_POLL_ARBITN,
145: SST_POLL_BEGIN_IO,
146: SST_POLL_RESELECT,
147: SST_REQ_SENSE,
148: SST_RESET_OFF
149: } SST_TYPE;
150:
151: typedef enum { /* values for input to recovery routine */
152: RV_A_TIMEOUT,
153: RV_P_TIMEOUT,
154: RV_R_TIMEOUT,
155: RV_BF_TIMEOUT,
156: RV_CS_BUSY,
157: RV_CS_CHECK
158: } RV_TYPE;
159:
160: typedef struct ss {
161: ulong capacity;
162: ulong blocklen;
163: ulong bno;
164: int msg_in;
165: int dr_watch;
166: unchar cmdbuf[G1CMDLEN];
167: int cmdlen;
168: int cmd_bytes_out;
169: int cmdstat;
170: BUF *bp; /* current I/O request node, or NULL */
171: struct fdisk_s parmp[NPARTN+1];
172: SST_TYPE state;
173: TIM tim; /* for target-specific timers */
174: unchar avl_count;
175: unchar bdr_count;
176: unchar bsy_count;
177: unchar try_count;
178: uint busy:1; /* 1 if command uses local buffer */
179: uint expired:1; /* 1 if target's timer has expired */
180: uint ptab_read:1; /* 1 if partition table has been read */
181: uint waiting:1; /* 1 if target timer is running */
182: } ss_type;
183:
184: typedef struct {
185: uint ncyl;
186: unchar nhead;
187: unchar nspt;
188: } drv_parm_type;
189:
190: /*
191: * Functions.
192: * Import Functions.
193: * Export Functions.
194: * Local Functions.
195: */
196:
197: /* functions from bufq.c */
198: extern int bufq_init();
199: extern void bufq_rlse();
200: extern void bufq_wr_tail();
201: extern BUF * bufq_rd_head();
202: extern BUF * bufq_rm_head();
203:
204: /* functions from ssas.s */
205: extern void ss_get();
206: extern int ss_put();
207: extern int nulldev();
208: extern int nonedev();
209: #ifndef _I386
210: extern unsigned char ffbyte();
211: #endif
212:
213: static void ssopen(); /* CON functions */
214: static void ssclose();
215: static void ssblock();
216: static void ssread();
217: static void sswrite();
218: static int ssioctl();
219: static void sswatch();
220: static void ssload();
221: static void ssunload();
222:
223: static int bus_dev_reset(); /* additional support functions */
224: static int chk_reconn();
225: static void do_connect();
226: static void dummy_reconn();
227: static int far_info_xfer();
228: static int host_ident();
229: static int init_call();
230: static void init_pointers();
231: static int inquiry();
232: static int local_info_xfer();
233: static int mode_sense();
234: static void next_req();
235: static void nonpolled();
236: static int read_cap();
237: static void recover();
238: static int req_sense();
239: static int rsel_handshake();
240: static void ssdelay();
241: static void ss_finished();
242: static void ss_mach();
243: static void set_timeout();
244: static int ssinit();
245: static void ssintr();
246: static int start_arb();
247: static void stop_timeout();
248: static void tbparms();
249: static unchar xpmod();
250:
251: /*
252: * Global Data.
253: * Import Variables.
254: * Export Variables.
255: * Local Variables.
256: */
257:
258: extern short n_atdr; /* set by atcount() before any load routines run */
259:
260: CON sscon = {
261: DFBLK|DFCHR, /* Flags */
262: SCSI_MAJOR, /* Major index */
263: ssopen, /* Open */
264: ssclose, /* Close */
265: ssblock, /* Block */
266: ssread, /* Read */
267: sswrite, /* Write */
268: ssioctl, /* Ioctl */
269: nulldev, /* Powerfail */
270: sswatch, /* Timeout */
271: ssload, /* Load */
272: ssunload, /* Unload */
273: nulldev /* Poll */
274: };
275:
276: /* Patch these Export Variables to configure the driver. */
277: /*
278: * In the low byte of NSDRIVE, bit n is 1 if SCSI ID n is an installed target.
279: * The high byte indicates which type of host adapter:
280: * 00 - ST01/ST02
281: * 80 - TMC-845/850/860/875/885
282: * 40 - TMC-840/841/880/881
283: */
284: uint NSDRIVE = 0x0001;
285: uint SS_INT = 5; /* ST0[12] use either IRQ3 or IRQ5 */
286: uint SS_BASE = 0xCA00; /* Segment addr of ST0x communication area */
287:
288: /* ncyl, nhead, nspt */
289: drv_parm_type drv_parm[MAX_SCSI_ID] = {
290: { 0, 0, 0},
291: { 0, 0, 0},
292: { 0, 0, 0},
293: { 0, 0, 0},
294: { 0, 0, 0},
295: { 0, 0, 0},
296: { 0, 0, 0}
297: };
298:
299: static BUF dbuf; /* For raw I/O */
300: static paddr_t ss_base; /* physical address of ST0x comm area */
301: static faddr_t ss_fp; /* (far *) to ST0x comm area */
302:
303: static faddr_t ss_ram; /* (far *) to parameter RAM */
304: static faddr_t ss_csr; /* (far *) to control/status */
305: static faddr_t ss_dat; /* (far *) to data port */
306:
307: static TIM delay_tim; /* needed for calls to ssdelay() */
308: static int do_sst_op; /* 1 when state machine iteration continues */
309: static int ss_expired; /* 1 after local timeout */
310:
311: static uint max_req_poll; /* this changes after initialization */
312:
313: static unchar host_id; /* Host is SCSI ID #7 for Seagate, 6 for FD */
314: static unchar swap_status_bits;
315:
316: static ss_type *ss_tbl; /* points to block of "ss" structs */
317: static ss_type *ss[MAX_SCSI_ID];
318:
319: /*
320: * host_claimed is -1 if host is available, else it's the SCSI id of the
321: * target that claims the host.
322: *
323: * host is claimed at start of any of the follwoing:
324: * SCSI bus reset
325: * arbitration for block i/o request
326: * reselect
327: *
328: * host is released at:
329: * end of SCSI bus reset
330: * completion (successful or not) of block i/o request (ss_finished)
331: * disconnect <-- temporarily disabled
332: */
333: static int host_claimed;
334:
335: /*
336: * ssload() - load routine.
337: *
338: * Action: The controller is reset and the interrupt vector is grabbed.
339: * The drive characteristics are set up at this time.
340: */
341: static void ssload()
342: {
343: int erf = 0; /* 1 if error occurs */
344: int i;
345: int max_id = -1;
346: int num_drives = 0;
347: int tbnum;
348:
349:
350: /*
351: * Allocate a selector to map into ST0x memory-mapped comm area.
352: */
353: ss_base = (paddr_t)((long)(unsigned)SS_BASE << 4);
354: #ifdef _I386
355: ss_fp = map_pv(ss_base, (fsize_t)SS_SEL_LEN);
356: #else /* _I386 */
357: ss_fp = ptov(ss_base, (fsize_t)SS_SEL_LEN);
358: #endif /* _I386 */
359: ss_ram = ss_fp + SS_RAM;
360:
361: /*
362: * Primitive test of ST0x RAM.
363: */
364: sfword(ss_ram, 0xA55A);
365: sfword(ss_ram + 2, 0x3CC3);
366: sfword(ss_ram + SS_RAM_LEN - 4, 0xA55A);
367: sfword(ss_ram + SS_RAM_LEN - 2, 0x3CC3);
368: if (ffword(ss_ram) != 0xA55A /* fetch a "far" word */
369: || ffword(ss_ram + 2) != 0x3CC3
370: || ffword(ss_ram + SS_RAM_LEN - 4) != 0xA55A
371: || ffword(ss_ram + SS_RAM_LEN - 2) != 0x3CC3) {
372: printf("Error - host failed memory test\n");
373: erf = 1;
374: }
375:
376: /*
377: * Set host-dependent constants.
378: */
379: switch(NSDRIVE >> 8) {
380: case 0x00: /* ST01/ST02 */
381: ss_csr = ss_fp + SS_CSR;
382: ss_dat = ss_fp + SS_DAT;
383: host_id = 0x80; /* host is id #7 */
384: break;
385: case 0x80: /* TMC-845/850/860/875/885 */
386: ss_csr = ss_fp + FD_CSR;
387: ss_dat = ss_fp + FD_DAT;
388: host_id = 0x40; /* host is id #6 */
389: break;
390: case 0x40: /* TMC-840/841/880/881 */
391: ss_csr = ss_fp + SS_CSR;
392: ss_dat = ss_fp + SS_DAT;
393: host_id = 0x40; /* host is id #6 */
394: swap_status_bits = 1;
395: break;
396: }
397: NSDRIVE &= ~(uint)host_id;
398:
399: /*
400: * Allocate drive structs.
401: *
402: * Do a single call to kalloc() then put allocated pieces into
403: * array ss.
404: *
405: * First allocate and clear storage. Then hook up the pointers.
406: */
407: if (!erf) {
408: for (i = 0; i < MAX_SCSI_ID; i++)
409: if ((NSDRIVE >> i) & 1) {
410: max_id = i;
411: num_drives++;
412: }
413: if (num_drives == 0) {
414: printf("Error - ss has no valid target id's\n");
415: erf = 1;
416: } else if ((ss_tbl = kalloc(num_drives*sizeof(ss_type)))
417: == NULL) {
418: printf("Error - ss can't allocate structs\n");
419: erf = 1;
420: } else
421: kclear(ss_tbl, num_drives * sizeof(ss_type));
422: }
423: if (!erf) {
424: ss_type *foo = ss_tbl;
425:
426: for (i = 0; i < MAX_SCSI_ID; i++)
427: if ((NSDRIVE >> i) & 1)
428: ss[i] = foo++;
429: }
430:
431: /*
432: * Claim IRQ vector.
433: */
434: setivec(SS_INT, ssintr);
435:
436: /*
437: * Initialize drives we know about (i.e. in NSDRIVE bitmap).
438: *
439: * Part of this is getting parameters from tboot, if any.
440: * The drive number in tboot's data block must be matched with
441: * the SCSI id in question. Drive numbering in tboot is assumed
442: * to start with any "at" drives (n_atdr counts these)
443: * then proceed with SCSI drives in increasing id number order.
444: */
445: tbnum = n_atdr; /* tboot drive number for first SCSI drive */
446: host_claimed = -1;
447: bufq_init(max_id + 1);
448: max_req_poll = INL_MAX_REQ_POLL;
449: if (!erf) {
450: for (i = 0; i < MAX_SCSI_ID; i++)
451: if ((NSDRIVE >> i) & 1) {
452: tbparms(tbnum, i); /* get tboot parms */
453: ssinit(i);
454: tbnum++;
455: }
456: }
457: max_req_poll = WKG_MAX_REQ_POLL;
458: }
459:
460: /*
461: * ssunload() - unload routine.
462: */
463: static void ssunload()
464: {
465: /*
466: * Deallocate driver heap space.
467: */
468: if (ss_tbl)
469: kfree(ss_tbl);
470: bufq_rlse();
471:
472: /*
473: * Free the ST0x selector.
474: */
475: #ifdef _I386
476: unmap_pv(ss_fp);
477: #else /* _I386 */
478: vrelse(ss_fp);
479: #endif /* _I386 */
480:
481: /*
482: * Release IRQ vector.
483: */
484: clrivec(SS_INT);
485: }
486:
487: /*
488: * ssopen()
489: *
490: * Input: dev = disk device to be opened.
491: * mode = access mode [IPR,IPW, IPR+IPW].
492: *
493: * Action: Validate the minor device.
494: * Update the paritition table if necessary.
495: */
496: static void ssopen(dev, mode)
497: register dev_t dev;
498: {
499: int drive, partn;
500: struct fdisk_s *fdp;
501: ss_type * ssp;
502: int s_id;
503: unchar * msg;
504:
505: /*
506: * Set up local variables.
507: */
508: drive = DEV_SCSI_ID(dev);
509: partn = DEV_PARTN(dev);
510: s_id = DEV_SCSI_ID(dev);
511: ssp = ss[s_id];
512: fdp = ssp->parmp;
513:
514: #if (DEBUG >= 3)
515: devmsg(dev, "ssopen");
516: #endif
517:
518: /*
519: * LUN must be zero.
520: * SCSI id must have corresponding 1 in NSDRIVE bitmapped variable.
521: */
522: if (DEV_LUN(dev) != 0 || ((1 << drive) & NSDRIVE) == 0) {
523: msg = "bad LUN or SCSI id";
524: u.u_error = ENXIO;
525: goto bad_open;
526: }
527:
528: /*
529: * If "special" bit is set, partition field must be zero.
530: */
531: if (DEV_SPECIAL(dev) && partn != 0) {
532: msg = "bad special partition";
533: u.u_error = ENXIO;
534: goto bad_open;
535: }
536:
537: /*
538: * Subscripting gimmick for partition table.
539: */
540: if (dev & SDEV)
541: partn = WHOLE_DRIVE;
542:
543: /*
544: * If not accessing whole drive and the partition table has not
545: * been read yet, try to read it now.
546: * Do this by calling fdisk() with partition table device on the drive
547: * that is being accessed.
548: */
549: if (partn != WHOLE_DRIVE && !(ssp->ptab_read)) {
550: int fdisk_dev;
551:
552: fdisk_dev = (dev | SDEV) & 0xfff0;
553:
554: #if (DEBUG >=3)
555: devmsg(fdisk_dev, "calling fdisk");
556: if (fdisk(fdisk_dev, fdp)) {
557: int p;
558:
559: fdp[WHOLE_DRIVE].p_size = ssp->capacity;
560: fdp[WHOLE_DRIVE].p_base = 0;
561: printf("fdisk() succeeded\n");
562: for (p=0; p<WHOLE_DRIVE; p++)
563: printf("p=%d base=%ld size=%ld\n", p, fdp[p].p_base, fdp[p].p_size);
564: ssp->ptab_read = 1;
565: } else {
566: printf("fdisk() failed\n");
567: u.u_error = ENXIO;
568: goto bad_open;
569: }
570: #else
571: if (fdisk(fdisk_dev, fdp)) {
572: fdp[WHOLE_DRIVE].p_size = ssp->capacity;
573: fdp[WHOLE_DRIVE].p_base = 0;
574: ssp->ptab_read = 1;
575: } else {
576: msg = "bad partition table";
577: u.u_error = ENXIO;
578: goto bad_open;
579: }
580: #endif
581:
582: }
583:
584: /*
585: * Ensure partition lies within drive boundaries and is non-zero size.
586: */
587: if (partn != WHOLE_DRIVE
588: && (fdp[partn].p_base+fdp[partn].p_size) > fdp[WHOLE_DRIVE].p_size) {
589: msg = "partition exceeds drive capacity";
590: #ifdef _I386
591: u.u_error = EINVAL;
592: #else
593: u.u_error = EBADFMT;
594: #endif /* _I386 */
595: goto bad_open;
596: }
597:
598: if (partn != WHOLE_DRIVE && fdp[partn].p_size == 0) {
599: msg = "partition not found";
600: u.u_error = ENODEV;
601: goto bad_open;
602: }
603:
604: /*
605: * OK to open the device.
606: * Start watchdog timer (if not already started) for the host adapter.
607: */
608: ++drvl[SCSI_MAJOR].d_time;
609: ++ssp->dr_watch;
610: goto end_open;
611:
612: bad_open:
613: devmsg(dev, msg);
614: end_open:
615: return;
616: }
617:
618: /*
619: * ssclose()
620: */
621: static void ssclose(dev)
622: dev_t dev;
623: {
624: ss_type * ssp;
625: int s_id;
626:
627: s_id = DEV_SCSI_ID(dev);
628: ssp = ss[s_id];
629:
630: /*
631: * Decrement the number of watchdog timer requests open for host
632: * adapter and for target.
633: */
634: --drvl[SCSI_MAJOR].d_time;
635: --ssp->dr_watch;
636:
637: #if (DEBUG >= 3)
638: devmsg(dev, "ssclose");
639: #endif
640:
641: }
642:
643: /*
644: * ssread() - read a block from the raw disk
645: *
646: * Input: dev = disk device to be written to.
647: * iop = pointer to source I/O structure.
648: *
649: * Action: Invoke the common raw I/O processing code.
650: */
651: static void ssread(dev, iop)
652: dev_t dev;
653: IO *iop;
654: {
655: T_PIGGY( 0x20, printf("ssread(iop->io.vbase: %x)", iop->io.vbase); );
656:
657: ioreq( &dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC );
658: }
659:
660: /*
661: * sswrite() - write a block to the raw disk
662: *
663: * Input: dev = disk device to be written to.
664: * iop = pointer to source I/O structure.
665: *
666: * Action: Invoke the common raw I/O processing code.
667: */
668: static void sswrite(dev, iop)
669: dev_t dev;
670: IO *iop;
671: {
672: T_PIGGY( 0x20, printf("sswrite(iop->io.vbase: %x)", iop->io.vbase); );
673:
674: ioreq( &dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC );
675: }
676:
677: /*
678: * ssioctl()
679: *
680: * Input: dev = disk device to be operated on.
681: * cmd = input/output request to be performed.
682: * vec = (pointer to) optional argument.
683: */
684: static int ssioctl(dev, cmd, vec)
685: register dev_t dev;
686: int cmd;
687: char * vec;
688: {
689: int ret = 0;
690: hdparm_t hdparm;
691: struct fdisk_s *fdp;
692: int s_id;
693: ss_type * ssp;
694:
695: s_id = DEV_SCSI_ID(dev);
696: ssp = ss[s_id];
697: fdp = ssp->parmp;
698:
699: switch(cmd) {
700: case HDGETA:
701: /*
702: * Get hard disk attributes.
703: */
704: PR3("HDGETA");
705: fdp = ssp->parmp;
706: *(short *)&hdparm.landc[0] =
707: *(short *)&hdparm.ncyl[0] = drv_parm[s_id].ncyl;
708: hdparm.nhead = drv_parm[s_id].nhead;
709: hdparm.nspt = drv_parm[s_id].nspt;
710: #if (DEBUG >= 3)
711: printf("ncyl=%d nhead=%d nspt=%d\n",
712: hdparm.ncyl[0]+((int)hdparm.ncyl[1]<<8), (int)hdparm.nhead, (int)hdparm.nspt);
713: #endif
714: kucopy(&hdparm, vec, sizeof hdparm);
715: ret = 0;
716: break;
717: case HDSETA:
718: /*
719: * Set hard disk attributes.
720: */
721: PR3("HDSETA");
722: fdp = ssp->parmp;
723: ukcopy(vec, &hdparm, sizeof hdparm);
724: drv_parm[s_id].ncyl = *(short *)&hdparm.ncyl[0];
725: drv_parm[s_id].nhead = hdparm.nhead;
726: drv_parm[s_id].nspt = hdparm.nspt;
727: #if (DEBUG >= 3)
728: printf("ncyl=%d nhead=%d nspt=%d\n",
729: hdparm.ncyl[0]+((int)hdparm.ncyl[1]<<8), (int)hdparm.nhead, (int)hdparm.nspt);
730: #endif
731: ret = 0;
732: break;
733: default:
734: u.u_error = EINVAL;
735: ret = -1;
736: }
737:
738: return ret;
739: }
740:
741: /*
742: * ssblock() - queue a block to the disk
743: *
744: * Input: bp = pointer to block to be queued.
745: *
746: * Action: Queue a block to the disk.
747: * Make sure that the transfer is within the disk partition.
748: */
749: static void ssblock(bp)
750: register BUF *bp;
751: {
752: struct fdisk_s *fdp;
753: int partition, drive, s_id;
754: dev_t dev;
755: ss_type * ssp;
756: unchar * msg = NULL;
757:
758: T_PIGGY( 0x20,
759: printf("ssblock(bp->b_vaddr: %x, bp->b_paddr: %x)",
760: bp->b_vaddr, bp->b_paddr);
761: );
762:
763: /*
764: * Set up local variables.
765: */
766: dev = bp->b_dev;
767: partition = DEV_PARTN(dev);
768: drive = DEV_DRIVE(dev);
769: s_id = DEV_SCSI_ID(dev);
770: ssp = ss[s_id];
771: if (dev & SDEV)
772: partition = WHOLE_DRIVE;
773: fdp = ssp->parmp;
774:
775: bp->b_resid = bp->b_count;
776: #if (DEBUG >= 2)
777: if (bp->b_count != BSIZE)
778: printf("b_count=%d ", bp->b_count);
779: #endif
780:
781: /*
782: * Range check disk region.
783: */
784: if (!(ssp->ptab_read)) {
785: if ( partition == WHOLE_DRIVE ) {
786: #if 0
787: /* Why did we only allow people to access the first block of WHOLE_DRIVE?
788: in cases where there was not a valid partition table? */
789: if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
790: msg = "invalid request";
791: bp->b_flag |= BFERR;
792: goto bad_blk;
793: }
794: #endif
795: } else {
796: msg = "no partition table";
797: bp->b_flag |= BFERR;
798: goto bad_blk;
799: }
800: }
801:
802: /*
803: * Check for read at end of partition.
804: * (Need to return with b_resid = BSIZE to signal end of volume.)
805: */
806: else if ((bp->b_req == BREAD) && (bp->b_bno == fdp[partition].p_size)) {
807: goto bad_blk;
808: }
809:
810: /*
811: * Check for read past end of partition.
812: */
813: else if ( (bp->b_bno + (bp->b_count/BSIZE))
814: > fdp[partition].p_size ) {
815: msg = "partition overrun";
816: bp->b_flag |= BFERR;
817: goto bad_blk;
818: }
819:
820: /*
821: * Fail if request is for zero bytes or is not even # of blocks.
822: */
823: if ((bp->b_count % BSIZE) || bp->b_count == 0) {
824: msg = "invalid byte count";
825: bp->b_flag |= BFERR;
826: goto bad_blk;
827: }
828:
829: /*
830: * Operation appears valid.
831: * Fill fields in the node and queue the request.
832: */
833: bufq_wr_tail(s_id, bp);
834: ss_mach(s_id);
835: goto end_blk;
836:
837: /*
838: * Operation cannot be done. Release the kernel buffer structure.
839: * Value of "bp->b_flag" tells caller if error occurred.
840: */
841: bad_blk:
842: if (msg)
843: devmsg(dev, msg);
844: bdone(bp);
845:
846: end_blk:
847: return;
848: }
849:
850: /*
851: * ssintr() - Interrupt routine.
852: *
853: * If we have been reselected by a recognized target device
854: * let kernel get out of interrupt mode (defer) and do SCSI
855: * reconnect stuff.
856: */
857: static void ssintr()
858: {
859: int s_id;
860:
861: s_id = chk_reconn();
862: if (s_id != -1) {
863: if (ss[s_id]->state == SST_POLL_RESELECT)
864: defer(ss_mach, s_id);
865: else
866: defer(dummy_reconn, s_id);
867: PR3("!");
868: }
869: }
870:
871: /*
872: * dummy_reconn()
873: *
874: * Somehow we are in a state where the driver software does not expect
875: * a reconnect but a device is trying one anyway. Go thru the motions
876: * of reconnect because not servicing a hanging reselect seems to leave
877: * the target hung - in such a way that it fails to respond to reset
878: * messages and to reset on the SCSI bus.
879: */
880: static void dummy_reconn(s_id)
881: int s_id;
882: {
883: int bus_timeout;
884: unchar phase_type;
885: int s;
886: int msg_in;
887: int cmdstat;
888: int xfer_good = 1;
889: PR1("DUM");
890: if (ss[s_id]->state == SST_POLL_RESELECT) {
891: defer(ss_mach, s_id);
892: goto dum_done;
893: }
894: if (!rsel_handshake())
895: goto dum_done;
896:
897: s = sphi();
898: while (req_wait(&bus_timeout) && xfer_good) {
899: phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
900: switch (xpmod(phase_type)) {
901: case XP_MSG_IN:
902: msg_in = ffbyte(ss_dat);
903: switch(msg_in){
904: case MSG_CMD_CMPLT:
905: case MSG_DISCONNECT:
906: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
907: break;
908: }
909: break;
910: case XP_MSG_OUT:
911: sfbyte(ss_dat, MSG_NOP);
912: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
913: break;
914: case XP_STAT_IN:
915: cmdstat = ffbyte(ss_dat);
916: break;
917: case XP_CMD_OUT:
918: case XP_DATA_OUT:
919: xfer_good = 0;
920: break;
921: case XP_DATA_IN:
922: ffbyte(ss_dat);
923: break;
924: default:
925: break;
926: } /* endswitch */
927: } /* endwhile */
928: spl(s);
929:
930: dum_done:
931: return;
932: }
933:
934: /*
935: * sswatch()
936: *
937: * Invoked once per second if any devices going through this driver are open.
938: * Poll for any reselect, in case interrupt got lost.
939: */
940: static void sswatch()
941: {
942: int s_id;
943: ss_type * ssp;
944:
945: for (s_id = 0; s_id < MAX_SCSI_ID; s_id++) {
946: ssp = ss[s_id];
947: if (ssp && ssp->dr_watch)
948: defer(ss_mach, s_id);
949: } /* endfor */
950: }
951:
952: /*
953: * bus_wait()
954: *
955: * Wait for specified bit values to appear in Status Register.
956: * This uses a tight loop and does not expect to be interrupted.
957: *
958: * Argument "flags" is a double-byte value; the high byte is ANDed with
959: * status register contents, and the result is tested for equality with
960: * the low byte.
961: *
962: * Return 1 if values wanted appeared, 0 if timeout occurred.
963: */
964: static int bus_wait(flags)
965: unsigned short flags;
966: {
967: int found, i;
968: unsigned char status;
969:
970: found = 0;
971: for ( i = 0; i < HIPRI_RETRIES; i++) {
972: status = ffbyte(ss_csr);
973: if ((status & (flags >> 8)) == (flags & 0xff)) {
974: found = 1;
975: break;
976: }
977: }
978:
979: #if (DEBUG >= 1)
980: if (!found)
981: printf("TO:f=%x s=%x ", flags, status);
982: #endif
983:
984: return found;
985: }
986:
987: /*
988: * ssinit()
989: *
990: * Attempt to initialize the (unique) drive with a given SCSI id.
991: * Assume only one drive per SCSI id, having LUN = 0.
992: *
993: * Return 1 if success, 0 if failure.
994: */
995: static int ssinit(s_id)
996: int s_id;
997: {
998: int retval = 1;
999: unchar query_buf[MODESENSELEN];
1000: ss_type * ssp = ss[s_id];
1001: int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
1002:
1003: printf("SCSI ID %d LUN 0\n", s_id);
1004: if (retval)
1005: if (init_call(inquiry, s_id, query_buf)) {
1006: query_buf[INQUIRYLEN] = 0;
1007: #if (debug >= 2)
1008: devmsg(dev, query_buf + 8);
1009: #endif
1010: if (query_buf[0] == 0) {
1011: retval = 1;
1012: } else
1013: devmsg(dev, "Not Direct Access Device");
1014: } else
1015: devmsg(dev, "Inquiry Failed");
1016:
1017: if (retval)
1018: if (init_call(read_cap, s_id, query_buf)) {
1019: retval = 1;
1020: ssp->capacity = query_buf[3] | (query_buf[2] << 8)
1021: | (((long)(query_buf[1])) << 16)
1022: | (((long)(query_buf[0])) << 24);
1023: ssp->blocklen = query_buf[7] | (query_buf[6] << 8)
1024: | (((long)(query_buf[5])) << 16)
1025: | (((long)(query_buf[4])) << 24);
1026:
1027: printf("Capacity=%ld blocks Block length=%ld\n",
1028: ssp->capacity, ssp->blocklen);
1029: } else
1030: devmsg(dev, "Read Capacity Failed");
1031:
1032: if (retval)
1033: if (init_call(mode_sense, s_id, query_buf)) {
1034: /*
1035: * Display physical drive parameters.
1036: */
1037: #define FMT_PG (4+8+8+12)
1038: #define DDG_PG (4+8+8+12+24)
1039: unchar heads;
1040: unsigned short spt;
1041: ulong cyls;
1042:
1043: spt=((int)query_buf[FMT_PG+10]<<8)
1044: + query_buf[FMT_PG+11];
1045: cyls=((int)query_buf[DDG_PG+2]<<16)
1046: + ((int)query_buf[DDG_PG+3]<<8)
1047: + query_buf[DDG_PG+4];
1048: heads=query_buf[DDG_PG+5];
1049:
1050: printf("Physical: cylinders=%ld ", cyls);
1051: printf("heads=%d ", heads);
1052: printf("spt=%d\n", spt);
1053:
1054: if (drv_parm[s_id].ncyl == 0) {
1055: drv_parm[s_id].ncyl = cyls;
1056: drv_parm[s_id].nhead = heads;
1057: drv_parm[s_id].nspt = spt;
1058: } else {
1059: printf("Logical: cylinders=%d ",
1060: drv_parm[s_id].ncyl);
1061: printf("heads=%d ", drv_parm[s_id].nhead);
1062: printf("spt=%d\n", drv_parm[s_id].nspt);
1063: }
1064: } else
1065: devmsg(dev, "Mode Sense Failed");
1066:
1067: return retval;
1068: }
1069:
1070: /*
1071: * far_info_xfer()
1072: *
1073: * Do bus cycle information transfer phases.
1074: * This includes message in/out, command in/out, and data in/out.
1075: *
1076: * If cmdlen is nonzero, cmdbuf is an array of bytes of that length,
1077: * to be sent to the target.
1078: *
1079: * Return 1 if bus timeout did not occur, else 0.
1080: *
1081: * pseudocode:
1082: *
1083: * while (wait for REQ true or BUSY false on SCSI bus)
1084: * if (BUSY false)
1085: * break from while loop
1086: * else
1087: * switch (xfer phase = RS_CTRL_DATA|RS_I_O|RS_MESSAGE)
1088: * case XP_MSG_IN/XP_MSG_OUT/...
1089: * handle the indicated information transfer phase
1090: * endswitch
1091: * endif
1092: * endwhile
1093: */
1094: static int far_info_xfer(s_id)
1095: int s_id;
1096: {
1097: int bus_timeout;
1098: unchar phase_type;
1099: unchar msg_in;
1100: int s;
1101: int bytes_to_send;
1102: ss_type * ssp = ss[s_id];
1103: BUF * bp = ssp->bp;
1104: int xfer_good = 1;
1105: int xfer_count = bp->b_count - bp->b_resid;
1106: int irpts_masked;
1107: int block_done=0;
1108:
1109: ssp->cmd_bytes_out = 0;
1110: ssp->msg_in = -1;
1111:
1112: irpts_masked = 0;
1113: while (req_wait(&bus_timeout) && xfer_good) {
1114: phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
1115: if (!irpts_masked) {
1116: s = sphi();
1117: irpts_masked = 1;
1118: }
1119: switch (xpmod(phase_type)) {
1120: case XP_MSG_IN:
1121: msg_in = ffbyte(ss_dat);
1122: switch(msg_in){
1123: case MSG_CMD_CMPLT:
1124: PR4("Mcc");
1125: ssp->msg_in = msg_in;
1126: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
1127: break;
1128: case MSG_DISCONNECT:
1129: PR4("Mdc");
1130: ssp->msg_in = msg_in;
1131: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
1132: break;
1133: case MSG_SAVE_DPTR:
1134: PR4("Msd");
1135: break;
1136: case MSG_RSTOR_DPTR:
1137: PR4("Mrd");
1138: break;
1139: case MSG_ABORT:
1140: PR4("Mab");
1141: break;
1142: case MSG_DEV_RESET:
1143: PR4("Mdr");
1144: break;
1145: case MSG_IDENTIFY:
1146: PR4("Mmi");
1147: break;
1148: case MSG_IDENT_DC:
1149: PR4("Mmd");
1150: break;
1151: }
1152: break;
1153: case XP_MSG_OUT:
1154: PR4("MO");
1155: /*
1156: * This case shouldn't happen. We weren't
1157: * asserting ATTENTION. Abort the bus cycle.
1158: */
1159: sfbyte(ss_dat, MSG_NOP);
1160: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
1161: break;
1162: case XP_STAT_IN:
1163: PR4("SI");
1164: ssp->cmdstat = ffbyte(ss_dat);
1165: break;
1166: case XP_CMD_OUT:
1167: /*
1168: * Ship out command bytes.
1169: * Reset SCSI bus if too many command bytes are wanted.
1170: */
1171: bytes_to_send = ssp->cmdlen - ssp->cmd_bytes_out;
1172: if(bytes_to_send > 0) {
1173: sfbyte(ss_dat, ssp->cmdbuf[ssp->cmd_bytes_out++]);
1174: /*
1175: * If just sent last byte, allow interrupts.
1176: */
1177: if (bytes_to_send == 1) {
1178: PR4("CO");
1179: if (bp->b_req == BREAD) {
1180: if (irpts_masked) {
1181: spl(s);
1182: irpts_masked = 0;
1183: }
1184: }
1185: }
1186: } else { /* This case should not happen. */
1187: xfer_good = 0;
1188: }
1189: break;
1190: case XP_DATA_IN:
1191: /*
1192: * If caller's buffer has room, keep incoming
1193: * data byte.
1194: */
1195: if (block_done) {
1196: xfer_good = 0;
1197: PR1("Data in overrun");
1198: } else if (bp->b_req != BREAD) {
1199: xfer_good = 0;
1200: } else {
1201: #if 0
1202: int getbval;
1203:
1204: block_done=1;
1205: PR4("DI");
1206: if(getbval = ss_getb(ss_dat,
1207: #ifdef _I386
1208: bp->b_vaddr + xfer_count)) {
1209: #else
1210: bp->b_faddr + xfer_count)) {
1211: #endif /* _I386 */
1212: xfer_good = 0;
1213: #if (DEBUG >= 1)
1214: printf("getb=%d ", getbval);
1215: #endif
1216: }
1217: #else
1218: block_done=1;
1219: #ifdef _I386
1220:
1221: if (BSIZE != xpcopy(ss_dat, bp->b_paddr + xfer_count,
1222: BSIZE, SEG_386_KD|SEG_VIRT)) {
1223: devmsg(bp->b_dev, "XP_DATA_IN: ss_dat: %x, bp->bpaddr: %x, xfer_count: %x\n",
1224: ss_dat, bp->b_paddr, xfer_count);
1225: break;
1226: }
1227: #else
1228: ffcopy(ss_dat, bp->b_faddr + xfer_count, BSIZE);
1229: #endif /* _I386 */
1230: #endif /* 0 */
1231: }
1232: break;
1233: case XP_DATA_OUT:
1234: /*
1235: * Copy output buffer bytes to data register.
1236: */
1237: if (block_done) {
1238: xfer_good = 0;
1239: PR1("Data out overrun");
1240: } else if (bp->b_req != BWRITE) {
1241: xfer_good = 0;
1242: } else {
1243: #if 0
1244: int putbval;
1245: block_done=1;
1246: PR4("DO");
1247: if (putbval = ss_putb(ss_dat,
1248: #ifdef _I386
1249: bp->b_vaddr + xfer_count)) {
1250: #else
1251: bp->b_faddr + xfer_count)) {
1252: #endif /* _I386 */
1253: xfer_good = 0;
1254: #if (DEBUG >= 1)
1255: printf("putb=%d ", putbval);
1256: #endif
1257: }
1258: #else
1259: block_done=1;
1260: #ifdef _I386
1261: if (BSIZE != pxcopy(bp->b_paddr + xfer_count, ss_dat,
1262: BSIZE, SEG_386_KD|SEG_VIRT)) {
1263: devmsg(bp->b_dev, "XP_DATA_OUT: bp->b_paddr: %x, xfer_count: %x, ss_dat: %x\n",
1264: bp->b_paddr, xfer_count, ss_dat);
1265: break;
1266: }
1267:
1268: #else
1269: ffcopy(bp->b_faddr + xfer_count, ss_dat, BSIZE);
1270: #endif /* _I386 */
1271: #endif
1272: if (irpts_masked) {
1273: spl(s);
1274: irpts_masked = 0;
1275: }
1276: }
1277: break;
1278: default:
1279: break;
1280: } /* endswitch */
1281: }
1282: if (irpts_masked)
1283: spl(s);
1284:
1285: #if (DEBUG >= 1)
1286: switch(ssp->cmdstat) {
1287: case -1:
1288: if (msg_in != MSG_DISCONNECT)
1289: printf("CS-",ssp->cmdstat);
1290: break;
1291: case CS_GOOD:
1292: break;
1293: case CS_CHECK:
1294: printf("CSK",ssp->cmdstat);
1295: break;
1296: case CS_BUSY:
1297: printf("CSY",ssp->cmdstat);
1298: break;
1299: case CS_RESERVED:
1300: default:
1301: printf("CS%x",ssp->cmdstat);
1302: }
1303: #endif
1304:
1305: return (bus_timeout) ? 0 : 1 ;
1306: }
1307:
1308: /*
1309: * req_wait()
1310: *
1311: * This routine is called at the start of each information transfer
1312: * phase and after the last such phase.
1313: *
1314: * It returns 1 if REQ is asserted on the SCSI bus, meaning another phase
1315: * may begin, and 0 otherwise. A REQ signal will not be seen if the function
1316: * times out or if BUSY drops. A value of 1 is written to the pointer argument
1317: * if timeout occurred, else 0 is written.
1318: */
1319: static int req_wait(to_ptr)
1320: int *to_ptr;
1321: {
1322: int req_found;
1323: unsigned char status;
1324: ulong poll_ct;
1325: int s;
1326:
1327: s = splo();
1328: *to_ptr = 1;
1329: req_found = 0;
1330: for (poll_ct = 0L; poll_ct < max_req_poll; poll_ct++) {
1331: status = ffbyte(ss_csr);
1332: if (status & RS_REQUEST) {
1333: req_found = 1;
1334: *to_ptr = 0;
1335: break;
1336: } else if ((status & RS_BUSY) == 0) {
1337: *to_ptr = 0;
1338: break;
1339: }
1340: }
1341:
1342: #if (DEBUG >= 1)
1343: if (*to_ptr) {
1344: printf("TX: s=%x ", status);
1345: }
1346: #endif
1347:
1348: spl(s);
1349: return req_found;
1350: }
1351:
1352: /*
1353: * req_sense()
1354: *
1355: * Request Sense for a device. The main reason for doing this is to
1356: * clear a standing Command Status of Device Check.
1357: *
1358: * Full results are discarded. Return 1 if Device returns No Sense or
1359: * or Unit Attention. Else return 0.
1360: *
1361: */
1362: static int req_sense(s_id)
1363: int s_id;
1364: {
1365: unchar sense_buf[SENSELEN];
1366: unchar cmdbuf[G0CMDLEN];
1367: int ret = 0;
1368:
1369: cmdbuf[0] = ScmdREQUESTSENSE;
1370: cmdbuf[1] = 0;
1371: cmdbuf[2] = 0;
1372: cmdbuf[3] = 0;
1373: cmdbuf[4] = SENSELEN;
1374: cmdbuf[5] = 0;
1375:
1376: #if (DEBUG >= 2)
1377: {int i; for (i=0; i<SENSELEN; i++) sense_buf[i]=0;}
1378: #endif
1379:
1380: PR2("rqs:");
1381: if (!start_arb()) {
1382: PR2("NO arb");
1383: #if (DEBUG >= 2)
1384: printf("status=%x ", ffbyte(ss_csr));
1385: #endif
1386: goto rqs_done;
1387: }
1388:
1389: if (!host_ident(s_id, 0)) {
1390: PR2("NO host ident");
1391: #if (DEBUG >= 2)
1392: printf("status=%x ", ffbyte(ss_csr));
1393: #endif
1394: goto rqs_done;
1395: }
1396:
1397: if(!local_info_xfer(cmdbuf, G0CMDLEN, sense_buf, SENSELEN, NULL, 0)) {
1398: PR2("NO local xfer");
1399: goto rqs_done;
1400: } else {
1401: /*
1402: * Return 1 if drive responded with any of these sense keys:
1403: * 0x00 No Sense
1404: * 0x06 Unit Attention
1405: * 0x0B Aborted Command
1406: * In any of the above cases, a retry will likely succeed
1407: * without Buse Device Reset or SCSI Bus Reset.
1408: */
1409: switch (sense_buf[2]) {
1410: case 0x00:
1411: case 0x06:
1412: case 0x0B:
1413: ret = 1;
1414: break;
1415: } /* endswitch */
1416: }
1417:
1418: rqs_done:
1419: #if (DEBUG >= 2)
1420: {
1421: int i;
1422:
1423: for (i=0; i<SENSELEN;i++)
1424: printf("%x ", sense_buf[i]);
1425: printf("\n");
1426: }
1427: #endif
1428: return ret;
1429: }
1430:
1431: /*
1432: * inquiry()
1433: *
1434: * Inquiry command for a device.
1435: * Find out if device is direct access, removable, etc.
1436: *
1437: * Put result of inquiry into supplied buffer.
1438: * Return 1 if command succeeds, else 0.
1439: */
1440: static int inquiry(s_id, buf)
1441: int s_id;
1442: unchar * buf;
1443: {
1444: int ret = 0;
1445: unchar cmdbuf[G0CMDLEN];
1446:
1447: cmdbuf[0] = ScmdINQUIRY;
1448: cmdbuf[1] = 0;
1449: cmdbuf[2] = 0;
1450: cmdbuf[3] = 0;
1451: cmdbuf[4] = INQUIRYLEN;
1452: cmdbuf[5] = 0;
1453:
1454: if (start_arb() && host_ident(s_id, 0) &&
1455: local_info_xfer(cmdbuf, G0CMDLEN, buf, INQUIRYLEN, NULL, 0))
1456: ret = 1;
1457:
1458: return ret;
1459: }
1460:
1461: /*
1462: * mode_sense()
1463: *
1464: * Mode Sense command for a device.
1465: * Use this to get disk parameters:
1466: * number of cylinders
1467: * number of heads
1468: * number of sectors per track.
1469: *
1470: * Put result of mode sense into supplied buffer.
1471: * Return 1 if command succeeds, else 0.
1472: */
1473: static int mode_sense(s_id, buf)
1474: int s_id;
1475: unchar * buf;
1476: {
1477: int ret = 0;
1478: unchar cmdbuf[G0CMDLEN];
1479:
1480: cmdbuf[0] = ScmdMODESENSE;
1481: cmdbuf[1] = 0;
1482: cmdbuf[2] = 0x3F;
1483: cmdbuf[3] = 0;
1484: cmdbuf[4] = MODESENSELEN;
1485: cmdbuf[5] = 0;
1486:
1487: if (start_arb() && host_ident(s_id, 0) &&
1488: local_info_xfer(cmdbuf, G0CMDLEN, buf, MODESENSELEN, NULL, 0))
1489: ret = 1;
1490:
1491: return ret;
1492: }
1493:
1494: /*
1495: * read_cap()
1496: *
1497: * Read Capacity command for a device.
1498: *
1499: * Return 1 if command succeeds, else 0.
1500: */
1501: static int read_cap(s_id, buf)
1502: int s_id;
1503: unchar * buf;
1504: {
1505: int ret = 0;
1506: unchar cmdbuf[G1CMDLEN];
1507:
1508: cmdbuf[0] = ScmdREADCAPACITY;
1509: cmdbuf[1] = 0;
1510: cmdbuf[2] = 0;
1511: cmdbuf[3] = 0;
1512: cmdbuf[4] = 0;
1513: cmdbuf[5] = 0;
1514: cmdbuf[6] = 0;
1515: cmdbuf[7] = 0;
1516: cmdbuf[8] = 0;
1517: cmdbuf[9] = 0;
1518:
1519: if (start_arb() && host_ident(s_id, 0) &&
1520: local_info_xfer(cmdbuf, G1CMDLEN, buf, READCAPLEN, NULL, 0))
1521: ret = 1;
1522:
1523: return ret;
1524: }
1525:
1526: /*
1527: * bus_dev_reset()
1528: *
1529: * Send Bus Device Reset message to the given SCSI id.
1530: * Return 1 if host adapter was not busy and no obvious timeouts occurred,
1531: * else 0.
1532: */
1533: static int bus_dev_reset(s_id)
1534: {
1535: int bdr_ok = 1;
1536: int dev = ((sscon.c_mind << 8) | 0x80 | (s_id << 4));
1537:
1538: PR1("BDR");
1539: if (bdr_ok) {
1540: /*
1541: * Do ST0x arbitration.
1542: *
1543: * De-assert SCSI enable bit.
1544: * Write my SCSI id to port.
1545: * Start arbitration.
1546: */
1547: sfbyte(ss_csr, WC_ENABLE_PRTY);
1548: sfbyte(ss_dat, host_id);
1549: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ARBITRATE);
1550:
1551: /*
1552: * SCSI spec says there is "no maximum" to the wait for
1553: * arbitration complete.
1554: */
1555: if (!bus_wait(RS_ARBIT_COMPL << 8 | RS_ARBIT_COMPL)) {
1556: bdr_ok = 0;
1557: }
1558: }
1559:
1560: /*
1561: * Arbitration complete. Now select, with ATN to allow messages.
1562: */
1563: if (bdr_ok) {
1564: sfbyte(ss_dat, host_id | (1 << s_id)); /* Write both SCSI id's */
1565: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
1566:
1567: if (!bus_wait(RS_BUSY << 8 | RS_BUSY))
1568: bdr_ok = 0;
1569: }
1570:
1571: if (bdr_ok) {
1572: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION);
1573:
1574: if (!bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
1575: | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE)))
1576: bdr_ok = 0;
1577: }
1578:
1579: if (bdr_ok) {
1580: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
1581: sfbyte(ss_dat, MSG_DEV_RESET);
1582: if (!bus_wait((0xFF << 8) | 0))
1583: bdr_ok = 0;
1584: }
1585:
1586: return bdr_ok;
1587: }
1588:
1589: /*
1590: * chk_reconn()
1591: *
1592: * Check SELECT to see if any SCSI device has tried to reconnect to the host
1593: * adapter. Called if there is an interrupt, and by the timer in case
1594: * we somehow lose an interrupt.
1595: *
1596: * Return -1 if no reselect detected, or the SCSI ID of the reselecting
1597: * target if there is one.
1598: */
1599: static int chk_reconn()
1600: {
1601: unchar csr, dat;
1602: int s_id = -1;
1603:
1604: csr = ffbyte(ss_csr);
1605: if (csr & (RS_SELECT | RS_I_O)) {
1606: dat = ffbyte(ss_dat);
1607: if ((dat & host_id) && (dat & NSDRIVE)) {
1608: dat &= ~host_id;
1609: s_id = 0;
1610: while (dat >>=1)
1611: s_id++;
1612: }
1613: }
1614:
1615: return s_id;
1616: }
1617:
1618: /*
1619: * ss_mach()
1620: *
1621: * Gives a distinct state machine for each target device.
1622: */
1623: void ss_mach(s_id)
1624: int s_id;
1625: {
1626: ss_type * ssp = ss[s_id];
1627: BUF * bp;
1628:
1629: do_sst_op = 1; /* plan to run this routine again in most cases */
1630: while (do_sst_op) {
1631: bp = ssp->bp; /* nonpolled() below can change ssp->bp */
1632: switch (ssp->state) {
1633: /*
1634: * Polling states execute whether ssp->waiting or not.
1635: */
1636: case SST_POLL_ARBITN:
1637: PR3("XPAR");
1638: if (ffbyte(ss_csr) & RS_ARBIT_COMPL) {
1639: ssp->waiting = 0;
1640: if (host_ident(s_id, 1))
1641: do_connect(s_id);
1642: else
1643: recover(s_id, RV_P_TIMEOUT);
1644: } else {
1645: if (ssp->expired) {
1646: ssp->expired = 0;
1647: recover(s_id, RV_A_TIMEOUT);
1648: } else
1649: do_sst_op = 0;
1650: }
1651: break;
1652: case SST_POLL_RESELECT:
1653: PR3("XPRS");
1654: if (TGT_RSEL) {
1655: ssp->waiting = 0;
1656: if (host_claimed == -1)
1657: host_claimed = s_id;
1658: else if (host_claimed != s_id) {
1659: #if (DEBUG >= 1)
1660: printf("%d->%d ", host_claimed, s_id);
1661: #endif
1662: }
1663: if (rsel_handshake()) {
1664: do_connect(s_id);
1665: } else {
1666: recover(s_id, RV_P_TIMEOUT);
1667: }
1668: } else { /* Reselect poll is negative */
1669: if (ssp->expired) {
1670: ssp->expired = 0;
1671: recover(s_id, RV_R_TIMEOUT);
1672: } else
1673: do_sst_op = 0;
1674: }
1675: break;
1676: case SST_POLL_BEGIN_IO:
1677: PR3("XPBI");
1678: if (bp == NULL)
1679: ssp->state = SST_DEQUEUE;
1680: else {
1681: /*
1682: * At this point a SCSI command is about to
1683: * be initiated. It may be a retry.
1684: */
1685: if (host_claimed == -1 && BUS_FREE && BUS_FREE) {
1686: ssp->waiting = 0;
1687: init_pointers(s_id);
1688: if (start_arb()) {
1689: host_claimed = s_id;
1690: if (host_ident(s_id, 1)) {
1691: do_connect(s_id);
1692: } else {
1693: recover(s_id, RV_P_TIMEOUT);
1694: }
1695: } else {
1696: /*
1697: * If arbitration does not succeed right away, it is usually
1698: * because another drive is trying to reselect the host.
1699: */
1700: set_timeout(s_id, DELAY_ARB);
1701: }
1702: } else { /* host busy or bus not free */
1703: int o_id;
1704:
1705: if ((o_id = chk_reconn()) != -1)
1706: defer(dummy_reconn, s_id);
1707: ++ssp->avl_count;
1708: if (ssp->avl_count >= MAX_AVL_COUNT)
1709: recover(s_id, RV_BF_TIMEOUT);
1710: else
1711: set_timeout(s_id, DELAY_BSY);
1712: }
1713: }
1714: break;
1715: default:
1716: if (ssp->waiting)
1717: do_sst_op = 0;
1718: else {
1719: /*
1720: * Nonpolling states execute only if no
1721: * target timer is running.
1722: */
1723: nonpolled(s_id);
1724: }
1725: } /* endswitch */
1726: } /* endwhile */
1727: }
1728:
1729: /*
1730: * nonpolled()
1731: *
1732: * Part of ss_mach() - handling of nonpolling states is taken out simply
1733: * for readability.
1734: */
1735: static void nonpolled(s_id)
1736: int s_id;
1737: {
1738: ss_type * ssp = ss[s_id];
1739: BUF * bp = ssp->bp;
1740: struct fdisk_s *fdp;
1741: int partition;
1742: dev_t dev;
1743:
1744: switch (ssp->state) {
1745: case SST_BUS_DEV_RESET:
1746: PR3("XBDR");
1747: if (bus_dev_reset(s_id)) {
1748: do_sst_op = 0;
1749: set_timeout(s_id, DELAY_BDR);
1750: ssp->state = SST_REQ_SENSE;
1751: } else
1752: recover(s_id, RV_P_TIMEOUT);
1753: break;
1754: case SST_DEQUEUE:
1755: if(bufq_rd_head(s_id) != NULL && !ssp->busy) {
1756: PR3("XDQU");
1757: ssp->busy = 1;
1758: bp = bufq_rm_head(s_id);
1759: ssp->bp = bp;
1760: dev = bp->b_dev;
1761: partition = DEV_PARTN(dev);
1762: if (dev & SDEV)
1763: partition = WHOLE_DRIVE;
1764: fdp = ssp->parmp;
1765: if (partition != WHOLE_DRIVE)
1766: ssp->bno = fdp[partition].p_base + bp->b_bno;
1767: else
1768: ssp->bno = bp->b_bno;
1769: if (bp->b_req == BREAD)
1770: ssp->cmdbuf[0] = ScmdREADEXTENDED;
1771: else
1772: ssp->cmdbuf[0] = ScmdWRITEXTENDED;
1773: ssp->cmdbuf[1] = 0;
1774: ssp->cmdbuf[2] = ssp->bno >> 24;
1775: ssp->cmdbuf[3] = ssp->bno >> 16;
1776: ssp->cmdbuf[4] = ssp->bno >> 8;
1777: ssp->cmdbuf[5] = ssp->bno;
1778: ssp->cmdbuf[6] = 0;
1779: ssp->cmdbuf[7] = 0;
1780: ssp->cmdbuf[8] = 1;
1781: ssp->cmdbuf[9] = 0;
1782: ssp->cmdlen = G1CMDLEN;
1783: init_pointers(s_id);
1784: ssp->bdr_count = 0;
1785: ssp->bsy_count = 0;
1786: ssp->try_count = 0;
1787: ssp->state = SST_POLL_BEGIN_IO;
1788: } else /* queue is empty or ssp->busy */
1789: do_sst_op = 0;
1790: break;
1791: case SST_HIPRI_RESET:
1792: case SST_LOPRI_RESET:
1793: PR1("XRST");
1794: /*
1795: * SST_LOPRI_RESET is same as SST_HIPRI_RESET for now.
1796: * Later, can implement a delay to allow other targets to
1797: * finish pending operations.
1798: */
1799: if (host_claimed == s_id || host_claimed == -1) {
1800: host_claimed = s_id;
1801: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_SCSI_RESET); /* reset ON */
1802: ssp->state = SST_RESET_OFF;
1803: set_timeout(s_id, DELAY_RST);
1804: PR1("+");
1805: } else
1806: set_timeout(s_id, DELAY_RST);
1807: break;
1808: case SST_REQ_SENSE:
1809: PR1("XRQS");
1810: /*
1811: * Come here at end of SCSI Bus reset (and at other times).
1812: * If we have host claimed, release it.
1813: */
1814: if (host_claimed == s_id)
1815: host_claimed = -1;
1816: if (req_sense(s_id))
1817: ssp->state = SST_POLL_BEGIN_IO;
1818: else
1819: recover(s_id, RV_P_TIMEOUT);
1820: break;
1821: case SST_RESET_OFF:
1822: PR3("XRFF");
1823: sfbyte(ss_csr, WC_ENABLE_PRTY); /* reset OFF */
1824: ssp->state = SST_REQ_SENSE;
1825: set_timeout(s_id, DELAY_RST);
1826: } /* endswitch */
1827: }
1828:
1829: /*
1830: * start_arb()
1831: *
1832: * return 1 if host adapter returned Arbitration Complete within allotted
1833: * number of tries, else 0
1834: */
1835: static int start_arb()
1836: {
1837: int ret = 0;
1838: int poll_ct;
1839:
1840: sfbyte(ss_csr, WC_ENABLE_PRTY);
1841: sfbyte(ss_dat, host_id);
1842: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ARBITRATE);
1843:
1844: /*
1845: * SCSI spec says there is "no maximum" to the wait for arbitration
1846: * complete.
1847: */
1848: for (poll_ct = 0; poll_ct < HIPRI_RETRIES; poll_ct++) {
1849: if (ffbyte(ss_csr) & RS_ARBIT_COMPL) {
1850: ret = 1;
1851: break;
1852: } else if (chk_reconn() != -1) {
1853: sfbyte(ss_csr, WC_ENABLE_PRTY);
1854: break;
1855: }
1856: }
1857: #if (DEBUG >= 1)
1858: if (!ret)
1859: PR1("oSA");
1860: #endif
1861: return ret;
1862: }
1863:
1864: /*
1865: * host_ident()
1866: *
1867: * This routine is the bridge in a SCSI bus cycle between Abitration
1868: * Complete and the Information Transfer phases.
1869: *
1870: * return 1 if everything went ok, 0 in case of timeout
1871: */
1872: static int host_ident(s_id, disconnect)
1873: int s_id;
1874: int disconnect;
1875: {
1876: int ret = 0;
1877:
1878: /*
1879: * Arbitration complete. Now select, with ATN to allow messages.
1880: */
1881: sfbyte(ss_dat, host_id | (1 << s_id)); /* Write both SCSI id's */
1882: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION | WC_SELECT);
1883:
1884: if (bus_wait(RS_BUSY << 8 | RS_BUSY)) {
1885: /*
1886: * Assert ATTN so target expects incoming message byte.
1887: */
1888: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ATTENTION);
1889:
1890: if (bus_wait(((RS_REQUEST|RS_CTRL_DATA|RS_I_O|RS_MESSAGE) << 8)
1891: | (RS_REQUEST|RS_CTRL_DATA|RS_MESSAGE))) {
1892: if (disconnect) {
1893: sfbyte(ss_dat, MSG_IDENT_DC);
1894: } else {
1895: sfbyte(ss_dat, MSG_IDENTIFY);
1896: }
1897: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_ENABLE_IRPT);
1898: ret = 1;
1899: } else {
1900: PR1("oHI2");
1901: }
1902: } else {
1903: PR1("oHI1");
1904: }
1905: return ret;
1906: }
1907:
1908: /*
1909: * rsel_handshake()
1910: *
1911: * After Reselect is detected, a couple steps are needed before entering
1912: * Information Transfer phases. This routine does those steps.
1913: *
1914: * return 1 if ok, 0 in case of timeout.
1915: */
1916: static int rsel_handshake()
1917: {
1918: int ret = 0;
1919:
1920: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_BUSY);
1921: if (bus_wait(RS_SELECT << 8 | 0)) {
1922: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
1923: ret = 1;
1924: }
1925: return ret;
1926: }
1927:
1928: /*
1929: * set_timeout()
1930: *
1931: * Start a timer so as not to wait forever in case something goes wrong while
1932: * waiting for an event. Available delays are:
1933: *
1934: * DELAY_ARB - wait for arbitration complete
1935: * DELAY_BDR - allow settling time after Bus Device Reset
1936: * DELAY_BSY - wait for not HOST_BUSY and bus free
1937: * DELAY_RES - wait for reselect by target
1938: * DELAY_RST - allow settling times when doing SCSI Bus Reset
1939: *
1940: * Second argument is number of clock ticks to wait until timer expiration.
1941: */
1942: static void set_timeout(s_id, delay)
1943: int s_id, delay;
1944: {
1945: ss_type * ssp = ss[s_id];
1946:
1947: ssp->expired = 0;
1948: ssp->waiting = 1;
1949: do_sst_op = 0;
1950: timeout(&(ssp->tim), delay, stop_timeout, s_id);
1951: }
1952:
1953: /*
1954: * stop_timeout()
1955: *
1956: * Called on expiration of the timer for a given target.
1957: * Don't expire a timer if it's no longer active.
1958: */
1959: static void stop_timeout(s_id)
1960: int s_id;
1961: {
1962: ss_type * ssp = ss[s_id];
1963:
1964: if (ssp->waiting) {
1965: ssp->expired = 1;
1966: ssp->waiting = 0;
1967: }
1968: ss_mach(s_id);
1969: }
1970:
1971: /*
1972: * init_pointers()
1973: *
1974: * Initialize command and data pointers when starting (or restarting)
1975: * a block i/o command.
1976: */
1977: static void init_pointers(s_id)
1978: int s_id;
1979: {
1980: ss_type * ssp = ss[s_id];
1981: BUF * bp = ssp->bp;
1982:
1983: ssp->cmdstat = -1;
1984: ssp->cmd_bytes_out = 0;
1985: ssp->avl_count = 0;
1986: }
1987:
1988: /*
1989: * recover()
1990: *
1991: * This routine is called directly or indirectly from ss_mach(). It
1992: * determines what to do when the interface fails to behave as desired.
1993: *
1994: * Arguments are the SCSI id of the target HDC and an error type.
1995: * Error types are:
1996: *
1997: * RV_A_TIMEOUT (arbitration timeout)
1998: * Host adapter takes too long to respond with arbitration complete.
1999: *
2000: * RV_P_TIMEOUT (protocol timeout)
2001: * Timeout waiting for desired SCSI bus status while connected to a target.
2002: *
2003: * RV_R_TIMEOUT (reconnect timeout)
2004: * Timeout after target disconnects, waiting for reconnect.
2005: *
2006: * RV_BF_TIMEOUT (bus free timeout)
2007: * Waited too long for host not busy and BUS_FREE.
2008: *
2009: * RV_CS_BUSY (target device busy)
2010: * Command status returned was Busy.
2011: *
2012: * RV_CS_CHECK (target device check)
2013: * Command status returned was CHECK.
2014: *
2015: * Whenever an error occurs, one of the above inputs, together with the SCSI id
2016: * of the target, is sent to the recovery process. The recovery process in turn
2017: * programs the next state for the machine.
2018: */
2019: static void recover(s_id, errtype)
2020: int s_id;
2021: RV_TYPE errtype;
2022: {
2023: ss_type * ssp = ss[s_id];
2024: BUF * bp = ssp->bp;
2025:
2026: #if (DEBUG >= 1)
2027: int foo;
2028: if ((foo=chk_reconn()) != -1)
2029: printf("HONK%d ", foo);
2030: #endif
2031:
2032: ++ssp->try_count;
2033: if (ssp->try_count < MAX_TRY_COUNT) {
2034:
2035: switch (errtype) {
2036:
2037: case RV_CS_BUSY:
2038: ++ssp->bsy_count;
2039: if (ssp->bsy_count < MAX_BSY_COUNT) {
2040: ssp->state = SST_POLL_BEGIN_IO;
2041: set_timeout(s_id, DELAY_BSY);
2042: } else
2043: ssp->state = SST_BUS_DEV_RESET;
2044: break;
2045:
2046: case RV_CS_CHECK:
2047: ssp->state = SST_REQ_SENSE;
2048: break;
2049:
2050: case RV_P_TIMEOUT:
2051: /* fall thru */
2052: case RV_R_TIMEOUT:
2053: ++ssp->bdr_count;
2054: if (ssp->bdr_count < MAX_BDR_COUNT)
2055: ssp->state = SST_BUS_DEV_RESET;
2056: else
2057: ssp->state = SST_LOPRI_RESET;
2058: break;
2059:
2060: case RV_BF_TIMEOUT:
2061: /* fall thru */
2062: case RV_A_TIMEOUT:
2063: ssp->state = SST_HIPRI_RESET;
2064: }
2065: } else { /* try_count >= MAX_TRY_COUNT */
2066: if (bp) {
2067: bp->b_flag |= BFERR;
2068: printf("(%d,%d): ", major(bp->b_dev), minor(bp->b_dev));
2069: printf("%s error bno=%ld\n",
2070: (bp->b_req == BREAD) ? "read" : "write",
2071: bp->b_bno);
2072: }
2073: ss_finished(s_id);
2074: }
2075: }
2076:
2077: /*
2078: * ss_finished
2079: *
2080: * Release current i/o buffer to the O/S.
2081: */
2082: static void ss_finished(s_id)
2083: int s_id;
2084: {
2085: ss_type * ssp = ss[s_id];
2086: BUF * bp = ssp->bp;
2087: int go_again = 1;
2088:
2089: if (host_claimed == s_id)
2090: host_claimed = -1;
2091: ssp->busy = 0;
2092: if (bp) {
2093: if (!(bp->b_flag & BFERR))
2094: bp->b_resid -= BSIZE;
2095: if ((bp->b_flag & BFERR) || bp->b_resid == 0) {
2096: ssp->bp = NULL;
2097: bdone(bp);
2098: go_again = 0;
2099: }
2100: }
2101: if (go_again) {
2102: ssp->state = SST_POLL_BEGIN_IO;
2103: ssp->bdr_count = 0;
2104: ssp->bsy_count = 0;
2105: ssp->try_count = 0;
2106:
2107: ssp->bno++;
2108: ssp->cmdbuf[2] = ssp->bno >> 24;
2109: ssp->cmdbuf[3] = ssp->bno >> 16;
2110: ssp->cmdbuf[4] = ssp->bno >> 8;
2111: ssp->cmdbuf[5] = ssp->bno;
2112: } else {
2113: /*
2114: * After processing a kernel i/o request, stop the
2115: * state machine for the current id. Then start
2116: * this or some other machine which has a request
2117: * pending.
2118: */
2119: do_sst_op = 0;
2120: ssp->state = SST_DEQUEUE;
2121: next_req(s_id);
2122: }
2123: }
2124:
2125: /*
2126: * next_req()
2127: *
2128: * Given the SCSI id where an i/o request just completed, start handling
2129: * another i/o request - which may be for the same or other SCSI id.
2130: * For now, use round-robin scheduling.
2131: */
2132: static void next_req(s_id)
2133: int s_id;
2134: {
2135: int next_id = s_id;
2136:
2137: while (1) {
2138: next_id++;
2139: if (next_id >= MAX_SCSI_ID)
2140: next_id = 0;
2141: if (ss[next_id]
2142: && (ss[next_id]->state != SST_DEQUEUE || bufq_rd_head(next_id))) {
2143: defer(ss_mach, next_id);
2144: break;
2145: }
2146: if (next_id == s_id)
2147: break;
2148: }
2149: }
2150:
2151: /*
2152: * do_connect()
2153: *
2154: * This function is called when the host is successfully connected to
2155: * the target. It invokes information transfer protocol and then sets
2156: * up some sort of recovery unless the command completed successfully
2157: * or there was a normal disconnect.
2158: */
2159: static void do_connect(s_id)
2160: int s_id;
2161: {
2162: int result;
2163: ss_type * ssp = ss[s_id];
2164:
2165: result = far_info_xfer(s_id);
2166: if (!result)
2167: recover(s_id, RV_P_TIMEOUT);
2168: else if (ssp->msg_in == MSG_DISCONNECT) {
2169: ssp->state = SST_POLL_RESELECT;
2170: set_timeout(s_id, DELAY_RES);
2171: #if 0
2172: if (host_claimed == s_id)
2173: host_claimed = -1;
2174: #endif
2175: } else if (ssp->msg_in == MSG_CMD_CMPLT && ssp->cmdstat == CS_GOOD)
2176: ss_finished(s_id);
2177: else if (ssp->cmdstat == CS_BUSY)
2178: recover(s_id, RV_CS_BUSY);
2179: else if (ssp->cmdstat == CS_CHECK)
2180: recover(s_id, RV_CS_CHECK);
2181: else /* something else went wrong */
2182: recover(s_id, RV_P_TIMEOUT);
2183: }
2184:
2185: /*
2186: * local_info_xfer()
2187: *
2188: * Do bus cycle information transfer phases.
2189: * Transfer is for a command which will produce local results in the driver.
2190: * Other ...info_xfer routine handles kernel block i/o commands.
2191: *
2192: * Return 1 if transfer succeeded, else 0.
2193: *
2194: */
2195: static int local_info_xfer(cmdbuf, cmdlen, inbuf, inlen, outbuf, outlen)
2196: unchar * cmdbuf, * inbuf, * outbuf;
2197: uint cmdlen, inlen, outlen;
2198: {
2199: int bus_timeout;
2200: unchar phase_type;
2201: int s;
2202: int cmd_bytes_out = 0;
2203: int data_bytes_in = 0;
2204: int data_bytes_out = 0;
2205: int ret = 0;
2206: int xfer_good = 1;
2207: int cmdstat = -1;
2208: int msg_in = -1;
2209: #if (DEBUG >= 1)
2210: int x, xct=0;
2211: unchar xch[100];
2212: #endif
2213:
2214: s = sphi();
2215: while (req_wait(&bus_timeout) && xfer_good) {
2216: phase_type = ffbyte(ss_csr) & (RS_MESSAGE|RS_I_O|RS_CTRL_DATA);
2217: #if (DEBUG >= 1)
2218: if (xct < 100)
2219: xch[xct++]=phase_type;
2220: #endif
2221: switch (xpmod(phase_type)) {
2222: case XP_MSG_IN:
2223: msg_in = ffbyte(ss_dat);
2224: switch(msg_in){
2225: case MSG_CMD_CMPLT:
2226: case MSG_DISCONNECT:
2227: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_IRPT);
2228: break;
2229: }
2230: break;
2231: case XP_MSG_OUT:
2232: /*
2233: * This case shouldn't happen. We weren't
2234: * asserting ATTENTION.
2235: */
2236: sfbyte(ss_dat, MSG_NOP);
2237: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI);
2238: break;
2239: case XP_STAT_IN:
2240: cmdstat = ffbyte(ss_dat);
2241: break;
2242: case XP_CMD_OUT:
2243: /*
2244: * Ship out command bytes.
2245: */
2246: if (cmd_bytes_out < cmdlen) {
2247: sfbyte(ss_dat, cmdbuf[cmd_bytes_out++]);
2248: #if 1
2249: /*
2250: * If just sent last byte, allow interrupts.
2251: */
2252: if (cmd_bytes_out == cmdlen) {
2253: spl(s);
2254: s = sphi();
2255: }
2256: #endif
2257: } else { /* This case should not happen. */
2258: xfer_good = 0;
2259: }
2260: break;
2261: case XP_DATA_IN:
2262: /*
2263: * If caller's buffer has room, keep incoming
2264: * data byte. Else toss it.
2265: */
2266: if (data_bytes_in < inlen) {
2267: #if 0
2268: do {
2269: inbuf[data_bytes_in++] = ffbyte(ss_dat);
2270: } while (data_bytes_in < inlen);
2271: #else
2272: inbuf[data_bytes_in++] = ffbyte(ss_dat);
2273: #endif
2274: } else
2275: xfer_good = 0;
2276: break;
2277: case XP_DATA_OUT:
2278: /*
2279: * Copy output buffer bytes to data register.
2280: */
2281: if (data_bytes_out < outlen) {
2282: sfbyte(outbuf[data_bytes_out++], ss_dat);
2283: } else { /* This case should not happen. */
2284: xfer_good = 0;
2285: }
2286: break;
2287: default:
2288: break;
2289: } /* endswitch */
2290: }
2291: spl(s);
2292:
2293: if (bus_timeout) {
2294: PR1("oLX1");
2295: } else if (!xfer_good) {
2296: PR1("oLX2");
2297: } else if (cmdstat != CS_GOOD) {
2298: PR1("oLX3");
2299: #if (DEBUG >= 1)
2300: printf("cmdstat=%x ", cmdstat);
2301: #endif
2302: } else
2303: ret = 1;
2304: #if (DEBUG >= 1)
2305: if (!ret) {
2306: printf("csr=%x ", ffbyte(ss_csr));
2307: printf("xct=%d ", xct);
2308: for (x=0; x < xct; x++)
2309: printf("%x ", xch[x]);
2310: }
2311: #endif
2312:
2313: return ret;
2314: }
2315:
2316: /*
2317: * scsireset()
2318: *
2319: * Reset the SCSI bus.
2320: * Allow settling time when turning reset on/off.
2321: * Settling times were determined empirically.
2322: * Each tick is 10 msec.
2323: */
2324: static void scsireset()
2325: {
2326: int s;
2327:
2328: #if (DEBUG >= 1)
2329: printf("scsireset ");
2330: #endif
2331: s = splo();
2332: sfbyte(ss_csr, WC_ENABLE_PRTY | WC_ENABLE_SCSI | WC_SCSI_RESET);
2333: ssdelay(RESET_TICKS);
2334: sfbyte(ss_csr, WC_ENABLE_PRTY);
2335: ssdelay(RESET_TICKS);
2336: spl(s);
2337: }
2338:
2339: /*
2340: * ssdelay()
2341: *
2342: * Delay for some number of arbitrary ticks.
2343: *
2344: * Using sleep() causes a panic if this driver is linked to the kernel,
2345: * even though this routine is called only via ssload().
2346: */
2347: static void ssdelay(ticks)
2348: int ticks;
2349: {
2350: #if 0
2351: timeout(&delay_tim, ticks, wakeup, (int)&delay_tim);
2352: sleep((char *)&delay_tim, CVPAUSE, IVPAUSE, SVPAUSE);
2353: #else
2354: int i, j;
2355:
2356: for (i = 0; i < ticks; i++)
2357: for (j = 0; j < LOAD_DELAY; j++);
2358: #endif
2359: }
2360:
2361: /*
2362: * init_call()
2363: *
2364: * Call SCSI command function during initialization, with error recovery.
2365: * If the simple command fails, try a Bus Device Reset, then SCSI Bus reset.
2366: */
2367: static int init_call(fn, s_id, buf)
2368: int (*fn)();
2369: int s_id;
2370: unchar * buf;
2371: {
2372: int ret = 1;
2373: int i;
2374: int o_id;
2375: int s;
2376: s=sphi();
2377: for (i = 0; i < 2; i++) {
2378: o_id = chk_reconn();
2379: if (o_id != -1)
2380: dummy_reconn(s_id);
2381: if ((*fn)(s_id, buf))
2382: goto init_call_done;
2383:
2384: req_sense(s_id);
2385: if ((*fn)(s_id, buf))
2386: goto init_call_done;
2387:
2388: if (bus_dev_reset(s_id)) {
2389: ssdelay(RESET_TICKS);
2390: req_sense(s_id);
2391: if ((*fn)(s_id, buf))
2392: goto init_call_done;
2393: }
2394:
2395: scsireset();
2396: req_sense(s_id);
2397: if ((*fn)(s_id, buf))
2398: goto init_call_done;
2399: }
2400:
2401: ret = 0;
2402:
2403: init_call_done:
2404: spl(s);
2405: return ret;
2406: }
2407:
2408: /*
2409: * xpmod()
2410: *
2411: * Command/Data and Message bits are swapped on-board (outside the chip)
2412: * on older Future Domain host boards.
2413: */
2414: static unchar xpmod(oldphase)
2415: unchar oldphase;
2416: {
2417: unchar ret = oldphase;
2418:
2419: if (swap_status_bits) {
2420: ret &= ~(RS_CTRL_DATA | RS_MESSAGE);
2421: if (oldphase & RS_MESSAGE)
2422: ret |= RS_CTRL_DATA;
2423: if (oldphase & RS_CTRL_DATA)
2424: ret |= RS_MESSAGE;
2425: }
2426: return ret;
2427: }
2428:
2429: /*
2430: * tbparms()
2431: *
2432: * If the drive table has already been patched for this SCSI id, do nothing.
2433: * Otherwise, given the real-mode drive number (tbnum) and the SCSI id (s_id),
2434: * look for drive parameters from tertiary boot, and copy into driver
2435: * data block if we find them.
2436: */
2437: static void tbparms(tbnum, s_id)
2438: int tbnum, s_id;
2439: {
2440: FIFO *ffp;
2441: typed_space *tp;
2442: extern typed_space boot_gift;
2443:
2444: if (drv_parm[s_id].ncyl == 0
2445: && F_NULL != (ffp = fifo_open(&boot_gift, 0))) {
2446:
2447: if (tp = fifo_read(ffp)) {
2448: BIOS_DISK *bdp = (BIOS_DISK *)tp->ts_data;
2449: if ((T_BIOS_DISK == tp->ts_type) &&
2450: (tbnum == bdp->dp_drive) ) {
2451: drv_parm[s_id].ncyl = bdp->dp_cylinders;
2452: drv_parm[s_id].nhead = bdp->dp_heads;
2453: drv_parm[s_id].nspt = bdp->dp_sectors;
2454: }
2455: }
2456: fifo_close(ffp);
2457: }
2458: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.