|
|
1.1 root 1: /*
2: ** Stand alone driver for the VDDC controller
3: ** TAHOE Version, Oct 1983.
4: **
5: */
6:
7: #include "../machine/mtpr.h"
8: #include "../h/param.h"
9: #include "../h/inode.h"
10: #include "../h/fs.h"
11: #define VDGENDATA 1
12: #include "../vba/vddc.h"
13: #undef VDGENDATA
14: #include "../stand/saio.h"
15:
16: #define NVD 4 /* Max number of controllers */
17:
18: #define TRUE 1
19: #define FALSE 0
20: #define VDUNIT(x) (minor(x) & 0x3)
21: #define VDCTLR(x) (minor(x) >> 2)
22:
23: /*
24: ** MDCB
25: */
26:
27: fmt_mdcb mdcb;
28:
29: /*
30: ** DCB
31: */
32:
33: fmt_dcb dcb;
34:
35: /*
36: ** Unit specific information.
37: */
38:
39: struct {
40: char configured;
41: fs_tab info;
42: }unit_info[NVD][16];
43:
44: /*
45: ** Controller specific information.
46: */
47:
48: struct {
49: unsigned char ctlr_type;
50: char *ctlr_name;
51: unsigned char initialized;
52: unsigned char ctlr_started;
53: } ctlr_info[NVD];
54:
55: static char junk[1024];
56:
57:
58: /*
59: **
60: */
61:
62: vdopen(io)
63: register struct iob *io;
64: {
65: register int ctlr = VDCTLR(io->i_unit);
66: register int unit = VDUNIT(io->i_unit);
67: register int i, j;
68:
69: /* Make sure controller number is in range */
70: if(ctlr >= NVD) {
71: printf("vd%d: Unit number can't be greater than %x!\n",
72: io->i_unit, (NVD * 4) - 1);
73: _stop("");
74: }
75: /* check file system for validity */
76: if((io->i_boff < 0) || (io->i_boff > 5)) {
77: printf("vd%d: File system #%d, should be less than #6.\n",
78: io->i_unit, io->i_boff);
79: _stop("");
80: }
81: if(!ctlr_info[ctlr].initialized) {
82: vdinit(io); /* initialize controller/drive */
83: ctlr_info[ctlr].initialized = TRUE;
84: for(i=0; i<NVD; i++)
85: for(j=0; j<16; j++)
86: unit_info[i][j].configured = FALSE;
87: }
88: if(!unit_info[ctlr][unit].configured) {
89: vdconfigure_drive(io);
90: unit_info[ctlr][unit].configured = TRUE;
91: }
92: io->i_boff = unit_info[ctlr][unit].info.partition[io->i_boff].par_start;
93: }
94:
95:
96: /*
97: **
98: */
99:
100: vdinit(io)
101: register struct iob *io;
102: {
103: register int ctlr = VDCTLR(io->i_unit);
104: register int unit = VDUNIT(io->i_unit);
105: register cdr *ctlr_addr = (cdr *)(vddcaddr[ctlr]+IOBASE);
106: register char *ctlr_type;
107:
108: /* Check to see if controller is really there */
109: if(badaddr(ctlr_addr, 2)) {
110: printf("vd%d: Controller %d is non-existant!\n",
111: io->i_unit, ctlr);
112: _stop("");
113: }
114: /* Probe further to find what kind of controller it is */
115: ctlr_addr->cdr_reset = 0xffffffff;
116: DELAY(1000000);
117: /* Probe further to find what kind of controller it is */
118: if(ctlr_addr->cdr_reset != 0xffffffff) {
119: ctlr_info[ctlr].ctlr_type = SMDCTLR;
120: ctlr_info[ctlr].ctlr_name = "SMD";
121: DELAY(1000000);
122: }
123: else {
124: ctlr_info[ctlr].ctlr_type = SMD_ECTLR;
125: ctlr_info[ctlr].ctlr_name = "SMD/E";
126: ctlr_addr->cdr_reserved = 0x0;
127: DELAY(3000000);
128: }
129: if(ctlr_info[ctlr].ctlr_type == SMD_ECTLR) {
130: ctlr_addr->cdr_csr = 0;
131: ctlr_addr->mdcb_tcf = AM_ENPDA;
132: ctlr_addr->dcb_tcf = AM_ENPDA;
133: ctlr_addr->trail_tcf = AM_ENPDA;
134: ctlr_addr->data_tcf = AM_ENPDA;
135: ctlr_addr->cdr_ccf = CCF_STS | XMD_32BIT | BSZ_16WRD |
136: CCF_ENP | CCF_EPE /* | CCF_EDE */ | CCF_ECE | CCF_ERR;
137: }
138: if(vdaccess_with_no_trailer(io, INIT, 8) & HRDERR) {
139: vdprint_error(io->i_unit, "Initialization error",
140: dcb.operrsta,dcb.err_code);
141: _stop("");
142: }
143: if(vdaccess_with_no_trailer(io, DIAG, 8) & HRDERR) {
144: vdprint_error(io->i_unit, "Diagnostic error",
145: dcb.operrsta, dcb.err_code);
146: _stop("");
147: }
148: }
149:
150:
151: /*
152: **
153: */
154:
155: vdconfigure_drive(io)
156: register struct iob *io;
157: {
158: register int ctlr = VDCTLR(io->i_unit);
159: register int unit = VDUNIT(io->i_unit);
160: register fs_tab *file_sys;
161: dskadr daddr;
162: register int i;
163:
164: for(i=0; i < nvddrv; i++) {
165: unit_info[ctlr][unit].info = vdst[i];
166: if(ctlr_info[ctlr].ctlr_type == SMDCTLR)
167: if(unit_info[ctlr][unit].info.nsec != 32)
168: continue;
169: vdconfigure(io, 0);
170: daddr.cylinder = unit_info[ctlr][unit].info.ncyl - 2;
171: daddr.track = unit_info[ctlr][unit].info.ntrak - 1;
172: daddr.sector = unit_info[ctlr][unit].info.nsec - 1;
173: io->i_ma = junk;
174: io->i_cc = unit_info[ctlr][unit].info.secsize;
175: if(!(vdaccess(io, &daddr, RD) & HRDERR))
176: return;
177: }
178: printf("vd%d: Unrecognizable drive; controller %d, unit %d!\n",
179: io->i_unit, ctlr, unit);
180: _stop("");
181: }
182:
183:
184: /*
185: **
186: */
187:
188: vdstart_drive(io)
189: register struct iob *io;
190: {
191: register int ctlr = VDCTLR(io->i_unit);
192: register int unit = VDUNIT(io->i_unit);
193: register int io_unit_save = io->i_unit;
194:
195: if(ctlr_info[ctlr].ctlr_started) {
196: DELAY(5500000);
197: return TRUE;
198: }
199: io->i_unit &= ~3;
200: if(vdaccess_with_no_trailer(io, VDSTART, ((unit * 6) + 62)) & HRDERR) {
201: vdprint_error(io->i_unit, "Start error",
202: dcb.operrsta, dcb.err_code);
203: _stop("");
204: }
205: ctlr_info[ctlr].ctlr_started = TRUE;
206: io->i_unit = io_unit_save;
207: DELAY((unit * 5500000) + 62000000);
208: return TRUE;
209: }
210:
211:
212: /*
213: ** This routine actually configures a particular drive.
214: **
215: ** If the controller is an SMD/E controller then the number of sectors per
216: ** track is loaded into the appropriate register, otherwise it is left
217: ** alone because the old SMD controller requires a constant 32 sectors
218: ** per track for it's drives. (an error would be returned if the value is
219: ** loaded.)
220: **
221: ** In the stand-alone spirit of things the system is halted if an error
222: ** occurs during this operation.
223: */
224:
225: vdconfigure(io, pass)
226: register struct iob *io;
227: int pass;
228: {
229: register int ctlr = VDCTLR(io->i_unit);
230: register int unit = VDUNIT(io->i_unit);
231: register cdr *ctlr_addr = (cdr *)(vddcaddr[ctlr]+IOBASE);
232:
233: dcb.opcode = RSTCFG; /* command */
234: dcb.intflg = NOINT;
235: dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */
236: dcb.operrsta = 0;
237: dcb.devselect = (char)unit;
238: dcb.trail.rstrail.ncyl = unit_info[ctlr][unit].info.ncyl;
239: dcb.trail.rstrail.nsurfaces = unit_info[ctlr][unit].info.ntrak;
240: if(ctlr_info[ctlr].ctlr_type == SMD_ECTLR) {
241: dcb.trailcnt = (char)4;
242: dcb.trail.rstrail.nsectors = unit_info[ctlr][unit].info.nsec;
243: dcb.trail.rstrail.slip_sec = unit_info[ctlr][unit].info.nslip;
244: }
245: else
246: dcb.trailcnt = (char)2;
247: mdcb.firstdcb = &dcb;
248: mdcb.vddcstat = 0;
249: VDDC_ATTENTION(ctlr_addr, &mdcb, ctlr_info[ctlr].ctlr_type);
250: POLLTILLDONE(ctlr_addr,&dcb,5,ctlr_info[ctlr].ctlr_type);
251: if(vdtimeout <= 0)
252: _stop(" during drive configuration.\n");
253: if(dcb.operrsta & (NOTCYLERR | DRVNRDY))
254: if(!pass) {
255: vdstart_drive(io);
256: vdconfigure(io, 1);
257: }
258: if(dcb.operrsta & HRDERR) {
259: vdprint_error(io->i_unit, "Configuration error",
260: dcb.operrsta, dcb.err_code);
261: _stop("");
262: }
263: }
264:
265:
266: /*
267: ** Strategy is called to the actual I/O to the disk drives.
268: **
269: ** Some simple checks are made to make sure we don't do anything rediculus,
270: ** If everything is sane then the request is issued.
271: **
272: ** If no errors occured then the original byte count is returned,
273: ** otherwise -1 is returned to indicate an error occured.
274: */
275:
276: vdstrategy(io, func)
277: register struct iob *io;
278: register int func;
279: {
280: dskadr daddr;
281: register int ctlr = VDCTLR(io->i_unit);
282: register int unit = VDUNIT(io->i_unit);
283: register fs_tab *u_info = &unit_info[ctlr][unit].info;
284: register int op = (func == READ) ? RD : WD;
285: register int blk;
286:
287: if(io->i_cc == 0)
288: _stop("vd: Can't transfer zero length records!\n");
289: if(io->i_cc > 0xffff)
290: _stop("vd: Can't transfer greater than 2 to the 16th bytes!\n");
291: blk = io->i_bn * DEV_BSIZE / u_info->secsize;
292: daddr.sector = blk % u_info->nsec;
293: daddr.track = (blk / u_info->nsec) % u_info->ntrak;
294: daddr.cylinder = (blk/u_info->nsec) / u_info->ntrak;
295: if(vdaccess(io, &daddr, op) & HRDERR) {
296: vdprint_error(io->i_unit,"I/O error",dcb.operrsta,dcb.err_code);
297: return(-1);
298: }
299: mtpr(0,PADC);
300: return(io->i_cc);
301: }
302:
303:
304:
305: /*
306: **
307: */
308:
309: vdprint_error(unit, str, status, smde_status)
310: int unit;
311: char *str;
312: unsigned long status;
313: unsigned long smde_status;
314: {
315: printf("vd%d: %s; ", unit, str);
316: if(status & DRVNRDY)
317: printf("Drive is not ready");
318: else if(status & INVDADR)
319: printf("Invalid disk address issued");
320: else if(status & DNEMEM)
321: printf("Non-existent memory error");
322: else if(status & PARERR)
323: printf("Main memory parity error");
324: else if(status & OPABRT)
325: printf("Program aborted operation");
326: else if(status & WPTERR)
327: printf("Drive is write protected");
328: else if(status & DSEEKERR)
329: printf("Disk seek error");
330: else if(status & UCDATERR)
331: printf("Uncorrectable data error");
332: else if(status & CTLRERR)
333: printf("Controller faulted");
334: else if(status & NOTCYLERR)
335: printf("Not on cylinder error");
336: else if(status & INVCMD)
337: printf("Invalid command issued to controller");
338: else
339: printf("Controller error");
340: printf("! Status = 0x%x", status);
341: if(smde_status)
342: printf(" Error code = %x", smde_status);
343: printf("\n");
344: }
345:
346:
347: /*
348: **
349: */
350:
351: vdaccess_with_no_trailer(io, function, time)
352: register struct iob *io;
353: register int function, time;
354: {
355: register int ctlr = VDCTLR(io->i_unit);
356: register cdr *ctlr_addr = (cdr *)(vddcaddr[ctlr]+IOBASE);
357:
358: dcb.opcode = function; /* command */
359: dcb.intflg = NOINT;
360: dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */
361: dcb.operrsta = 0;
362: dcb.devselect = (char)VDUNIT(io->i_unit);
363: dcb.trailcnt = (char)0;
364: mdcb.firstdcb = &dcb;
365: mdcb.vddcstat = 0;
366: VDDC_ATTENTION(ctlr_addr, &mdcb, ctlr_info[ctlr].ctlr_type);
367: POLLTILLDONE(ctlr_addr,&dcb,time,ctlr_info[ctlr].ctlr_type);
368: if(vdtimeout <= 0)
369: _stop(" during initialization operation.\n");
370: return dcb.operrsta;
371: }
372:
373:
374: /*
375: **
376: */
377:
378: vdaccess(io, daddr, func)
379: register struct iob *io;
380: dskadr *daddr;
381: int func;
382: {
383: register int ctlr = VDCTLR(io->i_unit);
384: register cdr *ctlr_addr = (cdr *)(vddcaddr[ctlr]+IOBASE);
385:
386: dcb.opcode = (short)func; /* format sector command */
387: dcb.intflg = NOINT;
388: dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */
389: dcb.operrsta = 0;
390: dcb.devselect = (char)VDUNIT(io->i_unit);
391: dcb.trailcnt = (char)(sizeof(trrw) / 4);
392: dcb.trail.rwtrail.memadr = io->i_ma;
393: dcb.trail.rwtrail.wcount = ((io->i_cc + 1) / sizeof(short));
394: dcb.trail.rwtrail.disk.cylinder = daddr->cylinder;
395: dcb.trail.rwtrail.disk.track = daddr->track;
396: dcb.trail.rwtrail.disk.sector = daddr->sector;
397: mdcb.firstdcb = &dcb;
398: mdcb.vddcstat = 0;
399: VDDC_ATTENTION(ctlr_addr, &mdcb, ctlr_info[ctlr].ctlr_type);
400: POLLTILLDONE(ctlr_addr, &dcb, 60, ctlr_info[ctlr].ctlr_type);
401: if(vdtimeout <= 0)
402: _stop(" during I/O operation.\n");
403: return dcb.operrsta;
404: }
405:
406: /*
407: ** Print_dcb() dumps the MDCB and DCB for diagnostic purposes. This
408: ** routine is called whenever a fatal error is encountered.
409: */
410:
411: vdprintdcb(ptr)
412: register long *ptr;
413: {
414: register long i;
415: register long trailer_count;
416:
417: printf("Dump of MDCB: ");
418: for(i=0; i<4; i++)
419: printf(" %lx", *(ptr+i));
420: if(ptr = (long *)*ptr) {
421: printf(" and DCB:");
422: trailer_count = *(ptr+3) & 0xff;
423: for(i=0; i<7+trailer_count; i++) {
424: uncache(ptr+i);
425: printf(" %lx", *(ptr+i));
426: }
427: }
428: printf("\n");
429: for(i=0; i<5000000; i++) ;
430: }
431:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.