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

##### Functions

    ra_step           X
    raclose           X
    racmd             X
    ralabel           X
    ramount           X
    raopen            X
    rastrategy        X

##### Variables

    RAcsr             X

##### Macros

    NRA               X
    RA_INT            X
    RA_OWN            X
    RA_SMASK          X
    ca_ringbase       X

##### struct's

    ra                X
    rdca              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:  *	@(#)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

- in line 54, 279-284(3)

ra_step defined in line 214; used 4 times

- in line 81-91(4)

raclose defined in line 110; used 2 times

- in /usr/src/sys/pdpstand/conf.c line 21, 46

racmd defined in line 132; used 4 times

- in line 94, 123, 209, 254

ralabel defined in line 241; used 2 times

- in /usr/src/sys/pdpstand/conf.c line 21, 47

ramount defined in line 117; used 1 times

- in line 102

raopen defined in line 64; used 2 times

- in /usr/src/sys/pdpstand/conf.c line 21, 46

rastrategy defined in line 189; used 2 times

- in /usr/src/sys/pdpstand/conf.c line 21, 46

#### Defined variables

RAcsr defined in line 20; used 3 times

- in line 76, 140
- in /usr/src/sys/pdpstand/conf.c line 46

rainit defined in line 53; used 2 times

- in line 79, 98

raonline defined in line 62; used 4 times

- in line 101, 113, 127, 246

rd defined in line 51; used 6 times

- in line 77, 127-128(2), 139, 201, 247

#### Defined struct's

ra defined in line 47; used 6 times

- in line 68(2), 139(2), 194(2)

rdca defined in line 30; used 2 times

- in line 48(2)

#### Defined macros

NRA defined in line 17; used 5 times

- in line 20, 51-53(2), 62, 74

RA_INT defined in line 45; never used
RA_OWN defined in line 44; used 5 times

- in line 151-155(2), 161-166(2), 177

RA_SMASK defined in line 18; used 2 times

- in line 163-168(2)

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