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:  *	@(#)ra.c	2.8 (2.11BSD GTE) 1998/1/30
   7:  */
   8: 
   9: /*
  10:  * MSCP disk device driver (rx23, rx33, rx50, rd??, ra??, rz??)
  11:  */
  12: #include "../h/param.h"
  13: #include "../machine/mscp.h"
  14: #include "../pdpuba/rareg.h"
  15: #include "saio.h"
  16: 
  17: #define NRA 2
  18: #define RA_SMASK    (RA_STEP4|RA_STEP3|RA_STEP2|RA_STEP1)
  19: 
  20:     struct  radevice *RAcsr[NRA + 1] =
  21:         {
  22:         (struct radevice *)0172150,
  23:         (struct radevice *)0,
  24:         (struct radevice *)-1
  25:         };
  26: 
  27: /*
  28:  * RA Communications Area
  29: */
  30: struct  rdca {
  31:     short   ca_xxx1;    /* unused */
  32:     char    ca_xxx2;    /* unused */
  33:     char    ca_bdp;     /* BDP to purge */
  34:     short   ca_cmdint;  /* command queue transition interrupt flag */
  35:     short   ca_rspint;  /* response queue transition interrupt flag */
  36:     short   ca_rspl;    /* response descriptors */
  37:     short   ca_rsph;
  38:     short   ca_cmdl;    /* command descriptors */
  39:     short   ca_cmdh;
  40: };
  41: 
  42: #define ca_ringbase ca_rspl
  43: 
  44: #define RA_OWN  0x8000  /* RQ owns this descriptor */
  45: #define RA_INT  0x4000  /* allow interrupt on ring transition */
  46: 
  47: static  struct  ra {
  48:     struct  rdca    ra_ca;
  49:     struct  mscp    ra_rsp;
  50:     struct  mscp    ra_cmd;
  51: } rd[NRA];
  52: 
  53: static  u_char  rainit[NRA];
  54: static  int mx();
  55: 
  56: /*
  57:  * This contains the volume size in sectors of units which have been
  58:  * brought online.  This value is used at default label generation time
  59:  * along with the results of a 'get unit status' command to compute the
  60:  * "geometry" of the drive.
  61: */
  62: static  long    raonline[NRA][8];
  63: 
  64: raopen(io)
  65:     register struct iob *io;
  66: {
  67:     register struct radevice *raaddr;
  68:     register struct ra *racom;
  69:     struct  disklabel *lp = &io->i_label;
  70:     int i, ctlr, unit, bae, lo16;
  71: 
  72:     ctlr = io->i_ctlr;
  73:     unit = io->i_unit;
  74:     if  (genopen(NRA, io) < 0)
  75:         return(-1);
  76:     raaddr = RAcsr[ctlr];
  77:     racom = &rd[ctlr];
  78: 
  79:     if (rainit[ctlr] == 0) {
  80: again:      raaddr->raip = 0;
  81:         if  (ra_step(raaddr, RA_STEP1, 1))
  82:             goto again;
  83:         raaddr->rasa = RA_ERR | (0154/4);
  84:         if  (ra_step(raaddr, RA_STEP2, 2))
  85:             goto again;
  86:         iomapadr(&racom->ra_ca.ca_ringbase, &bae, &lo16);
  87:         raaddr->rasa = lo16;
  88:         if  (ra_step(raaddr, RA_STEP3, 3))
  89:             goto again;
  90:         raaddr->rasa = bae;
  91:         if  (ra_step(raaddr, RA_STEP4, 4))
  92:             goto again;
  93:         raaddr->rasa = RA_GO;
  94:         if (racmd(M_OP_STCON, io) < 0) {
  95:             printf("%s STCON err\n", devname(io));
  96:             return(-1);
  97:         }
  98:         rainit[ctlr] = 1;
  99:     }
 100: 
 101:     if (raonline[ctlr][unit] == 0)
 102:         if (ramount(io) == -1)
 103:             return(-1);
 104:     if  (devlabel(io, READLABEL) == -1)
 105:         return(-1);
 106:     io->i_boff = lp->d_partitions[io->i_part].p_offset;
 107:     return(0);
 108: }
 109: 
 110: raclose(io)
 111:     register struct iob *io;
 112: {
 113:     raonline[io->i_ctlr][io->i_unit] = 0;
 114:     return(0);
 115: }
 116: 
 117: ramount(io)
 118:     register struct iob *io;
 119: {
 120:     register int ctlr = io->i_ctlr;
 121:     register int unit = io->i_unit;
 122: 
 123:     if (racmd(M_OP_ONLIN, io) < 0) {
 124:         printf("%s !online\n", devname(io));
 125:         return(-1);
 126:     }
 127:     raonline[ctlr][unit] = rd[ctlr].ra_rsp.m_uslow +
 128:         ((long)(rd[ctlr].ra_rsp.m_ushigh) << 16);
 129:     return(0);
 130: }
 131: 
 132: racmd(op, io)
 133:     int op;
 134:     struct iob *io;
 135: {
 136:     register struct mscp *mp;
 137:     int ctlr = io->i_ctlr;
 138:     int unit = io->i_unit;
 139:     register struct ra *racom = &rd[ctlr];
 140:     struct  radevice *csr = RAcsr[ctlr];
 141:     int i, bae, lo16;
 142: 
 143:     racom->ra_cmd.m_opcode = op;
 144:     racom->ra_cmd.m_unit = unit;
 145:     racom->ra_cmd.m_cntflgs = 0;
 146:     racom->ra_rsp.m_header.mscp_msglen = sizeof(struct mscp);
 147:     racom->ra_cmd.m_header.mscp_msglen = sizeof(struct mscp);
 148: 
 149:     iomapadr(&racom->ra_rsp.m_cmdref, &bae, &lo16);
 150:     racom->ra_ca.ca_rspl = lo16;
 151:     racom->ra_ca.ca_rsph = RA_OWN | bae;
 152: 
 153:     iomapadr(&racom->ra_cmd.m_cmdref, &bae, &lo16);
 154:     racom->ra_ca.ca_cmdl = lo16;
 155:     racom->ra_ca.ca_cmdh = RA_OWN | bae;
 156: 
 157:     i = csr->raip;
 158: 
 159:     mp = &racom->ra_rsp;
 160:     while (1) {
 161:         while   (racom->ra_ca.ca_cmdh & RA_OWN) {
 162:             delay(200);     /* SA access delay */
 163:             if  (csr->rasa & (RA_ERR|RA_SMASK))
 164:                 goto fail;
 165:         }
 166:         while   (racom->ra_ca.ca_rsph & RA_OWN) {
 167:             delay(200);     /* SA access delay */
 168:             if  (csr->rasa & (RA_ERR|RA_SMASK))
 169:                 goto fail;
 170:         }
 171:         racom->ra_ca.ca_cmdint = 0;
 172:         racom->ra_ca.ca_rspint = 0;
 173:         if (mp->m_opcode == (op | M_OP_END))
 174:             break;
 175:         printf("%s rsp %x op %x ignored\n", devname(io),
 176:             mp->m_header.mscp_credits & 0xf0, mp->m_opcode);
 177:         racom->ra_ca.ca_rsph |= RA_OWN;
 178:     }
 179:     if ((mp->m_status & M_ST_MASK) != M_ST_SUCC) {
 180:         printf("%s err op=%x sts=%x\n", devname(io),
 181:             mp->m_opcode, mp->m_status);
 182:         return(-1);
 183:     }
 184:     return(0);
 185: fail:
 186:     printf("%s rasa=%x\n", devname(io), csr->rasa);
 187: }
 188: 
 189: rastrategy(io, func)
 190:     register struct iob *io;
 191:     int func;
 192: {
 193:     register struct mscp *mp;
 194:     struct ra *racom;
 195:     int bae, lo16, i;
 196: 
 197:     i = deveovchk(io);      /* check for end of volume/partition */
 198:     if  (i <= 0)
 199:         return(i);
 200: 
 201:     racom = &rd[io->i_ctlr];
 202:     mp = &racom->ra_cmd;
 203:     iomapadr(io->i_ma, &bae, &lo16);
 204:     mp->m_lbn_l = loint(io->i_bn);
 205:     mp->m_lbn_h = hiint(io->i_bn);
 206:     mp->m_bytecnt = io->i_cc;
 207:     mp->m_buf_l = lo16;
 208:     mp->m_buf_h = bae;
 209:     if  (racmd(func == READ ? M_OP_READ : M_OP_WRITE, io) < 0)
 210:         return(-1);
 211:     return(io->i_cc);
 212: }
 213: 
 214: ra_step(csr, mask, step)
 215:     register struct radevice *csr;
 216:     int mask, step;
 217:     {
 218:     register int    cnt;
 219: 
 220:     for (cnt = 0; (csr->rasa & mask) == 0; )
 221:         {
 222:         delay(2000);
 223:         cnt++;
 224:         if  (cnt < 5000)
 225:             continue;
 226:         printf("ra(%o) fail step %d. retrying\n",csr,step);
 227:         return(1);
 228:         }
 229:     return(0);
 230:     }
 231: 
 232: /*
 233:  * This routine is called by the general 'devlabel' routine out of conf.c
 234:  * and is used by the standalone disklabel program to initialize the
 235:  * default disklabel.  The MSCP driver does not need geometry info but
 236:  * it is almost trivial (because the drive has already been brought online by
 237:  * 'raopen') to fetch the required information with a 'get unit status'
 238:  * command.
 239: */
 240: 
 241: ralabel(io)
 242:     struct  iob *io;
 243:     {
 244:     register struct disklabel *lp = &io->i_label;
 245:     register char *cp, *dp;
 246:     daddr_t nblks = raonline[io->i_ctlr][io->i_unit];
 247:     struct  mscp *mp = &rd[io->i_ctlr].ra_rsp;
 248:     int nameid, numid;
 249: 
 250:     lp->d_type = DTYPE_MSCP;
 251:     lp->d_partitions[0].p_size = nblks;  /* span the drive with 'a' */
 252: /*	lp->d_secperunit = nblks;	     /* size of entire volume */
 253: 
 254:     if  (racmd(M_OP_GTUNT, io) != 0)
 255:         {
 256:         printf("%s GTUNT failed\n", devname(io));
 257:         return(-1);
 258:         }
 259: /*
 260:  * Yes it's a lot of code but since the standalone utilities (at least 'restor')
 261:  * are likely going to end up split I/D anyhow why not get the information.
 262:  *
 263:  * sectors/track
 264:  * tracks/group * group/cyl = tracks/cyl
 265:  * sectors/track * tracks/cyl = sectors/cyl
 266:  * sectors / sectors/cyl = cyl
 267: */
 268:     lp->d_nsectors = mp->m_track;
 269:     lp->d_ntracks = mp->m_group * mp->m_cylinder;
 270:     lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
 271:     lp->d_ncylinders = nblks / lp->d_secpercyl;
 272:     nameid = (((loint(mp->m_mediaid) & 0x3f) << 9) |
 273:           ((hiint(mp->m_mediaid) >> 7) & 0x1ff));
 274:     numid = hiint(mp->m_mediaid) & 0x7f;
 275: /*
 276:  * Next put 'RA81' or 'RD54', etc into the typename field.
 277: */
 278:     cp = lp->d_typename;
 279:     *cp++ = mx(nameid, 2);
 280:     *cp++ = mx(nameid, 1);
 281:     dp = itoa(numid);
 282:     while   (*cp++ = *dp++)
 283:         ;
 284:     *cp = mx(nameid, 0);
 285:     if  (*cp != ' ')
 286:         cp++;
 287:     *cp = '\0';
 288:     return(0);
 289:     }
 290: 
 291: /*
 292:  * this is a routine rather than a macro to save space - shifting, etc
 293:  * generates a lot of code.
 294: */
 295: 
 296: static
 297: mx(l, i)
 298:     int l, i;
 299:     {
 300:     register int c;
 301: 
 302:     c = (l >> (5 * i)) & 0x1f;
 303:     if  (c == 0)
 304:         c = ' ' - '@';
 305:     return(c + '@');
 306:     }

Defined functions

mx defined in line 296; used 4 times
ra_step defined in line 214; used 4 times
raclose defined in line 110; used 2 times
racmd defined in line 132; used 4 times
ralabel defined in line 241; used 2 times
ramount defined in line 117; used 1 times
raopen defined in line 64; used 2 times
rastrategy defined in line 189; used 2 times

Defined variables

RAcsr defined in line 20; used 3 times
rainit defined in line 53; used 2 times
raonline defined in line 62; used 4 times
rd defined in line 51; used 6 times

Defined struct's

ra defined in line 47; used 6 times
rdca defined in line 30; used 2 times
  • in line 48(2)

Defined macros

NRA defined in line 17; used 5 times
RA_INT defined in line 45; never used
RA_OWN defined in line 44; used 5 times
RA_SMASK defined in line 18; used 2 times
ca_ringbase defined in line 42; used 1 times
  • in line 86
Last modified: 1998-01-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3789
Valid CSS Valid XHTML 1.0 Strict