1*10693Shelge /* hp.c 4.8 83/02/02 */ 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 4510334Shelge short hptypes[] = 4610334Shelge { MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, MBDT_RP05, MBDT_RP07, 4710626Shelge MBDT_ML11A, MBDT_ML11B, -1/*9755*/, -1/*9730*/, -1/*Capr*/, 48*10693Shelge -1/* eagle */, -1/* 48 sect eagle*/, MBDT_RM02, 0}; 4910334Shelge 5010626Shelge #define RP06 (hptypes[hp_type[unit]] <= MBDT_RP06) 5110626Shelge #define ML11 (hptypes[hp_type[unit]] == MBDT_ML11A) 5210626Shelge #define RM80 (hptypes[hp_type[unit]] == MBDT_RM80) 5310334Shelge 5410334Shelge u_char hp_offset[16] = { 5510334Shelge HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400, 5610334Shelge HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800, 5710334Shelge HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200, 5810334Shelge 0, 0, 0, 0, 5910334Shelge }; 6010334Shelge 6110353Shelge struct st hpst[] = { 6210647Shelge 32, 5, 32*5, 823, rm3_off, /* RM03 */ 6310647Shelge 32, 19, 32*19, 823, rm5_off, /* RM05 */ 6410647Shelge 22, 19, 22*19, 815, hp6_off, /* RP06 */ 6510647Shelge 31, 14, 31*14, 559, rm80_off, /* RM80 */ 6610647Shelge 22, 19, 22*19, 411, hp6_off, /* RP06 */ 6710647Shelge 50, 32, 50*32, 630, hp7_off, /* RP07 */ 6810647Shelge 1, 1, 1, 1, ml_off, /* ML11A */ 6910647Shelge 1, 1, 1, 1, ml_off, /* ML11B */ 7010647Shelge 32, 40, 32*40, 843, si9775_off, /* 9775 */ 7110647Shelge 32, 10, 32*10, 823, si9730_off, /* 9730 */ 7210647Shelge 32, 16, 32*16, 1024, hpam_off, /* capricorn */ 7310647Shelge 43, 20, 43*20, 842, hpfj_off, /* Eagle */ 74*10693Shelge 48, 20, 48*20, 842, hpfj_off, /* modif. eagle */ 7510647Shelge 1, 1, 1, 1, 0, /* rm02 - not used */ 7610334Shelge }; 7710334Shelge struct dkbad hpbad[MAXNMBA*8]; 7810334Shelge int sectsiz; 7910334Shelge 8010334Shelge hpopen(io) 8110334Shelge register struct iob *io; 8210334Shelge { 8310334Shelge register unit = io->i_unit; 8410334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 8510353Shelge register struct st *st; 8610334Shelge 8710334Shelge mbainit(UNITTOMBA(unit)); 8810334Shelge if (hp_type[unit] == 0) { 8910334Shelge register type = hpaddr->hpdt & MBDT_TYPE; 9010334Shelge register int i; 9110334Shelge struct iob tio; 9210334Shelge 9310334Shelge for (i = 0; hptypes[i]; i++) 9410334Shelge if (hptypes[i] == type) 9510334Shelge goto found; 9610334Shelge _stop("unknown drive type"); 9710334Shelge found: 9810334Shelge switch (i) { 9910334Shelge case 0: case 1: { /* rm03 or rm05 */ 10010334Shelge register hpsn = hpaddr->hpsn; 10110334Shelge 10210334Shelge if ((hpsn & SIMB_LU) != unit) 10310334Shelge break; 10410334Shelge switch ((hpsn & SIMB_MB) &~ (SIMB_S6|SIRM03|SIRM05)) { 10510334Shelge case SI9775D: 10610334Shelge i = 8; /* si9775 */ 10710334Shelge break; 10810334Shelge case SI9730D: 10910334Shelge i = 9; /* si9730 */ 11010334Shelge break; 11110334Shelge case SI9766: 11210334Shelge i = 1; /* rm05 */ 11310334Shelge hpaddr->hpcs1 = HP_RECAL|HP_GO; 11410334Shelge DELAY(100000); 11510334Shelge break; 11610334Shelge case SI9762: 11710334Shelge i = 0; /* rm03 */ 11810334Shelge break; 11910334Shelge } 12010334Shelge break; 12110334Shelge } 12210334Shelge 123*10693Shelge case 13: /* rm02 */ 124*10693Shelge 12510334Shelge hpaddr->hpcs1 = HP_NOP; 12610334Shelge hpaddr->hphr = HPHR_MAXTRAK; 127*10693Shelge 12810334Shelge if (MASKREG(hpaddr->hphr) == 15) 12910334Shelge i = 10; /* ampex capricorn */ 130*10693Shelge else { 131*10693Shelge hpaddr->hphr = HPHR_MAXSECT; 132*10693Shelge if (MASKREG(hpaddr->hphr) == 47) 133*10693Shelge i = 12; /* modified eagle */ 134*10693Shelge else 135*10693Shelge i = 11; /* eagle */ 136*10693Shelge } 13710334Shelge break; 13810334Shelge 13910334Shelge case 6: case 7: /* ml11a ml11b */ 14010334Shelge i = 6; /* ml11a */ 14110334Shelge break; 14210334Shelge } 14310334Shelge hp_type[unit] = i; 14410647Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; /* init drive */ 14510647Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 14610647Shelge if (!ML11) 14710647Shelge hpaddr->hpof = HPOF_FMT22; 14810334Shelge /* 14910334Shelge * Read in the bad sector table: 15010334Shelge * copy the contents of the io structure 15110334Shelge * to tio for use during the bb pointer 15210334Shelge * read operation. 15310334Shelge */ 15410626Shelge st = &hpst[i]; 15510334Shelge tio = *io; 15610334Shelge tio.i_bn = st->nspc * st->ncyl - st->nsect; 15710626Shelge tio.i_ma = (char *)&hpbad[unit]; 15810628Shelge tio.i_cc = sizeof (struct dkbad); 15910334Shelge tio.i_flgs |= F_RDDATA; 16010334Shelge for (i = 0; i < 5; i++) { 16110628Shelge if (hpstrategy(&tio, READ) == sizeof (struct dkbad)) 16210334Shelge break; 16310334Shelge tio.i_bn += 2; 16410334Shelge } 16510334Shelge if (i == 5) { 16610334Shelge printf("Unable to read bad sector table\n"); 16710334Shelge for (i = 0; i < MAXBADDESC; i++) { 16810334Shelge hpbad[unit].bt_bad[i].bt_cyl = -1; 16910334Shelge hpbad[unit].bt_bad[i].bt_trksec = -1; 17010334Shelge } 17110334Shelge } 17210334Shelge } 17310334Shelge if (io->i_boff < 0 || io->i_boff > 7 || 17410334Shelge st->off[io->i_boff]== -1) 17510334Shelge _stop("hp bad minor"); 17610334Shelge io->i_boff = st->off[io->i_boff] * st->nspc; 17710334Shelge } 17810334Shelge 17910647Shelge int ssect; /* set to 1 if we are on a track with skip sectors */ 18010647Shelge 18110334Shelge hpstrategy(io, func) 18210334Shelge register struct iob *io; 18310334Shelge { 18410334Shelge register unit = io->i_unit; 18510334Shelge struct mba_regs *mba = mbamba(unit); 18610334Shelge daddr_t bn; 18710334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 18810353Shelge struct st *st = &hpst[hp_type[unit]]; 18910334Shelge int cn, tn, sn, bytecnt, bytesleft; 19010334Shelge daddr_t startblock; 19110334Shelge char *membase; 19210334Shelge int er1, er2, hprecal; 19310334Shelge 19410334Shelge sectsiz = SECTSIZ; 19510334Shelge if ((io->i_flgs & (F_HDR|F_HCHECK)) != 0) 19610334Shelge sectsiz += HDRSIZ; 19710334Shelge if ((hpaddr->hpds & HPDS_VV) == 0) { 19810334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 19910334Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 20010647Shelge if (!ML11) /* any but ml11 */ 20110334Shelge hpaddr->hpof = HPOF_FMT22; 20210334Shelge } 20310334Shelge io->i_errcnt = 0; 20410647Shelge ssect = 0; 20510334Shelge bytecnt = io->i_cc; 20610334Shelge membase = io->i_ma; 20710334Shelge startblock = io->i_bn; 20810608Ssam hprecal = 0; 20910626Shelge restart: 21010334Shelge bn = io->i_bn; 21110334Shelge cn = bn/st->nspc; 21210334Shelge sn = bn%st->nspc; 21310334Shelge tn = sn/st->nsect; 21410647Shelge sn = sn%st->nsect + ssect; 21510334Shelge 21610334Shelge while ((hpaddr->hpds & HPDS_DRY) == 0) 21710334Shelge ; 21810626Shelge mba->mba_sr = -1; 21910647Shelge if (ML11) 22010334Shelge hpaddr->hpda = bn; 22110334Shelge else { 22210334Shelge hpaddr->hpdc = cn; 22310334Shelge hpaddr->hpda = (tn << 8) + sn; 22410334Shelge } 22510334Shelge if (mbastart(io, func) != 0) /* start transfer */ 22610334Shelge return (-1); 22710334Shelge 22810334Shelge while ((hpaddr->hpds & HPDS_DRY) == 0) 22910334Shelge ; 23010334Shelge if (((hpaddr->hpds&HPDS_ERR) | (mba->mba_sr&MBSR_EBITS)) == 0 ) 23110334Shelge return(bytecnt); 23210334Shelge 23310334Shelge /* ------- error handling ------- */ 23410334Shelge 23510334Shelge if (bytesleft = MASKREG(mba->mba_bcr>>16)) 23610334Shelge bytesleft |= 0xffff0000; /* sign ext */ 23710334Shelge bn = io->i_bn + (io->i_cc + bytesleft)/sectsiz; 23810334Shelge cn = bn/st->nspc; 23910334Shelge sn = bn%st->nspc; 24010334Shelge tn = sn/st->nsect; 24110334Shelge sn = sn%st->nsect; 24210334Shelge er1 = MASKREG(hpaddr->hper1); 24310334Shelge er2 = MASKREG(hpaddr->hper2); 24410334Shelge #ifdef HPDEBUG 24510334Shelge printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n", 24610334Shelge cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 24710626Shelge printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS); 24810626Shelge printf("\nbytes left: %d, of 0x%x, da 0x%x",-bytesleft, 24910626Shelge hpaddr->hpof, hpaddr->hpda); 25010334Shelge printf("\n"); 25110334Shelge #endif 25210334Shelge if (er1 & HPER1_HCRC) { 25310334Shelge er1 &= ~(HPER1_HCE|HPER1_FER); 25410334Shelge er2 &= ~HPER2_BSE; 25510334Shelge } 25610334Shelge if (er1&HPER1_WLE) { 25710334Shelge printf("hp%d: write locked\n", unit); 25810334Shelge return(-1); 25910626Shelge } else if (MASKREG(er1) == HPER1_FER && RP06) { 26010334Shelge goto badsect; 26110334Shelge 26210334Shelge } else if (++io->i_errcnt > 27 || 26310334Shelge er1 & HPER1_HARD || 26410334Shelge (!ML11 && (er2 & HPER2_HARD))) { 26510608Ssam hard0: 26610334Shelge io->i_error = EHER; 26710334Shelge if ((mba->mba_sr & (MBSR_WCKUP | MBSR_WCKLWR)) != 0) 26810334Shelge io->i_error = EWCK; 26910334Shelge hard: 27010647Shelge io->i_errblk = bn + ssect; 27110334Shelge printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n", 27210334Shelge cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 27310334Shelge printf("er1=%b er2=%b", 27410334Shelge er1, HPER1_BITS, 27510334Shelge er2, HPER2_BITS); 27610334Shelge if (hpaddr->hpmr) 27710626Shelge printf(" mr1=%o", MASKREG(hpaddr->hpmr)); 27810334Shelge if (hpaddr->hpmr2) 27910626Shelge printf(" mr2=%o", MASKREG(hpaddr->hpmr2)); 28010626Shelge #ifdef HPDEBUG 28110626Shelge printf("dc: %d, da: 0x%x",MASKREG(hpaddr->hpdc), 28210626Shelge MASKREG(hpaddr->hpda)); 28310626Shelge #endif 28410626Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 28510334Shelge printf("\n"); 28610334Shelge return(-1); 28710334Shelge 28810334Shelge } else if ((er2 & HPER2_BSE) && !ML11) { 28910334Shelge badsect: 29010647Shelge if (!ssect && (er2&HPER2_SSE)) 29110647Shelge goto skipsect; 29210334Shelge if ((io->i_flgs & F_NBSF) != 0) { 29310334Shelge io->i_error = EBSE; 29410334Shelge goto hard; 29510334Shelge } 29610334Shelge if (hpecc(io, BSE) == 0) 29710334Shelge goto success; 29810334Shelge else { 29910334Shelge io->i_error = EBSE; 30010334Shelge goto hard; 30110334Shelge } 30210647Shelge } else if (RM80 && er2&HPER2_SSE) { 30310647Shelge skipsect: 30410334Shelge /* skip sector error */ 30510334Shelge (void) hpecc(io, SSE); 30610647Shelge ssect=1; 30710334Shelge goto success; 30810334Shelge } else if ((er1&(HPER1_DCK|HPER1_ECH))==HPER1_DCK) { 30910334Shelge if ( hpecc(io, ECC) == 0) 31010334Shelge goto success; 31110334Shelge else { 31210334Shelge io->i_error = EECC; 31310334Shelge return(1); 31410334Shelge } 31510608Ssam } 31610334Shelge 31710608Ssam if (ML11 && (io->i_errcnt >= 16)) 31810608Ssam goto hard0; 31910608Ssam 32010608Ssam /* fall thru to retry */ 32110608Ssam 32210334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 32310334Shelge while ((hpaddr->hpds & HPDS_DRY) == 0) 32410334Shelge ; 32510608Ssam if (((io->i_errcnt&07) == 4) ) { 32610334Shelge hpaddr->hpcs1 = HP_RECAL|HP_GO; 32710608Ssam hprecal = 1; 32810608Ssam goto try_again; 32910334Shelge } 33010334Shelge switch (hprecal) { 33110334Shelge 33210334Shelge case 1: 33310334Shelge hpaddr->hpdc = cn; 33410334Shelge hpaddr->hpcs1 = HP_SEEK|HP_GO; 33510608Ssam hprecal++; 33610608Ssam goto try_again; 33710334Shelge case 2: 33810608Ssam if (io->i_errcnt < 16 || (io->i_flgs & F_READ) == 0) 33910334Shelge goto donerecal; 34010334Shelge hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22; 34110334Shelge hpaddr->hpcs1 = HP_OFFSET|HP_GO; 34210334Shelge hprecal++; 34310334Shelge goto try_again; 34410334Shelge donerecal: 34510334Shelge case 3: 34610334Shelge hprecal = 0; 34710334Shelge goto try_again; 34810334Shelge } 34910608Ssam if (io->i_errcnt >= 16) { 35010608Ssam hpaddr->hpcs1 = HP_RTC|HP_GO; 35110608Ssam while (hpaddr->hpds & HPDS_PIP) 35210608Ssam ; 35310334Shelge } 35410608Ssam goto try_again; 35510334Shelge success: /* continue with the next block */ 35610334Shelge bn++; 35710334Shelge if ((bn-startblock) * sectsiz < bytecnt) { 35810334Shelge 35910334Shelge try_again: /* re-read same block */ 36010334Shelge io->i_bn = bn; 36110334Shelge io->i_ma = membase + (io->i_bn - startblock)*sectsiz; 36210334Shelge io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz; 36310334Shelge #ifdef HPDEBUG 36410608Ssam printf("restart: bl %d, byte %d, mem 0x%x hprecal %d\n", 36510608Ssam io->i_bn, io->i_cc, io->i_ma, hprecal); 36610334Shelge #endif 36710626Shelge goto restart; 36810334Shelge } 36910334Shelge return (bytecnt); 37010334Shelge } 37110334Shelge hpecc(io, flag) 37210334Shelge register struct iob *io; 37310334Shelge int flag; 37410334Shelge { 37510334Shelge register unit = io->i_unit; 37610334Shelge register struct mba_regs *mbp = mbamba(unit); 37710334Shelge register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit); 37810353Shelge register struct st *st = &hpst[hp_type[unit]]; 37910334Shelge int npf; 38010334Shelge int bn, cn, tn, sn; 38110626Shelge int bcr; 38210334Shelge 38310334Shelge if (bcr = MASKREG(mbp->mba_bcr>>16)) 38410334Shelge bcr |= 0xffff0000; /* sxt */ 38510334Shelge npf = (bcr + io->i_cc)/sectsiz; /* number of sectors read */ 38610647Shelge bn = io->i_bn + npf + ssect; /* bn is physical block number*/ 38710334Shelge switch (flag) { 38810334Shelge case ECC: 38910334Shelge { 39010334Shelge register int i; 39110334Shelge caddr_t addr; 39210334Shelge int bit, byte, mask, ecccnt = 0; 39310334Shelge 39410413Shelge printf("hp%d: soft ecc sn%d\n", unit, bn); 39510334Shelge mask = MASKREG(rp->hpec2); 39610334Shelge i = MASKREG(rp->hpec1) - 1; /* -1 makes 0 origin */ 39710334Shelge bit = i&07; 39810334Shelge i = (i&~07)>>3; 39910334Shelge byte = i; 40010334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 40110334Shelge while (i <sectsiz && npf*sectsiz + i < io->i_cc && bit > -11) { 40210334Shelge addr = io->i_ma + (npf*sectsiz) + byte; 40310334Shelge #ifdef HPECCDEBUG 40410334Shelge printf("addr %x old:%x ",addr, (*addr&0xff)); 40510334Shelge #endif 40610334Shelge if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) 40710334Shelge *addr ^= (mask << bit); /* don't 'correct' mem- 40810334Shelge * ory during Wcheck */ 40910334Shelge #ifdef HPECCDEBUG 41010334Shelge printf("new:%x\n",(*addr&0xff)); 41110334Shelge #endif 41210334Shelge byte++; 41310334Shelge i++; 41410334Shelge bit -= 8; 41510334Shelge if ((ecccnt++>=MAXECC) && ((io->i_flgs&F_ECCLM) != 0)) 41610334Shelge return(1); 41710334Shelge } 41810334Shelge return(0); 41910334Shelge } 42010334Shelge 42110413Shelge case SSE: /* skip sector error */ 42210413Shelge /* set skip-sector-inhibit and read next sector */ 42310334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 42410413Shelge while(rp->hpds & HPDS_DRY == 0) 42510413Shelge ; /* avoid RMR error */ 42610334Shelge rp->hpof |= HPOF_SSEI; 42710334Shelge return(0); 42810334Shelge 42910334Shelge #ifndef NOBADSECT 43010334Shelge case BSE: 43110626Shelge { 43210626Shelge int bbn; 43310626Shelge rp->hpcs1 = HP_DCLR | HP_GO; 43410334Shelge #ifdef HPDEBUG 43510334Shelge printf("hpecc: BSE @ bn %d\n", bn); 43610334Shelge #endif 43710334Shelge cn = bn/st->nspc; 43810334Shelge sn = bn%st->nspc; 43910334Shelge tn = sn/st->nsect; 44010626Shelge sn = sn%st->nsect; 44110626Shelge bcr += sectsiz; 44210626Shelge if ((bbn = isbad(&hpbad[unit], cn, tn, sn)) < 0) 44310626Shelge return(1); 44410626Shelge bbn = st->ncyl*st->nspc - st->nsect - 1 - bbn; 44510626Shelge cn = bbn/st->nspc; 44610626Shelge sn = bbn%st->nspc; 44710626Shelge tn = sn/st->nsect; 44810626Shelge sn = sn%st->nsect; 44910626Shelge io->i_cc = sectsiz; 45010626Shelge io->i_ma += npf*sectsiz; 45110626Shelge #ifdef HPDEBUG 45210626Shelge printf("revector to cn %d tn %d sn %d mem: 0x%x\n", 45310626Shelge cn, tn, sn, io->i_ma); 45410626Shelge #endif 45510647Shelge rp->hpof &= ~HPOF_SSEI; /* clear skip sector inhibit if set */ 45610626Shelge mbp->mba_sr = -1; 45710334Shelge rp->hpdc = cn; 45810334Shelge rp->hpda = (tn<<8) + sn; 45910334Shelge mbastart(io,io->i_flgs); 46010334Shelge io->i_errcnt = 0; /* error has been corrected */ 46110626Shelge while(rp->hpds & HPDS_DRY == 0) 46210626Shelge ; /* wait for the read to complete */ 46310334Shelge if (rp->hpds&HPDS_ERR) 46410334Shelge return(1); 46510334Shelge else 46610334Shelge return(0); 46710626Shelge } 46810334Shelge } 46910334Shelge } 47010334Shelge /*ARGSUSED*/ 47110334Shelge hpioctl(io, cmd, arg) 47210334Shelge struct iob *io; 47310334Shelge int cmd; 47410334Shelge caddr_t arg; 47510334Shelge { 47610334Shelge 47710647Shelge register unit = io->i_unit; 47810647Shelge struct st *st = &hpst[hp_type[unit]], *tmp; 47910647Shelge struct mba_drv *drv = mbadrv(unit); 48010334Shelge 48110334Shelge switch(cmd) { 48210334Shelge 48310334Shelge case SAIODEVDATA: 48410334Shelge if ((drv->mbd_dt&MBDT_TAP) == 0) { 48510353Shelge tmp = (struct st *)arg; 48610353Shelge *tmp = *st; 48710334Shelge return(0); 48810334Shelge } 48910334Shelge else 49010334Shelge return(ECMD); 49110334Shelge 49210626Shelge case SAIOSSI: /* set the skip-sector-inhibit flag */ 49310626Shelge if ((drv->mbd_dt&MBDT_TAP) == 0) { 49410626Shelge if ((io->i_flgs&F_SSI)==0) { /* make sure this is */ 49510626Shelge io->i_flgs |= F_SSI; /* done only once */ 49610626Shelge st->nsect++; 49710626Shelge st->nspc += st->ntrak; 49810626Shelge } 49910626Shelge return(0); 50010626Shelge } else 50110626Shelge return(ECMD); 50210626Shelge 50310626Shelge case SAIONOSSI: /* remove the skip-sector-inh. flag */ 50410626Shelge if (io->i_flgs & F_SSI) { 50510626Shelge io->i_flgs &= ~F_SSI; 50610626Shelge drv->mbd_of &= ~HPOF_SSEI; 50710626Shelge st->nsect--; 50810626Shelge st->nspc -= st->ntrak; 50910626Shelge } 51010626Shelge return(0); 51110626Shelge 51210647Shelge case SAIOSSDEV: /* return null if device has skip sector 51310647Shelge * handling, otherwise return ECMD 51410647Shelge */ 51510647Shelge if (RM80) 51610647Shelge return(0); 51710647Shelge else 51810647Shelge return(ECMD); 51910647Shelge 52010334Shelge default: 52110334Shelge return (ECMD); 52210334Shelge } 52310334Shelge } 52410334Shelge 525