|
|
1.1 root 1: /*
2: * Copyright (c) 1988 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Harris Corp.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that the above copyright notice and this paragraph are
10: * duplicated in all such forms and that any documentation,
11: * advertising materials, and other materials related to such
12: * distribution and use acknowledge that the software was developed
13: * by the University of California, Berkeley. The name of the
14: * University may not be used to endorse or promote products derived
15: * from this software without specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: *
20: * @(#)hd.c 7.6 (Berkeley) 5/1/89
21: */
22:
23: #include "param.h"
24: #include "inode.h"
25: #include "fs.h"
26: #include "buf.h"
27: #include "ioctl.h"
28: #include "disklabel.h"
29: #include "saio.h"
30: #include "../tahoe/mtpr.h"
31: #include "../tahoevba/hdreg.h"
32:
33: static struct registers *hdc_regs[HDC_MAXCTLR][HDC_MAXBUS];
34: static struct disklabel dklabel[HDC_MAXDRIVE][HDC_MAXCTLR][HDC_MAXBUS];
35:
36: hdopen(io)
37: register struct iob *io;
38: {
39: register struct disklabel *dlp;
40: struct status status;
41: struct module_id id;
42: struct registers *hr;
43: struct mcb mcb;
44: long junk, dlbuf[DEV_BSIZE/sizeof(long)];
45:
46: /* validate the device specification */
47: if ((u_int)io->i_bus >= HDC_MAXBUS)
48: return(EADAPT);
49: if ((u_int)io->i_ctlr >= HDC_MAXCTLR)
50: return(ECTLR);
51: if ((u_int)io->i_unit >= HDC_MAXDRIVE)
52: return(EUNIT);
53: if ((u_int)io->i_part > 7)
54: return(EPART);
55:
56: /* init drive structure. */
57: hdc_regs[io->i_ctlr][io->i_bus] = hr = (struct registers *)(io->i_bus ?
58: 0x80000000 | io->i_ctlr << 24 | HDC_MID << 16 :
59: 0xC0000000 | io->i_ctlr << 24 | HDC_MID << 16);
60:
61: /* insure that this is an hdc, then reset the hdc. */
62: if (wbadaddr(&hr->module_id, 4, &junk)) {
63: printf("hd%d: %x: invalid csr\n", io->i_ctlr, (u_int)hr);
64: return(ENXIO);
65: }
66: hr->soft_reset = 0;
67: DELAY(1000000);
68:
69: /*
70: * read in the hdc module id word. The controller is bad if the
71: * hdc's writeable control store is not loaded or if the hdc failed
72: * the functional integrity test for any reason.
73: */
74: hr->module_id = (u_long)&id;
75: DELAY(10000);
76: mtpr(PADC, 0);
77: if (id.module_id != (u_char)HDC_MID) {
78: printf("hdc: controller bad module id: id = %x\n",
79: id.module_id);
80: return(ENXIO);
81: }
82: if (id.code_rev == (u_char)0xff) {
83: printf("hdc: controller micro-code is not loaded.\n");
84: return(ENXIO);
85: }
86: if (id.fit != (u_char)0xff) {
87: printf("hdc: controller FIT test failed: error= %x\n",
88: id.fit);
89: return(ENXIO);
90: }
91:
92: /* read the drive status */
93: mcb.command = HCMD_STATUS;
94: mcb.drive = io->i_unit;
95: mcb.cyl = 0;
96: mcb.head = 0;
97: mcb.sector = 0;
98: mcb.chain[0].wcount = (long)(sizeof(struct status) / sizeof(long));
99: mcb.chain[0].memadr = (long)&status;
100: if (hdimcb(&mcb, io))
101: return(EIO);
102:
103: /*
104: * Report drive down if anything in the drive status is bad.
105: * If fault condition, reading will try to clear the fault.
106: */
107: if (status.drs&DRS_FAULT)
108: printf("hdc: clearing drive fault.\n");
109: if (!(status.drs&DRS_ONLINE)) {
110: printf("hdc: drive is not online.\n");
111: return(EIO);
112: }
113:
114: /* read in the pack label */
115: mcb.command = HCMD_READ;
116: mcb.drive = io->i_unit;
117: mcb.cyl = 0;
118: mcb.head = 0;
119: mcb.sector = LABELSECTOR;
120: mcb.chain[0].wcount = (long)(DEV_BSIZE / sizeof(long));
121: mcb.chain[0].memadr = (long)dlbuf;
122: if (hdimcb(&mcb, io))
123: return(ERDLAB);
124: dlp = (struct disklabel *)(dlbuf + (LABELOFFSET / sizeof(long)));
125: if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC)
126: #ifdef COMPAT_42
127: {
128: int error;
129:
130: if (error = hdmaptype(io, dlp, &status, io->i_unit))
131: return(error);
132: }
133: #else
134: return(EUNLAB);
135: #endif
136: dklabel[io->i_unit][io->i_ctlr][io->i_bus] = *dlp;
137: if (io->i_part >= dlp->d_npartitions ||
138: dlp->d_partitions[io->i_part].p_size == 0)
139: return(EPART);
140: io->i_boff = (dlp->d_partitions[io->i_part].p_offset *
141: dlp->d_secsize) / DEV_BSIZE;
142: return(0);
143: }
144:
145: hdstrategy(io, cmd)
146: register struct iob *io;
147: int cmd;
148: {
149: register struct disklabel *dlp;
150: struct mcb mcb;
151: long sector;
152:
153: if (io->i_cc&3) {
154: printf("hd%d: i/o not a longword multiple.\n", io->i_unit);
155: return(0);
156: }
157: dlp = &dklabel[io->i_unit][io->i_ctlr][io->i_bus];
158: sector = io->i_bn * HDC_SPB;
159: mcb.command = (cmd == READ) ? HCMD_READ : HCMD_WRITE;
160: mcb.drive = io->i_unit;
161: mcb.cyl = sector / dlp->d_secpercyl;
162: mcb.head = (sector / dlp->d_nsectors) % dlp->d_ntracks;
163: mcb.sector = sector % dlp->d_nsectors;
164: mcb.chain[0].wcount = io->i_cc / sizeof(long);
165: mcb.chain[0].memadr = (u_long)io->i_ma;
166: return(hdimcb(&mcb, io) ? -1 : io->i_cc);
167: }
168:
169: hdimcb(mcb, io)
170: register struct mcb *mcb;
171: register struct iob *io;
172: {
173: struct master_mcb master;
174: int timeout;
175:
176: /* fill in mcb */
177: mcb->interrupt = 0;
178: mcb->forw_phaddr = 0;
179:
180: /* fill in master mcb */
181: master.mcw = MCL_IMMEDIATE;
182: master.forw_phaddr = (u_long)mcb;
183: master.mcs = 0;
184:
185: hdc_regs[io->i_ctlr][io->i_bus]->master_mcb = (u_long)&master;
186: for (timeout = 15000; timeout; --timeout) {
187: DELAY(1000);
188: mtpr(PADC, 0);
189: if (master.mcs&MCS_FATALERROR) {
190: printf("hdc%d: fatal error.\n", io->i_ctlr);
191: return(1);
192: }
193: if (master.mcs&MCS_DONE)
194: return(0);
195: }
196: printf("hdc%d: timed out.\n", io->i_ctlr);
197: return(1);
198: }
199:
200: #ifdef COMPAT_42
201: hdmaptype(io, dlp, status, unit)
202: register struct iob *io;
203: register struct disklabel *dlp;
204: struct status *status;
205: int unit;
206: {
207: geometry_sector geometry;
208: geometry_block *geo;
209: struct mcb mcb;
210: int cnt;
211: char *strcpy();
212:
213: printf("hd%d: unlabeled\n", unit);
214: /*
215: * Read the geometry block (at head = 0 sector = 0 of the drive
216: * definition cylinder), validate it (must have the correct version
217: * number, header, and checksum).
218: */
219: mcb.command = HCMD_READ;
220: mcb.drive = unit;
221: mcb.cyl = status->def_cyl;
222: mcb.head = 0;
223: mcb.sector = 0;
224: mcb.chain[0].wcount = (long)(sizeof(geometry_sector) / sizeof(long));
225: mcb.chain[0].memadr = (long)&geometry;
226: if (hdimcb(&mcb, io)) {
227: printf("hd%d: can't read default geometry.\n", io->i_unit);
228: return(ERDLAB);
229: }
230: geo = &geometry.geometry_block;
231: if (geo->version > 64000 || geo->version < 0) {
232: printf("hd%d: bad default geometry version#.\n", io->i_unit);
233: return(ENXIO);
234: }
235: if (strcmp(&geo->id[0], GB_ID)) {
236: printf("hd%d: bad default geometry header.\n", io->i_unit);
237: return(ENXIO);
238: }
239: GB_CHECKSUM(geo, cnt);
240: if (geometry.checksum != cnt) {
241: printf("hd%d: bad default geometry checksum.\n", io->i_unit);
242: return(ENXIO);
243: }
244: for (cnt = 0; cnt < GB_MAXPART; cnt++) {
245: dlp->d_partitions[cnt].p_offset = geo->partition[cnt].start;
246: dlp->d_partitions[cnt].p_size = geo->partition[cnt].length;
247: }
248: #ifdef RAW_SIZE
249: dlp->d_secsize = status->bytes_per_sec;
250: #else
251: dlp->d_secsize = 512;
252: #endif
253: dlp->d_nsectors = status->max_sector + 1;
254: dlp->d_ncylinders = status->max_cyl + 1;
255: dlp->d_ntracks = status->max_head + 1;
256: dlp->d_secpercyl = dlp->d_ntracks * dlp->d_nsectors;
257: dlp->d_npartitions = GB_MAXPART;
258: dlp->d_rpm = status->rpm;
259: (void)strcpy(dlp->d_typename, "hdc (prom)");
260: return(0);
261: }
262: #endif /* COMPAT_42 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.