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: }

Defined functions

rlioctl defined in line 215; used 4 times
rlopen defined in line 35; used 4 times
rlstrategy defined in line 83; used 4 times
rlwait defined in line 207; used 5 times

Defined variables

rl_off defined in line 25; used 2 times
rl_stat defined in line 33; used 2 times
rlstd defined in line 24; used 2 times

Defined struct's

rl_stat defined in line 28; used 4 times
  • in line 40(2), 88(2)
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1057
Valid CSS Valid XHTML 1.0 Strict