|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)rl.c 7.1 (Berkeley) 6/5/86 ! 7: */ ! 8: ! 9: /* ! 10: * Standalone RL02 disk driver ! 11: */ ! 12: #include "../machine/pte.h" ! 13: ! 14: #include "../h/param.h" ! 15: #include "../h/inode.h" ! 16: #include "../h/fs.h" ! 17: ! 18: #include "../vaxuba/rlreg.h" ! 19: #include "../vaxuba/ubareg.h" ! 20: ! 21: #include "saio.h" ! 22: #include "savax.h" ! 23: ! 24: u_short rlstd[] = { 0774400 }; ! 25: short rl_off[] = { 0, 361, 0, -1, -1, -1, -1, -1 }; ! 26: ! 27: /* struct to keep state info about the controller */ ! 28: struct rl_stat { ! 29: short rl_dn; /* drive number */ ! 30: short rl_cylnhd; /* cylinder and head */ ! 31: u_short rl_bleft; /* bytes left to transfer */ ! 32: u_short rl_bpart; /* bytes transferred */ ! 33: } rl_stat[] = { -1, 0, 0, 0}; ! 34: ! 35: rlopen(io) ! 36: register struct iob *io; ! 37: { ! 38: register struct rldevice *rladdr = ! 39: (struct rldevice *)ubamem(io->i_unit, rlstd[0]); ! 40: register struct rl_stat *st = &rl_stat[0]; ! 41: register int ctr = 0; ! 42: ! 43: if (rl_off[io->i_boff] == -1 || ! 44: io->i_boff < 0 || io->i_boff > 7) ! 45: _stop("rl bad unit"); ! 46: ! 47: /* ! 48: * DEC reports that: ! 49: * For some unknown reason the RL02 (seems to be only drive 1) ! 50: * does not return a valid drive status the first time that a ! 51: * GET STATUS request is issued for the drive, in fact it can ! 52: * take up to three or more GET STATUS requests to obtain the ! 53: * correct status. ! 54: * In order to overcome this, the driver has been modified to ! 55: * issue a GET STATUS request and validate the drive status ! 56: * returned. If a valid status is not returned after eight ! 57: * attempts, then an error message is printed. ! 58: */ ! 59: do { ! 60: rladdr->rlda.getstat = RL_RESET; ! 61: rladdr->rlcs = (io->i_unit <<8) | RL_GETSTAT; /* Get status*/ ! 62: rlwait(rladdr); ! 63: } while( (rladdr->rlmp.getstat&RLMP_STATUS) != RLMP_STATOK && ++ctr<8 ); ! 64: ! 65: if ((rladdr->rlcs & RL_DE) || (ctr >= 8)) ! 66: _stop("rl unit does not respond"); ! 67: ! 68: if ((rladdr->rlmp.getstat & RLMP_DT) == 0 ) /* NO RL01'S */ ! 69: _stop("rl01 unit not supported"); ! 70: ! 71: /* Determine disk posistion */ ! 72: rladdr->rlcs = (io->i_unit << 8) | RL_RHDR; ! 73: rlwait(rladdr); ! 74: ! 75: /* save disk drive posistion */ ! 76: st->rl_cylnhd = (rladdr->rlmp.readhdr & 0177700) >> 6; ! 77: st->rl_dn = io->i_unit; ! 78: ! 79: /* byte offset for cylinder desired */ ! 80: io->i_boff = rl_off[io->i_boff] * NRLBPSC * NRLTRKS * NRLSECT; ! 81: } ! 82: ! 83: rlstrategy(io, func) ! 84: register struct iob *io; ! 85: { ! 86: register struct rldevice *rladdr = ! 87: (struct rldevice *)ubamem(io->i_unit, rlstd[0]); ! 88: register struct rl_stat *st = &rl_stat[0]; ! 89: int com; ! 90: daddr_t bn; ! 91: short cn, sn, head; ! 92: int diff, ubinfo, ubaddr, errcnt = 0; ! 93: ! 94: retry: ! 95: ubinfo = ubasetup(io, 1); ! 96: bn = io->i_bn; /* block number */ ! 97: cn = bn / 40; /* 40 512 byte blocks per cylinder */ ! 98: sn = (bn % 20) << 1; ! 99: head = (bn / 20) & 1; ! 100: st->rl_bleft = io->i_cc; /* total number of bytes to trans */ ! 101: ubaddr = ubinfo; ! 102: ! 103: stupid_rl: ! 104: /* find out how many cylinders to seek */ ! 105: diff = (st->rl_cylnhd >> 1) - cn; ! 106: if ( diff == 0 && (st->rl_cylnhd & 1) == head ) ! 107: goto noseek; ! 108: ! 109: /* first time or we switched drives */ ! 110: st->rl_dn = io->i_unit; /* drive number */ ! 111: ! 112: if ( diff < 0 ) ! 113: rladdr->rlda.seek = -diff<<7 | RLDA_HGH | head << 4; ! 114: else ! 115: rladdr->rlda.seek = diff<<7 | RLDA_LOW | head << 4; ! 116: rladdr->rlcs = (st->rl_dn << 8) | RL_SEEK; ! 117: ! 118: /* reset position of drive */ ! 119: st->rl_cylnhd = (cn << 1) | head; ! 120: ! 121: noseek: ! 122: /* wait for controller and drive */ ! 123: while( (rladdr->rlcs & RL_DCRDY) != RL_DCRDY) ! 124: continue; ! 125: ! 126: /* calculate the max number of bytes we can trans */ ! 127: st->rl_bpart = NRLSECT * NRLBPSC - (sn * NRLBPSC); ! 128: if ( st->rl_bleft < st->rl_bpart ) ! 129: st->rl_bpart = st->rl_bleft; ! 130: ! 131: rladdr->rlda.rw = (st->rl_cylnhd << 6) | sn; ! 132: rladdr->rlmp.rw = -(st->rl_bpart >> 1); ! 133: rladdr->rlba = ubaddr; ! 134: ! 135: com = (st->rl_dn << 8) | ((ubaddr>>12)&RL_BAE); ! 136: ! 137: if (func == READ) ! 138: com |= RL_READ; ! 139: else ! 140: com |= RL_WRITE; ! 141: rladdr->rlcs = com; ! 142: ! 143: /* wait for controller and drive */ ! 144: while( (rladdr->rlcs & RL_DCRDY) != RL_DCRDY) ! 145: continue; ! 146: ! 147: if (rladdr->rlcs & RL_ERR) { ! 148: int status; ! 149: ! 150: if ( rladdr->rlcs & RL_DE ) { ! 151: rladdr->rlda.getstat = RL_GSTAT; ! 152: rladdr->rlcs = (st->rl_dn << 8) | RL_GETSTAT; ! 153: rlwait(rladdr); ! 154: status = rladdr->rlmp.getstat; ! 155: rladdr->rlda.getstat = RL_RESET; ! 156: rladdr->rlcs = (st->rl_dn <<8) | RL_GETSTAT; ! 157: rlwait(rladdr); ! 158: } ! 159: printf("rl error: (cyl,head,sec)=(%d,%d,%d) cs=%b mp=%b\n", ! 160: cn, head, sn, rladdr->rlcs & 0xffff, RLCS_BITS, ! 161: status, RLER_BITS); ! 162: ! 163: /* Determine disk posistion */ ! 164: rladdr->rlcs = (st->rl_dn << 8) | RL_RHDR; ! 165: rlwait(rladdr); ! 166: ! 167: /* save disk drive posistion */ ! 168: st->rl_cylnhd = (rladdr->rlmp.readhdr & 0177700) >> 6; ! 169: ! 170: if (errcnt == 10) { ! 171: printf("rl: unrecovered error\n"); ! 172: return (-1); ! 173: } ! 174: errcnt++; ! 175: goto retry; ! 176: } ! 177: ! 178: /* do we have to finish off the rest of the transfer? */ ! 179: if ( (st->rl_bleft -= st->rl_bpart) > 0 ) { ! 180: /* increment head and/or cylinder */ ! 181: if ( ++head > 1 ) { ! 182: cn++; /* want next cyl, head 0 sector 0 */ ! 183: head = 0; ! 184: } ! 185: ! 186: /* we always want sector to be zero */ ! 187: sn = 0; ! 188: ! 189: /* ! 190: * standalone code for ubafree does what regular ! 191: * ubapurge does and we want to purge last transfer ! 192: */ ! 193: ubafree(io, ubinfo); ! 194: ! 195: ubaddr = ubinfo + io->i_cc - st->rl_bleft; ! 196: ! 197: goto stupid_rl; ! 198: } ! 199: ! 200: ubafree(io, ubinfo); ! 201: ! 202: if (errcnt) ! 203: printf("rl: recovered by retry\n"); ! 204: return (io->i_cc); ! 205: } ! 206: ! 207: rlwait(rladdr) ! 208: register struct rldevice *rladdr; ! 209: { ! 210: ! 211: while ((rladdr->rlcs & RL_CRDY) == 0) ! 212: continue; ! 213: } ! 214: ! 215: rlioctl(io, cmd, arg) ! 216: struct iob *io; ! 217: int cmd; ! 218: caddr_t arg; ! 219: { ! 220: ! 221: return (ECMD); ! 222: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.