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