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