1: /*
   2:  * Copyright (c) 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	2.6 (2.11BSD) 1997/11/7
   7:  */
   8: 
   9: /*
  10:  *  RL disk driver
  11:  *
  12:  *	Modified to handle disklabels - 1995/06/15
  13:  *	RL driver modified for the standalone shell.
  14:  *	Armando P. Stettner  Digital Equipment Corp.  July, 1980
  15:  */
  16: 
  17: #include "../h/param.h"
  18: #include "../pdpuba/rlreg.h"
  19: #include "saio.h"
  20: 
  21: #define NRL 2
  22: 
  23:     struct  rldevice *RLcsr[NRL + 1] =
  24:         {
  25:         (struct rldevice *)0174400,
  26:         (struct rldevice *)0,
  27:         (struct rldevice *)-1
  28:         };
  29: 
  30: #define BLKRL1  10240       /* Number of UNIX blocks for an RL01 drive */
  31: #define BLKRL2  20480       /* Number of UNIX blocks for an RL02 drive */
  32: #define RLCYLSZ 10240       /* bytes per cylinder */
  33: #define RLSECSZ 256     /* bytes per sector */
  34: 
  35: struct  Rldrives
  36: {
  37:     int cn[4];      /* location of heads for each drive */
  38:     int type[4];    /* # blocks on drive (RL01/02) */
  39:     int com;        /* read or write command word */
  40:     int chn;        /* cylinder and head number */
  41:     unsigned int bleft; /* bytes left to be transferred */
  42:     unsigned int bpart; /* number of bytes transferred */
  43:     int sn;     /* sector number */
  44:     union {
  45:         int w[2];
  46:         long    l;
  47:     } addr;         /* address of memory for transfer */
  48: 
  49: } rl[NRL] = {{-1,-1,-1,-1,-1,-1,-1,-1},
  50:          {-1,-1,-1,-1,-1,-1,-1,-1}};  /* initialize cn[] and type[] */
  51: 
  52: rlstrategy(io, func)
  53:     register struct iob *io;
  54:     int func;
  55: {
  56:     int drive = io->i_unit;
  57:     int dif;
  58:     int head;
  59:     int bae, lo16;
  60:     int ctlr = io->i_ctlr;
  61:     register struct rldevice *rladdr;
  62:     register struct Rldrives *rlp;
  63: 
  64:     rladdr = RLcsr[ctlr];
  65:     rlp = &rl[ctlr];
  66: 
  67:     dif = deveovchk(io);
  68:     if  (dif <= 0)
  69:         return(dif);
  70: 
  71:     iomapadr(io->i_ma, &bae, &lo16);
  72:     rlp->chn = io->i_bn/20;
  73:     rlp->sn = (io->i_bn%20) << 1;
  74:     rlp->bleft = io->i_cc;
  75:     rlp->addr.w[0] = bae;
  76:     rlp->addr.w[1] = lo16;
  77:     rlp->com = (drive << 8);
  78:     if (func == READ)
  79:         rlp->com |= RL_RCOM;
  80:     else
  81:         rlp->com |= RL_WCOM;
  82: reading:
  83:     /*
  84: 	 * One has to seek an RL head, relativily.
  85: 	 */
  86:     dif =(rlp->cn[drive] >> 1) - (rlp->chn >>1);
  87:     head = (rlp->chn & 1) << 4;
  88:     if (dif < 0)
  89:         rladdr->rlda = (-dif <<7) | RLDA_SEEKHI | head;
  90:     else
  91:         rladdr->rlda = (dif << 7) | RLDA_SEEKLO | head;
  92:     rladdr->rlcs = (drive << 8) | RL_SEEK;
  93:     rlp->cn[drive] = rlp->chn;  /* keep current, our notion of where the heads are */
  94:     if (rlp->bleft < (rlp->bpart = RLCYLSZ - (rl->sn * RLSECSZ)))
  95:         rlp->bpart = rlp->bleft;
  96:     while ((rladdr->rlcs&RL_CRDY) == 0)
  97:         continue;
  98:     rladdr->rlda = (rlp->chn << 6) | rlp->sn;
  99:     rladdr->rlba = (caddr_t) rlp->addr.w[1];
 100:     rladdr->rlmp = -(rlp->bpart >> 1);
 101:     rladdr->rlcs = rlp->com | rlp->addr.w[0] << 4;
 102:     while ((rladdr->rlcs & RL_CRDY) == 0)   /* wait for completion */
 103:         continue;
 104:     if (rladdr->rlcs < 0) {
 105:         /* check error bit */
 106:         if (rladdr->rlcs & 040000) {
 107:             /* Drive error */
 108:             /*
 109: 			 * get status from drive
 110: 			 */
 111:             rladdr->rlda = RLDA_GS;
 112:             rladdr->rlcs = (drive << 8) | RL_GETSTATUS;
 113:             while ((rladdr->rlcs & RL_CRDY) == 0)   /* wait for controller */
 114:                 continue;
 115:         }
 116:         printf("%s err cy=%d, hd=%d, sc=%d, rlcs=%o, rlmp=%o\n",
 117:             devname(io), rlp->chn>>01, rlp->chn&01, rlp->sn,
 118:             rladdr->rlcs, rladdr->rlmp);
 119:         return(-1);
 120:     }
 121:     /*
 122: 	 * Determine if there is more to read to satisfy this request.
 123: 	 * This is to compensate for the lack of spiraling reads.
 124: 	 */
 125:     if ((rlp->bleft -= rlp->bpart) > 0) {
 126:         rlp->addr.l += rlp->bpart;
 127:         rlp->sn = 0;
 128:         rlp->chn++;
 129:         goto reading;   /* read some more */
 130:     }
 131:     return(io->i_cc);
 132: }
 133: 
 134: rlopen(io)
 135:     register struct iob *io;
 136:     {
 137: 
 138:     if  (io->i_unit > 3)
 139:         return(-1);
 140:     if  (genopen(NRL, io) < 0)
 141:         return(-1);
 142:     rlgsts(io);     /* get status and head position */
 143:     if  (devlabel(io, READLABEL) < 0)
 144:         return(-1);
 145:     io->i_boff = io->i_label.d_partitions[io->i_part].p_offset;
 146:     return(0);
 147:     }
 148: 
 149: /*
 150:  * We must determine what type of drive we are talking to in order
 151:  * to determine how many blocks are on the device.  The rl.type[]
 152:  * array has been initialized with -1's so that we may test first
 153:  * contact with a particular drive and do this determination only once.
 154:  *
 155:  * RL02 GET STATUS BAND-AID - Fred Canter 10/14/80
 156:  *
 157:  * For some unknown reason the RL02 (seems to be
 158:  * only drive 1) does not return a valid drive status
 159:  * the first time that a GET STATUS request is issued
 160:  * for the drive, in fact it can take up to three or more
 161:  * GET STATUS requests to obtain the correct status.
 162:  * In order to overcome this "HACK" the driver has been
 163:  * modified to issue a GET STATUS request, validate the
 164:  * drive status returned, and then use it to determine the
 165:  * drive type. If a valid status is not returned after eight
 166:  * attempts, then an error message is printed.
 167:  */
 168: 
 169: rlgsts(io)
 170:     struct  iob *io;
 171:     {
 172:     int ctr;
 173:     int drive = io->i_unit;
 174:     int ctlr = io->i_ctlr;
 175:     register struct Rldrives *rlp = &rl[ctlr];
 176:     register struct rldevice *rladdr = RLcsr[ctlr];
 177: 
 178: 
 179:     if (rlp->type[drive] < 0) {
 180:         ctr = 0;
 181:         do {
 182:             /* load this register; what a dumb controller */
 183:             rladdr->rlda = RLDA_RESET|RLDA_GS;
 184:             /* set up csr */
 185:             rladdr->rlcs = (drive << 8) | RL_GETSTATUS;
 186:             while ((rladdr->rlcs & RL_CRDY) == 0)   /* wait for it */
 187:                 continue;
 188:         } while (((rladdr->rlmp & 0177477) != 035) && (++ctr < 8));
 189:         if (ctr >= 8)
 190:             printf("\nCan't get %s sts\n", devname(io));
 191:         if (rladdr->rlmp & RLMP_DTYP)
 192:             rlp->type[drive] = BLKRL2;  /* drive is RL02 */
 193:         else
 194:             rlp->type[drive] = BLKRL1;  /* drive RL01 */
 195:         /*
 196: 		 * When device is first touched, find out where the heads are.
 197: 		 */
 198:         rladdr->rlcs = (drive << 8) | RL_RHDR;
 199:         while ((rladdr->rlcs&RL_CRDY) == 0)
 200:             continue;
 201:         rlp->cn[drive] = ((rladdr->rlmp) >> 6) & 01777;
 202:     }
 203:     return;
 204: }
 205: 
 206: /*
 207:  * This generates a default label.  'rlopen' has already been called so
 208:  * we can use the 'types' field as the number of sectors on the device.
 209: */
 210: 
 211: rllabel(io)
 212:     register struct iob *io;
 213:     {
 214:     register struct disklabel *lp = &io->i_label;
 215:     daddr_t nblks = rl[io->i_ctlr].type[io->i_unit];
 216: 
 217:     lp->d_type = DTYPE_DEC;
 218:     lp->d_partitions[0].p_size = nblks;
 219:     lp->d_nsectors = 20;        /* sectors per track */
 220:     lp->d_ntracks = 2;      /* tracks per cylinder */
 221:     lp->d_secpercyl = 40;       /* sectors per cylinder */
 222:     lp->d_ncylinders = nblks / (20 * 2);
 223:     lp->d_secperunit = nblks;
 224:     return(0);
 225:     }

Defined functions

rlgsts defined in line 169; used 1 times
rllabel defined in line 211; used 2 times
rlopen defined in line 134; used 2 times
rlstrategy defined in line 52; used 2 times

Defined variables

RLcsr defined in line 23; used 3 times
rl defined in line 49; used 4 times

Defined struct's

Rldrives defined in line 35; used 4 times

Defined macros

BLKRL1 defined in line 30; used 1 times
BLKRL2 defined in line 31; used 1 times
NRL defined in line 21; used 3 times
RLCYLSZ defined in line 32; used 1 times
  • in line 94
RLSECSZ defined in line 33; used 1 times
  • in line 94
Last modified: 1997-11-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3284
Valid CSS Valid XHTML 1.0 Strict