1*10334Shelge /* hp.c 4.1 83/01/16 */ 2*10334Shelge 3*10334Shelge /* 4*10334Shelge * RP??/RM?? disk driver 5*10334Shelge * with ECC handling and bad block forwarding. 6*10334Shelge * Also supports header io operations and 7*10334Shelge * commands to write check header and data. 8*10334Shelge */ 9*10334Shelge 10*10334Shelge #include "../h/param.h" 11*10334Shelge #include "../h/inode.h" 12*10334Shelge #include "../h/fs.h" 13*10334Shelge #include "../h/dkbad.h" 14*10334Shelge 15*10334Shelge #include "../vax/pte.h" 16*10334Shelge #include "../vaxmba/hpreg.h" 17*10334Shelge #include "../vaxmba/mbareg.h" 18*10334Shelge 19*10334Shelge #include "saio.h" 20*10334Shelge #include "savax.h" 21*10334Shelge 22*10334Shelge #define MASKREG(reg) ((reg)&0xffff) 23*10334Shelge 24*10334Shelge #define MAXBADDESC 126 25*10334Shelge #define SECTSIZ 512 /* sector size in bytes */ 26*10334Shelge #define HDRSIZ 4 /* number of bytes in sector header */ 27*10334Shelge #define MAXECC 5 /* the maximum number of bad bits accepted in 28*10334Shelge * an ecc error when F_ECCLM is set */ 29*10334Shelge 30*10334Shelge char hp_type[MAXNMBA*8] = { 0 }; 31*10334Shelge 32*10334Shelge /* THIS SHOULD BE READ IN OFF THE PACK, PER DRIVE */ 33*10334Shelge short hp6_off[8] = { 0, 38, 0, -1, -1, -1, 118, -1 }; 34*10334Shelge short rm3_off[8] = { 0, 100, 0, -1, -1, -1, 310, -1 }; 35*10334Shelge short rm5_off[8] = { 0, 27, 0, 562, 589, 681, 562, 82 }; 36*10334Shelge short rm80_off[8] = { 0, 37, 0, -1, -1, -1, 115, 305 }; 37*10334Shelge short hp7_off[8] = { 0, 10, 0, 330, 340, 500, 330, 50 }; 38*10334Shelge short ml_off[8] = { 0, -1, -1, -1, -1, -1, -1, -1 }; 39*10334Shelge short si9775_off[8] = { 0, 13, 0, -1, -1, -1, 40, 441 }; 40*10334Shelge short si9730_off[8] = { 0, 50, 0, -1, -1, -1, -1, 155 }; 41*10334Shelge short hpam_off[8] = { 0, 32, 0, 668, 723, 778, 668, 98 }; 42*10334Shelge /* END SHOULD BE READ IN */ 43*10334Shelge 44*10334Shelge short hptypes[] = 45*10334Shelge { MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, MBDT_RP05, MBDT_RP07, 46*10334Shelge MBDT_ML11A, MBDT_ML11B, -1/*9755*/, -1/*9730*/, -1/*Capr*/, MBDT_RM02, 0}; 47*10334Shelge 48*10334Shelge #define RP06 (hptypes[UNITTODRIVE(unit)] <= MBDT_RP06) 49*10334Shelge #define ML11 (hptypes[UNITTODRIVE(unit)] <= MBDT_ML11A) 50*10334Shelge #define RM80 (hptypes[UNITTODRIVE(unit)] <= MBDT_RM80) 51*10334Shelge 52*10334Shelge u_char hp_offset[16] = { 53*10334Shelge HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400, 54*10334Shelge HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800, 55*10334Shelge HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200, 56*10334Shelge 0, 0, 0, 0, 57*10334Shelge }; 58*10334Shelge 59*10334Shelge struct hpst { 60*10334Shelge short nsect; 61*10334Shelge short ntrak; 62*10334Shelge short nspc; 63*10334Shelge short ncyl; 64*10334Shelge short *off; 65*10334Shelge } hpst[] = { 66*10334Shelge 32, 5, 32*5, 823, rm3_off, /* RM03 */ 67*10334Shelge 32, 19, 32*19, 823, rm5_off, /* RM05 */ 68*10334Shelge 22, 19, 22*19, 815, hp6_off, /* RP06 */ 69*10334Shelge 31, 14, 31*14, 559, rm80_off, /* RM80 */ 70*10334Shelge 22, 19, 22*19, 411, hp6_off, /* RP06 */ 71*10334Shelge 50, 32, 50*32, 630, hp7_off, /* RP07 */ 72*10334Shelge 1, 1, 1, 1, ml_off, /* ML11A */ 73*10334Shelge 1, 1, 1, 1, ml_off, /* ML11B */ 74*10334Shelge 32, 40, 32*40, 843, si9775_off, /* 9775 */ 75*10334Shelge 32, 10, 32*10, 823, si9730_off, /* 9730 */ 76*10334Shelge 32, 16, 32*16, 1024, hpam_off, /* AMPEX capricorn */ 77*10334Shelge 1, 1, 1, 1, 0, /* rm02 - not used */ 78*10334Shelge }; 79*10334Shelge struct dkbad hpbad[MAXNMBA*8]; 80*10334Shelge int sectsiz; 81*10334Shelge 82*10334Shelge hpopen(io) 83*10334Shelge register struct iob *io; 84*10334Shelge { 85*10334Shelge register unit = io->i_unit; 86*10334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 87*10334Shelge register struct hpst *st; 88*10334Shelge 89*10334Shelge mbainit(UNITTOMBA(unit)); 90*10334Shelge if (hp_type[unit] == 0) { 91*10334Shelge register type = hpaddr->hpdt & MBDT_TYPE; 92*10334Shelge register int i; 93*10334Shelge struct iob tio; 94*10334Shelge 95*10334Shelge for (i = 0; hptypes[i]; i++) 96*10334Shelge if (hptypes[i] == type) 97*10334Shelge goto found; 98*10334Shelge _stop("unknown drive type"); 99*10334Shelge found: 100*10334Shelge switch (i) { 101*10334Shelge case 0: case 1: { /* rm03 or rm05 */ 102*10334Shelge register hpsn = hpaddr->hpsn; 103*10334Shelge 104*10334Shelge if ((hpsn & SIMB_LU) != unit) 105*10334Shelge break; 106*10334Shelge switch ((hpsn & SIMB_MB) &~ (SIMB_S6|SIRM03|SIRM05)) { 107*10334Shelge case SI9775D: 108*10334Shelge i = 8; /* si9775 */ 109*10334Shelge break; 110*10334Shelge case SI9730D: 111*10334Shelge i = 9; /* si9730 */ 112*10334Shelge break; 113*10334Shelge case SI9766: 114*10334Shelge i = 1; /* rm05 */ 115*10334Shelge hpaddr->hpcs1 = HP_RECAL|HP_GO; 116*10334Shelge DELAY(100000); 117*10334Shelge break; 118*10334Shelge case SI9762: 119*10334Shelge i = 0; /* rm03 */ 120*10334Shelge break; 121*10334Shelge } 122*10334Shelge break; 123*10334Shelge } 124*10334Shelge 125*10334Shelge case 11: /* rm02 */ 126*10334Shelge hpaddr->hpcs1 = HP_NOP; 127*10334Shelge hpaddr->hphr = HPHR_MAXTRAK; 128*10334Shelge if (MASKREG(hpaddr->hphr) == 15) 129*10334Shelge i = 10; /* ampex capricorn */ 130*10334Shelge else 131*10334Shelge i = 0; /* rm03 */ 132*10334Shelge break; 133*10334Shelge 134*10334Shelge case 6: case 7: /* ml11a ml11b */ 135*10334Shelge i = 6; /* ml11a */ 136*10334Shelge break; 137*10334Shelge } 138*10334Shelge hp_type[unit] = i; 139*10334Shelge /* 140*10334Shelge * Read in the bad sector table: 141*10334Shelge * copy the contents of the io structure 142*10334Shelge * to tio for use during the bb pointer 143*10334Shelge * read operation. 144*10334Shelge */ 145*10334Shelge st = &hpst[hp_type[unit]]; 146*10334Shelge tio = *io; 147*10334Shelge tio.i_bn = st->nspc * st->ncyl - st->nsect; 148*10334Shelge tio.i_ma = (char *)&hpbad[tio.i_unit]; 149*10334Shelge tio.i_cc = sizeof (hpbad); 150*10334Shelge tio.i_flgs |= F_RDDATA; 151*10334Shelge for (i = 0; i < 5; i++) { 152*10334Shelge if (hpstrategy(&tio, READ) == sizeof (hpbad)) 153*10334Shelge break; 154*10334Shelge tio.i_bn += 2; 155*10334Shelge } 156*10334Shelge if (i == 5) { 157*10334Shelge printf("Unable to read bad sector table\n"); 158*10334Shelge for (i = 0; i < MAXBADDESC; i++) { 159*10334Shelge hpbad[unit].bt_bad[i].bt_cyl = -1; 160*10334Shelge hpbad[unit].bt_bad[i].bt_trksec = -1; 161*10334Shelge } 162*10334Shelge } 163*10334Shelge } 164*10334Shelge if (io->i_boff < 0 || io->i_boff > 7 || 165*10334Shelge st->off[io->i_boff]== -1) 166*10334Shelge _stop("hp bad minor"); 167*10334Shelge io->i_boff = st->off[io->i_boff] * st->nspc; 168*10334Shelge } 169*10334Shelge 170*10334Shelge hpstrategy(io, func) 171*10334Shelge register struct iob *io; 172*10334Shelge { 173*10334Shelge register unit = io->i_unit; 174*10334Shelge struct mba_regs *mba = mbamba(unit); 175*10334Shelge daddr_t bn; 176*10334Shelge struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit); 177*10334Shelge struct hpst *st = &hpst[hp_type[unit]]; 178*10334Shelge int cn, tn, sn, bytecnt, bytesleft; 179*10334Shelge daddr_t startblock; 180*10334Shelge char *membase; 181*10334Shelge int er1, er2, hprecal; 182*10334Shelge 183*10334Shelge sectsiz = SECTSIZ; 184*10334Shelge if ((io->i_flgs & (F_HDR|F_HCHECK)) != 0) 185*10334Shelge sectsiz += HDRSIZ; 186*10334Shelge if ((hpaddr->hpds & HPDS_VV) == 0) { 187*10334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 188*10334Shelge hpaddr->hpcs1 = HP_PRESET|HP_GO; 189*10334Shelge if (hp_type[unit] != 6) /* any but ml11 */ 190*10334Shelge hpaddr->hpof = HPOF_FMT22; 191*10334Shelge } 192*10334Shelge io->i_errcnt = 0; 193*10334Shelge bytecnt = io->i_cc; 194*10334Shelge membase = io->i_ma; 195*10334Shelge startblock = io->i_bn; 196*10334Shelge hprecal = 1; 197*10334Shelge readmore: 198*10334Shelge bn = io->i_bn; 199*10334Shelge cn = bn/st->nspc; 200*10334Shelge sn = bn%st->nspc; 201*10334Shelge tn = sn/st->nsect; 202*10334Shelge sn = sn%st->nsect; 203*10334Shelge 204*10334Shelge while ((hpaddr->hpds & HPDS_DRY) == 0) 205*10334Shelge ; 206*10334Shelge if (hp_type[unit] == 6) /* ml11 */ 207*10334Shelge hpaddr->hpda = bn; 208*10334Shelge else { 209*10334Shelge hpaddr->hpdc = cn; 210*10334Shelge hpaddr->hpda = (tn << 8) + sn; 211*10334Shelge } 212*10334Shelge if (mbastart(io, func) != 0) /* start transfer */ 213*10334Shelge return (-1); 214*10334Shelge 215*10334Shelge while ((hpaddr->hpds & HPDS_DRY) == 0) 216*10334Shelge ; 217*10334Shelge if (((hpaddr->hpds&HPDS_ERR) | (mba->mba_sr&MBSR_EBITS)) == 0 ) 218*10334Shelge return(bytecnt); 219*10334Shelge 220*10334Shelge /* ------- error handling ------- */ 221*10334Shelge 222*10334Shelge if (bytesleft = MASKREG(mba->mba_bcr>>16)) 223*10334Shelge bytesleft |= 0xffff0000; /* sign ext */ 224*10334Shelge bn = io->i_bn + (io->i_cc + bytesleft)/sectsiz; 225*10334Shelge cn = bn/st->nspc; 226*10334Shelge sn = bn%st->nspc; 227*10334Shelge tn = sn/st->nsect; 228*10334Shelge sn = sn%st->nsect; 229*10334Shelge er1 = MASKREG(hpaddr->hper1); 230*10334Shelge er2 = MASKREG(hpaddr->hper2); 231*10334Shelge #ifdef HPDEBUG 232*10334Shelge printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n", 233*10334Shelge cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 234*10334Shelge printf("er1=%b er2=%b", 235*10334Shelge er1, HPER1_BITS, 236*10334Shelge er2, HPER2_BITS); 237*10334Shelge printf("\n"); 238*10334Shelge #endif 239*10334Shelge if (er1 & HPER1_HCRC) { 240*10334Shelge er1 &= ~(HPER1_HCE|HPER1_FER); 241*10334Shelge er2 &= ~HPER2_BSE; 242*10334Shelge } 243*10334Shelge if (er1&HPER1_WLE) { 244*10334Shelge printf("hp%d: write locked\n", unit); 245*10334Shelge return(-1); 246*10334Shelge } else if ((er1&0xffff) == HPER1_FER && RP06) { 247*10334Shelge goto badsect; 248*10334Shelge 249*10334Shelge } else if (++io->i_errcnt > 27 || 250*10334Shelge er1 & HPER1_HARD || 251*10334Shelge (!ML11 && (er2 & HPER2_HARD))) { 252*10334Shelge io->i_error = EHER; 253*10334Shelge if ((mba->mba_sr & (MBSR_WCKUP | MBSR_WCKLWR)) != 0) 254*10334Shelge io->i_error = EWCK; 255*10334Shelge hard: 256*10334Shelge io->i_errblk = bn; 257*10334Shelge printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n", 258*10334Shelge cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); 259*10334Shelge printf("er1=%b er2=%b", 260*10334Shelge er1, HPER1_BITS, 261*10334Shelge er2, HPER2_BITS); 262*10334Shelge if (hpaddr->hpmr) 263*10334Shelge printf(" mr=%o", hpaddr->hpmr&0xffff); 264*10334Shelge if (hpaddr->hpmr2) 265*10334Shelge printf(" mr2=%o", hpaddr->hpmr2&0xffff); 266*10334Shelge printf("\n"); 267*10334Shelge return(-1); 268*10334Shelge 269*10334Shelge } else if ((er2 & HPER2_BSE) && !ML11) { 270*10334Shelge badsect: 271*10334Shelge if ((io->i_flgs & F_NBSF) != 0) { 272*10334Shelge io->i_error = EBSE; 273*10334Shelge goto hard; 274*10334Shelge } 275*10334Shelge if (hpecc(io, BSE) == 0) 276*10334Shelge goto success; 277*10334Shelge else { 278*10334Shelge io->i_error = EBSE; 279*10334Shelge goto hard; 280*10334Shelge } 281*10334Shelge } else if (RM80 && er2&HPER2_SSE) { 282*10334Shelge /* skip sector error */ 283*10334Shelge (void) hpecc(io, SSE); 284*10334Shelge goto success; 285*10334Shelge } else if ((er1&(HPER1_DCK|HPER1_ECH))==HPER1_DCK) { 286*10334Shelge if ( hpecc(io, ECC) == 0) 287*10334Shelge goto success; 288*10334Shelge else { 289*10334Shelge io->i_error = EECC; 290*10334Shelge return(1); 291*10334Shelge } 292*10334Shelge } else 293*10334Shelge io->i_active = 0; /* force retry */ 294*10334Shelge 295*10334Shelge hpaddr->hpcs1 = HP_DCLR|HP_GO; 296*10334Shelge while ((hpaddr->hpds & HPDS_DRY) == 0) 297*10334Shelge ; 298*10334Shelge if (ML11) { 299*10334Shelge if (io->i_errcnt >= 16) 300*10334Shelge goto hard; 301*10334Shelge } else if (((io->i_errcnt&07) == 4) && (io->i_active == 0)) { 302*10334Shelge hpaddr->hpcs1 = HP_RECAL|HP_GO; 303*10334Shelge hprecal = 0; 304*10334Shelge goto nextrecal; 305*10334Shelge } 306*10334Shelge switch (hprecal) { 307*10334Shelge 308*10334Shelge case 1: 309*10334Shelge hpaddr->hpdc = cn; 310*10334Shelge hpaddr->hpcs1 = HP_SEEK|HP_GO; 311*10334Shelge goto nextrecal; 312*10334Shelge case 2: 313*10334Shelge if (io->i_errcnt < 16 || (func & READ) == 0) 314*10334Shelge goto donerecal; 315*10334Shelge hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22; 316*10334Shelge hpaddr->hpcs1 = HP_OFFSET|HP_GO; 317*10334Shelge nextrecal: 318*10334Shelge hprecal++; 319*10334Shelge io->i_active = 1; 320*10334Shelge goto try_again; 321*10334Shelge donerecal: 322*10334Shelge case 3: 323*10334Shelge hprecal = 0; 324*10334Shelge io->i_active = 0; 325*10334Shelge goto try_again; 326*10334Shelge } 327*10334Shelge if (io->i_active) { 328*10334Shelge if (io->i_errcnt >= 16) { 329*10334Shelge hpaddr->hpcs1 = HP_RTC|HP_GO; 330*10334Shelge while (hpaddr->hpds & HPDS_PIP) 331*10334Shelge ; 332*10334Shelge } 333*10334Shelge } 334*10334Shelge success: /* continue with the next block */ 335*10334Shelge bn++; 336*10334Shelge if ((bn-startblock) * sectsiz < bytecnt) { 337*10334Shelge 338*10334Shelge try_again: /* re-read same block */ 339*10334Shelge io->i_bn = bn; 340*10334Shelge mba->mba_sr = -1; 341*10334Shelge io->i_ma = membase + (io->i_bn - startblock)*sectsiz; 342*10334Shelge io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz; 343*10334Shelge #ifdef HPDEBUG 344*10334Shelge printf("restart: bl %d, byte %d, mem 0x%x %d\n", 345*10334Shelge io->i_bn, io->i_cc, io->i_ma, io->i_ma); 346*10334Shelge #endif 347*10334Shelge goto readmore; 348*10334Shelge } 349*10334Shelge return (bytecnt); 350*10334Shelge } 351*10334Shelge hpecc(io, flag) 352*10334Shelge register struct iob *io; 353*10334Shelge int flag; 354*10334Shelge { 355*10334Shelge register unit = io->i_unit; 356*10334Shelge register struct mba_regs *mbp = mbamba(unit); 357*10334Shelge register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit); 358*10334Shelge register struct hpst *st = &hpst[hp_type[unit]]; 359*10334Shelge int npf; 360*10334Shelge int bn, cn, tn, sn; 361*10334Shelge int bcr, tad; 362*10334Shelge 363*10334Shelge if (bcr = MASKREG(mbp->mba_bcr>>16)) 364*10334Shelge bcr |= 0xffff0000; /* sxt */ 365*10334Shelge npf = (bcr + io->i_cc)/sectsiz; /* number of sectors read */ 366*10334Shelge switch (flag) { 367*10334Shelge case ECC: 368*10334Shelge { 369*10334Shelge register int i; 370*10334Shelge caddr_t addr; 371*10334Shelge int bit, byte, mask, ecccnt = 0; 372*10334Shelge 373*10334Shelge printf("hp%d: soft ecc sn%d\n", unit, io->i_bn + npf); 374*10334Shelge mask = MASKREG(rp->hpec2); 375*10334Shelge i = MASKREG(rp->hpec1) - 1; /* -1 makes 0 origin */ 376*10334Shelge bit = i&07; 377*10334Shelge i = (i&~07)>>3; 378*10334Shelge byte = i; 379*10334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 380*10334Shelge while (i <sectsiz && npf*sectsiz + i < io->i_cc && bit > -11) { 381*10334Shelge addr = io->i_ma + (npf*sectsiz) + byte; 382*10334Shelge #ifdef HPECCDEBUG 383*10334Shelge printf("addr %x old:%x ",addr, (*addr&0xff)); 384*10334Shelge #endif 385*10334Shelge if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) 386*10334Shelge *addr ^= (mask << bit); /* don't 'correct' mem- 387*10334Shelge * ory during Wcheck */ 388*10334Shelge #ifdef HPECCDEBUG 389*10334Shelge printf("new:%x\n",(*addr&0xff)); 390*10334Shelge #endif 391*10334Shelge byte++; 392*10334Shelge i++; 393*10334Shelge bit -= 8; 394*10334Shelge if ((ecccnt++>=MAXECC) && ((io->i_flgs&F_ECCLM) != 0)) 395*10334Shelge return(1); 396*10334Shelge } 397*10334Shelge return(0); 398*10334Shelge } 399*10334Shelge 400*10334Shelge case SSE: /* skip sector error */ 401*10334Shelge /* -----this section must be fixed------*/ 402*10334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 403*10334Shelge rp->hpof |= HPOF_SSEI; 404*10334Shelge mbp->mba_bcr = -(io->i_cc - npf*sectsiz); 405*10334Shelge /* presumably the disk address has already 406*10334Shelge * been incremented to point to the next sector */ 407*10334Shelge return(0); 408*10334Shelge 409*10334Shelge #ifndef NOBADSECT 410*10334Shelge case BSE: 411*10334Shelge #ifdef HPDEBUG 412*10334Shelge printf("hpecc: BSE @ bn %d\n", bn); 413*10334Shelge #endif 414*10334Shelge rp->hpcs1 = HP_DCLR | HP_GO; 415*10334Shelge bcr += SECTSIZ; 416*10334Shelge tad = rp->hpda; 417*10334Shelge if ((bn = isbad(&hpbad[unit], bcr, tad>>8, tad&0x7f)) < 0) 418*10334Shelge return(1); 419*10334Shelge bn = st->ncyl*st->nspc - st->nsect - 1 - bn; 420*10334Shelge cn = bn/st->nspc; 421*10334Shelge sn = bn%st->nspc; 422*10334Shelge tn = sn/st->nsect; 423*10334Shelge sn %= st->nsect; 424*10334Shelge io->i_cc = -SECTSIZ; 425*10334Shelge io->i_ma = (char *)((io->i_bn + npf -1)*SECTSIZ); 426*10334Shelge #ifdef HPDEBUG 427*10334Shelge printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 428*10334Shelge #endif 429*10334Shelge rp->hpdc = cn; 430*10334Shelge rp->hpda = (tn<<8) + sn; 431*10334Shelge mbp->mba_sr = -1; 432*10334Shelge mbastart(io,io->i_flgs); 433*10334Shelge io->i_errcnt = 0; /* error has been corrected */ 434*10334Shelge while(rp->hpds & HPDS_DRY == 0) 435*10334Shelge ; 436*10334Shelge if (rp->hpds&HPDS_ERR) 437*10334Shelge return(1); 438*10334Shelge else 439*10334Shelge return(0); 440*10334Shelge } 441*10334Shelge } 442*10334Shelge /*ARGSUSED*/ 443*10334Shelge hpioctl(io, cmd, arg) 444*10334Shelge struct iob *io; 445*10334Shelge int cmd; 446*10334Shelge caddr_t arg; 447*10334Shelge { 448*10334Shelge 449*10334Shelge struct hpst *st = &hpst[hp_type[io->i_unit]]; 450*10334Shelge struct mba_drv *drv = mbadrv(io->i_unit); 451*10334Shelge struct devdata *devd; 452*10334Shelge 453*10334Shelge switch(cmd) { 454*10334Shelge 455*10334Shelge case SAIODEVDATA: 456*10334Shelge if ((drv->mbd_dt&MBDT_TAP) == 0) { 457*10334Shelge devd = (struct devdata *)arg; 458*10334Shelge devd->ncyl = st->ncyl; 459*10334Shelge devd->ntrak = st->ntrak; 460*10334Shelge devd->nspc = st->nspc; 461*10334Shelge devd->nsect = st->nsect; 462*10334Shelge return(0); 463*10334Shelge } 464*10334Shelge else 465*10334Shelge return(ECMD); 466*10334Shelge 467*10334Shelge default: 468*10334Shelge return (ECMD); 469*10334Shelge } 470*10334Shelge } 471*10334Shelge 472*10334Shelge /* this routine is common to up & hp, move to a separate file */ 473*10334Shelge 474*10334Shelge /* 475*10334Shelge * Search the bad sector table looking for 476*10334Shelge * the specified sector. Return index if found. 477*10334Shelge * Return -1 if not found. 478*10334Shelge */ 479*10334Shelge 480*10334Shelge isbad(bt, st, blno) 481*10334Shelge register struct dkbad *bt; 482*10334Shelge register struct devdata *st; /* dirty, must be fixed */ 483*10334Shelge { 484*10334Shelge register int i; 485*10334Shelge register long blk, bblk; 486*10334Shelge int trk, sec; 487*10334Shelge 488*10334Shelge sec = blno % st->nspc; 489*10334Shelge trk = sec / st->nsect; 490*10334Shelge sec %= st->nsect; 491*10334Shelge blk = ((long)(blno/st->nspc) << 16) + (trk << 8) + sec; 492*10334Shelge for (i = 0; i < MAXBADDESC; i++) { 493*10334Shelge bblk = ((long)bt->bt_bad[i].bt_cyl << 16) + 494*10334Shelge bt->bt_bad[i].bt_trksec; 495*10334Shelge if (blk == bblk) 496*10334Shelge return (i); 497*10334Shelge if (blk < bblk || bblk < 0) 498*10334Shelge break; 499*10334Shelge } 500*10334Shelge return (-1); 501*10334Shelge } 502