1*11115Ssam /* hp.c 4.14 83/02/17 */ 210334Shelge 310334Shelge /* 410334Shelge * RP??/RM?? disk driver 510334Shelge * with ECC handling and bad block forwarding. 610334Shelge * Also supports header io operations and 710334Shelge * commands to write check header and data. 810334Shelge */ 910334Shelge 1010334Shelge #include "../h/param.h" 1110334Shelge #include "../h/inode.h" 1210334Shelge #include "../h/fs.h" 1310334Shelge #include "../h/dkbad.h" 1410334Shelge 1510334Shelge #include "../vax/pte.h" 1610334Shelge #include "../vaxmba/hpreg.h" 1710334Shelge #include "../vaxmba/mbareg.h" 1810334Shelge 1910334Shelge #include "saio.h" 2010334Shelge #include "savax.h" 2110334Shelge 2210334Shelge #define MASKREG(reg) ((reg)&0xffff) 2310334Shelge 2410334Shelge #define MAXBADDESC 126 2510334Shelge #define SECTSIZ 512 /* sector size in bytes */ 2610334Shelge #define HDRSIZ 4 /* number of bytes in sector header */ 2710334Shelge #define MAXECC 5 /* the maximum number of bad bits accepted in 2810334Shelge * an ecc error when F_ECCLM is set */ 2910334Shelge 3010334Shelge char hp_type[MAXNMBA*8] = { 0 }; 3110334Shelge 3210334Shelge /* THIS SHOULD BE READ IN OFF THE PACK, PER DRIVE */ 3310334Shelge short hp6_off[8] = { 0, 38, 0, -1, -1, -1, 118, -1 }; 3410334Shelge short rm3_off[8] = { 0, 100, 0, -1, -1, -1, 310, -1 }; 3510334Shelge short rm5_off[8] = { 0, 27, 0, 562, 589, 681, 562, 82 }; 3610334Shelge short rm80_off[8] = { 0, 37, 0, -1, -1, -1, 115, 305 }; 3710334Shelge short hp7_off[8] = { 0, 10, 0, 330, 340, 500, 330, 50 }; 3810334Shelge short ml_off[8] = { 0, -1, -1, -1, -1, -1, -1, -1 }; 3910334Shelge short si9775_off[8] = { 0, 13, 0, -1, -1, -1, 40, 441 }; 4010334Shelge short si9730_off[8] = { 0, 50, 0, -1, -1, -1, -1, 155 }; 4110334Shelge short hpam_off[8] = { 0, 32, 0, 668, 723, 778, 668, 98 }; 4210626Shelge short hpfj_off[8] = { 0, 19, 0, -1, -1, -1, 398, 59 }; 4310334Shelge /* END SHOULD BE READ IN */ 4410334Shelge 45*11115Ssam short hptypes[] = { 46*11115Ssam MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, 47*11115Ssam MBDT_RP05, MBDT_RP07, MBDT_ML11A, MBDT_ML11B, 48*11115Ssam -1 /*9755*/, -1 /*9730*/, -1 /*Cap*/, -1 /* Eagle */, 49*11115Ssam -1 /* Eagle */, MBDT_RM02, 0 50*11115Ssam }; 5110334Shelge 5210626Shelge #define RP06 (hptypes[hp_type[unit]] <= MBDT_RP06) 5310626Shelge #define ML11 (hptypes[hp_type[unit]] == MBDT_ML11A) 5410626Shelge #define RM80 (hptypes[hp_type[unit]] == MBDT_RM80) 5510334Shelge 5610334Shelge u_char hp_offset[16] = { 5710334Shelge HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400, 5810334Shelge HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800, 5910334Shelge HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200, 6010334Shelge 0, 0, 0, 0, 6110334Shelge }; 6210334Shelge 6310353Shelge struct st hpst[] = { 6410647Shelge 32, 5, 32*5, 823, rm3_off, /* RM03 */ 6510647Shelge 32, 19, 32*19, 823, rm5_off, /* RM05 */ 6610647Shelge 22, 19, 22*19, 815, hp6_off, /* RP06 */ 6710647Shelge 31, 14, 31*14, 559, rm80_off, /* RM80 */ 6810647Shelge 22, 19, 22*19, 411, hp6_off, /* RP06 */ 6910647Shelge 50, 32, 50*32, 630, hp7_off, /* RP07 */ 7010647Shelge 1, 1, 1, 1, ml_off, /* ML11A */ 7110647Shelge 1, 1, 1, 1, ml_off, /* ML11B */ 7210647Shelge 32, 40, 32*40, 843, si9775_off, /* 9775 */ 7310647Shelge 32, 10, 32*10, 823, si9730_off, /* 9730 */ 7410647Shelge 32, 16, 32*16, 1024, hpam_off, /* capricorn */ 7510647Shelge 43, 20, 43*20, 842, hpfj_off, /* Eagle */ 7610693Shelge 48, 20, 48*20, 842, hpfj_off, /* modif. eagle */ 77*11115Ssam 1, 1, 1, 1, 0, /* rm02 - not used */ 7810334Shelge }; 7911084Ssam 8010334Shelge struct dkbad hpbad[MAXNMBA*8]; 8110334Shelge int sectsiz; 8210334Shelge 8310864Ssam /* 8410864Ssam * When awaiting command completion, don't 8510864Ssam * hang on to the status register since 8610864Ssam * this ties up the controller. 8710864Ssam */ 8810864Ssam #define HPWAIT(addr) while ((((addr)->hpds)&HPDS_DRY)==0) DELAY(500); 8910864Ssam 9010334Shelge hpopen(io) 9110334Shelge register struct iob *io; 9210334Shelge { 9310334Shelge register unit = io->i_unit; 9410334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 9510353Shelge register struct st *st; 9610334Shelge 9710334Shelge mbainit(UNITTOMBA(unit)); 9810334Shelge if (hp_type[unit] == 0) { 9910334Shelge register type = hpaddr->hpdt & MBDT_TYPE; 10010334Shelge register int i; 10110334Shelge struct iob tio; 10210334Shelge 10310334Shelge for (i = 0; hptypes[i]; i++) 10410334Shelge if (hptypes[i] == type) 10510334Shelge goto found; 10610334Shelge _stop("unknown drive type"); 10710334Shelge found: 10810647Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; /* init drive */ 10910647Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 11010647Shelge if (!ML11) 11110647Shelge hpaddr->hpof = HPOF_FMT22; 11211113Shelge hp_type[unit] = hpmaptype(hpaddr, i, unit); 11310334Shelge /* 11410334Shelge * Read in the bad sector table: 11510334Shelge * copy the contents of the io structure 11610334Shelge * to tio for use during the bb pointer 11710334Shelge * read operation. 11810334Shelge */ 11910626Shelge st = &hpst[i]; 12010334Shelge tio = *io; 12110334Shelge tio.i_bn = st->nspc * st->ncyl - st->nsect; 12210626Shelge tio.i_ma = (char *)&hpbad[unit]; 12310628Shelge tio.i_cc = sizeof (struct dkbad); 12410334Shelge tio.i_flgs |= F_RDDATA; 12510334Shelge for (i = 0; i < 5; i++) { 12610628Shelge if (hpstrategy(&tio, READ) == sizeof (struct dkbad)) 12710334Shelge break; 12810334Shelge tio.i_bn += 2; 12910334Shelge } 13010334Shelge if (i == 5) { 13110334Shelge printf("Unable to read bad sector table\n"); 13210334Shelge for (i = 0; i < MAXBADDESC; i++) { 13310334Shelge hpbad[unit].bt_bad[i].bt_cyl = -1; 13410334Shelge hpbad[unit].bt_bad[i].bt_trksec = -1; 13510334Shelge } 13610334Shelge } 13710334Shelge } 13810334Shelge if (io->i_boff < 0 || io->i_boff > 7 || 13910334Shelge st->off[io->i_boff]== -1) 14010334Shelge _stop("hp bad minor"); 14110334Shelge io->i_boff = st->off[io->i_boff] * st->nspc; 14210334Shelge } 14310334Shelge 14411084Ssam hpmaptype(hpaddr, type, unit) 14511084Ssam register struct hpdevice *hpaddr; 14611084Ssam unsigned type; 14711084Ssam int unit; 14811084Ssam { 14911084Ssam int ntracks, hpsn; 15011084Ssam 15111084Ssam /* 15211084Ssam * Handle SI model byte stuff when 15311084Ssam * we think it's an RM03 or RM05. 15411084Ssam */ 15511084Ssam if (type == 0 || type == 1) { 15611084Ssam hpsn = hpaddr->hpsn; 15711084Ssam if ((hpsn & SIMB_LU) != unit) 15811084Ssam return (type); 15911084Ssam switch ((hpsn & SIMB_MB) &~ (SIMB_S6|SIRM03|SIRM05)) { 16011084Ssam case SI9775D: 16111084Ssam return (8); 16211084Ssam case SI9730D: 16311084Ssam return (9); 16411084Ssam case SI9766: 16511084Ssam hpaddr->hpcs1 = HP_RECAL|HP_GO; 16611084Ssam DELAY(100000); 16711084Ssam return (1); 16811084Ssam 16911084Ssam case SI9762: 17011084Ssam return (0); 17111084Ssam } 17211084Ssam return (type); 17311084Ssam } 17411084Ssam /* 17511084Ssam * RM03: EMULEX controller. Map to correct 17611084Ssam * drive type by checking the holding 17711084Ssam * register for the disk geometry. 17811084Ssam */ 17911084Ssam if (type == 13) { 18011084Ssam hpaddr->hpcs1 = HP_NOP; 18111084Ssam hpaddr->hphr = HPHR_MAXTRAK; 18211084Ssam ntracks = MASKREG(hpaddr->hphr) + 1; 18311084Ssam if (ntracks == 16) 18411084Ssam return (10); /* AMPEX capricorn */ 18511084Ssam hpaddr->hphr = HPHR_MAXSECT; 18611113Shelge ntracks = MASKREG(hpaddr->hphr) + 1; 18711084Ssam if (ntracks == 48) 18811084Ssam return (12); /* 48 sector Eagle */ 18911084Ssam if (ntracks == 43) 19011084Ssam return (11); /* 43 sector Eagle */ 19111114Shelge printf("RM02 with %d sectors/track?\n", ntracks); 19211084Ssam return (type); 19311084Ssam } 19411084Ssam /* 19511084Ssam * ML11's all map to the same type. 19611084Ssam */ 19711084Ssam if (type == 6 || type == 7) 19811084Ssam return (6); 19911084Ssam return (type); 20011084Ssam } 20111084Ssam 20210647Shelge int ssect; /* set to 1 if we are on a track with skip sectors */ 20310647Shelge 20410334Shelge hpstrategy(io, func) 20510334Shelge register struct iob *io; 20610334Shelge { 20710334Shelge register unit = io->i_unit; 20810334Shelge struct mba_regs *mba = mbamba(unit); 20910334Shelge daddr_t bn; 21010334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 21110353Shelge struct st *st = &hpst[hp_type[unit]]; 21210334Shelge int cn, tn, sn, bytecnt, bytesleft; 21310334Shelge daddr_t startblock; 21410334Shelge char *membase; 21510334Shelge int er1, er2, hprecal; 21610334Shelge 21710334Shelge sectsiz = SECTSIZ; 21810334Shelge if ((io->i_flgs & (F_HDR|F_HCHECK)) != 0) 21910334Shelge sectsiz += HDRSIZ; 22010334Shelge if ((hpaddr->hpds & HPDS_VV) == 0) { 22110334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 22210334Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 22311084Ssam if (!ML11) 22410334Shelge hpaddr->hpof = HPOF_FMT22; 22510334Shelge } 22610334Shelge io->i_errcnt = 0; 22710647Shelge ssect = 0; 22810334Shelge bytecnt = io->i_cc; 22910334Shelge membase = io->i_ma; 23010334Shelge startblock = io->i_bn; 23110608Ssam hprecal = 0; 23210626Shelge restart: 23310334Shelge bn = io->i_bn; 23410334Shelge cn = bn/st->nspc; 23510334Shelge sn = bn%st->nspc; 23610334Shelge tn = sn/st->nsect; 23710647Shelge sn = sn%st->nsect + ssect; 23810334Shelge 23910864Ssam HPWAIT(hpaddr); 24010626Shelge mba->mba_sr = -1; 24110647Shelge if (ML11) 24210334Shelge hpaddr->hpda = bn; 24310334Shelge else { 24410334Shelge hpaddr->hpdc = cn; 24510334Shelge hpaddr->hpda = (tn << 8) + sn; 24610334Shelge } 24710334Shelge if (mbastart(io, func) != 0) /* start transfer */ 24810334Shelge return (-1); 24910864Ssam HPWAIT(hpaddr); 25011084Ssam if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0) 25111084Ssam return (bytecnt); 25210334Shelge 25310334Shelge /* ------- error handling ------- */ 25410334Shelge 25510334Shelge if (bytesleft = MASKREG(mba->mba_bcr>>16)) 25610334Shelge bytesleft |= 0xffff0000; /* sign ext */ 25710334Shelge bn = io->i_bn + (io->i_cc + bytesleft)/sectsiz; 25810334Shelge cn = bn/st->nspc; 25910334Shelge sn = bn%st->nspc; 26010334Shelge tn = sn/st->nsect; 26110334Shelge sn = sn%st->nsect; 26210334Shelge er1 = MASKREG(hpaddr->hper1); 26310334Shelge er2 = MASKREG(hpaddr->hper2); 26410334Shelge #ifdef HPDEBUG 26510334Shelge printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n", 26610334Shelge cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 26710626Shelge printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS); 26810626Shelge printf("\nbytes left: %d, of 0x%x, da 0x%x",-bytesleft, 26910626Shelge hpaddr->hpof, hpaddr->hpda); 27010334Shelge printf("\n"); 27110334Shelge #endif 27210334Shelge if (er1 & HPER1_HCRC) { 27310334Shelge er1 &= ~(HPER1_HCE|HPER1_FER); 27410334Shelge er2 &= ~HPER2_BSE; 27510334Shelge } 27610334Shelge if (er1&HPER1_WLE) { 27710334Shelge printf("hp%d: write locked\n", unit); 27811084Ssam return (-1); 27911084Ssam } 28011084Ssam if (MASKREG(er1) == HPER1_FER && RP06) 28110334Shelge goto badsect; 28211084Ssam if (++io->i_errcnt > 27 || (er1 & HPER1_HARD) || 28311084Ssam (!ML11 && (er2 & HPER2_HARD))) { 28410608Ssam hard0: 28510334Shelge io->i_error = EHER; 28611084Ssam if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR)) 28710334Shelge io->i_error = EWCK; 28810334Shelge hard: 28910647Shelge io->i_errblk = bn + ssect; 29010334Shelge printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n", 29110334Shelge cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 29211084Ssam printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS); 29310334Shelge if (hpaddr->hpmr) 29410626Shelge printf(" mr1=%o", MASKREG(hpaddr->hpmr)); 29510334Shelge if (hpaddr->hpmr2) 29610626Shelge printf(" mr2=%o", MASKREG(hpaddr->hpmr2)); 29710626Shelge #ifdef HPDEBUG 29810626Shelge printf("dc: %d, da: 0x%x",MASKREG(hpaddr->hpdc), 29911084Ssam MASKREG(hpaddr->hpda)); 30010626Shelge #endif 30110626Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 30210334Shelge printf("\n"); 30311084Ssam return (-1); 30410334Shelge 30511084Ssam } 30611084Ssam if ((er2 & HPER2_BSE) && !ML11) { 30710334Shelge badsect: 30810647Shelge if (!ssect && (er2&HPER2_SSE)) 30910647Shelge goto skipsect; 31011084Ssam if (io->i_flgs & F_NBSF) { 31110334Shelge io->i_error = EBSE; 31210334Shelge goto hard; 31310334Shelge } 31410334Shelge if (hpecc(io, BSE) == 0) 31510334Shelge goto success; 31611084Ssam io->i_error = EBSE; 31711084Ssam goto hard; 31811084Ssam } 31911084Ssam if (RM80 && er2&HPER2_SSE) { 32010647Shelge skipsect: 32110334Shelge (void) hpecc(io, SSE); 32211084Ssam ssect = 1; 32310334Shelge goto success; 32411084Ssam } 32511084Ssam if ((er1 & (HPER1_DCK|HPER1_ECH)) == HPER1_DCK) { 32610864Ssam if (hpecc(io, ECC) == 0) 32710334Shelge goto success; 32811084Ssam io->i_error = EECC; 32911084Ssam return (-1); 33010608Ssam } 33110608Ssam if (ML11 && (io->i_errcnt >= 16)) 33211084Ssam goto hard0; 33310608Ssam /* fall thru to retry */ 33410334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 33510864Ssam HPWAIT(hpaddr); 33610608Ssam if (((io->i_errcnt&07) == 4) ) { 33710334Shelge hpaddr->hpcs1 = HP_RECAL|HP_GO; 33810608Ssam hprecal = 1; 33911084Ssam goto again; 34010334Shelge } 34110334Shelge switch (hprecal) { 34210334Shelge 34310334Shelge case 1: 34410334Shelge hpaddr->hpdc = cn; 34510334Shelge hpaddr->hpcs1 = HP_SEEK|HP_GO; 34611084Ssam hprecal = 2; 34711084Ssam goto again; 34810864Ssam 34910334Shelge case 2: 35010608Ssam if (io->i_errcnt < 16 || (io->i_flgs & F_READ) == 0) 35110334Shelge goto donerecal; 35210334Shelge hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22; 35310334Shelge hpaddr->hpcs1 = HP_OFFSET|HP_GO; 35411084Ssam hprecal = 3; 35511084Ssam goto again; 35610864Ssam 35711084Ssam case 3: 35810334Shelge donerecal: 35910334Shelge hprecal = 0; 36011084Ssam goto again; 36110334Shelge } 36210608Ssam if (io->i_errcnt >= 16) { 36310608Ssam hpaddr->hpcs1 = HP_RTC|HP_GO; 36410608Ssam while (hpaddr->hpds & HPDS_PIP) 36510608Ssam ; 36610334Shelge } 36711084Ssam goto again; 36811084Ssam 36911084Ssam success: /* continue with the next block */ 37010334Shelge bn++; 37110334Shelge if ((bn-startblock) * sectsiz < bytecnt) { 37211084Ssam again: /* re-read same block */ 37310334Shelge io->i_bn = bn; 37410334Shelge io->i_ma = membase + (io->i_bn - startblock)*sectsiz; 37510334Shelge io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz; 37610334Shelge #ifdef HPDEBUG 37710608Ssam printf("restart: bl %d, byte %d, mem 0x%x hprecal %d\n", 37810608Ssam io->i_bn, io->i_cc, io->i_ma, hprecal); 37910334Shelge #endif 38010626Shelge goto restart; 38110334Shelge } 38210334Shelge return (bytecnt); 38310334Shelge } 38410864Ssam 38510334Shelge hpecc(io, flag) 38610334Shelge register struct iob *io; 38710334Shelge int flag; 38810334Shelge { 38910334Shelge register unit = io->i_unit; 39010334Shelge register struct mba_regs *mbp = mbamba(unit); 39110334Shelge register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit); 39210353Shelge register struct st *st = &hpst[hp_type[unit]]; 39311084Ssam int npf, bn, cn, tn, sn, bcr; 39410334Shelge 39510334Shelge if (bcr = MASKREG(mbp->mba_bcr>>16)) 39610334Shelge bcr |= 0xffff0000; /* sxt */ 39711084Ssam npf = (bcr + io->i_cc) / sectsiz; /* # sectors read */ 39811084Ssam bn = io->i_bn + npf + ssect; /* physical block #*/ 39910334Shelge switch (flag) { 40011084Ssam 40110864Ssam case ECC: { 40210334Shelge register int i; 40310334Shelge caddr_t addr; 40410334Shelge int bit, byte, mask, ecccnt = 0; 40510334Shelge 40610413Shelge printf("hp%d: soft ecc sn%d\n", unit, bn); 40710334Shelge mask = MASKREG(rp->hpec2); 40811084Ssam i = MASKREG(rp->hpec1) - 1; /* -1 makes 0 origin */ 40910334Shelge bit = i&07; 41010334Shelge i = (i&~07)>>3; 41110334Shelge byte = i; 41210334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 41310334Shelge while (i <sectsiz && npf*sectsiz + i < io->i_cc && bit > -11) { 41410334Shelge addr = io->i_ma + (npf*sectsiz) + byte; 41510334Shelge #ifdef HPECCDEBUG 41610334Shelge printf("addr %x old:%x ",addr, (*addr&0xff)); 41710334Shelge #endif 41810334Shelge if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) 41910334Shelge *addr ^= (mask << bit); /* don't 'correct' mem- 42010334Shelge * ory during Wcheck */ 42110334Shelge #ifdef HPECCDEBUG 42210334Shelge printf("new:%x\n",(*addr&0xff)); 42310334Shelge #endif 42410334Shelge byte++; 42510334Shelge i++; 42610334Shelge bit -= 8; 42711109Ssam if ((io->i_flgs & F_ECCLM) && ecccnt++ >= MAXECC) 42811084Ssam return (1); 42910334Shelge } 43010334Shelge return(0); 43111084Ssam } 43210334Shelge 43311084Ssam /* 43411084Ssam * Skip sector error. 43511084Ssam * Set skip-sector-inhibit and 43611084Ssam * read next sector 43711084Ssam */ 43811084Ssam case SSE: 43910334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 44010864Ssam HPWAIT(rp); 44110334Shelge rp->hpof |= HPOF_SSEI; 44211084Ssam return (0); 44310334Shelge 44410864Ssam case BSE: { 44510626Shelge int bbn; 44611084Ssam 44710626Shelge rp->hpcs1 = HP_DCLR | HP_GO; 44810334Shelge #ifdef HPDEBUG 44910334Shelge printf("hpecc: BSE @ bn %d\n", bn); 45010334Shelge #endif 45110334Shelge cn = bn/st->nspc; 45210334Shelge sn = bn%st->nspc; 45310334Shelge tn = sn/st->nsect; 45410626Shelge sn = sn%st->nsect; 45510626Shelge bcr += sectsiz; 45610626Shelge if ((bbn = isbad(&hpbad[unit], cn, tn, sn)) < 0) 45711084Ssam return (1); 45810626Shelge bbn = st->ncyl*st->nspc - st->nsect - 1 - bbn; 45910626Shelge cn = bbn/st->nspc; 46010626Shelge sn = bbn%st->nspc; 46110626Shelge tn = sn/st->nsect; 46210626Shelge sn = sn%st->nsect; 46310626Shelge io->i_cc = sectsiz; 46410626Shelge io->i_ma += npf*sectsiz; 46510626Shelge #ifdef HPDEBUG 46610626Shelge printf("revector to cn %d tn %d sn %d mem: 0x%x\n", 46710626Shelge cn, tn, sn, io->i_ma); 46810626Shelge #endif 46910647Shelge rp->hpof &= ~HPOF_SSEI; /* clear skip sector inhibit if set */ 47010626Shelge mbp->mba_sr = -1; 47110334Shelge rp->hpdc = cn; 47210334Shelge rp->hpda = (tn<<8) + sn; 47310334Shelge mbastart(io,io->i_flgs); 47410334Shelge io->i_errcnt = 0; /* error has been corrected */ 47510864Ssam HPWAIT(rp); 47610864Ssam return (rp->hpds&HPDS_ERR); 47710334Shelge } 47811084Ssam } 47911084Ssam printf("hpecc: flag=%d\n", flag); 48011084Ssam return (1); 48110334Shelge } 48210334Shelge /*ARGSUSED*/ 48310334Shelge hpioctl(io, cmd, arg) 48410334Shelge struct iob *io; 48510334Shelge int cmd; 48610334Shelge caddr_t arg; 48710334Shelge { 48810647Shelge register unit = io->i_unit; 48910647Shelge struct st *st = &hpst[hp_type[unit]], *tmp; 49010647Shelge struct mba_drv *drv = mbadrv(unit); 49110334Shelge 49210334Shelge switch(cmd) { 49310334Shelge 49410334Shelge case SAIODEVDATA: 49510334Shelge if ((drv->mbd_dt&MBDT_TAP) == 0) { 49610353Shelge tmp = (struct st *)arg; 49710353Shelge *tmp = *st; 49811084Ssam return (0); 49910334Shelge } 50011084Ssam return (ECMD); 50110334Shelge 50211084Ssam case SAIOSSI: /* skip-sector-inhibit */ 50311084Ssam if (drv->mbd_dt&MBDT_TAP) 50411084Ssam return (ECMD); 50511084Ssam if ((io->i_flgs&F_SSI) == 0) { 50611084Ssam /* make sure this is done once only */ 50711084Ssam io->i_flgs |= F_SSI; 50811084Ssam st->nsect++; 50911084Ssam st->nspc += st->ntrak; 51010864Ssam } 51111084Ssam return (0); 51210626Shelge 51311084Ssam case SAIONOSSI: /* remove skip-sector-inhibit */ 51410626Shelge if (io->i_flgs & F_SSI) { 51510626Shelge io->i_flgs &= ~F_SSI; 51610626Shelge drv->mbd_of &= ~HPOF_SSEI; 51710626Shelge st->nsect--; 51810626Shelge st->nspc -= st->ntrak; 51910626Shelge } 52010626Shelge return(0); 52110626Shelge 52210864Ssam case SAIOSSDEV: /* drive have skip sector? */ 52311084Ssam return (RM80 ? 0 : ECMD); 52410334Shelge } 52511084Ssam return (ECMD); 52610334Shelge } 527