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