123225Smckusick /* 2*30547Skarels * Copyright (c) 1982 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*30547Skarels * @(#)hp.c 6.8 (Berkeley) 11/8/85 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 */ 1510334Shelge #include "../h/param.h" 1610334Shelge #include "../h/inode.h" 1710334Shelge #include "../h/fs.h" 1810334Shelge #include "../h/dkbad.h" 19*30547Skarels #include "../h/disklabel.h" 2010334Shelge 2110334Shelge #include "../vax/pte.h" 2210334Shelge #include "../vaxmba/hpreg.h" 2310334Shelge #include "../vaxmba/mbareg.h" 2410334Shelge 2510334Shelge #include "saio.h" 2610334Shelge #include "savax.h" 2710334Shelge 2825439Skarels #define RETRIES 27 2925439Skarels 3010334Shelge #define MASKREG(reg) ((reg)&0xffff) 3110334Shelge 3211366Ssam #define MAXBADDESC 126 3311366Ssam #define SECTSIZ 512 /* sector size in bytes */ 3411366Ssam #define HDRSIZ 4 /* number of bytes in sector header */ 3510334Shelge 36*30547Skarels char lbuf[SECTSIZ]; 3710334Shelge 38*30547Skarels #define RP06(type) ((type) == MBDT_RP06 || (type) == MBDT_RP05 \ 39*30547Skarels || (type) == MBDT_RP04) 40*30547Skarels #define ML11(type) ((type) == MBDT_ML11A) 41*30547Skarels #define RM80(type) ((type) == MBDT_RM80) 4210334Shelge 4310334Shelge u_char hp_offset[16] = { 4410334Shelge HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400, 4510334Shelge HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800, 4610334Shelge HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200, 4710334Shelge 0, 0, 0, 0, 4810334Shelge }; 4910334Shelge 50*30547Skarels struct disklabel hplabel[MAXNMBA*8]; 51*30547Skarels #ifndef SMALL 5211366Ssam struct dkbad hpbad[MAXNMBA*8]; 53*30547Skarels int sectsiz; 54*30547Skarels #endif 5510334Shelge 5625439Skarels struct hp_softc { 5725439Skarels char type; 5825439Skarels char gottype; 5925439Skarels char ssect; /* 1 when on track w/skip sector */ 6025439Skarels char debug; 6125439Skarels # define HPF_BSEDEBUG 01 /* debugging bad sector forwarding */ 6225439Skarels # define HPF_ECCDEBUG 02 /* debugging ecc correction */ 6325439Skarels int ecclim; 6425439Skarels int retries; 6525439Skarels } hp_softc[MAXNMBA * 8]; 6611366Ssam 6710864Ssam /* 6810864Ssam * When awaiting command completion, don't 6910864Ssam * hang on to the status register since 7011366Ssam * this ties up some controllers. 7110864Ssam */ 7211366Ssam #define HPWAIT(addr) \ 7311366Ssam while ((((addr)->hpds)&HPDS_DRY)==0) DELAY(500); 7410864Ssam 7510334Shelge hpopen(io) 7610334Shelge register struct iob *io; 7710334Shelge { 7810334Shelge register unit = io->i_unit; 7910334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 8025439Skarels register struct hp_softc *sc = &hp_softc[unit]; 81*30547Skarels register struct disklabel *lp = &hplabel[unit]; 8210334Shelge 83*30547Skarels if (mbainit(UNITTOMBA(unit)) == 0) { 84*30547Skarels printf("nonexistent mba"); 85*30547Skarels return (ENXIO); 86*30547Skarels } 8725439Skarels if (sc->gottype == 0) { 88*30547Skarels register i; 8910334Shelge struct iob tio; 9010334Shelge 91*30547Skarels #ifndef SMALL 9225439Skarels sc->retries = RETRIES; 9325439Skarels sc->ecclim = 11; 9425439Skarels sc->debug = 0; 95*30547Skarels #endif 9610647Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; /* init drive */ 9710647Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 98*30547Skarels #ifndef SMALL 99*30547Skarels if ((hpaddr->hpds & HPDS_DPR) == 0) 100*30547Skarels _stop("drive nonexistent"); 101*30547Skarels sc->type = hpaddr->hpdt & MBDT_TYPE; 102*30547Skarels if (sc->type == MBDT_ML11B) 103*30547Skarels sc->type == MBDT_ML11A; 104*30547Skarels if (!ML11(sc->type)) 105*30547Skarels #endif 10610647Shelge hpaddr->hpof = HPOF_FMT22; 10710334Shelge /* 108*30547Skarels * Read in the pack label. 109*30547Skarels */ 110*30547Skarels lp->d_nsectors = 32; 111*30547Skarels lp->d_secpercyl = 20*32; 112*30547Skarels tio = *io; 113*30547Skarels tio.i_bn = LABELSECTOR; 114*30547Skarels tio.i_ma = lbuf; 115*30547Skarels tio.i_cc = SECTSIZ; 116*30547Skarels tio.i_flgs |= F_RDDATA; 117*30547Skarels if (hpstrategy(&tio, READ) != SECTSIZ) { 118*30547Skarels printf("can't read disk label"); 119*30547Skarels return (EIO); 120*30547Skarels } 121*30547Skarels *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 122*30547Skarels #ifndef SMALL 123*30547Skarels if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 124*30547Skarels printf("hp%d: unlabeled\n", unit); 125*30547Skarels #ifdef COMPAT_42 126*30547Skarels hpmaptype(hpaddr, hpaddr->hpdt & MBDT_TYPE, 127*30547Skarels UNITTODRIVE(unit), lp); 128*30547Skarels #else 129*30547Skarels return (ENXIO); 130*30547Skarels #endif 131*30547Skarels } 132*30547Skarels /* 13311366Ssam * Read in the bad sector table. 13410334Shelge */ 135*30547Skarels tio.i_bn = lp->d_secpercyl * lp->d_ncylinders - lp->d_nsectors; 13610626Shelge tio.i_ma = (char *)&hpbad[unit]; 13710628Shelge tio.i_cc = sizeof (struct dkbad); 13810334Shelge for (i = 0; i < 5; i++) { 13910628Shelge if (hpstrategy(&tio, READ) == sizeof (struct dkbad)) 14010334Shelge break; 14110334Shelge tio.i_bn += 2; 14210334Shelge } 14310334Shelge if (i == 5) { 14410334Shelge printf("Unable to read bad sector table\n"); 14510334Shelge for (i = 0; i < MAXBADDESC; i++) { 14610334Shelge hpbad[unit].bt_bad[i].bt_cyl = -1; 14710334Shelge hpbad[unit].bt_bad[i].bt_trksec = -1; 14810334Shelge } 14925439Skarels } 15025439Skarels sc->gottype = 1; 151*30547Skarels #endif 15210334Shelge } 153*30547Skarels if (io->i_boff < 0 || io->i_boff >= lp->d_npartitions || 154*30547Skarels lp->d_partitions[io->i_boff].p_size == 0) { 155*30547Skarels printf("hp bad minor"); 156*30547Skarels return (EUNIT); 157*30547Skarels } 158*30547Skarels io->i_boff = lp->d_partitions[io->i_boff].p_offset; 159*30547Skarels return (0); 16010334Shelge } 16110334Shelge 16210334Shelge hpstrategy(io, func) 16310334Shelge register struct iob *io; 16410334Shelge { 16510334Shelge register unit = io->i_unit; 16610334Shelge struct mba_regs *mba = mbamba(unit); 16711366Ssam daddr_t bn, startblock; 16810334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 16925439Skarels register struct hp_softc *sc = &hp_softc[unit]; 170*30547Skarels register struct disklabel *lp = &hplabel[unit]; 17125439Skarels int cn, tn, sn, bytecnt, bytesleft, rv; 17210334Shelge char *membase; 17310334Shelge int er1, er2, hprecal; 17410334Shelge 175*30547Skarels #ifndef SMALL 17610334Shelge sectsiz = SECTSIZ; 17710334Shelge if ((io->i_flgs & (F_HDR|F_HCHECK)) != 0) 17810334Shelge sectsiz += HDRSIZ; 17910334Shelge if ((hpaddr->hpds & HPDS_VV) == 0) { 18010334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 18110334Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 182*30547Skarels if (!ML11(sc->type)) 18310334Shelge hpaddr->hpof = HPOF_FMT22; 18410334Shelge } 18510334Shelge io->i_errcnt = 0; 18625439Skarels sc->ssect = 0; 18725439Skarels rv = bytecnt = io->i_cc; 18810334Shelge membase = io->i_ma; 18910334Shelge startblock = io->i_bn; 19010608Ssam hprecal = 0; 191*30547Skarels #endif 19211140Ssam 19310626Shelge restart: 19410334Shelge bn = io->i_bn; 195*30547Skarels cn = bn / lp->d_secpercyl; 196*30547Skarels sn = bn % lp->d_secpercyl; 197*30547Skarels tn = sn / lp->d_nsectors; 198*30547Skarels sn = sn % lp->d_nsectors + sc->ssect; 19910334Shelge 20010864Ssam HPWAIT(hpaddr); 20110626Shelge mba->mba_sr = -1; 202*30547Skarels if (ML11(sc->type)) 20310334Shelge hpaddr->hpda = bn; 20410334Shelge else { 20510334Shelge hpaddr->hpdc = cn; 20610334Shelge hpaddr->hpda = (tn << 8) + sn; 20710334Shelge } 208*30547Skarels #ifdef SMALL 209*30547Skarels mbastart(io, func); /* start transfer */ 210*30547Skarels HPWAIT(hpaddr); 211*30547Skarels if (hpaddr->hpds & HPDS_ERR) { 212*30547Skarels printf("hp error: sn [%d-%d) ds=%b er1=%b\n", 213*30547Skarels bn, bn + io->i_cc/SECTSIZ, MASKREG(hpaddr->hpds), HPDS_BITS, 214*30547Skarels MASKREG(hpaddr->hper1), HPER1_BITS); 215*30547Skarels return (-1); 216*30547Skarels } 217*30547Skarels return (io->i_cc); 218*30547Skarels #else 21925439Skarels if (mbastart(io, func) != 0) { /* start transfer */ 22025439Skarels rv = -1; 22125439Skarels goto done; 22225439Skarels } 22310864Ssam HPWAIT(hpaddr); 22411366Ssam /* 22511366Ssam * Successful data transfer, return. 22611366Ssam */ 22715068Skarels if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0) 22815068Skarels goto done; 22910334Shelge 23011366Ssam /* 23111366Ssam * Error handling. Calculate location of error. 23211366Ssam */ 23311366Ssam bytesleft = MASKREG(mba->mba_bcr); 23411366Ssam if (bytesleft) 23511366Ssam bytesleft |= 0xffff0000; /* sxt */ 23611366Ssam bn = io->i_bn + (io->i_cc + bytesleft) / sectsiz; 23715052Skarels er1 = MASKREG(hpaddr->hper1); 23815052Skarels er2 = MASKREG(hpaddr->hper2); 23915052Skarels if (er1 & (HPER1_DCK|HPER1_ECH)) 24015052Skarels bn--; /* Error is in Prev block */ 241*30547Skarels cn = bn/lp->d_secpercyl; 242*30547Skarels sn = bn%lp->d_secpercyl; 243*30547Skarels tn = sn/lp->d_nsectors; 244*30547Skarels sn = sn%lp->d_nsectors; 24525439Skarels if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) { 24625439Skarels printf("hp error: sn%d (cyl,trk,sec)=(%d,%d,%d) ds=%b\n", 24725439Skarels bn, cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 24811366Ssam printf("er1=%b er2=%b\n", er1, HPER1_BITS, er2, HPER2_BITS); 24911366Ssam printf("bytes left: %d, of 0x%x, da 0x%x\n",-bytesleft, 25011366Ssam hpaddr->hpof, hpaddr->hpda); 25111366Ssam } 25210334Shelge if (er1 & HPER1_HCRC) { 25310334Shelge er1 &= ~(HPER1_HCE|HPER1_FER); 25410334Shelge er2 &= ~HPER2_BSE; 25525439Skarels if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0) 25625439Skarels goto success; 25710334Shelge } 25811140Ssam /* 25911140Ssam * Give up early if drive write locked. 26011140Ssam */ 26110334Shelge if (er1&HPER1_WLE) { 26210334Shelge printf("hp%d: write locked\n", unit); 26325439Skarels rv = -1; 26425439Skarels goto done; 26511084Ssam } 26611140Ssam /* 26725439Skarels * Skip sector handling. 26811140Ssam */ 269*30547Skarels if (RM80(sc->type) && (er2 & HPER2_SSE)) { 27025439Skarels (void) hpecc(io, SSE); 27125439Skarels sc->ssect = 1; 27225439Skarels goto restart; 27311084Ssam } 27411140Ssam /* 27525439Skarels * Attempt to forward bad sectors on anything but an ML11. 27625439Skarels * Interpret format error bit as a bad block on RP06's. 27711140Ssam */ 278*30547Skarels if (((er2 & HPER2_BSE) && !ML11(sc->type)) || 279*30547Skarels (MASKREG(er1) == HPER1_FER && RP06(sc->type))) { 28011084Ssam if (io->i_flgs & F_NBSF) { 28110334Shelge io->i_error = EBSE; 28210334Shelge goto hard; 28310334Shelge } 28410334Shelge if (hpecc(io, BSE) == 0) 28510334Shelge goto success; 28611084Ssam io->i_error = EBSE; 28711084Ssam goto hard; 28811084Ssam } 28911140Ssam /* 29011366Ssam * ECC correction? 29111140Ssam */ 29211084Ssam if ((er1 & (HPER1_DCK|HPER1_ECH)) == HPER1_DCK) { 29310864Ssam if (hpecc(io, ECC) == 0) 29410334Shelge goto success; 29511084Ssam io->i_error = EECC; 29625439Skarels goto hard; 29710608Ssam } 29825439Skarels 29925439Skarels /* 30025439Skarels * If a hard error, or maximum retry count 30125439Skarels * exceeded, clear controller state and 30225439Skarels * pass back error to caller. 30325439Skarels */ 30425439Skarels if (++io->i_errcnt > sc->retries || (er1 & HPER1_HARD) || 305*30547Skarels (!ML11(sc->type) && (er2 & HPER2_HARD)) || 306*30547Skarels (ML11(sc->type) && (io->i_errcnt >= 16))) { 30725439Skarels io->i_error = EHER; 30825439Skarels if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR)) 30925439Skarels io->i_error = EWCK; 31025439Skarels hard: 31125439Skarels io->i_errblk = bn + sc->ssect; 31225439Skarels if (sc->debug & (HPF_BSEDEBUG|HPF_ECCDEBUG)) 31325439Skarels printf(" dc=%d, da=0x%x",MASKREG(hpaddr->hpdc), 31425439Skarels MASKREG(hpaddr->hpda)); 31525439Skarels else { 31625439Skarels printf("hp error: sn%d (cyl,trk,sec)=(%d,%d,%d) ds=%b \n", 31725439Skarels bn, cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 31825439Skarels printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS); 31925439Skarels } 32025439Skarels hpaddr->hpcs1 = HP_DCLR|HP_GO; 32125439Skarels printf("\n"); 32225439Skarels rv = -1; 32325439Skarels goto done; 32425439Skarels 32525439Skarels } 32610608Ssam /* fall thru to retry */ 32710334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 32810864Ssam HPWAIT(hpaddr); 32911140Ssam 33011140Ssam /* 33111140Ssam * Every fourth retry recalibrate. 33211140Ssam */ 33311366Ssam if (((io->i_errcnt & 07) == 4) ) { 33410334Shelge hpaddr->hpcs1 = HP_RECAL|HP_GO; 33515052Skarels HPWAIT(hpaddr); 33610334Shelge hpaddr->hpdc = cn; 33710334Shelge hpaddr->hpcs1 = HP_SEEK|HP_GO; 33815052Skarels HPWAIT(hpaddr); 33915052Skarels } 34010864Ssam 34115052Skarels if (io->i_errcnt >= 16 && (io->i_flgs & F_READ)) { 34210334Shelge hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22; 34310334Shelge hpaddr->hpcs1 = HP_OFFSET|HP_GO; 34415052Skarels HPWAIT(hpaddr); 34510334Shelge } 34625439Skarels if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) 34715052Skarels printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n", 34815052Skarels io->i_bn, io->i_cc, io->i_ma, hprecal); 34925439Skarels goto restart; 35011084Ssam 35111140Ssam success: 35211140Ssam /* 35311140Ssam * On successful error recovery, bump 35411140Ssam * block number to advance to next portion 35511140Ssam * of i/o transfer. 35611140Ssam */ 35710334Shelge bn++; 35810334Shelge if ((bn-startblock) * sectsiz < bytecnt) { 35910334Shelge io->i_bn = bn; 36010334Shelge io->i_ma = membase + (io->i_bn - startblock)*sectsiz; 36110334Shelge io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz; 36225439Skarels if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) 36311366Ssam printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n", 36411366Ssam io->i_bn, io->i_cc, io->i_ma, hprecal); 36510626Shelge goto restart; 36610334Shelge } 36715068Skarels done: 36815052Skarels if (io->i_errcnt >= 16) { 36915052Skarels hpaddr->hpcs1 = HP_RTC|HP_GO; 37015052Skarels while (hpaddr->hpds & HPDS_PIP) 37115052Skarels ; 37215052Skarels } 37325439Skarels io->i_bn = startblock; /*reset i_bn to original */ 37418515Smiriam io->i_cc = bytecnt; /*reset i_cc to total count xfered*/ 37525439Skarels io->i_ma = membase; /*reset i_ma to original */ 37625439Skarels return (rv); 377*30547Skarels #endif 37810334Shelge } 37910864Ssam 380*30547Skarels #ifndef SMALL 38110334Shelge hpecc(io, flag) 38210334Shelge register struct iob *io; 38310334Shelge int flag; 38410334Shelge { 38510334Shelge register unit = io->i_unit; 38610334Shelge register struct mba_regs *mbp = mbamba(unit); 38710334Shelge register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit); 38825439Skarels register struct hp_softc *sc = &hp_softc[unit]; 389*30547Skarels register struct disklabel *lp = &hplabel[unit]; 39011084Ssam int npf, bn, cn, tn, sn, bcr; 39110334Shelge 39211366Ssam bcr = MASKREG(mbp->mba_bcr); 39311366Ssam if (bcr) 39411366Ssam bcr |= 0xffff0000; /* sxt */ 39511084Ssam npf = (bcr + io->i_cc) / sectsiz; /* # sectors read */ 39615052Skarels if (flag == ECC) 39715052Skarels npf--; /* Error is in prev block --ghg */ 39825439Skarels bn = io->i_bn + npf + sc->ssect; /* physical block #*/ 39925439Skarels if (sc->debug & HPF_ECCDEBUG) 40011366Ssam printf("bcr=%d npf=%d ssect=%d sectsiz=%d i_cc=%d\n", 40125439Skarels bcr, npf, sc->ssect, sectsiz, io->i_cc); 40211140Ssam /* 40311140Ssam * ECC correction logic. 40411140Ssam */ 40511140Ssam if (flag == ECC) { 40610334Shelge register int i; 40710334Shelge caddr_t addr; 40825439Skarels int bit, o, mask; 40910334Shelge 41010413Shelge printf("hp%d: soft ecc sn%d\n", unit, bn); 41110334Shelge mask = MASKREG(rp->hpec2); 41225439Skarels for (i = mask, bit = 0; i; i >>= 1) 41325439Skarels if (i & 1) 41425439Skarels bit++; 41525439Skarels if (bit > sc->ecclim) { 41625439Skarels printf("%d-bit error\n", bit); 41725439Skarels return (1); 41825439Skarels } 41911084Ssam i = MASKREG(rp->hpec1) - 1; /* -1 makes 0 origin */ 42010334Shelge bit = i&07; 42111366Ssam o = (i & ~07) >> 3; 42210334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 42311179Ssam while (o <sectsiz && npf*sectsiz + o < io->i_cc && bit > -11) { 42411179Ssam addr = io->i_ma + (npf*sectsiz) + o; 42511179Ssam /* 42611179Ssam * No data transfer occurs with a write check, 42711179Ssam * so don't correct the resident copy of data. 42811179Ssam */ 42911366Ssam if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) { 43025439Skarels if (sc->debug & HPF_ECCDEBUG) 43111366Ssam printf("addr=%x old=%x ", addr, 43211366Ssam (*addr & 0xff)); 43311140Ssam *addr ^= (mask << bit); 43425439Skarels if (sc->debug & HPF_ECCDEBUG) 43511366Ssam printf("new=%x\n",(*addr & 0xff)); 43611366Ssam } 43711179Ssam o++, bit -= 8; 43810334Shelge } 43911179Ssam return (0); 44011084Ssam } 44110334Shelge 44211084Ssam /* 44311084Ssam * Skip sector error. 44411084Ssam * Set skip-sector-inhibit and 44511084Ssam * read next sector 44611084Ssam */ 44711140Ssam if (flag == SSE) { 44810334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 44910864Ssam HPWAIT(rp); 45010334Shelge rp->hpof |= HPOF_SSEI; 45111084Ssam return (0); 45211140Ssam } 45310334Shelge 45411140Ssam /* 45511140Ssam * Bad block forwarding. 45611140Ssam */ 45711140Ssam if (flag == BSE) { 45810626Shelge int bbn; 45911084Ssam 46010626Shelge rp->hpcs1 = HP_DCLR | HP_GO; 46125439Skarels if (sc->debug & HPF_BSEDEBUG) 46211366Ssam printf("hpecc: BSE @ bn %d\n", bn); 463*30547Skarels cn = bn / lp->d_secpercyl; 464*30547Skarels sn = bn % lp->d_secpercyl; 465*30547Skarels tn = sn / lp->d_nsectors; 466*30547Skarels sn = sn % lp->d_nsectors; 46710626Shelge bcr += sectsiz; 46810626Shelge if ((bbn = isbad(&hpbad[unit], cn, tn, sn)) < 0) 46911084Ssam return (1); 470*30547Skarels bbn = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors - 1 471*30547Skarels - bbn; 472*30547Skarels cn = bbn / lp->d_secpercyl; 473*30547Skarels sn = bbn % lp->d_secpercyl; 474*30547Skarels tn = sn / lp->d_nsectors; 475*30547Skarels sn = sn % lp ->d_nsectors; 47610626Shelge io->i_cc = sectsiz; 477*30547Skarels io->i_ma += npf * sectsiz; 47825439Skarels if (sc->debug & HPF_BSEDEBUG) 47911366Ssam printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 48011366Ssam rp->hpof &= ~HPOF_SSEI; 48110626Shelge mbp->mba_sr = -1; 48210334Shelge rp->hpdc = cn; 48310334Shelge rp->hpda = (tn<<8) + sn; 48410334Shelge mbastart(io,io->i_flgs); 48511366Ssam io->i_errcnt = 0; 48610864Ssam HPWAIT(rp); 48710864Ssam return (rp->hpds&HPDS_ERR); 48810334Shelge } 48911084Ssam printf("hpecc: flag=%d\n", flag); 49011084Ssam return (1); 49110334Shelge } 492*30547Skarels #endif 49311140Ssam 49410334Shelge /*ARGSUSED*/ 49510334Shelge hpioctl(io, cmd, arg) 49610334Shelge struct iob *io; 49710334Shelge int cmd; 49810334Shelge caddr_t arg; 49910334Shelge { 500*30547Skarels #ifdef SMALL 501*30547Skarels return (ECMD); 502*30547Skarels #else 50310647Shelge register unit = io->i_unit; 50425439Skarels register struct hp_softc *sc = &hp_softc[unit]; 505*30547Skarels register struct disklabel *lp = &hplabel[unit]; 50610647Shelge struct mba_drv *drv = mbadrv(unit); 50710334Shelge 50810334Shelge switch(cmd) { 50910334Shelge 51011366Ssam case SAIODEBUG: 51125439Skarels sc->debug = (int)arg; 51225439Skarels break; 51311366Ssam 51410334Shelge case SAIODEVDATA: 51525439Skarels if (drv->mbd_dt&MBDT_TAP) 51625439Skarels return (ECMD); 517*30547Skarels *(struct disklabel *)arg = *lp; 51825439Skarels break; 51910334Shelge 52025439Skarels case SAIOGBADINFO: 52125439Skarels if (drv->mbd_dt&MBDT_TAP) 52225439Skarels return (ECMD); 52325439Skarels *(struct dkbad *)arg = hpbad[unit]; 52425439Skarels break; 52525439Skarels 52625439Skarels case SAIOECCLIM: 52725439Skarels sc->ecclim = (int)arg; 52825439Skarels break; 52925439Skarels 53025439Skarels case SAIORETRIES: 53125439Skarels sc->retries = (int)arg; 53225439Skarels break; 53325439Skarels 53411084Ssam case SAIOSSI: /* skip-sector-inhibit */ 53511084Ssam if (drv->mbd_dt&MBDT_TAP) 53611084Ssam return (ECMD); 53711084Ssam if ((io->i_flgs&F_SSI) == 0) { 53811084Ssam /* make sure this is done once only */ 53911084Ssam io->i_flgs |= F_SSI; 540*30547Skarels lp->d_nsectors++; 541*30547Skarels lp->d_secpercyl += lp->d_ntracks; 54210864Ssam } 54325439Skarels break; 54410626Shelge 54511084Ssam case SAIONOSSI: /* remove skip-sector-inhibit */ 54610626Shelge if (io->i_flgs & F_SSI) { 54710626Shelge io->i_flgs &= ~F_SSI; 54810626Shelge drv->mbd_of &= ~HPOF_SSEI; 549*30547Skarels lp->d_nsectors--; 550*30547Skarels lp->d_secpercyl -= lp->d_ntracks; 55110626Shelge } 55225439Skarels break; 55310626Shelge 55410864Ssam case SAIOSSDEV: /* drive have skip sector? */ 555*30547Skarels return (RM80(sc->type) ? 0 : ECMD); 55625439Skarels 55725439Skarels default: 55825439Skarels return (ECMD); 55910334Shelge } 56025439Skarels return (0); 561*30547Skarels #endif 56210334Shelge } 563