# 2.11BSD#431 - /usr/src/sys/pdpstand/rl.c

##### Functions

    rlgsts            X
    rllabel           X
    rlopen            X
    rlstrategy        X

##### Variables

    RLcsr             X
    rl                X

##### Macros

    BLKRL1            X
    BLKRL2            X
    NRL               X
    RLCYLSZ           X
    RLSECSZ           X

##### struct's

    Rldrives          X

       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

- in line 142

rllabel defined in line 211; used 2 times

- in /usr/src/sys/pdpstand/conf.c line 19, 51

rlopen defined in line 134; used 2 times

- in /usr/src/sys/pdpstand/conf.c line 19, 50

rlstrategy defined in line 52; used 2 times

- in /usr/src/sys/pdpstand/conf.c line 19, 50

#### Defined variables

RLcsr defined in line 23; used 3 times

- in line 64, 176
- in /usr/src/sys/pdpstand/conf.c line 50

rl defined in line 49; used 4 times

- in line 65, 94, 175, 215

#### Defined struct's

Rldrives defined in line 35; used 4 times

- in line 62(2), 175(2)

#### Defined macros

BLKRL1 defined in line 30; used 1 times

- in line 194

BLKRL2 defined in line 31; used 1 times

- in line 192

NRL defined in line 21; used 3 times

- in line 23, 49, 140

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