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