mv pcs750.bin to /usr/src/etc/vax
[unix-history] / usr / src / sys / vax / stand / hp.c
CommitLineData
8ae0e4b4 1/*
39c71180 2 * Copyright (c) 1982, 1986 Regents of the University of California.
8ae0e4b4
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
ae64a1dd 6 * @(#)hp.c 7.10 (Berkeley) %G%
8ae0e4b4 7 */
63c82e3f
HS
8
9/*
4dbcd6a1
KB
10 * RP??/RM?? disk driver with ECC handling and bad block forwarding.
11 * Also supports header io operations and commands to write check
12 * header and data.
63c82e3f 13 */
39c71180
MK
14#include "param.h"
15#include "inode.h"
16#include "fs.h"
17#include "dkbad.h"
18#include "disklabel.h"
63c82e3f
HS
19
20#include "../vax/pte.h"
39c71180 21
63c82e3f
HS
22#include "../vaxmba/hpreg.h"
23#include "../vaxmba/mbareg.h"
24
25#include "saio.h"
26#include "savax.h"
27
f834e141
MK
28#define RETRIES 27
29
63c82e3f
HS
30#define MASKREG(reg) ((reg)&0xffff)
31
356d90a8
SL
32#define MAXBADDESC 126
33#define SECTSIZ 512 /* sector size in bytes */
34#define HDRSIZ 4 /* number of bytes in sector header */
63c82e3f 35
80c81fbf 36char lbuf[SECTSIZ];
63c82e3f 37
80c81fbf
MK
38#define RP06(type) ((type) == MBDT_RP06 || (type) == MBDT_RP05 \
39 || (type) == MBDT_RP04)
40#define ML11(type) ((type) == MBDT_ML11A)
41#define RM80(type) ((type) == MBDT_RM80)
63c82e3f
HS
42
43u_char hp_offset[16] = {
4dbcd6a1
KB
44 HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400,
45 HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800,
46 HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200,
47 0, 0, 0, 0,
63c82e3f
HS
48};
49
4dbcd6a1
KB
50#define MAXUNIT 8
51struct disklabel hplabel[MAXNMBA][MAXUNIT];
80c81fbf 52#ifndef SMALL
4dbcd6a1 53struct dkbad hpbad[MAXNMBA][MAXUNIT];
80c81fbf
MK
54int sectsiz;
55#endif
356d90a8 56
f834e141
MK
57struct hp_softc {
58 char type;
59 char gottype;
4dbcd6a1 60 char ssect; /* 1 when on track w/skip sector */
f834e141
MK
61 char debug;
62# define HPF_BSEDEBUG 01 /* debugging bad sector forwarding */
63# define HPF_ECCDEBUG 02 /* debugging ecc correction */
64 int ecclim;
65 int retries;
4dbcd6a1 66} hp_softc[MAXNMBA][MAXUNIT];
356d90a8 67
4b5bcdd9 68/*
4dbcd6a1
KB
69 * When awaiting command completion, don't hang on to the status register
70 * since this ties up some controllers.
4b5bcdd9 71 */
356d90a8 72#define HPWAIT(addr) \
4dbcd6a1
KB
73 while ((((addr)->hpds)&HPDS_DRY) == 0) \
74 DELAY(500);
4b5bcdd9 75
63c82e3f
HS
76hpopen(io)
77 register struct iob *io;
78{
79 register unit = io->i_unit;
4dbcd6a1
KB
80 register struct hp_softc *sc;
81 register struct disklabel *lp;
82 struct hpdevice *hpaddr;
60bc077a 83 struct disklabel *dlp;
f2f9e58f 84 int error = 0;
63c82e3f 85
ae64a1dd
MK
86 /*
87 * Accept adaptor number as either controller or adaptor,
88 * but not both.
89 */
90 if (io->i_ctlr) {
91 if (io->i_adapt == 0)
92 io->i_adapt = io->i_ctlr;
93 else
94 return (ECTLR);
95 }
4dbcd6a1
KB
96 if ((u_int)io->i_adapt >= MAXNMBA || !mbainit(io->i_adapt))
97 return (EADAPT);
4dbcd6a1
KB
98 if ((u_int)unit >= MAXUNIT)
99 return (EUNIT);
100 hpaddr = (struct hpdevice *)mbadrv(io->i_adapt, unit);
101 sc = &hp_softc[io->i_adapt][unit];
102 lp = &hplabel[io->i_adapt][unit];
f834e141 103 if (sc->gottype == 0) {
4dbcd6a1 104 register int i;
63c82e3f
HS
105 struct iob tio;
106
80c81fbf 107#ifndef SMALL
f834e141
MK
108 sc->retries = RETRIES;
109 sc->ecclim = 11;
110 sc->debug = 0;
80c81fbf 111#endif
7fc00e31
HS
112 hpaddr->hpcs1 = HP_DCLR|HP_GO; /* init drive */
113 hpaddr->hpcs1 = HP_PRESET|HP_GO;
80c81fbf 114#ifndef SMALL
9ab9be08 115 if ((hpaddr->hpds & HPDS_DPR) == 0)
39c71180 116 return (ENXIO);
80c81fbf
MK
117 sc->type = hpaddr->hpdt & MBDT_TYPE;
118 if (sc->type == MBDT_ML11B)
39c71180 119 sc->type = MBDT_ML11A;
80c81fbf
MK
120 if (!ML11(sc->type))
121#endif
7fc00e31 122 hpaddr->hpof = HPOF_FMT22;
63c82e3f 123 /*
80c81fbf 124 * Read in the pack label.
63c82e3f 125 */
80c81fbf
MK
126 lp->d_nsectors = 32;
127 lp->d_secpercyl = 20*32;
63c82e3f 128 tio = *io;
80c81fbf
MK
129 tio.i_bn = LABELSECTOR;
130 tio.i_ma = lbuf;
131 tio.i_cc = SECTSIZ;
132 tio.i_flgs |= F_RDDATA;
b04dd895 133 if (hpstrategy(&tio, READ) != SECTSIZ)
f2f9e58f 134 error = ERDLAB;
60bc077a 135 dlp = (struct disklabel *)(lbuf + LABELOFFSET);
f2f9e58f
MK
136 if (error == 0 && (dlp->d_magic != DISKMAGIC ||
137 dlp->d_magic2 != DISKMAGIC))
138 error = EUNLAB;
139 if (error == 0)
140 *lp = *dlp;
141 else
b04dd895 142#ifdef COMPAT_42
f2f9e58f 143 if (hpmaptype(hpaddr, hpaddr->hpdt & MBDT_TYPE, unit, lp) == 0)
80c81fbf 144#endif
f2f9e58f
MK
145 return (error);
146
60bc077a 147#ifndef SMALL
80c81fbf
MK
148 /*
149 * Read in the bad sector table.
150 */
151 tio.i_bn = lp->d_secpercyl * lp->d_ncylinders - lp->d_nsectors;
4dbcd6a1
KB
152 tio.i_ma = (char *)&hpbad[io->i_adapt][unit];
153 tio.i_cc = sizeof(struct dkbad);
63c82e3f 154 for (i = 0; i < 5; i++) {
4dbcd6a1 155 if (hpstrategy(&tio, READ) == sizeof(struct dkbad))
63c82e3f
HS
156 break;
157 tio.i_bn += 2;
158 }
159 if (i == 5) {
4dbcd6a1 160 printf("hp: can't read bad sector table\n");
63c82e3f 161 for (i = 0; i < MAXBADDESC; i++) {
4dbcd6a1
KB
162 hpbad[io->i_adapt][unit].bt_bad[i].bt_cyl = -1;
163 hpbad[io->i_adapt][unit].bt_bad[i].bt_trksec = -1;
63c82e3f 164 }
f834e141 165 }
80c81fbf 166#endif
60bc077a 167 sc->gottype = 1;
63c82e3f 168 }
4dbcd6a1
KB
169 if (io->i_part >= lp->d_npartitions ||
170 lp->d_partitions[io->i_part].p_size == 0)
171 return (EPART);
172 io->i_boff = lp->d_partitions[io->i_part].p_offset;
80c81fbf 173 return (0);
63c82e3f
HS
174}
175
176hpstrategy(io, func)
177 register struct iob *io;
178{
4dbcd6a1
KB
179 register int unit = io->i_unit;
180 register struct hp_softc *sc;
181 register struct disklabel *lp;
182 struct mba_regs *mba;
183 struct hpdevice *hpaddr;
356d90a8 184 daddr_t bn, startblock;
39c71180 185 int cn, tn, sn, bytecnt, bytesleft, rv;
63c82e3f 186 int er1, er2, hprecal;
4dbcd6a1 187 char *membase;
63c82e3f 188
4dbcd6a1
KB
189 mba = mbamba(io->i_adapt);
190 hpaddr = (struct hpdevice *)mbadrv(io->i_adapt, unit);
191 sc = &hp_softc[io->i_adapt][unit];
192 lp = &hplabel[io->i_adapt][unit];
80c81fbf 193#ifndef SMALL
63c82e3f
HS
194 sectsiz = SECTSIZ;
195 if ((io->i_flgs & (F_HDR|F_HCHECK)) != 0)
196 sectsiz += HDRSIZ;
197 if ((hpaddr->hpds & HPDS_VV) == 0) {
198 hpaddr->hpcs1 = HP_DCLR|HP_GO;
199 hpaddr->hpcs1 = HP_PRESET|HP_GO;
80c81fbf 200 if (!ML11(sc->type))
63c82e3f
HS
201 hpaddr->hpof = HPOF_FMT22;
202 }
203 io->i_errcnt = 0;
f834e141
MK
204 sc->ssect = 0;
205 rv = bytecnt = io->i_cc;
63c82e3f
HS
206 membase = io->i_ma;
207 startblock = io->i_bn;
308847fc 208 hprecal = 0;
80c81fbf 209#endif
86bcc486 210
ccc991c5 211restart:
63c82e3f 212 bn = io->i_bn;
80c81fbf
MK
213 cn = bn / lp->d_secpercyl;
214 sn = bn % lp->d_secpercyl;
215 tn = sn / lp->d_nsectors;
216 sn = sn % lp->d_nsectors + sc->ssect;
63c82e3f 217
4b5bcdd9 218 HPWAIT(hpaddr);
ccc991c5 219 mba->mba_sr = -1;
80c81fbf 220 if (ML11(sc->type))
63c82e3f
HS
221 hpaddr->hpda = bn;
222 else {
223 hpaddr->hpdc = cn;
224 hpaddr->hpda = (tn << 8) + sn;
225 }
80c81fbf 226#ifdef SMALL
4dbcd6a1 227 mbastart(io, io->i_unit, func); /* start transfer */
80c81fbf
MK
228 HPWAIT(hpaddr);
229 if (hpaddr->hpds & HPDS_ERR) {
230 printf("hp error: sn [%d-%d) ds=%b er1=%b\n",
231 bn, bn + io->i_cc/SECTSIZ, MASKREG(hpaddr->hpds), HPDS_BITS,
232 MASKREG(hpaddr->hper1), HPER1_BITS);
233 return (-1);
234 }
235 return (io->i_cc);
236#else
4dbcd6a1 237 if (mbastart(io, io->i_unit, func) != 0) { /* start transfer */
f834e141
MK
238 rv = -1;
239 goto done;
240 }
4b5bcdd9 241 HPWAIT(hpaddr);
356d90a8
SL
242 /*
243 * Successful data transfer, return.
244 */
c5fc2df8
MK
245 if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0)
246 goto done;
63c82e3f 247
356d90a8
SL
248 /*
249 * Error handling. Calculate location of error.
250 */
251 bytesleft = MASKREG(mba->mba_bcr);
252 if (bytesleft)
253 bytesleft |= 0xffff0000; /* sxt */
254 bn = io->i_bn + (io->i_cc + bytesleft) / sectsiz;
71da8ead
MK
255 er1 = MASKREG(hpaddr->hper1);
256 er2 = MASKREG(hpaddr->hper2);
257 if (er1 & (HPER1_DCK|HPER1_ECH))
258 bn--; /* Error is in Prev block */
80c81fbf
MK
259 cn = bn/lp->d_secpercyl;
260 sn = bn%lp->d_secpercyl;
261 tn = sn/lp->d_nsectors;
262 sn = sn%lp->d_nsectors;
f834e141
MK
263 if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) {
264 printf("hp error: sn%d (cyl,trk,sec)=(%d,%d,%d) ds=%b\n",
265 bn, cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
356d90a8
SL
266 printf("er1=%b er2=%b\n", er1, HPER1_BITS, er2, HPER2_BITS);
267 printf("bytes left: %d, of 0x%x, da 0x%x\n",-bytesleft,
268 hpaddr->hpof, hpaddr->hpda);
269 }
63c82e3f
HS
270 if (er1 & HPER1_HCRC) {
271 er1 &= ~(HPER1_HCE|HPER1_FER);
272 er2 &= ~HPER2_BSE;
f834e141
MK
273 if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0)
274 goto success;
63c82e3f 275 }
86bcc486
SL
276 /*
277 * Give up early if drive write locked.
278 */
63c82e3f
HS
279 if (er1&HPER1_WLE) {
280 printf("hp%d: write locked\n", unit);
f834e141
MK
281 rv = -1;
282 goto done;
9d78a350 283 }
86bcc486 284 /*
f834e141 285 * Skip sector handling.
86bcc486 286 */
80c81fbf 287 if (RM80(sc->type) && (er2 & HPER2_SSE)) {
f834e141
MK
288 (void) hpecc(io, SSE);
289 sc->ssect = 1;
290 goto restart;
9d78a350 291 }
86bcc486 292 /*
f834e141
MK
293 * Attempt to forward bad sectors on anything but an ML11.
294 * Interpret format error bit as a bad block on RP06's.
86bcc486 295 */
80c81fbf
MK
296 if (((er2 & HPER2_BSE) && !ML11(sc->type)) ||
297 (MASKREG(er1) == HPER1_FER && RP06(sc->type))) {
9d78a350 298 if (io->i_flgs & F_NBSF) {
4dbcd6a1 299 io->i_error = EBSE;
63c82e3f
HS
300 goto hard;
301 }
302 if (hpecc(io, BSE) == 0)
303 goto success;
9d78a350
SL
304 io->i_error = EBSE;
305 goto hard;
306 }
86bcc486 307 /*
356d90a8 308 * ECC correction?
86bcc486 309 */
9d78a350 310 if ((er1 & (HPER1_DCK|HPER1_ECH)) == HPER1_DCK) {
4b5bcdd9 311 if (hpecc(io, ECC) == 0)
63c82e3f 312 goto success;
9d78a350 313 io->i_error = EECC;
71da8ead 314 goto hard;
f834e141
MK
315 }
316
317 /*
318 * If a hard error, or maximum retry count
319 * exceeded, clear controller state and
320 * pass back error to caller.
321 */
322 if (++io->i_errcnt > sc->retries || (er1 & HPER1_HARD) ||
80c81fbf
MK
323 (!ML11(sc->type) && (er2 & HPER2_HARD)) ||
324 (ML11(sc->type) && (io->i_errcnt >= 16))) {
f834e141
MK
325 io->i_error = EHER;
326 if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR))
327 io->i_error = EWCK;
328hard:
329 io->i_errblk = bn + sc->ssect;
330 if (sc->debug & (HPF_BSEDEBUG|HPF_ECCDEBUG))
331 printf(" dc=%d, da=0x%x",MASKREG(hpaddr->hpdc),
332 MASKREG(hpaddr->hpda));
333 else {
334 printf("hp error: sn%d (cyl,trk,sec)=(%d,%d,%d) ds=%b \n",
335 bn, cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
336 printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS);
337 }
338 hpaddr->hpcs1 = HP_DCLR|HP_GO;
339 printf("\n");
340 rv = -1;
341 goto done;
342
343 }
308847fc 344 /* fall thru to retry */
63c82e3f 345 hpaddr->hpcs1 = HP_DCLR|HP_GO;
4b5bcdd9 346 HPWAIT(hpaddr);
86bcc486
SL
347
348 /*
349 * Every fourth retry recalibrate.
350 */
356d90a8 351 if (((io->i_errcnt & 07) == 4) ) {
63c82e3f 352 hpaddr->hpcs1 = HP_RECAL|HP_GO;
71da8ead 353 HPWAIT(hpaddr);
63c82e3f
HS
354 hpaddr->hpdc = cn;
355 hpaddr->hpcs1 = HP_SEEK|HP_GO;
71da8ead
MK
356 HPWAIT(hpaddr);
357 }
4b5bcdd9 358
71da8ead 359 if (io->i_errcnt >= 16 && (io->i_flgs & F_READ)) {
63c82e3f
HS
360 hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22;
361 hpaddr->hpcs1 = HP_OFFSET|HP_GO;
71da8ead 362 HPWAIT(hpaddr);
63c82e3f 363 }
f834e141 364 if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG))
71da8ead
MK
365 printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n",
366 io->i_bn, io->i_cc, io->i_ma, hprecal);
f834e141 367 goto restart;
9d78a350 368
86bcc486
SL
369success:
370 /*
371 * On successful error recovery, bump
372 * block number to advance to next portion
373 * of i/o transfer.
374 */
63c82e3f
HS
375 bn++;
376 if ((bn-startblock) * sectsiz < bytecnt) {
63c82e3f 377 io->i_bn = bn;
63c82e3f
HS
378 io->i_ma = membase + (io->i_bn - startblock)*sectsiz;
379 io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz;
f834e141 380 if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG))
356d90a8
SL
381 printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n",
382 io->i_bn, io->i_cc, io->i_ma, hprecal);
ccc991c5 383 goto restart;
63c82e3f 384 }
c5fc2df8 385done:
71da8ead
MK
386 if (io->i_errcnt >= 16) {
387 hpaddr->hpcs1 = HP_RTC|HP_GO;
388 while (hpaddr->hpds & HPDS_PIP)
389 ;
390 }
f834e141 391 io->i_bn = startblock; /*reset i_bn to original */
2f1563bc 392 io->i_cc = bytecnt; /*reset i_cc to total count xfered*/
f834e141
MK
393 io->i_ma = membase; /*reset i_ma to original */
394 return (rv);
80c81fbf 395#endif
63c82e3f 396}
4b5bcdd9 397
80c81fbf 398#ifndef SMALL
63c82e3f
HS
399hpecc(io, flag)
400 register struct iob *io;
401 int flag;
402{
4dbcd6a1
KB
403 register int unit = io->i_unit;
404 register struct mba_regs *mbp;
405 register struct hpdevice *rp;
406 register struct hp_softc *sc;
407 register struct disklabel *lp;
9d78a350 408 int npf, bn, cn, tn, sn, bcr;
63c82e3f 409
4dbcd6a1
KB
410 mbp = mbamba(io->i_adapt);
411 rp = (struct hpdevice *)mbadrv(io->i_adapt, unit);
412 sc = &hp_softc[io->i_adapt][unit];
413 lp = &hplabel[io->i_adapt][unit];
356d90a8
SL
414 bcr = MASKREG(mbp->mba_bcr);
415 if (bcr)
416 bcr |= 0xffff0000; /* sxt */
9d78a350 417 npf = (bcr + io->i_cc) / sectsiz; /* # sectors read */
71da8ead
MK
418 if (flag == ECC)
419 npf--; /* Error is in prev block --ghg */
f834e141
MK
420 bn = io->i_bn + npf + sc->ssect; /* physical block #*/
421 if (sc->debug & HPF_ECCDEBUG)
356d90a8 422 printf("bcr=%d npf=%d ssect=%d sectsiz=%d i_cc=%d\n",
f834e141 423 bcr, npf, sc->ssect, sectsiz, io->i_cc);
86bcc486
SL
424 /*
425 * ECC correction logic.
426 */
427 if (flag == ECC) {
63c82e3f
HS
428 register int i;
429 caddr_t addr;
f834e141 430 int bit, o, mask;
63c82e3f 431
0cd55454 432 printf("hp%d: soft ecc sn%d\n", unit, bn);
63c82e3f 433 mask = MASKREG(rp->hpec2);
f834e141
MK
434 for (i = mask, bit = 0; i; i >>= 1)
435 if (i & 1)
436 bit++;
437 if (bit > sc->ecclim) {
438 printf("%d-bit error\n", bit);
439 return (1);
440 }
9d78a350 441 i = MASKREG(rp->hpec1) - 1; /* -1 makes 0 origin */
63c82e3f 442 bit = i&07;
356d90a8 443 o = (i & ~07) >> 3;
63c82e3f 444 rp->hpcs1 = HP_DCLR | HP_GO;
10860662
SL
445 while (o <sectsiz && npf*sectsiz + o < io->i_cc && bit > -11) {
446 addr = io->i_ma + (npf*sectsiz) + o;
10860662
SL
447 /*
448 * No data transfer occurs with a write check,
449 * so don't correct the resident copy of data.
450 */
356d90a8 451 if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) {
f834e141 452 if (sc->debug & HPF_ECCDEBUG)
356d90a8
SL
453 printf("addr=%x old=%x ", addr,
454 (*addr & 0xff));
86bcc486 455 *addr ^= (mask << bit);
f834e141 456 if (sc->debug & HPF_ECCDEBUG)
356d90a8
SL
457 printf("new=%x\n",(*addr & 0xff));
458 }
10860662 459 o++, bit -= 8;
63c82e3f 460 }
10860662 461 return (0);
9d78a350 462 }
63c82e3f 463
9d78a350
SL
464 /*
465 * Skip sector error.
466 * Set skip-sector-inhibit and
467 * read next sector
468 */
86bcc486 469 if (flag == SSE) {
63c82e3f 470 rp->hpcs1 = HP_DCLR | HP_GO;
4b5bcdd9 471 HPWAIT(rp);
63c82e3f 472 rp->hpof |= HPOF_SSEI;
4dbcd6a1 473 return (0);
86bcc486 474 }
63c82e3f 475
86bcc486
SL
476 /*
477 * Bad block forwarding.
478 */
479 if (flag == BSE) {
ccc991c5 480 int bbn;
9d78a350 481
ccc991c5 482 rp->hpcs1 = HP_DCLR | HP_GO;
f834e141 483 if (sc->debug & HPF_BSEDEBUG)
356d90a8 484 printf("hpecc: BSE @ bn %d\n", bn);
80c81fbf
MK
485 cn = bn / lp->d_secpercyl;
486 sn = bn % lp->d_secpercyl;
487 tn = sn / lp->d_nsectors;
488 sn = sn % lp->d_nsectors;
ccc991c5 489 bcr += sectsiz;
4dbcd6a1 490 if ((bbn = isbad(&hpbad[io->i_adapt][unit], cn, tn, sn)) < 0)
9d78a350 491 return (1);
80c81fbf
MK
492 bbn = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors - 1
493 - bbn;
494 cn = bbn / lp->d_secpercyl;
495 sn = bbn % lp->d_secpercyl;
496 tn = sn / lp->d_nsectors;
39c71180 497 sn = sn % lp->d_nsectors;
ccc991c5 498 io->i_cc = sectsiz;
80c81fbf 499 io->i_ma += npf * sectsiz;
f834e141 500 if (sc->debug & HPF_BSEDEBUG)
356d90a8
SL
501 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
502 rp->hpof &= ~HPOF_SSEI;
ccc991c5 503 mbp->mba_sr = -1;
63c82e3f
HS
504 rp->hpdc = cn;
505 rp->hpda = (tn<<8) + sn;
4dbcd6a1 506 mbastart(io, io->i_unit, io->i_flgs);
356d90a8 507 io->i_errcnt = 0;
4b5bcdd9
SL
508 HPWAIT(rp);
509 return (rp->hpds&HPDS_ERR);
63c82e3f 510 }
9d78a350
SL
511 printf("hpecc: flag=%d\n", flag);
512 return (1);
63c82e3f 513}
86bcc486 514
63c82e3f
HS
515/*ARGSUSED*/
516hpioctl(io, cmd, arg)
517 struct iob *io;
518 int cmd;
519 caddr_t arg;
520{
7fc00e31 521 register unit = io->i_unit;
4dbcd6a1
KB
522 register struct hp_softc *sc = &hp_softc[io->i_adapt][unit];
523 register struct disklabel *lp = &hplabel[io->i_adapt][unit];
524 struct mba_drv *drv = mbadrv(io->i_adapt, unit);
63c82e3f
HS
525
526 switch(cmd) {
527
356d90a8 528 case SAIODEBUG:
f834e141
MK
529 sc->debug = (int)arg;
530 break;
356d90a8 531
63c82e3f 532 case SAIODEVDATA:
f834e141
MK
533 if (drv->mbd_dt&MBDT_TAP)
534 return (ECMD);
80c81fbf 535 *(struct disklabel *)arg = *lp;
f834e141
MK
536 break;
537
538 case SAIOGBADINFO:
539 if (drv->mbd_dt&MBDT_TAP)
540 return (ECMD);
4dbcd6a1 541 *(struct dkbad *)arg = hpbad[io->i_adapt][unit];
f834e141
MK
542 break;
543
544 case SAIOECCLIM:
545 sc->ecclim = (int)arg;
546 break;
547
548 case SAIORETRIES:
549 sc->retries = (int)arg;
550 break;
63c82e3f 551
9d78a350
SL
552 case SAIOSSI: /* skip-sector-inhibit */
553 if (drv->mbd_dt&MBDT_TAP)
554 return (ECMD);
555 if ((io->i_flgs&F_SSI) == 0) {
556 /* make sure this is done once only */
557 io->i_flgs |= F_SSI;
80c81fbf
MK
558 lp->d_nsectors++;
559 lp->d_secpercyl += lp->d_ntracks;
4b5bcdd9 560 }
f834e141 561 break;
ccc991c5 562
9d78a350 563 case SAIONOSSI: /* remove skip-sector-inhibit */
ccc991c5
HS
564 if (io->i_flgs & F_SSI) {
565 io->i_flgs &= ~F_SSI;
566 drv->mbd_of &= ~HPOF_SSEI;
80c81fbf
MK
567 lp->d_nsectors--;
568 lp->d_secpercyl -= lp->d_ntracks;
ccc991c5 569 }
f834e141 570 break;
ccc991c5 571
4b5bcdd9 572 case SAIOSSDEV: /* drive have skip sector? */
80c81fbf 573 return (RM80(sc->type) ? 0 : ECMD);
f834e141
MK
574
575 default:
576 return (ECMD);
63c82e3f 577 }
f834e141 578 return (0);
63c82e3f 579}
4dbcd6a1 580#endif /* !SMALL */