|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)hp.c 7.10 (Berkeley) 7/8/88 ! 7: */ ! 8: ! 9: /* ! 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. ! 13: */ ! 14: #include "param.h" ! 15: #include "inode.h" ! 16: #include "fs.h" ! 17: #include "dkbad.h" ! 18: #include "disklabel.h" ! 19: ! 20: #include "../vax/pte.h" ! 21: ! 22: #include "../vaxmba/hpreg.h" ! 23: #include "../vaxmba/mbareg.h" ! 24: ! 25: #include "saio.h" ! 26: #include "savax.h" ! 27: ! 28: #define RETRIES 27 ! 29: ! 30: #define MASKREG(reg) ((reg)&0xffff) ! 31: ! 32: #define MAXBADDESC 126 ! 33: #define SECTSIZ 512 /* sector size in bytes */ ! 34: #define HDRSIZ 4 /* number of bytes in sector header */ ! 35: ! 36: char lbuf[SECTSIZ]; ! 37: ! 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) ! 42: ! 43: u_char hp_offset[16] = { ! 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, ! 48: }; ! 49: ! 50: #define MAXUNIT 8 ! 51: struct disklabel hplabel[MAXNMBA][MAXUNIT]; ! 52: #ifndef SMALL ! 53: struct dkbad hpbad[MAXNMBA][MAXUNIT]; ! 54: int sectsiz; ! 55: #endif ! 56: ! 57: struct hp_softc { ! 58: char type; ! 59: char gottype; ! 60: char ssect; /* 1 when on track w/skip sector */ ! 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; ! 66: } hp_softc[MAXNMBA][MAXUNIT]; ! 67: ! 68: /* ! 69: * When awaiting command completion, don't hang on to the status register ! 70: * since this ties up some controllers. ! 71: */ ! 72: #define HPWAIT(addr) \ ! 73: while ((((addr)->hpds)&HPDS_DRY) == 0) \ ! 74: DELAY(500); ! 75: ! 76: hpopen(io) ! 77: register struct iob *io; ! 78: { ! 79: register unit = io->i_unit; ! 80: register struct hp_softc *sc; ! 81: register struct disklabel *lp; ! 82: struct hpdevice *hpaddr; ! 83: struct disklabel *dlp; ! 84: int error = 0; ! 85: ! 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: } ! 96: if ((u_int)io->i_adapt >= MAXNMBA || !mbainit(io->i_adapt)) ! 97: return (EADAPT); ! 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]; ! 103: if (sc->gottype == 0) { ! 104: register int i; ! 105: struct iob tio; ! 106: ! 107: #ifndef SMALL ! 108: sc->retries = RETRIES; ! 109: sc->ecclim = 11; ! 110: sc->debug = 0; ! 111: #endif ! 112: hpaddr->hpcs1 = HP_DCLR|HP_GO; /* init drive */ ! 113: hpaddr->hpcs1 = HP_PRESET|HP_GO; ! 114: #ifndef SMALL ! 115: if ((hpaddr->hpds & HPDS_DPR) == 0) ! 116: return (ENXIO); ! 117: sc->type = hpaddr->hpdt & MBDT_TYPE; ! 118: if (sc->type == MBDT_ML11B) ! 119: sc->type = MBDT_ML11A; ! 120: if (!ML11(sc->type)) ! 121: #endif ! 122: hpaddr->hpof = HPOF_FMT22; ! 123: /* ! 124: * Read in the pack label. ! 125: */ ! 126: lp->d_nsectors = 32; ! 127: lp->d_secpercyl = 20*32; ! 128: tio = *io; ! 129: tio.i_bn = LABELSECTOR; ! 130: tio.i_ma = lbuf; ! 131: tio.i_cc = SECTSIZ; ! 132: tio.i_flgs |= F_RDDATA; ! 133: if (hpstrategy(&tio, READ) != SECTSIZ) ! 134: error = ERDLAB; ! 135: dlp = (struct disklabel *)(lbuf + LABELOFFSET); ! 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 ! 142: #ifdef COMPAT_42 ! 143: if (hpmaptype(hpaddr, hpaddr->hpdt & MBDT_TYPE, unit, lp) == 0) ! 144: #endif ! 145: return (error); ! 146: ! 147: #ifndef SMALL ! 148: /* ! 149: * Read in the bad sector table. ! 150: */ ! 151: tio.i_bn = lp->d_secpercyl * lp->d_ncylinders - lp->d_nsectors; ! 152: tio.i_ma = (char *)&hpbad[io->i_adapt][unit]; ! 153: tio.i_cc = sizeof(struct dkbad); ! 154: for (i = 0; i < 5; i++) { ! 155: if (hpstrategy(&tio, READ) == sizeof(struct dkbad)) ! 156: break; ! 157: tio.i_bn += 2; ! 158: } ! 159: if (i == 5) { ! 160: printf("hp: can't read bad sector table\n"); ! 161: for (i = 0; i < MAXBADDESC; i++) { ! 162: hpbad[io->i_adapt][unit].bt_bad[i].bt_cyl = -1; ! 163: hpbad[io->i_adapt][unit].bt_bad[i].bt_trksec = -1; ! 164: } ! 165: } ! 166: #endif ! 167: sc->gottype = 1; ! 168: } ! 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; ! 173: return (0); ! 174: } ! 175: ! 176: hpstrategy(io, func) ! 177: register struct iob *io; ! 178: { ! 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; ! 184: daddr_t bn, startblock; ! 185: int cn, tn, sn, bytecnt, bytesleft, rv; ! 186: int er1, er2, hprecal; ! 187: char *membase; ! 188: ! 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]; ! 193: #ifndef SMALL ! 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; ! 200: if (!ML11(sc->type)) ! 201: hpaddr->hpof = HPOF_FMT22; ! 202: } ! 203: io->i_errcnt = 0; ! 204: sc->ssect = 0; ! 205: rv = bytecnt = io->i_cc; ! 206: membase = io->i_ma; ! 207: startblock = io->i_bn; ! 208: hprecal = 0; ! 209: #endif ! 210: ! 211: restart: ! 212: bn = io->i_bn; ! 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; ! 217: ! 218: HPWAIT(hpaddr); ! 219: mba->mba_sr = -1; ! 220: if (ML11(sc->type)) ! 221: hpaddr->hpda = bn; ! 222: else { ! 223: hpaddr->hpdc = cn; ! 224: hpaddr->hpda = (tn << 8) + sn; ! 225: } ! 226: #ifdef SMALL ! 227: mbastart(io, io->i_unit, func); /* start transfer */ ! 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 ! 237: if (mbastart(io, io->i_unit, func) != 0) { /* start transfer */ ! 238: rv = -1; ! 239: goto done; ! 240: } ! 241: HPWAIT(hpaddr); ! 242: /* ! 243: * Successful data transfer, return. ! 244: */ ! 245: if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0) ! 246: goto done; ! 247: ! 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; ! 255: er1 = MASKREG(hpaddr->hper1); ! 256: er2 = MASKREG(hpaddr->hper2); ! 257: if (er1 & (HPER1_DCK|HPER1_ECH)) ! 258: bn--; /* Error is in Prev block */ ! 259: cn = bn/lp->d_secpercyl; ! 260: sn = bn%lp->d_secpercyl; ! 261: tn = sn/lp->d_nsectors; ! 262: sn = sn%lp->d_nsectors; ! 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); ! 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: } ! 270: if (er1 & HPER1_HCRC) { ! 271: er1 &= ~(HPER1_HCE|HPER1_FER); ! 272: er2 &= ~HPER2_BSE; ! 273: if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0) ! 274: goto success; ! 275: } ! 276: /* ! 277: * Give up early if drive write locked. ! 278: */ ! 279: if (er1&HPER1_WLE) { ! 280: printf("hp%d: write locked\n", unit); ! 281: rv = -1; ! 282: goto done; ! 283: } ! 284: /* ! 285: * Skip sector handling. ! 286: */ ! 287: if (RM80(sc->type) && (er2 & HPER2_SSE)) { ! 288: (void) hpecc(io, SSE); ! 289: sc->ssect = 1; ! 290: goto restart; ! 291: } ! 292: /* ! 293: * Attempt to forward bad sectors on anything but an ML11. ! 294: * Interpret format error bit as a bad block on RP06's. ! 295: */ ! 296: if (((er2 & HPER2_BSE) && !ML11(sc->type)) || ! 297: (MASKREG(er1) == HPER1_FER && RP06(sc->type))) { ! 298: if (io->i_flgs & F_NBSF) { ! 299: io->i_error = EBSE; ! 300: goto hard; ! 301: } ! 302: if (hpecc(io, BSE) == 0) ! 303: goto success; ! 304: io->i_error = EBSE; ! 305: goto hard; ! 306: } ! 307: /* ! 308: * ECC correction? ! 309: */ ! 310: if ((er1 & (HPER1_DCK|HPER1_ECH)) == HPER1_DCK) { ! 311: if (hpecc(io, ECC) == 0) ! 312: goto success; ! 313: io->i_error = EECC; ! 314: goto hard; ! 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) || ! 323: (!ML11(sc->type) && (er2 & HPER2_HARD)) || ! 324: (ML11(sc->type) && (io->i_errcnt >= 16))) { ! 325: io->i_error = EHER; ! 326: if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR)) ! 327: io->i_error = EWCK; ! 328: hard: ! 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: } ! 344: /* fall thru to retry */ ! 345: hpaddr->hpcs1 = HP_DCLR|HP_GO; ! 346: HPWAIT(hpaddr); ! 347: ! 348: /* ! 349: * Every fourth retry recalibrate. ! 350: */ ! 351: if (((io->i_errcnt & 07) == 4) ) { ! 352: hpaddr->hpcs1 = HP_RECAL|HP_GO; ! 353: HPWAIT(hpaddr); ! 354: hpaddr->hpdc = cn; ! 355: hpaddr->hpcs1 = HP_SEEK|HP_GO; ! 356: HPWAIT(hpaddr); ! 357: } ! 358: ! 359: if (io->i_errcnt >= 16 && (io->i_flgs & F_READ)) { ! 360: hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22; ! 361: hpaddr->hpcs1 = HP_OFFSET|HP_GO; ! 362: HPWAIT(hpaddr); ! 363: } ! 364: if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) ! 365: printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n", ! 366: io->i_bn, io->i_cc, io->i_ma, hprecal); ! 367: goto restart; ! 368: ! 369: success: ! 370: /* ! 371: * On successful error recovery, bump ! 372: * block number to advance to next portion ! 373: * of i/o transfer. ! 374: */ ! 375: bn++; ! 376: if ((bn-startblock) * sectsiz < bytecnt) { ! 377: io->i_bn = bn; ! 378: io->i_ma = membase + (io->i_bn - startblock)*sectsiz; ! 379: io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz; ! 380: if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) ! 381: printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n", ! 382: io->i_bn, io->i_cc, io->i_ma, hprecal); ! 383: goto restart; ! 384: } ! 385: done: ! 386: if (io->i_errcnt >= 16) { ! 387: hpaddr->hpcs1 = HP_RTC|HP_GO; ! 388: while (hpaddr->hpds & HPDS_PIP) ! 389: ; ! 390: } ! 391: io->i_bn = startblock; /*reset i_bn to original */ ! 392: io->i_cc = bytecnt; /*reset i_cc to total count xfered*/ ! 393: io->i_ma = membase; /*reset i_ma to original */ ! 394: return (rv); ! 395: #endif ! 396: } ! 397: ! 398: #ifndef SMALL ! 399: hpecc(io, flag) ! 400: register struct iob *io; ! 401: int flag; ! 402: { ! 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; ! 408: int npf, bn, cn, tn, sn, bcr; ! 409: ! 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]; ! 414: bcr = MASKREG(mbp->mba_bcr); ! 415: if (bcr) ! 416: bcr |= 0xffff0000; /* sxt */ ! 417: npf = (bcr + io->i_cc) / sectsiz; /* # sectors read */ ! 418: if (flag == ECC) ! 419: npf--; /* Error is in prev block --ghg */ ! 420: bn = io->i_bn + npf + sc->ssect; /* physical block #*/ ! 421: if (sc->debug & HPF_ECCDEBUG) ! 422: printf("bcr=%d npf=%d ssect=%d sectsiz=%d i_cc=%d\n", ! 423: bcr, npf, sc->ssect, sectsiz, io->i_cc); ! 424: /* ! 425: * ECC correction logic. ! 426: */ ! 427: if (flag == ECC) { ! 428: register int i; ! 429: caddr_t addr; ! 430: int bit, o, mask; ! 431: ! 432: printf("hp%d: soft ecc sn%d\n", unit, bn); ! 433: mask = MASKREG(rp->hpec2); ! 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: } ! 441: i = MASKREG(rp->hpec1) - 1; /* -1 makes 0 origin */ ! 442: bit = i&07; ! 443: o = (i & ~07) >> 3; ! 444: rp->hpcs1 = HP_DCLR | HP_GO; ! 445: while (o <sectsiz && npf*sectsiz + o < io->i_cc && bit > -11) { ! 446: addr = io->i_ma + (npf*sectsiz) + o; ! 447: /* ! 448: * No data transfer occurs with a write check, ! 449: * so don't correct the resident copy of data. ! 450: */ ! 451: if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) { ! 452: if (sc->debug & HPF_ECCDEBUG) ! 453: printf("addr=%x old=%x ", addr, ! 454: (*addr & 0xff)); ! 455: *addr ^= (mask << bit); ! 456: if (sc->debug & HPF_ECCDEBUG) ! 457: printf("new=%x\n",(*addr & 0xff)); ! 458: } ! 459: o++, bit -= 8; ! 460: } ! 461: return (0); ! 462: } ! 463: ! 464: /* ! 465: * Skip sector error. ! 466: * Set skip-sector-inhibit and ! 467: * read next sector ! 468: */ ! 469: if (flag == SSE) { ! 470: rp->hpcs1 = HP_DCLR | HP_GO; ! 471: HPWAIT(rp); ! 472: rp->hpof |= HPOF_SSEI; ! 473: return (0); ! 474: } ! 475: ! 476: /* ! 477: * Bad block forwarding. ! 478: */ ! 479: if (flag == BSE) { ! 480: int bbn; ! 481: ! 482: rp->hpcs1 = HP_DCLR | HP_GO; ! 483: if (sc->debug & HPF_BSEDEBUG) ! 484: printf("hpecc: BSE @ bn %d\n", bn); ! 485: cn = bn / lp->d_secpercyl; ! 486: sn = bn % lp->d_secpercyl; ! 487: tn = sn / lp->d_nsectors; ! 488: sn = sn % lp->d_nsectors; ! 489: bcr += sectsiz; ! 490: if ((bbn = isbad(&hpbad[io->i_adapt][unit], cn, tn, sn)) < 0) ! 491: return (1); ! 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; ! 497: sn = sn % lp->d_nsectors; ! 498: io->i_cc = sectsiz; ! 499: io->i_ma += npf * sectsiz; ! 500: if (sc->debug & HPF_BSEDEBUG) ! 501: printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); ! 502: rp->hpof &= ~HPOF_SSEI; ! 503: mbp->mba_sr = -1; ! 504: rp->hpdc = cn; ! 505: rp->hpda = (tn<<8) + sn; ! 506: mbastart(io, io->i_unit, io->i_flgs); ! 507: io->i_errcnt = 0; ! 508: HPWAIT(rp); ! 509: return (rp->hpds&HPDS_ERR); ! 510: } ! 511: printf("hpecc: flag=%d\n", flag); ! 512: return (1); ! 513: } ! 514: ! 515: /*ARGSUSED*/ ! 516: hpioctl(io, cmd, arg) ! 517: struct iob *io; ! 518: int cmd; ! 519: caddr_t arg; ! 520: { ! 521: register unit = io->i_unit; ! 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); ! 525: ! 526: switch(cmd) { ! 527: ! 528: case SAIODEBUG: ! 529: sc->debug = (int)arg; ! 530: break; ! 531: ! 532: case SAIODEVDATA: ! 533: if (drv->mbd_dt&MBDT_TAP) ! 534: return (ECMD); ! 535: *(struct disklabel *)arg = *lp; ! 536: break; ! 537: ! 538: case SAIOGBADINFO: ! 539: if (drv->mbd_dt&MBDT_TAP) ! 540: return (ECMD); ! 541: *(struct dkbad *)arg = hpbad[io->i_adapt][unit]; ! 542: break; ! 543: ! 544: case SAIOECCLIM: ! 545: sc->ecclim = (int)arg; ! 546: break; ! 547: ! 548: case SAIORETRIES: ! 549: sc->retries = (int)arg; ! 550: break; ! 551: ! 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; ! 558: lp->d_nsectors++; ! 559: lp->d_secpercyl += lp->d_ntracks; ! 560: } ! 561: break; ! 562: ! 563: case SAIONOSSI: /* remove skip-sector-inhibit */ ! 564: if (io->i_flgs & F_SSI) { ! 565: io->i_flgs &= ~F_SSI; ! 566: drv->mbd_of &= ~HPOF_SSEI; ! 567: lp->d_nsectors--; ! 568: lp->d_secpercyl -= lp->d_ntracks; ! 569: } ! 570: break; ! 571: ! 572: case SAIOSSDEV: /* drive have skip sector? */ ! 573: return (RM80(sc->type) ? 0 : ECMD); ! 574: ! 575: default: ! 576: return (ECMD); ! 577: } ! 578: return (0); ! 579: } ! 580: #endif /* !SMALL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.