1: /*
   2:  *  RL disk driver
   3:  *
   4:  *	RL driver modified for the standalone shell.
   5:  *	Armando P. Stettner  Digital Equipment Corp.  July, 1980
   6:  */
   7: 
   8: #include    <sys/param.h>
   9: #include    <sys/inode.h>
  10: #include    "../saio.h"
  11: 
  12: #define BLKRL1  10240       /* Number of UNIX blocks for an RL01 drive */
  13: #define BLKRL2  20480       /* Number of UNIX blocks for an RL02 drive */
  14: #define RLCYLSZ 10240       /* bytes per cylinder */
  15: #define RLSECSZ 256     /* bytes per sector */
  16: 
  17: #define RESET 013
  18: #define RL02TYP 0200    /* drive type bit */
  19: #define STAT 03
  20: #define GETSTAT 04
  21: #define WCOM 012
  22: #define RCOM 014
  23: #define SEEK 06
  24: #define SEEKHI 5
  25: #define SEEKLO 1
  26: #define RDHDR 010
  27: #define IENABLE 0100
  28: #define CRDY 0200
  29: #define OPI 02000
  30: #define CRCERR 04000
  31: #define TIMOUT 010000
  32: #define NXM 020000
  33: #define DE  040000
  34: 
  35: struct device
  36: {
  37:     int rlcs ,
  38:     rlba ,
  39:     rlda ,
  40:     rlmp ;
  41: } ;
  42: 
  43: #define RLADDR  ((struct device *)0174400)
  44: #define RL_CNT 1
  45: 
  46: struct
  47: {
  48:     int cn[4] ;     /* location of heads for each drive */
  49:     int type[4] ;   /* parameter dependent upon drive type  (RL01/02) */
  50:     int com ;       /* read or write command word */
  51:     int chn ;       /* cylinder and head number */
  52:     unsigned int    bleft ; /* bytes left to be transferred */
  53:     unsigned int    bpart ; /* number of bytes transferred */
  54:     int sn ;        /* sector number */
  55:     union {
  56:         int w[2] ;
  57:         long    l ;
  58:     } addr ;            /* address of memory for transfer */
  59: 
  60: }   rl = {-1,-1,-1,-1, -1,-1,-1,-1} ;   /* initialize cn[] and type[] */
  61: 
  62: rlstrategy(io, func)
  63: register struct iob *io ;
  64: int func ;
  65: {
  66:     int nblocks ;   /* number of UNIX blocks for the drive in question */
  67:     int drive ;
  68:     int dif ;
  69:     int head ;
  70:     int ctr ;
  71: 
  72: 
  73:     /*
  74: 	 * We must determine what type of drive we are talking to in order
  75: 	 * to determine how many blocks are on the device.  The rl.type[]
  76: 	 * array has been initialized with -1's so that we may test first
  77: 	 * contact with a particular drive and do this determination only once.
  78: 	 * Sorry tjk for this hack.
  79: 	 *
  80: 	 * RL02 GET STATUS BAND-AID - Fred Canter 10/14/80
  81: 	 *
  82: 	 * For some unknown reason the RL02 (seems to be
  83: 	 * only drive 1) does not return a valid drive status
  84: 	 * the first time that a GET STATUS request is issued
  85: 	 * for the drive, in fact it can take up to three or more
  86: 	 * GET STATUS requests to obtain the correct status.
  87: 	 * In order to overcome this "HACK" the driver has been
  88: 	 * modified to issue a GET STATUS request, validate the
  89: 	 * drive status returned, and then use it to determine the
  90: 	 * drive type. If a valid status is not returned after eight
  91: 	 * attempts, then an error message is printed.
  92: 	 */
  93:     drive = io->i_unit ;
  94:     if (rl.type[drive] < 0)
  95:         {
  96:         ctr = 0;
  97:         do {
  98:         RLADDR->rlda = RESET ;  /* load this register; what a dumb controller */
  99:         RLADDR->rlcs = (drive << 8) | GETSTAT ; /* set up csr */
 100:         while ((RLADDR->rlcs & CRDY) == 0)  /* wait for it */
 101:             ;
 102:         } while (((RLADDR->rlmp & 0177477) != 035) && (++ctr < 8)) ;
 103:         if (ctr >= 8)
 104:             printf("\nCan't get status of RL unit %d\n",drive) ;
 105:         if (RLADDR->rlmp & RL02TYP)
 106:             rl.type[drive] = BLKRL2 ;   /* drive is RL02 */
 107:         else
 108:             rl.type[drive] = BLKRL1 ;   /* drive RL01 */
 109:         /*
 110: 		 * When the device is first touched, find out where the heads are.
 111: 		 */
 112:         /* find where the heads are */
 113:         RLADDR->rlcs = (drive << 8) | RDHDR;
 114:         while ((RLADDR->rlcs&CRDY) == 0)
 115:             ;
 116:         /*rl.cn[drive] = (RLADDR->rlmp&0177700) >> 6;*/
 117:         rl.cn[drive] = ((RLADDR->rlmp) >> 6) & 01777; /* fix sign bug */
 118:         }
 119:     nblocks = rl.type[drive] ;  /* how many blocks on this drive */
 120:     if(io->i_bn >= nblocks)
 121:         return -1 ;
 122:     rl.chn = io->i_bn/20;
 123:     rl.sn = (io->i_bn%20) << 1;
 124:     rl.bleft = io->i_cc;
 125:     rl.addr.w[0] = segflag & 3;
 126:     rl.addr.w[1] = (int)io->i_ma ;
 127:     rl.com = (drive << 8) ;
 128:     if (func == READ)
 129:         rl.com |= RCOM;
 130:     else
 131:         rl.com |= WCOM;
 132: reading:
 133:     /*
 134: 	 * One has to seek an RL head, relativily.
 135: 	 */
 136:     dif =(rl.cn[drive] >> 1) - (rl.chn >>1);
 137:     head = (rl.chn & 1) << 4;
 138:     if (dif < 0)
 139:         RLADDR->rlda = (-dif <<7) | SEEKHI | head;
 140:     else
 141:         RLADDR->rlda = (dif << 7) | SEEKLO | head;
 142:     RLADDR->rlcs = (drive << 8) | SEEK;
 143:     rl.cn[drive] = rl.chn;  /* keep current, our notion of where the heads are */
 144:     if (rl.bleft < (rl.bpart = RLCYLSZ - (rl.sn * RLSECSZ)))
 145:         rl.bpart = rl.bleft;
 146:     while ((RLADDR->rlcs&CRDY) == 0) ;
 147:     RLADDR->rlda = (rl.chn << 6) | rl.sn;
 148:     RLADDR->rlba = rl.addr.w[1];
 149:     RLADDR->rlmp = -(rl.bpart >> 1);
 150:     RLADDR->rlcs = rl.com | rl.addr.w[0] << 4;
 151:     while ((RLADDR->rlcs & CRDY) == 0)  /* wait for completion */
 152:         ;
 153:     if (RLADDR->rlcs < 0)   /* check error bit */
 154:         {
 155:         if (RLADDR->rlcs & 040000)  /* Drive error */
 156:             {
 157:             /*
 158: 			 * get status from drive
 159: 			 */
 160:             RLADDR->rlda = STAT;
 161:             RLADDR->rlcs = (drive << 8) | GETSTAT;
 162:             while ((RLADDR->rlcs & CRDY) == 0)  /* wait for controller */
 163:                 ;
 164:             }
 165:         printf("Rl disk error: cyl=%d, head=%d, sector=%d, rlcs=%o, rlmp=%o\n",
 166:             rl.chn>>01, rl.chn&01, rl.sn, RLADDR->rlcs, RLADDR->rlmp) ;
 167:         return -1 ;
 168:         }
 169:     /*
 170: 	 * Determine if there is more to read to satisfy this request.
 171: 	 * This is to compensate for the lacl of spiraling reads.
 172: 	 */
 173:     if ((rl.bleft -= rl.bpart) > 0)
 174:         {
 175:         rl.addr.l += rl.bpart ;
 176:         rl.sn = 0 ;
 177:         rl.chn++ ;
 178:         goto reading ;  /* read some more */
 179:         }
 180:     return io->i_cc ;
 181: }

Defined functions

rlstrategy defined in line 62; used 2 times

Defined struct's

device defined in line 35; never used

Defined macros

BLKRL1 defined in line 12; used 1 times
BLKRL2 defined in line 13; used 1 times
CRCERR defined in line 30; never used
CRDY defined in line 28; used 5 times
DE defined in line 33; never used
GETSTAT defined in line 20; used 2 times
IENABLE defined in line 27; never used
NXM defined in line 32; never used
OPI defined in line 29; never used
RCOM defined in line 22; used 1 times
RDHDR defined in line 26; used 1 times
RESET defined in line 17; used 1 times
  • in line 98
RL02TYP defined in line 18; used 1 times
RLADDR defined in line 43; used 24 times
RLCYLSZ defined in line 14; used 1 times
RLSECSZ defined in line 15; used 1 times
RL_CNT defined in line 44; never used
SEEK defined in line 23; used 1 times
SEEKHI defined in line 24; used 1 times
SEEKLO defined in line 25; used 1 times
STAT defined in line 19; used 1 times
TIMOUT defined in line 31; never used
WCOM defined in line 21; used 1 times
Last modified: 1983-07-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1031
Valid CSS Valid XHTML 1.0 Strict