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