merge in NFS code from Rick Macklem
[unix-history] / usr / src / sys / vax / stand / up.c
CommitLineData
da7c5cc6 1/*
f75b5a26 2 * Copyright (c) 1982, 1988 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
b2291f86 6 * @(#)up.c 7.8 (Berkeley) %G%
da7c5cc6 7 */
258a5c40 8
0839bdeb 9/*
d483c0fd
KB
10 * UNIBUS peripheral standalone driver with ECC correction and bad
11 * block forwarding. Also supports header operation and write check
12 * for data and/or header.
0839bdeb 13 */
233fc5c1
MK
14#include "param.h"
15#include "inode.h"
16#include "fs.h"
17#include "dkbad.h"
d483c0fd 18#include "disklabel.h"
258a5c40 19
39c71180
MK
20#include "../vax/pte.h"
21
22#include "../vaxuba/upreg.h"
23#include "../vaxuba/ubareg.h"
258a5c40 24
0839bdeb 25#include "saio.h"
258a5c40
SL
26#include "savax.h"
27
31fec9db
MK
28#define RETRIES 27
29
b8ca3ab9
HS
30#define MAXBADDESC 126 /* max number of bad sectors recorded */
31#define SECTSIZ 512 /* sector size in bytes */
32#define HDRSIZ 4 /* number of bytes in sector header */
dda2842d 33
d483c0fd 34#define MAXUNIT 8
c48789a9 35#define MAXCTLR 1 /* all addresses must be specified */
b2291f86
KB
36static u_short upstd[MAXCTLR] = { 0776700 };
37static struct disklabel uplabel[MAXNUBA][MAXCTLR][MAXUNIT];
38static char lbuf[SECTSIZ];
0839bdeb 39
b4736392 40extern struct st upst[];
0839bdeb 41
233fc5c1 42#ifndef SMALL
d483c0fd 43struct dkbad upbad[MAXNUBA][MAXCTLR][MAXUNIT]; /* bad sector table */
233fc5c1 44#endif
d483c0fd 45int sectsiz; /* real sector size */
31fec9db
MK
46
47struct up_softc {
48 char gottype;
49 char type;
50 char debug;
51# define UPF_BSEDEBUG 01 /* debugging bad sector forwarding */
52# define UPF_ECCDEBUG 02 /* debugging ecc correction */
53 int retries;
54 int ecclim;
d483c0fd 55} up_softc[MAXNUBA][MAXCTLR][MAXUNIT];
dda2842d 56
258a5c40
SL
57u_char up_offset[16] = {
58 UPOF_P400, UPOF_M400, UPOF_P400, UPOF_M400,
59 UPOF_P800, UPOF_M800, UPOF_P800, UPOF_M800,
60 UPOF_P1200, UPOF_M1200, UPOF_P1200, UPOF_M1200,
61 0, 0, 0, 0
62};
63
64upopen(io)
65 register struct iob *io;
66{
0839bdeb 67 register struct updevice *upaddr;
c48789a9 68 register struct up_softc *sc;
31fa9244 69 register struct st *st;
f75b5a26
MK
70 register struct disklabel *lp;
71 struct disklabel *dlp;
d483c0fd 72 register int unit;
f75b5a26 73 int error = 0, uba, ctlr;
258a5c40 74
f75b5a26
MK
75 if ((u_int)(uba = io->i_adapt) >= nuba)
76 return (EADAPT);
77 if ((u_int)(ctlr = io->i_ctlr) >= MAXCTLR)
c48789a9 78 return (ECTLR);
d483c0fd 79 unit = io->i_unit;
f75b5a26
MK
80 if ((u_int)unit >= MAXUNIT)
81 return (EUNIT);
b2291f86 82 upaddr = (struct updevice *)ubamem(uba, upstd[ctlr]);
f75b5a26 83 upaddr->upcs2 = unit;
c48789a9 84 while ((upaddr->upcs1 & UP_DVA) == 0);
f75b5a26
MK
85 sc = &up_softc[uba][ctlr][unit];
86 lp = &uplabel[uba][ctlr][unit];
31fec9db 87 if (sc->gottype == 0) {
0839bdeb
SL
88 register int i;
89 struct iob tio;
90
d483c0fd 91#ifndef SMALL
31fec9db
MK
92 sc->retries = RETRIES;
93 sc->ecclim = 11;
94 sc->debug = 0;
d483c0fd
KB
95#endif
96 /* Read in the pack label. */
97 lp->d_nsectors = 32;
98 lp->d_secpercyl = 19*32;
99 tio = *io;
100 tio.i_bn = LABELSECTOR;
101 tio.i_ma = lbuf;
102 tio.i_cc = SECTSIZ;
103 tio.i_flgs |= F_RDDATA;
104 if (upstrategy(&tio, READ) != SECTSIZ)
f2f9e58f 105 error = ERDLAB;
d483c0fd 106 dlp = (struct disklabel *)(lbuf + LABELOFFSET);
f2f9e58f
MK
107 if (error == 0 && (dlp->d_magic != DISKMAGIC ||
108 dlp->d_magic2 != DISKMAGIC))
109 error = EUNLAB;
110 if (error == 0)
111 *lp = *dlp;
112 else
d483c0fd 113#ifdef COMPAT_42
f2f9e58f 114 if (upmaptype(unit, upaddr, lp) == 0)
d483c0fd 115#endif
f2f9e58f 116 return (error);
d483c0fd 117
233fc5c1 118#ifndef SMALL
d483c0fd
KB
119 /* Read in the bad sector table. */
120 tio.i_bn = lp->d_secpercyl * lp->d_ncylinders - lp->d_nsectors;
f75b5a26 121 tio.i_ma = (char *)&upbad[uba][ctlr][unit];
d483c0fd 122 tio.i_cc = sizeof(struct dkbad);
0839bdeb
SL
123 tio.i_flgs |= F_RDDATA;
124 for (i = 0; i < 5; i++) {
d483c0fd 125 if (upstrategy(&tio, READ) == sizeof(struct dkbad))
0839bdeb 126 break;
258a5c40
SL
127 tio.i_bn += 2;
128 }
129 if (i == 5) {
d483c0fd 130 printf("up: can't read bad sector table\n");
b8ca3ab9 131 for (i = 0; i < MAXBADDESC; i++) {
f75b5a26
MK
132 upbad[uba][ctlr][unit].bt_bad[i].bt_cyl = -1;
133 upbad[uba][ctlr][unit].bt_bad[i].bt_trksec = -1;
258a5c40 134 }
d483c0fd 135 }
233fc5c1 136#endif
31fec9db 137 sc->gottype = 1;
258a5c40 138 }
d483c0fd
KB
139 if (io->i_part >= lp->d_npartitions ||
140 lp->d_partitions[io->i_part].p_size == 0)
f75b5a26 141 return (EPART);
d483c0fd 142 io->i_boff = lp->d_partitions[io->i_part].p_offset;
0839bdeb 143 io->i_flgs &= ~F_TYPEMASK;
39c71180 144 return (0);
258a5c40
SL
145}
146
147upstrategy(io, func)
148 register struct iob *io;
d483c0fd 149 int func;
258a5c40 150{
1f4919da 151 int cn, tn, sn, o;
b8ca3ab9 152 register unit = io->i_unit;
39c71180 153 register daddr_t bn;
258a5c40 154 int recal, info, waitdry;
c48789a9 155 register struct updevice *upaddr;
d483c0fd 156 register struct disklabel *lp;
c48789a9 157 struct up_softc *sc;
39c71180
MK
158 int error, rv = io->i_cc;
159#ifndef SMALL
160 int doprintf = 0;
161#endif
258a5c40 162
b2291f86 163 upaddr = (struct updevice *)ubamem(io->i_adapt, upstd[io->i_ctlr]);
c48789a9 164 sc = &up_softc[io->i_adapt][io->i_ctlr][unit];
d483c0fd 165 lp = &uplabel[io->i_adapt][io->i_ctlr][unit];
b8ca3ab9 166 sectsiz = SECTSIZ;
f75b5a26 167#ifndef SMALL
3ab40097 168 if (io->i_flgs & (F_HDR|F_HCHECK))
b8ca3ab9 169 sectsiz += HDRSIZ;
f75b5a26
MK
170#endif
171 upaddr->upcs2 = unit;
258a5c40
SL
172 if ((upaddr->upds & UPDS_VV) == 0) {
173 upaddr->upcs1 = UP_DCLR|UP_GO;
174 upaddr->upcs1 = UP_PRESET|UP_GO;
175 upaddr->upof = UPOF_FMT22;
176 }
31fec9db 177 if ((upaddr->upds & UPDS_DREADY) == 0) {
f75b5a26 178 printf("up%d not ready\n", unit);
31fec9db
MK
179 return (-1);
180 }
258a5c40
SL
181 info = ubasetup(io, 1);
182 upaddr->upwc = -io->i_cc / sizeof (short);
3ab40097
SL
183 recal = 0;
184 io->i_errcnt = 0;
185
960ade39 186restart:
1f4919da
SL
187 o = io->i_cc + (upaddr->upwc * sizeof (short));
188 upaddr->upba = info + o;
189 bn = io->i_bn + o / sectsiz;
39c71180 190#ifndef SMALL
f75b5a26 191 error = 0;
31fec9db 192 if (doprintf && sc->debug & (UPF_ECCDEBUG|UPF_BSEDEBUG))
3beb607b 193 printf("wc=%d o=%d i_bn=%d bn=%d\n",
dda2842d 194 upaddr->upwc, o, io->i_bn, bn);
39c71180 195#endif
f75b5a26 196 upwaitdry(upaddr);
d483c0fd 197 if (upstart(io, bn, lp) != 0) {
31fec9db
MK
198 rv = -1;
199 goto done;
b8ca3ab9 200 }
f75b5a26 201 upwaitrdy(upaddr);
3ab40097
SL
202 /*
203 * If transfer has completed, free UNIBUS
204 * resources and return transfer size.
205 */
73abfe3c
MK
206 if ((upaddr->upds&UPDS_ERR) == 0 && (upaddr->upcs1&UP_TRE) == 0)
207 goto done;
31fec9db
MK
208 bn = io->i_bn +
209 (io->i_cc + upaddr->upwc * sizeof (short)) / sectsiz;
210 if (upaddr->uper1 & (UPER1_DCK|UPER1_ECH))
211 bn--;
d483c0fd
KB
212 cn = bn / lp->d_secpercyl;
213 sn = bn % lp->d_secpercyl;
214 tn = sn / lp->d_nsectors;
215 sn = sn % lp->d_nsectors;
233fc5c1 216#ifndef SMALL
31fec9db
MK
217 if (sc->debug & (UPF_ECCDEBUG|UPF_BSEDEBUG)) {
218 printf("up error: sn%d (cyl,trk,sec)=(%d,%d,%d) ",
219 bn, cn, tn, sn);
3beb607b 220 printf("cs2=%b er1=%b er2=%b wc=%d\n",
dda2842d 221 upaddr->upcs2, UPCS2_BITS, upaddr->uper1,
3beb607b 222 UPER1_BITS, upaddr->uper2, UPER2_BITS, upaddr->upwc);
dda2842d 223 }
233fc5c1 224#endif
258a5c40 225 waitdry = 0;
3beb607b 226 while ((upaddr->upds&UPDS_DRY) == 0 && ++waitdry < sectsiz)
0839bdeb 227 DELAY(5);
233fc5c1 228#ifndef SMALL
3ab40097
SL
229 if (upaddr->uper1&UPER1_WLE) {
230 /*
231 * Give up on write locked devices immediately.
232 */
233 printf("up%d: write locked\n", unit);
31fec9db
MK
234 rv = -1;
235 goto done;
3ab40097 236 }
31fec9db
MK
237 if (upaddr->uper2 & UPER2_BSE) {
238 if ((io->i_flgs&F_NBSF) == 0 && upecc(io, BSE) == 0)
239 goto success;
240 error = EBSE;
241 goto hard;
242 }
243 /*
244 * ECC error. If a soft error, correct it;
245 * if correction is too large, no more retries.
246 */
247 if ((upaddr->uper1 & (UPER1_DCK|UPER1_ECH|UPER1_HCRC)) == UPER1_DCK) {
248 if (upecc(io, ECC) == 0)
249 goto success;
250 error = EECC;
251 goto hard;
252 }
253 /*
d483c0fd
KB
254 * If the error is a header CRC, check if a replacement sector
255 * exists in the bad sector table.
31fec9db
MK
256 */
257 if ((upaddr->uper1&UPER1_HCRC) && (io->i_flgs&F_NBSF) == 0 &&
258 upecc(io, BSE) == 0)
259 goto success;
233fc5c1 260#endif
31fec9db 261 if (++io->i_errcnt > sc->retries) {
258a5c40
SL
262 /*
263 * After 28 retries (16 without offset, and
264 * 12 with offset positioning) give up.
265 */
b8ca3ab9 266hard:
f75b5a26 267#ifndef SMALL
31fec9db
MK
268 if (error == 0) {
269 error = EHER;
270 if (upaddr->upcs2 & UPCS2_WCE)
271 error = EWCK;
272 }
f75b5a26
MK
273 io->i_error = error;
274#endif
31fec9db
MK
275 printf("up error: sn%d (cyl,trk,sec)=(%d,%d,%d) ",
276 bn, cn, tn, sn);
277 printf("cs2=%b er1=%b er2=%b\n",
3ab40097
SL
278 upaddr->upcs2, UPCS2_BITS, upaddr->uper1,
279 UPER1_BITS, upaddr->uper2, UPER2_BITS);
258a5c40 280 upaddr->upcs1 = UP_TRE|UP_DCLR|UP_GO;
b8ca3ab9 281 io->i_errblk = bn;
73abfe3c
MK
282 if (io->i_errcnt >= 16) {
283 upaddr->upof = UPOF_FMT22;
284 upaddr->upcs1 = UP_RTC|UP_GO;
f75b5a26 285 upwaitdry(upaddr);
73abfe3c 286 }
31fec9db
MK
287 rv = -1;
288 goto done;
258a5c40 289 }
258a5c40 290 /*
d483c0fd
KB
291 * Clear drive error and, every eight attempts, (starting with the
292 * fourth) recalibrate to clear the slate.
258a5c40
SL
293 */
294 upaddr->upcs1 = UP_TRE|UP_DCLR|UP_GO;
960ade39 295 if ((io->i_errcnt&07) == 4 ) {
258a5c40 296 upaddr->upcs1 = UP_RECAL|UP_GO;
f75b5a26 297 upwaitdry(upaddr);
258a5c40
SL
298 upaddr->updc = cn;
299 upaddr->upcs1 = UP_SEEK|UP_GO;
f75b5a26 300 upwaitdry(upaddr);
73abfe3c
MK
301 }
302 if (io->i_errcnt >= 16 && (func & READ)) {
258a5c40
SL
303 upaddr->upof = up_offset[io->i_errcnt & 017] | UPOF_FMT22;
304 upaddr->upcs1 = UP_OFFSET|UP_GO;
f75b5a26 305 upwaitdry(upaddr);
258a5c40 306 }
960ade39 307 goto restart;
3ab40097 308
258a5c40 309success:
3beb607b
SL
310#define rounddown(x, y) (((x) / (y)) * (y))
311 upaddr->upwc = rounddown(upaddr->upwc, sectsiz / sizeof (short));
312 if (upaddr->upwc) {
39c71180 313#ifndef SMALL
1f4919da 314 doprintf++;
39c71180 315#endif
960ade39 316 goto restart;
1f4919da 317 }
73abfe3c 318done:
258a5c40 319 ubafree(io, info);
73abfe3c
MK
320 /*
321 * If we were offset positioning,
322 * return to centerline.
323 */
324 if (io->i_errcnt >= 16) {
325 upaddr->upof = UPOF_FMT22;
326 upaddr->upcs1 = UP_RTC|UP_GO;
f75b5a26 327 upwaitdry(upaddr);
73abfe3c 328 }
31fec9db 329 return (rv);
258a5c40
SL
330}
331
f75b5a26
MK
332upwaitrdy(upaddr)
333 register struct updevice *upaddr;
334{
335 do {
336 DELAY(25);
337 } while ((upaddr->upcs1 & UP_RDY) == 0);
338}
339
340upwaitdry(upaddr)
341 register struct updevice *upaddr;
342{
343 while ((upaddr->upds&UPDS_DRY) == 0)
344 DELAY(25);
345}
346
233fc5c1 347#ifndef SMALL
258a5c40 348/*
d483c0fd
KB
349 * Correct an ECC error, and restart the i/o to complete the transfer (if
350 * necessary). This is quite complicated because the transfer may be going
351 * to an odd memory address base and/or across a page boundary.
258a5c40 352 */
0839bdeb 353upecc(io, flag)
258a5c40
SL
354 register struct iob *io;
355 int flag;
356{
c48789a9
KB
357 register i, unit;
358 register struct up_softc *sc;
359 register struct updevice *up;
d483c0fd 360 register struct disklabel *lp;
258a5c40 361 caddr_t addr;
6796f4df 362 int bn, twc, npf, mask, cn, tn, sn;
b8ca3ab9 363 daddr_t bbn;
258a5c40
SL
364
365 /*
b4736392
SL
366 * Npf is the number of sectors transferred
367 * before the sector containing the ECC error;
368 * bn is the current block number.
258a5c40 369 */
c48789a9
KB
370 unit = io->i_unit;
371 sc = &up_softc[io->i_adapt][io->i_ctlr][unit];
d483c0fd 372 lp = &uplabel[io->i_adapt][io->i_ctlr][unit];
b2291f86 373 up = (struct updevice *)ubamem(io->i_adapt, upstd[io->i_ctlr]);
b8ca3ab9 374 twc = up->upwc;
b4736392 375 npf = ((twc * sizeof(short)) + io->i_cc) / sectsiz;
73abfe3c
MK
376 if (flag == ECC)
377 npf--;
31fec9db 378 if (sc->debug & UPF_ECCDEBUG)
3beb607b
SL
379 printf("npf=%d mask=0x%x ec1=%d wc=%d\n",
380 npf, up->upec2, up->upec1, twc);
1f4919da 381 bn = io->i_bn + npf;
d483c0fd
KB
382 cn = bn / lp->d_secpercyl;
383 sn = bn % lp->d_secpercyl;
384 tn = sn / lp->d_nsectors;
385 sn = sn % lp->d_nsectors;
b4736392 386
258a5c40 387 /*
b4736392 388 * ECC correction.
258a5c40
SL
389 */
390 if (flag == ECC) {
31fec9db 391 int bit, o;
3ab40097 392
258a5c40 393 mask = up->upec2;
dda2842d 394 printf("up%d: soft ecc sn%d\n", unit, bn);
31fec9db
MK
395 for (i = mask, bit = 0; i; i >>= 1)
396 if (i & 1)
397 bit++;
398 if (bit > sc->ecclim) {
399 printf("%d-bit error\n", bit);
400 return (1);
401 }
258a5c40 402 /*
1f4919da
SL
403 * Compute the byte and bit position of
404 * the error. o is the byte offset in
405 * the transfer at which the correction
406 * applied.
258a5c40
SL
407 */
408 i = up->upec1 - 1; /* -1 makes 0 origin */
3beb607b
SL
409 bit = i & 07;
410 o = (i & ~07) >> 3;
258a5c40
SL
411 up->upcs1 = UP_TRE|UP_DCLR|UP_GO;
412 /*
b4736392
SL
413 * Correct while possible bits remain of mask.
414 * Since mask contains 11 bits, we continue while
415 * the bit offset is > -11. Also watch out for
416 * end of this block and the end of the transfer.
258a5c40 417 */
1f4919da 418 while (o < sectsiz && (npf*sectsiz)+o < io->i_cc && bit > -11) {
258a5c40 419 /*
b4736392 420 * addr =
1f4919da 421 * (base address of transfer) +
b4736392
SL
422 * (# sectors transferred before the error) *
423 * (sector size) +
1f4919da 424 * (byte offset to incorrect data)
258a5c40 425 */
1f4919da 426 addr = io->i_ma + (npf * sectsiz) + o;
1f4919da
SL
427 /*
428 * No data transfer occurs with a write check,
429 * so don't correct the resident copy of data.
430 */
dda2842d 431 if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) {
31fec9db 432 if (sc->debug & UPF_ECCDEBUG)
dda2842d
SL
433 printf("addr=0x%x old=0x%x ", addr,
434 (*addr&0xff));
b8ca3ab9 435 *addr ^= (mask << bit);
31fec9db 436 if (sc->debug & UPF_ECCDEBUG)
dda2842d
SL
437 printf("new=0x%x\n", (*addr&0xff));
438 }
1f4919da 439 o++, bit -= 8;
73abfe3c 440 }
3ab40097
SL
441 return (0);
442 }
b4736392
SL
443
444 /*
445 * Bad sector forwarding.
446 */
3ab40097 447 if (flag == BSE) {
258a5c40 448 /*
b4736392
SL
449 * If not in bad sector table,
450 * indicate a hard error to caller.
258a5c40 451 */
258a5c40 452 up->upcs1 = UP_TRE|UP_DCLR|UP_GO;
c48789a9 453 if ((bbn = isbad(&upbad[io->i_adapt][io->i_ctlr][unit], cn, tn, sn)) < 0)
3ab40097 454 return (1);
d483c0fd
KB
455 bbn = (lp->d_ncylinders * lp->d_secpercyl) -
456 lp->d_nsectors - 1 - bbn;
b8ca3ab9 457 twc = up->upwc + sectsiz;
3ab40097 458 up->upwc = - (sectsiz / sizeof (short));
31fec9db 459 if (sc->debug & UPF_BSEDEBUG)
dda2842d 460 printf("revector sn %d to %d\n", sn, bbn);
258a5c40 461 /*
b4736392
SL
462 * Clear the drive & read the replacement
463 * sector. If this is in the middle of a
464 * transfer, then set up the controller
465 * registers in a normal fashion.
466 * The UNIBUS address need not be changed.
467 */
f75b5a26 468 upwaitrdy(up);
d483c0fd 469 if (upstart(io, bbn, lp))
b8ca3ab9
HS
470 return (1); /* error */
471 io->i_errcnt = 0; /* success */
f75b5a26 472 upwaitrdy(up);
3beb607b
SL
473 if ((up->upds & UPDS_ERR) || (up->upcs1 & UP_TRE)) {
474 up->upwc = twc - sectsiz;
b8ca3ab9 475 return (1);
258a5c40
SL
476 }
477 }
960ade39 478 if (twc)
258a5c40 479 up->upwc = twc;
b8ca3ab9 480 return (0);
258a5c40 481}
c48789a9 482#endif /* !SMALL */
258a5c40 483
d483c0fd 484upstart(io, bn, lp)
0839bdeb
SL
485 register struct iob *io;
486 daddr_t bn;
d483c0fd 487 register struct disklabel *lp;
258a5c40 488{
c48789a9
KB
489 register struct updevice *upaddr;
490 register struct up_softc *sc;
258a5c40
SL
491 int sn, tn;
492
b2291f86 493 upaddr = (struct updevice *)ubamem(io->i_adapt, upstd[io->i_ctlr]);
c48789a9 494 sc = &up_softc[io->i_adapt][io->i_ctlr][io->i_unit];
d483c0fd
KB
495 sn = bn % lp->d_secpercyl;
496 tn = sn / lp->d_nsectors;
497 sn = sn % lp->d_nsectors;
498 upaddr->updc = bn / lp->d_secpercyl;
258a5c40 499 upaddr->upda = (tn << 8) + sn;
b8ca3ab9 500 switch (io->i_flgs & F_TYPEMASK) {
0839bdeb
SL
501
502 case F_RDDATA:
503 upaddr->upcs1 = UP_RCOM|UP_GO;
504 break;
505
506 case F_WRDATA:
507 upaddr->upcs1 = UP_WCOM|UP_GO;
258a5c40 508 break;
0839bdeb 509
233fc5c1 510#ifndef SMALL
c48789a9 511 case F_HDR|F_RDDATA:
0839bdeb
SL
512 upaddr->upcs1 = UP_RHDR|UP_GO;
513 break;
514
515 case F_HDR|F_WRDATA:
516 upaddr->upcs1 = UP_WHDR|UP_GO;
258a5c40 517 break;
0839bdeb
SL
518
519 case F_CHECK|F_WRDATA:
520 case F_CHECK|F_RDDATA:
258a5c40
SL
521 upaddr->upcs1 = UP_WCDATA|UP_GO;
522 break;
0839bdeb
SL
523
524 case F_HCHECK|F_WRDATA:
525 case F_HCHECK|F_RDDATA:
258a5c40
SL
526 upaddr->upcs1 = UP_WCHDR|UP_GO;
527 break;
233fc5c1 528#endif
0839bdeb 529
258a5c40 530 default:
0839bdeb
SL
531 io->i_error = ECMD;
532 io->i_flgs &= ~F_TYPEMASK;
533 return (1);
258a5c40 534 }
0839bdeb 535 return (0);
258a5c40
SL
536}
537
c48789a9 538#ifndef SMALL
0839bdeb
SL
539/*ARGSUSED*/
540upioctl(io, cmd, arg)
541 struct iob *io;
542 int cmd;
543 caddr_t arg;
544{
c48789a9 545 register struct up_softc *sc;
b8ca3ab9 546
d483c0fd 547 sc = &up_softc[io->i_adapt][io->i_ctlr][io->i_unit];
b8ca3ab9 548 switch(cmd) {
dda2842d 549 case SAIODEBUG:
31fec9db
MK
550 sc->debug = (int)arg;
551 break;
b8ca3ab9 552 case SAIODEVDATA:
d483c0fd
KB
553 *(struct disklabel *)arg =
554 uplabel[io->i_adapt][io->i_ctlr][io->i_unit];
31fec9db 555 break;
31fec9db 556 case SAIOGBADINFO:
d483c0fd
KB
557 *(struct dkbad *)arg =
558 upbad[io->i_adapt][io->i_ctlr][io->i_unit];
31fec9db 559 break;
31fec9db
MK
560 case SAIOECCLIM:
561 sc->ecclim = (int)arg;
562 break;
31fec9db
MK
563 case SAIORETRIES:
564 sc->retries = (int)arg;
565 break;
31fec9db
MK
566 default:
567 return (ECMD);
b8ca3ab9 568 }
31fec9db 569 return (0);
b8ca3ab9 570}
c48789a9 571#endif /* !SMALL */