123225Smckusick /* 2*33409Skarels * Copyright (c) 1982, 1986 Regents of the University of California. 323225Smckusick * All rights reserved. The Berkeley software License Agreement 423225Smckusick * specifies the terms and conditions for redistribution. 523225Smckusick * 6*33409Skarels * @(#)hp.c 7.5 (Berkeley) 01/28/88 723225Smckusick */ 810334Shelge 910334Shelge /* 1010334Shelge * RP??/RM?? disk driver 1110334Shelge * with ECC handling and bad block forwarding. 1210334Shelge * Also supports header io operations and 1310334Shelge * commands to write check header and data. 1410334Shelge */ 15*33409Skarels #include "param.h" 16*33409Skarels #include "inode.h" 17*33409Skarels #include "fs.h" 18*33409Skarels #include "dkbad.h" 19*33409Skarels #include "disklabel.h" 2010334Shelge 2110334Shelge #include "../vax/pte.h" 22*33409Skarels 2310334Shelge #include "../vaxmba/hpreg.h" 2410334Shelge #include "../vaxmba/mbareg.h" 2510334Shelge 2610334Shelge #include "saio.h" 2710334Shelge #include "savax.h" 2810334Shelge 2925439Skarels #define RETRIES 27 3025439Skarels 3110334Shelge #define MASKREG(reg) ((reg)&0xffff) 3210334Shelge 3311366Ssam #define MAXBADDESC 126 3411366Ssam #define SECTSIZ 512 /* sector size in bytes */ 3511366Ssam #define HDRSIZ 4 /* number of bytes in sector header */ 3610334Shelge 3730547Skarels char lbuf[SECTSIZ]; 3810334Shelge 3930547Skarels #define RP06(type) ((type) == MBDT_RP06 || (type) == MBDT_RP05 \ 4030547Skarels || (type) == MBDT_RP04) 4130547Skarels #define ML11(type) ((type) == MBDT_ML11A) 4230547Skarels #define RM80(type) ((type) == MBDT_RM80) 4310334Shelge 4410334Shelge u_char hp_offset[16] = { 4510334Shelge HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400, 4610334Shelge HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800, 4710334Shelge HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200, 4810334Shelge 0, 0, 0, 0, 4910334Shelge }; 5010334Shelge 5130547Skarels struct disklabel hplabel[MAXNMBA*8]; 5230547Skarels #ifndef SMALL 5311366Ssam struct dkbad hpbad[MAXNMBA*8]; 5430547Skarels int sectsiz; 5530547Skarels #endif 5610334Shelge 5725439Skarels struct hp_softc { 5825439Skarels char type; 5925439Skarels char gottype; 6025439Skarels char ssect; /* 1 when on track w/skip sector */ 6125439Skarels char debug; 6225439Skarels # define HPF_BSEDEBUG 01 /* debugging bad sector forwarding */ 6325439Skarels # define HPF_ECCDEBUG 02 /* debugging ecc correction */ 6425439Skarels int ecclim; 6525439Skarels int retries; 6625439Skarels } hp_softc[MAXNMBA * 8]; 6711366Ssam 6810864Ssam /* 6910864Ssam * When awaiting command completion, don't 7010864Ssam * hang on to the status register since 7111366Ssam * this ties up some controllers. 7210864Ssam */ 7311366Ssam #define HPWAIT(addr) \ 7411366Ssam while ((((addr)->hpds)&HPDS_DRY)==0) DELAY(500); 7510864Ssam 7610334Shelge hpopen(io) 7710334Shelge register struct iob *io; 7810334Shelge { 7910334Shelge register unit = io->i_unit; 8010334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 8125439Skarels register struct hp_softc *sc = &hp_softc[unit]; 8230547Skarels register struct disklabel *lp = &hplabel[unit]; 8333041Skarels struct disklabel *dlp; 8410334Shelge 85*33409Skarels if (mbainit(UNITTOMBA(unit)) == 0) 8630547Skarels return (ENXIO); 8725439Skarels if (sc->gottype == 0) { 8830547Skarels register i; 8910334Shelge struct iob tio; 9010334Shelge 9130547Skarels #ifndef SMALL 9225439Skarels sc->retries = RETRIES; 9325439Skarels sc->ecclim = 11; 9425439Skarels sc->debug = 0; 9530547Skarels #endif 9610647Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; /* init drive */ 9710647Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 9830547Skarels #ifndef SMALL 99*33409Skarels if ((hpaddr->hpds & HPDS_DPR) == 0) { 100*33409Skarels printf("drive nonexistent\n"); 101*33409Skarels return (ENXIO); 102*33409Skarels } 10330547Skarels sc->type = hpaddr->hpdt & MBDT_TYPE; 10430547Skarels if (sc->type == MBDT_ML11B) 105*33409Skarels sc->type = MBDT_ML11A; 10630547Skarels if (!ML11(sc->type)) 10730547Skarels #endif 10810647Shelge hpaddr->hpof = HPOF_FMT22; 10910334Shelge /* 11030547Skarels * Read in the pack label. 11130547Skarels */ 11230547Skarels lp->d_nsectors = 32; 11330547Skarels lp->d_secpercyl = 20*32; 11430547Skarels tio = *io; 11530547Skarels tio.i_bn = LABELSECTOR; 11630547Skarels tio.i_ma = lbuf; 11730547Skarels tio.i_cc = SECTSIZ; 11830547Skarels tio.i_flgs |= F_RDDATA; 11930547Skarels if (hpstrategy(&tio, READ) != SECTSIZ) { 120*33409Skarels printf("can't read disk label\n"); 12130547Skarels return (EIO); 12230547Skarels } 12333041Skarels dlp = (struct disklabel *)(lbuf + LABELOFFSET); 12433041Skarels if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { 12530547Skarels printf("hp%d: unlabeled\n", unit); 126*33409Skarels #if defined(COMPAT_42) /* && !defined(SMALL) */ 12730547Skarels hpmaptype(hpaddr, hpaddr->hpdt & MBDT_TYPE, 12830547Skarels UNITTODRIVE(unit), lp); 12930547Skarels #else 13030547Skarels return (ENXIO); 13130547Skarels #endif 13233041Skarels } else 13333041Skarels *lp = *dlp; 13433041Skarels #ifndef SMALL 13530547Skarels /* 13611366Ssam * Read in the bad sector table. 13710334Shelge */ 13830547Skarels tio.i_bn = lp->d_secpercyl * lp->d_ncylinders - lp->d_nsectors; 13910626Shelge tio.i_ma = (char *)&hpbad[unit]; 14010628Shelge tio.i_cc = sizeof (struct dkbad); 14110334Shelge for (i = 0; i < 5; i++) { 14210628Shelge if (hpstrategy(&tio, READ) == sizeof (struct dkbad)) 14310334Shelge break; 14410334Shelge tio.i_bn += 2; 14510334Shelge } 14610334Shelge if (i == 5) { 147*33409Skarels printf("can't read bad sector table\n"); 14810334Shelge for (i = 0; i < MAXBADDESC; i++) { 14910334Shelge hpbad[unit].bt_bad[i].bt_cyl = -1; 15010334Shelge hpbad[unit].bt_bad[i].bt_trksec = -1; 15110334Shelge } 15225439Skarels } 15333041Skarels #endif 15425439Skarels sc->gottype = 1; 15510334Shelge } 156*33409Skarels if ((unsigned)io->i_boff >= lp->d_npartitions || 15730547Skarels lp->d_partitions[io->i_boff].p_size == 0) { 158*33409Skarels printf("hp bad minor\n"); 15930547Skarels return (EUNIT); 16030547Skarels } 16130547Skarels io->i_boff = lp->d_partitions[io->i_boff].p_offset; 16230547Skarels return (0); 16310334Shelge } 16410334Shelge 16510334Shelge hpstrategy(io, func) 16610334Shelge register struct iob *io; 16710334Shelge { 16810334Shelge register unit = io->i_unit; 16910334Shelge struct mba_regs *mba = mbamba(unit); 17011366Ssam daddr_t bn, startblock; 17110334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 17225439Skarels register struct hp_softc *sc = &hp_softc[unit]; 17330547Skarels register struct disklabel *lp = &hplabel[unit]; 174*33409Skarels int cn, tn, sn, bytecnt, bytesleft, rv; 17510334Shelge char *membase; 17610334Shelge int er1, er2, hprecal; 17710334Shelge 17830547Skarels #ifndef SMALL 17910334Shelge sectsiz = SECTSIZ; 18010334Shelge if ((io->i_flgs & (F_HDR|F_HCHECK)) != 0) 18110334Shelge sectsiz += HDRSIZ; 18210334Shelge if ((hpaddr->hpds & HPDS_VV) == 0) { 18310334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 18410334Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 18530547Skarels if (!ML11(sc->type)) 18610334Shelge hpaddr->hpof = HPOF_FMT22; 18710334Shelge } 18810334Shelge io->i_errcnt = 0; 18925439Skarels sc->ssect = 0; 19025439Skarels rv = bytecnt = io->i_cc; 19110334Shelge membase = io->i_ma; 19210334Shelge startblock = io->i_bn; 19310608Ssam hprecal = 0; 19430547Skarels #endif 19511140Ssam 19610626Shelge restart: 19710334Shelge bn = io->i_bn; 19830547Skarels cn = bn / lp->d_secpercyl; 19930547Skarels sn = bn % lp->d_secpercyl; 20030547Skarels tn = sn / lp->d_nsectors; 20130547Skarels sn = sn % lp->d_nsectors + sc->ssect; 20210334Shelge 20310864Ssam HPWAIT(hpaddr); 20410626Shelge mba->mba_sr = -1; 20530547Skarels if (ML11(sc->type)) 20610334Shelge hpaddr->hpda = bn; 20710334Shelge else { 20810334Shelge hpaddr->hpdc = cn; 20910334Shelge hpaddr->hpda = (tn << 8) + sn; 21010334Shelge } 21130547Skarels #ifdef SMALL 21230547Skarels mbastart(io, func); /* start transfer */ 21330547Skarels HPWAIT(hpaddr); 21430547Skarels if (hpaddr->hpds & HPDS_ERR) { 21530547Skarels printf("hp error: sn [%d-%d) ds=%b er1=%b\n", 21630547Skarels bn, bn + io->i_cc/SECTSIZ, MASKREG(hpaddr->hpds), HPDS_BITS, 21730547Skarels MASKREG(hpaddr->hper1), HPER1_BITS); 21830547Skarels return (-1); 21930547Skarels } 22030547Skarels return (io->i_cc); 22130547Skarels #else 22225439Skarels if (mbastart(io, func) != 0) { /* start transfer */ 22325439Skarels rv = -1; 22425439Skarels goto done; 22525439Skarels } 22610864Ssam HPWAIT(hpaddr); 22711366Ssam /* 22811366Ssam * Successful data transfer, return. 22911366Ssam */ 23015068Skarels if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0) 23115068Skarels goto done; 23210334Shelge 23311366Ssam /* 23411366Ssam * Error handling. Calculate location of error. 23511366Ssam */ 23611366Ssam bytesleft = MASKREG(mba->mba_bcr); 23711366Ssam if (bytesleft) 23811366Ssam bytesleft |= 0xffff0000; /* sxt */ 23911366Ssam bn = io->i_bn + (io->i_cc + bytesleft) / sectsiz; 24015052Skarels er1 = MASKREG(hpaddr->hper1); 24115052Skarels er2 = MASKREG(hpaddr->hper2); 24215052Skarels if (er1 & (HPER1_DCK|HPER1_ECH)) 24315052Skarels bn--; /* Error is in Prev block */ 24430547Skarels cn = bn/lp->d_secpercyl; 24530547Skarels sn = bn%lp->d_secpercyl; 24630547Skarels tn = sn/lp->d_nsectors; 24730547Skarels sn = sn%lp->d_nsectors; 24825439Skarels if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) { 24925439Skarels printf("hp error: sn%d (cyl,trk,sec)=(%d,%d,%d) ds=%b\n", 25025439Skarels bn, cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 25111366Ssam printf("er1=%b er2=%b\n", er1, HPER1_BITS, er2, HPER2_BITS); 25211366Ssam printf("bytes left: %d, of 0x%x, da 0x%x\n",-bytesleft, 25311366Ssam hpaddr->hpof, hpaddr->hpda); 25411366Ssam } 25510334Shelge if (er1 & HPER1_HCRC) { 25610334Shelge er1 &= ~(HPER1_HCE|HPER1_FER); 25710334Shelge er2 &= ~HPER2_BSE; 25825439Skarels if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0) 25925439Skarels goto success; 26010334Shelge } 26111140Ssam /* 26211140Ssam * Give up early if drive write locked. 26311140Ssam */ 26410334Shelge if (er1&HPER1_WLE) { 26510334Shelge printf("hp%d: write locked\n", unit); 26625439Skarels rv = -1; 26725439Skarels goto done; 26811084Ssam } 26911140Ssam /* 27025439Skarels * Skip sector handling. 27111140Ssam */ 27230547Skarels if (RM80(sc->type) && (er2 & HPER2_SSE)) { 27325439Skarels (void) hpecc(io, SSE); 27425439Skarels sc->ssect = 1; 27525439Skarels goto restart; 27611084Ssam } 27711140Ssam /* 27825439Skarels * Attempt to forward bad sectors on anything but an ML11. 27925439Skarels * Interpret format error bit as a bad block on RP06's. 28011140Ssam */ 28130547Skarels if (((er2 & HPER2_BSE) && !ML11(sc->type)) || 28230547Skarels (MASKREG(er1) == HPER1_FER && RP06(sc->type))) { 28311084Ssam if (io->i_flgs & F_NBSF) { 28410334Shelge io->i_error = EBSE; 28510334Shelge goto hard; 28610334Shelge } 28710334Shelge if (hpecc(io, BSE) == 0) 28810334Shelge goto success; 28911084Ssam io->i_error = EBSE; 29011084Ssam goto hard; 29111084Ssam } 29211140Ssam /* 29311366Ssam * ECC correction? 29411140Ssam */ 29511084Ssam if ((er1 & (HPER1_DCK|HPER1_ECH)) == HPER1_DCK) { 29610864Ssam if (hpecc(io, ECC) == 0) 29710334Shelge goto success; 29811084Ssam io->i_error = EECC; 29925439Skarels goto hard; 30010608Ssam } 30125439Skarels 30225439Skarels /* 30325439Skarels * If a hard error, or maximum retry count 30425439Skarels * exceeded, clear controller state and 30525439Skarels * pass back error to caller. 30625439Skarels */ 30725439Skarels if (++io->i_errcnt > sc->retries || (er1 & HPER1_HARD) || 30830547Skarels (!ML11(sc->type) && (er2 & HPER2_HARD)) || 30930547Skarels (ML11(sc->type) && (io->i_errcnt >= 16))) { 31025439Skarels io->i_error = EHER; 31125439Skarels if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR)) 31225439Skarels io->i_error = EWCK; 31325439Skarels hard: 31425439Skarels io->i_errblk = bn + sc->ssect; 31525439Skarels if (sc->debug & (HPF_BSEDEBUG|HPF_ECCDEBUG)) 31625439Skarels printf(" dc=%d, da=0x%x",MASKREG(hpaddr->hpdc), 31725439Skarels MASKREG(hpaddr->hpda)); 31825439Skarels else { 31925439Skarels printf("hp error: sn%d (cyl,trk,sec)=(%d,%d,%d) ds=%b \n", 32025439Skarels bn, cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 32125439Skarels printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS); 32225439Skarels } 32325439Skarels hpaddr->hpcs1 = HP_DCLR|HP_GO; 32425439Skarels printf("\n"); 32525439Skarels rv = -1; 32625439Skarels goto done; 32725439Skarels 32825439Skarels } 32910608Ssam /* fall thru to retry */ 33010334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 33110864Ssam HPWAIT(hpaddr); 33211140Ssam 33311140Ssam /* 33411140Ssam * Every fourth retry recalibrate. 33511140Ssam */ 33611366Ssam if (((io->i_errcnt & 07) == 4) ) { 33710334Shelge hpaddr->hpcs1 = HP_RECAL|HP_GO; 33815052Skarels HPWAIT(hpaddr); 33910334Shelge hpaddr->hpdc = cn; 34010334Shelge hpaddr->hpcs1 = HP_SEEK|HP_GO; 34115052Skarels HPWAIT(hpaddr); 34215052Skarels } 34310864Ssam 34415052Skarels if (io->i_errcnt >= 16 && (io->i_flgs & F_READ)) { 34510334Shelge hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22; 34610334Shelge hpaddr->hpcs1 = HP_OFFSET|HP_GO; 34715052Skarels HPWAIT(hpaddr); 34810334Shelge } 34925439Skarels if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) 35015052Skarels printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n", 35115052Skarels io->i_bn, io->i_cc, io->i_ma, hprecal); 35225439Skarels goto restart; 35311084Ssam 35411140Ssam success: 35511140Ssam /* 35611140Ssam * On successful error recovery, bump 35711140Ssam * block number to advance to next portion 35811140Ssam * of i/o transfer. 35911140Ssam */ 36010334Shelge bn++; 36110334Shelge if ((bn-startblock) * sectsiz < bytecnt) { 36210334Shelge io->i_bn = bn; 36310334Shelge io->i_ma = membase + (io->i_bn - startblock)*sectsiz; 36410334Shelge io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz; 36525439Skarels if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) 36611366Ssam printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n", 36711366Ssam io->i_bn, io->i_cc, io->i_ma, hprecal); 36810626Shelge goto restart; 36910334Shelge } 37015068Skarels done: 37115052Skarels if (io->i_errcnt >= 16) { 37215052Skarels hpaddr->hpcs1 = HP_RTC|HP_GO; 37315052Skarels while (hpaddr->hpds & HPDS_PIP) 37415052Skarels ; 37515052Skarels } 37625439Skarels io->i_bn = startblock; /*reset i_bn to original */ 37718515Smiriam io->i_cc = bytecnt; /*reset i_cc to total count xfered*/ 37825439Skarels io->i_ma = membase; /*reset i_ma to original */ 37925439Skarels return (rv); 38030547Skarels #endif 38110334Shelge } 38210864Ssam 38330547Skarels #ifndef SMALL 38410334Shelge hpecc(io, flag) 38510334Shelge register struct iob *io; 38610334Shelge int flag; 38710334Shelge { 38810334Shelge register unit = io->i_unit; 38910334Shelge register struct mba_regs *mbp = mbamba(unit); 39010334Shelge register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit); 39125439Skarels register struct hp_softc *sc = &hp_softc[unit]; 39230547Skarels register struct disklabel *lp = &hplabel[unit]; 39311084Ssam int npf, bn, cn, tn, sn, bcr; 39410334Shelge 39511366Ssam bcr = MASKREG(mbp->mba_bcr); 39611366Ssam if (bcr) 39711366Ssam bcr |= 0xffff0000; /* sxt */ 39811084Ssam npf = (bcr + io->i_cc) / sectsiz; /* # sectors read */ 39915052Skarels if (flag == ECC) 40015052Skarels npf--; /* Error is in prev block --ghg */ 40125439Skarels bn = io->i_bn + npf + sc->ssect; /* physical block #*/ 40225439Skarels if (sc->debug & HPF_ECCDEBUG) 40311366Ssam printf("bcr=%d npf=%d ssect=%d sectsiz=%d i_cc=%d\n", 40425439Skarels bcr, npf, sc->ssect, sectsiz, io->i_cc); 40511140Ssam /* 40611140Ssam * ECC correction logic. 40711140Ssam */ 40811140Ssam if (flag == ECC) { 40910334Shelge register int i; 41010334Shelge caddr_t addr; 41125439Skarels int bit, o, mask; 41210334Shelge 41310413Shelge printf("hp%d: soft ecc sn%d\n", unit, bn); 41410334Shelge mask = MASKREG(rp->hpec2); 41525439Skarels for (i = mask, bit = 0; i; i >>= 1) 41625439Skarels if (i & 1) 41725439Skarels bit++; 41825439Skarels if (bit > sc->ecclim) { 41925439Skarels printf("%d-bit error\n", bit); 42025439Skarels return (1); 42125439Skarels } 42211084Ssam i = MASKREG(rp->hpec1) - 1; /* -1 makes 0 origin */ 42310334Shelge bit = i&07; 42411366Ssam o = (i & ~07) >> 3; 42510334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 42611179Ssam while (o <sectsiz && npf*sectsiz + o < io->i_cc && bit > -11) { 42711179Ssam addr = io->i_ma + (npf*sectsiz) + o; 42811179Ssam /* 42911179Ssam * No data transfer occurs with a write check, 43011179Ssam * so don't correct the resident copy of data. 43111179Ssam */ 43211366Ssam if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) { 43325439Skarels if (sc->debug & HPF_ECCDEBUG) 43411366Ssam printf("addr=%x old=%x ", addr, 43511366Ssam (*addr & 0xff)); 43611140Ssam *addr ^= (mask << bit); 43725439Skarels if (sc->debug & HPF_ECCDEBUG) 43811366Ssam printf("new=%x\n",(*addr & 0xff)); 43911366Ssam } 44011179Ssam o++, bit -= 8; 44110334Shelge } 44211179Ssam return (0); 44311084Ssam } 44410334Shelge 44511084Ssam /* 44611084Ssam * Skip sector error. 44711084Ssam * Set skip-sector-inhibit and 44811084Ssam * read next sector 44911084Ssam */ 45011140Ssam if (flag == SSE) { 45110334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 45210864Ssam HPWAIT(rp); 45310334Shelge rp->hpof |= HPOF_SSEI; 45411084Ssam return (0); 45511140Ssam } 45610334Shelge 45711140Ssam /* 45811140Ssam * Bad block forwarding. 45911140Ssam */ 46011140Ssam if (flag == BSE) { 46110626Shelge int bbn; 46211084Ssam 46310626Shelge rp->hpcs1 = HP_DCLR | HP_GO; 46425439Skarels if (sc->debug & HPF_BSEDEBUG) 46511366Ssam printf("hpecc: BSE @ bn %d\n", bn); 46630547Skarels cn = bn / lp->d_secpercyl; 46730547Skarels sn = bn % lp->d_secpercyl; 46830547Skarels tn = sn / lp->d_nsectors; 46930547Skarels sn = sn % lp->d_nsectors; 47010626Shelge bcr += sectsiz; 47110626Shelge if ((bbn = isbad(&hpbad[unit], cn, tn, sn)) < 0) 47211084Ssam return (1); 47330547Skarels bbn = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors - 1 47430547Skarels - bbn; 47530547Skarels cn = bbn / lp->d_secpercyl; 47630547Skarels sn = bbn % lp->d_secpercyl; 47730547Skarels tn = sn / lp->d_nsectors; 478*33409Skarels sn = sn % lp->d_nsectors; 47910626Shelge io->i_cc = sectsiz; 48030547Skarels io->i_ma += npf * sectsiz; 48125439Skarels if (sc->debug & HPF_BSEDEBUG) 48211366Ssam printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 48311366Ssam rp->hpof &= ~HPOF_SSEI; 48410626Shelge mbp->mba_sr = -1; 48510334Shelge rp->hpdc = cn; 48610334Shelge rp->hpda = (tn<<8) + sn; 48710334Shelge mbastart(io,io->i_flgs); 48811366Ssam io->i_errcnt = 0; 48910864Ssam HPWAIT(rp); 49010864Ssam return (rp->hpds&HPDS_ERR); 49110334Shelge } 49211084Ssam printf("hpecc: flag=%d\n", flag); 49311084Ssam return (1); 49410334Shelge } 49530547Skarels #endif 49611140Ssam 49710334Shelge /*ARGSUSED*/ 49810334Shelge hpioctl(io, cmd, arg) 49910334Shelge struct iob *io; 50010334Shelge int cmd; 50110334Shelge caddr_t arg; 50210334Shelge { 50330547Skarels #ifdef SMALL 50430547Skarels return (ECMD); 50530547Skarels #else 50610647Shelge register unit = io->i_unit; 50725439Skarels register struct hp_softc *sc = &hp_softc[unit]; 50830547Skarels register struct disklabel *lp = &hplabel[unit]; 50910647Shelge struct mba_drv *drv = mbadrv(unit); 51010334Shelge 51110334Shelge switch(cmd) { 51210334Shelge 51311366Ssam case SAIODEBUG: 51425439Skarels sc->debug = (int)arg; 51525439Skarels break; 51611366Ssam 51710334Shelge case SAIODEVDATA: 51825439Skarels if (drv->mbd_dt&MBDT_TAP) 51925439Skarels return (ECMD); 52030547Skarels *(struct disklabel *)arg = *lp; 52125439Skarels break; 52210334Shelge 52325439Skarels case SAIOGBADINFO: 52425439Skarels if (drv->mbd_dt&MBDT_TAP) 52525439Skarels return (ECMD); 52625439Skarels *(struct dkbad *)arg = hpbad[unit]; 52725439Skarels break; 52825439Skarels 52925439Skarels case SAIOECCLIM: 53025439Skarels sc->ecclim = (int)arg; 53125439Skarels break; 53225439Skarels 53325439Skarels case SAIORETRIES: 53425439Skarels sc->retries = (int)arg; 53525439Skarels break; 53625439Skarels 53711084Ssam case SAIOSSI: /* skip-sector-inhibit */ 53811084Ssam if (drv->mbd_dt&MBDT_TAP) 53911084Ssam return (ECMD); 54011084Ssam if ((io->i_flgs&F_SSI) == 0) { 54111084Ssam /* make sure this is done once only */ 54211084Ssam io->i_flgs |= F_SSI; 54330547Skarels lp->d_nsectors++; 54430547Skarels lp->d_secpercyl += lp->d_ntracks; 54510864Ssam } 54625439Skarels break; 54710626Shelge 54811084Ssam case SAIONOSSI: /* remove skip-sector-inhibit */ 54910626Shelge if (io->i_flgs & F_SSI) { 55010626Shelge io->i_flgs &= ~F_SSI; 55110626Shelge drv->mbd_of &= ~HPOF_SSEI; 55230547Skarels lp->d_nsectors--; 55330547Skarels lp->d_secpercyl -= lp->d_ntracks; 55410626Shelge } 55525439Skarels break; 55610626Shelge 55710864Ssam case SAIOSSDEV: /* drive have skip sector? */ 55830547Skarels return (RM80(sc->type) ? 0 : ECMD); 55925439Skarels 56025439Skarels default: 56125439Skarels return (ECMD); 56210334Shelge } 56325439Skarels return (0); 56430547Skarels #endif 56510334Shelge } 566