Annotation of 42BSD/sys/stand/hp.c, revision 1.1

1.1     ! root        1: /*     hp.c    6.3     83/09/23        */
        !             2: 
        !             3: /*
        !             4:  * RP??/RM?? disk driver
        !             5:  * with ECC handling and bad block forwarding.
        !             6:  * Also supports header io operations and
        !             7:  * commands to write check header and data.
        !             8:  */
        !             9: #include "../h/param.h"
        !            10: #include "../h/inode.h"
        !            11: #include "../h/fs.h"
        !            12: #include "../h/dkbad.h"
        !            13: 
        !            14: #include "../vax/pte.h"
        !            15: #include "../vaxmba/hpreg.h"
        !            16: #include "../vaxmba/mbareg.h"
        !            17: 
        !            18: #include "saio.h"
        !            19: #include "savax.h"
        !            20: 
        !            21: #define        MASKREG(reg)    ((reg)&0xffff)
        !            22: 
        !            23: #define        MAXBADDESC      126
        !            24: #define        SECTSIZ         512     /* sector size in bytes */
        !            25: #define        HDRSIZ          4       /* number of bytes in sector header */
        !            26: #define        MAXECC          5       /* max # bits allow in ecc error w/ F_ECCLM */
        !            27: 
        !            28: char   hp_type[MAXNMBA*8] = { 0 };
        !            29: extern struct st hpst[];
        !            30: 
        !            31: short  hptypes[] = {
        !            32:        MBDT_RM03,
        !            33:        MBDT_RM05,
        !            34:        MBDT_RP06,
        !            35:        MBDT_RM80,
        !            36:        MBDT_RP05,
        !            37:        MBDT_RP07,
        !            38:        MBDT_ML11A,
        !            39:        MBDT_ML11B,
        !            40:        -1,             /* 9755 */
        !            41:        -1,             /* 9730 */
        !            42:        -1,             /* Capricorn */
        !            43:        -1,             /* Eagle */
        !            44:        MBDT_RM02,      /* actually something else */
        !            45:        -1,             /* 9300 */
        !            46:        0
        !            47: };
        !            48: 
        !            49: #define        RP06 (hptypes[hp_type[unit]] <= MBDT_RP06)
        !            50: #define        ML11 (hptypes[hp_type[unit]] == MBDT_ML11A)
        !            51: #define        RM80 (hptypes[hp_type[unit]] == MBDT_RM80)
        !            52: 
        !            53: u_char hp_offset[16] = {
        !            54:     HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400,
        !            55:     HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800,
        !            56:     HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200,
        !            57:     0, 0, 0, 0,
        !            58: };
        !            59: 
        !            60: struct dkbad hpbad[MAXNMBA*8];
        !            61: int    ssect[MAXNMBA*8];               /* 1 when on track w/skip sector */
        !            62: 
        !            63: int    hpdebug[MAXNMBA*8];
        !            64: #define        HPF_BSEDEBUG    01      /* debugging bad sector forwarding */
        !            65: #define        HPF_ECCDEBUG    02      /* debugging ecc correction */
        !            66: 
        !            67: int    sectsiz;
        !            68: 
        !            69: /*
        !            70:  * When awaiting command completion, don't
        !            71:  * hang on to the status register since
        !            72:  * this ties up some controllers.
        !            73:  */
        !            74: #define        HPWAIT(addr) \
        !            75:        while ((((addr)->hpds)&HPDS_DRY)==0) DELAY(500);
        !            76: 
        !            77: hpopen(io)
        !            78:        register struct iob *io;
        !            79: {
        !            80:        register unit = io->i_unit;
        !            81:        struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit);
        !            82:        register struct st *st;
        !            83: 
        !            84:        mbainit(UNITTOMBA(unit));
        !            85:        if (hp_type[unit] == 0) {
        !            86:                register i, type = hpaddr->hpdt & MBDT_TYPE;
        !            87:                struct iob tio;
        !            88: 
        !            89:                for (i = 0; hptypes[i]; i++)
        !            90:                        if (hptypes[i] == type)
        !            91:                                goto found;
        !            92:                _stop("unknown drive type");
        !            93: found:
        !            94:                hpaddr->hpcs1 = HP_DCLR|HP_GO;          /* init drive */
        !            95:                hpaddr->hpcs1 = HP_PRESET|HP_GO;
        !            96:                if (!ML11)
        !            97:                        hpaddr->hpof = HPOF_FMT22;
        !            98:                hp_type[unit] = hpmaptype(hpaddr, i, unit);
        !            99:                /*
        !           100:                 * Read in the bad sector table.
        !           101:                 */
        !           102:                st = &hpst[hp_type[unit]];
        !           103:                tio = *io;
        !           104:                tio.i_bn = st->nspc * st->ncyl - st->nsect;
        !           105:                tio.i_ma = (char *)&hpbad[unit];
        !           106:                tio.i_cc = sizeof (struct dkbad);
        !           107:                tio.i_flgs |= F_RDDATA;
        !           108:                for (i = 0; i < 5; i++) {
        !           109:                        if (hpstrategy(&tio, READ) == sizeof (struct dkbad))
        !           110:                                break;
        !           111:                        tio.i_bn += 2;
        !           112:                }
        !           113:                if (i == 5) {
        !           114:                        printf("Unable to read bad sector table\n");
        !           115:                        for (i = 0; i < MAXBADDESC; i++) {
        !           116:                                hpbad[unit].bt_bad[i].bt_cyl = -1;
        !           117:                                hpbad[unit].bt_bad[i].bt_trksec = -1;
        !           118:                        }
        !           119:                }       
        !           120:        }
        !           121:        if (io->i_boff < 0 || io->i_boff > 7 ||
        !           122:            st->off[io->i_boff]== -1)
        !           123:                _stop("hp bad minor");
        !           124:        io->i_boff = st->off[io->i_boff] * st->nspc;
        !           125: }
        !           126: 
        !           127: hpstrategy(io, func)
        !           128:        register struct iob *io;
        !           129: {
        !           130:        register unit = io->i_unit;
        !           131:        struct mba_regs *mba = mbamba(unit);
        !           132:        daddr_t bn, startblock;
        !           133:        struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit);
        !           134:        struct st *st = &hpst[hp_type[unit]];
        !           135:        int cn, tn, sn, bytecnt, bytesleft; 
        !           136:        char *membase;
        !           137:        int er1, er2, hprecal;
        !           138: 
        !           139:        sectsiz = SECTSIZ;
        !           140:        if ((io->i_flgs & (F_HDR|F_HCHECK)) != 0)
        !           141:                sectsiz += HDRSIZ;
        !           142:        if ((hpaddr->hpds & HPDS_VV) == 0) {
        !           143:                hpaddr->hpcs1 = HP_DCLR|HP_GO;
        !           144:                hpaddr->hpcs1 = HP_PRESET|HP_GO;
        !           145:                if (!ML11)
        !           146:                        hpaddr->hpof = HPOF_FMT22;
        !           147:        }
        !           148:        io->i_errcnt = 0;
        !           149:        ssect[unit] = 0;
        !           150:        bytecnt = io->i_cc;
        !           151:        membase = io->i_ma;
        !           152:        startblock = io->i_bn;
        !           153:        hprecal = 0;
        !           154: 
        !           155: restart:
        !           156:        bn = io->i_bn;
        !           157:        cn = bn/st->nspc;
        !           158:        sn = bn%st->nspc;
        !           159:        tn = sn/st->nsect;
        !           160:        sn = sn%st->nsect + ssect[unit];
        !           161: 
        !           162:        HPWAIT(hpaddr);
        !           163:        mba->mba_sr = -1;
        !           164:        if (ML11)
        !           165:                hpaddr->hpda = bn;
        !           166:        else {
        !           167:                hpaddr->hpdc = cn;
        !           168:                hpaddr->hpda = (tn << 8) + sn;
        !           169:        }
        !           170:        if (mbastart(io, func) != 0)            /* start transfer */
        !           171:                return (-1);
        !           172:        HPWAIT(hpaddr);
        !           173:        /*
        !           174:         * Successful data transfer, return.
        !           175:         */
        !           176:        if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0)
        !           177:                goto done;
        !           178: 
        !           179:        /*
        !           180:         * Error handling.  Calculate location of error.
        !           181:         */
        !           182:        bytesleft = MASKREG(mba->mba_bcr);
        !           183:        if (bytesleft) 
        !           184:                bytesleft |= 0xffff0000;        /* sxt */
        !           185:        bn = io->i_bn + (io->i_cc + bytesleft) / sectsiz;
        !           186:        er1 = MASKREG(hpaddr->hper1);
        !           187:        er2 = MASKREG(hpaddr->hper2);
        !           188:        if (er1 & (HPER1_DCK|HPER1_ECH))
        !           189:                bn--;   /* Error is in Prev block */
        !           190:        cn = bn/st->nspc;
        !           191:        sn = bn%st->nspc;
        !           192:        tn = sn/st->nsect;
        !           193:        sn = sn%st->nsect;
        !           194:        if (hpdebug[unit] & (HPF_ECCDEBUG|HPF_BSEDEBUG)) {
        !           195:                printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b\n",
        !           196:                        cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
        !           197:                printf("er1=%b er2=%b\n", er1, HPER1_BITS, er2, HPER2_BITS);
        !           198:                printf("bytes left: %d, of 0x%x, da 0x%x\n",-bytesleft,
        !           199:                        hpaddr->hpof, hpaddr->hpda);
        !           200:        }
        !           201:        if (er1 & HPER1_HCRC) {
        !           202:                er1 &= ~(HPER1_HCE|HPER1_FER);
        !           203:                er2 &= ~HPER2_BSE;
        !           204:        }
        !           205:        /*
        !           206:         * Give up early if drive write locked.
        !           207:         */
        !           208:        if (er1&HPER1_WLE) {
        !           209:                printf("hp%d: write locked\n", unit);
        !           210:                return (-1);
        !           211:        }
        !           212:        /*
        !           213:         * Interpret format error bit as a bad block on RP06's.
        !           214:         */
        !           215:        if (MASKREG(er1) == HPER1_FER && RP06)
        !           216:                goto badsect;
        !           217: 
        !           218:        /*
        !           219:         * If a hard error, or maximum retry count
        !           220:         * exceeded, clear controller state and
        !           221:         * pass back error to caller.
        !           222:         */
        !           223:        if (++io->i_errcnt > 27 || (er1 & HPER1_HARD) ||
        !           224:            (!ML11 && (er2 & HPER2_HARD))) {
        !           225:                /*
        !           226:                 * The last ditch effort to bad sector forward
        !           227:                 * below will probably fail since mba byte ctr
        !           228:                 * (bcr) is different for BSE and ECC errors and
        !           229:                 * the wrong block will be revectored to if one
        !           230:                 * has 2 contiguous bad blocks and reads the second.
        !           231:                 * For now, we can probably just let a header CRC
        !           232:                 * error be handled like a BSE since no data will
        !           233:                 * have been transferred and the bcr should the same
        !           234:                 * as it would with a BSE error.
        !           235:                 * --ghg.
        !           236:                 */
        !           237:                if (er1 & HPER1_HCRC) 
        !           238:                        if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0)
        !           239:                                goto success;
        !           240: hard0:
        !           241:                io->i_error = EHER;
        !           242:                if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR))
        !           243:                        io->i_error = EWCK;
        !           244: hard:
        !           245:                io->i_errblk = bn + ssect[unit];
        !           246:                printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n",
        !           247:                           cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
        !           248:                printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS);
        !           249:                if (hpaddr->hpmr)
        !           250:                        printf(" mr1=%o", MASKREG(hpaddr->hpmr));
        !           251:                if (hpaddr->hpmr2)
        !           252:                        printf(" mr2=%o", MASKREG(hpaddr->hpmr2));
        !           253:                if (hpdebug[unit] & (HPF_BSEDEBUG|HPF_ECCDEBUG))
        !           254:                        printf(" dc=%d, da=0x%x",MASKREG(hpaddr->hpdc),
        !           255:                          MASKREG(hpaddr->hpda));
        !           256:                hpaddr->hpcs1 = HP_DCLR|HP_GO;
        !           257:                printf("\n");
        !           258:                bytecnt = -1;
        !           259:                goto done;
        !           260: 
        !           261:        }
        !           262:        /*
        !           263:         * Attempt to forward bad sectors on
        !           264:         * anything but an ML11.  If drive
        !           265:         * supports skip sector handling, try to
        !           266:         * use it first; otherwise try the
        !           267:         * bad sector table.
        !           268:         */
        !           269:        if ((er2 & HPER2_BSE) && !ML11) {
        !           270: badsect:
        !           271:                if (!ssect[unit] && (er2&HPER2_SSE))
        !           272:                        goto skipsect;
        !           273:                if (io->i_flgs & F_NBSF) {
        !           274:                        io->i_error = EBSE;     
        !           275:                        goto hard;
        !           276:                }
        !           277:                if (hpecc(io, BSE) == 0)
        !           278:                        goto success;
        !           279:                io->i_error = EBSE;
        !           280:                goto hard;
        !           281:        }
        !           282: 
        !           283:        /*
        !           284:         * Skip sector handling.
        !           285:         */
        !           286:        if (RM80 && (er2 & HPER2_SSE)) {
        !           287: skipsect:
        !           288:                (void) hpecc(io, SSE);
        !           289:                ssect[unit] = 1;
        !           290:                goto success;
        !           291:        }
        !           292:        /*
        !           293:         * ECC correction?
        !           294:         */
        !           295:        if ((er1 & (HPER1_DCK|HPER1_ECH)) == HPER1_DCK) {
        !           296:                if (hpecc(io, ECC) == 0)
        !           297:                        goto success;
        !           298:                io->i_error = EECC;
        !           299:                io->i_errblk = bn + ssect[unit];
        !           300:                return (-1);    
        !           301:        } 
        !           302: #ifdef F_SEVRE
        !           303:        if (io->i_flgs & F_SEVRE)
        !           304:                goto hard;
        !           305: #endif
        !           306:        if (ML11 && (io->i_errcnt >= 16))
        !           307:                goto hard0;
        !           308:        /* fall thru to retry */
        !           309:        hpaddr->hpcs1 = HP_DCLR|HP_GO;
        !           310:        HPWAIT(hpaddr);
        !           311: 
        !           312:        /* 
        !           313:         * Every fourth retry recalibrate.
        !           314:         */
        !           315:        if (((io->i_errcnt & 07) == 4) ) {
        !           316:                hpaddr->hpcs1 = HP_RECAL|HP_GO;
        !           317:                HPWAIT(hpaddr);
        !           318:                hpaddr->hpdc = cn;
        !           319:                hpaddr->hpcs1 = HP_SEEK|HP_GO;
        !           320:                HPWAIT(hpaddr);
        !           321:        }
        !           322: 
        !           323:        if (io->i_errcnt >= 16 && (io->i_flgs & F_READ)) {
        !           324:                hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22;
        !           325:                hpaddr->hpcs1 = HP_OFFSET|HP_GO;
        !           326:                HPWAIT(hpaddr);
        !           327:        }
        !           328:        if (hpdebug[unit] & (HPF_ECCDEBUG|HPF_BSEDEBUG))
        !           329:                printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n",
        !           330:                  io->i_bn, io->i_cc, io->i_ma, hprecal);
        !           331:        goto restart;   /* retry whole transfer  --ghg */
        !           332: 
        !           333: success:
        !           334:        /*
        !           335:         * On successful error recovery, bump
        !           336:         * block number to advance to next portion
        !           337:         * of i/o transfer.
        !           338:         */
        !           339:        bn++;
        !           340:        if ((bn-startblock) * sectsiz < bytecnt) {
        !           341:                io->i_bn = bn;
        !           342:                io->i_ma = membase + (io->i_bn - startblock)*sectsiz;
        !           343:                io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz;
        !           344:                if (hpdebug[unit] & (HPF_ECCDEBUG|HPF_BSEDEBUG))
        !           345:                        printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n",
        !           346:                          io->i_bn, io->i_cc, io->i_ma, hprecal);
        !           347:                goto restart;
        !           348:        }
        !           349: done:
        !           350:        if (io->i_errcnt >= 16) {
        !           351:                hpaddr->hpcs1 = HP_RTC|HP_GO;
        !           352:                while (hpaddr->hpds & HPDS_PIP)
        !           353:                        ;
        !           354:        }
        !           355:        return (bytecnt);
        !           356: }
        !           357: 
        !           358: hpecc(io, flag)
        !           359:        register struct iob *io;
        !           360:        int flag;
        !           361: {
        !           362:        register unit = io->i_unit;
        !           363:        register struct mba_regs *mbp = mbamba(unit);
        !           364:        register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit);
        !           365:        register struct st *st = &hpst[hp_type[unit]];
        !           366:        int npf, bn, cn, tn, sn, bcr;
        !           367: 
        !           368:        bcr = MASKREG(mbp->mba_bcr);
        !           369:        if (bcr)
        !           370:                bcr |= 0xffff0000;              /* sxt */
        !           371:        npf = (bcr + io->i_cc) / sectsiz;       /* # sectors read */
        !           372:        if (flag == ECC)
        !           373:                npf--;          /* Error is in prev block --ghg */
        !           374:        bn = io->i_bn + npf + ssect[unit];      /* physical block #*/
        !           375:        if (hpdebug[unit]&HPF_ECCDEBUG)
        !           376:                printf("bcr=%d npf=%d ssect=%d sectsiz=%d i_cc=%d\n",
        !           377:                        bcr, npf, ssect[unit], sectsiz, io->i_cc);
        !           378:        /*
        !           379:         * ECC correction logic.
        !           380:         */
        !           381:        if (flag == ECC) {
        !           382:                register int i;
        !           383:                caddr_t addr;
        !           384:                int bit, o, mask, ecccnt = 0;
        !           385: 
        !           386:                printf("hp%d: soft ecc sn%d\n", unit, bn);
        !           387:                mask = MASKREG(rp->hpec2);
        !           388:                i = MASKREG(rp->hpec1) - 1;     /* -1 makes 0 origin */
        !           389:                bit = i&07;
        !           390:                o = (i & ~07) >> 3;
        !           391:                rp->hpcs1 = HP_DCLR | HP_GO;
        !           392:                while (o <sectsiz && npf*sectsiz + o < io->i_cc && bit > -11) {
        !           393:                        addr = io->i_ma + (npf*sectsiz) + o;
        !           394:                        /*
        !           395:                         * No data transfer occurs with a write check,
        !           396:                         * so don't correct the resident copy of data.
        !           397:                         */
        !           398:                        if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) {
        !           399:                                if (hpdebug[unit] & HPF_ECCDEBUG)
        !           400:                                        printf("addr=%x old=%x ", addr,
        !           401:                                                (*addr & 0xff));
        !           402:                                *addr ^= (mask << bit);
        !           403:                                if (hpdebug[unit] & HPF_ECCDEBUG)
        !           404:                                        printf("new=%x\n",(*addr & 0xff));
        !           405:                        }
        !           406:                        o++, bit -= 8;
        !           407:                        if ((io->i_flgs & F_ECCLM) && ecccnt++ >= MAXECC)
        !           408:                                return (1);
        !           409:                }
        !           410: #ifdef F_SEVRE
        !           411:                if (io->i_flgs & F_SEVRE)
        !           412:                        return(1);
        !           413: #endif
        !           414:                return (0);
        !           415:        }
        !           416: 
        !           417:        /*
        !           418:         * Skip sector error.
        !           419:         * Set skip-sector-inhibit and
        !           420:         * read next sector
        !           421:         */
        !           422:        if (flag == SSE) {
        !           423:                rp->hpcs1 = HP_DCLR | HP_GO;
        !           424:                HPWAIT(rp);
        !           425:                rp->hpof |= HPOF_SSEI;
        !           426:                return (0);     
        !           427:        }
        !           428: 
        !           429:        /*
        !           430:         * Bad block forwarding.
        !           431:         */
        !           432:         if (flag == BSE) {
        !           433:                int bbn;
        !           434: 
        !           435:                rp->hpcs1 = HP_DCLR | HP_GO;
        !           436:                if (hpdebug[unit] & HPF_BSEDEBUG)
        !           437:                        printf("hpecc: BSE @ bn %d\n", bn);
        !           438:                cn = bn/st->nspc;
        !           439:                sn = bn%st->nspc;
        !           440:                tn = sn/st->nsect;
        !           441:                sn = sn%st->nsect;
        !           442:                bcr += sectsiz;
        !           443:                if ((bbn = isbad(&hpbad[unit], cn, tn, sn)) < 0)
        !           444:                        return (1);
        !           445:                bbn = st->ncyl*st->nspc - st->nsect - 1 - bbn;
        !           446:                cn = bbn/st->nspc;
        !           447:                sn = bbn%st->nspc;
        !           448:                tn = sn/st->nsect;
        !           449:                sn = sn%st->nsect;
        !           450:                io->i_cc = sectsiz;
        !           451:                io->i_ma += npf*sectsiz;
        !           452:                if (hpdebug[unit] & HPF_BSEDEBUG)
        !           453:                        printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
        !           454:                rp->hpof &= ~HPOF_SSEI;
        !           455:                mbp->mba_sr = -1;
        !           456:                rp->hpdc = cn;
        !           457:                rp->hpda = (tn<<8) + sn;
        !           458:                mbastart(io,io->i_flgs);
        !           459:                io->i_errcnt = 0;
        !           460:                HPWAIT(rp);
        !           461:                return (rp->hpds&HPDS_ERR);
        !           462:        }
        !           463:        printf("hpecc: flag=%d\n", flag);
        !           464:        return (1);
        !           465: }
        !           466: 
        !           467: /*ARGSUSED*/
        !           468: hpioctl(io, cmd, arg)
        !           469:        struct iob *io;
        !           470:        int cmd;
        !           471:        caddr_t arg;
        !           472: {
        !           473:        register unit = io->i_unit;
        !           474:        struct st *st = &hpst[hp_type[unit]], *tmp;
        !           475:        struct mba_drv *drv = mbadrv(unit);
        !           476:        int flag;
        !           477: 
        !           478:        switch(cmd) {
        !           479: 
        !           480:        case SAIODEBUG:
        !           481:                flag = (int)arg;
        !           482:                if (flag > 0)
        !           483:                        hpdebug[unit] |= flag;
        !           484:                else
        !           485:                        hpdebug[unit] &= ~flag;
        !           486:                return (0);
        !           487: 
        !           488:        case SAIODEVDATA:
        !           489:                if ((drv->mbd_dt&MBDT_TAP) == 0) {
        !           490:                        tmp = (struct st *)arg;
        !           491:                        *tmp = *st;
        !           492:                        return (0);
        !           493:                }
        !           494:                return (ECMD);
        !           495: 
        !           496:        case SAIOSSI:                   /* skip-sector-inhibit */
        !           497:                if (drv->mbd_dt&MBDT_TAP)
        !           498:                        return (ECMD);
        !           499:                if ((io->i_flgs&F_SSI) == 0) {
        !           500:                        /* make sure this is done once only */
        !           501:                        io->i_flgs |= F_SSI;
        !           502:                        st->nsect++;
        !           503:                        st->nspc += st->ntrak;
        !           504:                }
        !           505:                return (0);
        !           506: 
        !           507:        case SAIONOSSI:                 /* remove skip-sector-inhibit */
        !           508:                if (io->i_flgs & F_SSI) {
        !           509:                        io->i_flgs &= ~F_SSI;
        !           510:                        drv->mbd_of &= ~HPOF_SSEI;
        !           511:                        st->nsect--;
        !           512:                        st->nspc -= st->ntrak;
        !           513:                }
        !           514:                return(0);
        !           515: 
        !           516:        case SAIOSSDEV:                 /* drive have skip sector? */
        !           517:                return (RM80 ? 0 : ECMD);
        !           518:        }
        !           519:        return (ECMD);
        !           520: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.