1: 
   2: /*	@(#)tmscp.c	7.1 (Berkeley) 6/5/86 */
   3: 
   4: /****************************************************************
   5:  *                                                              *
   6:  *        Licensed from Digital Equipment Corporation           *
   7:  *                       Copyright (c)                          *
   8:  *               Digital Equipment Corporation                  *
   9:  *                   Maynard, Massachusetts                     *
  10:  *                         1985, 1986                           *
  11:  *                    All rights reserved.                      *
  12:  *                                                              *
  13:  *        The Information in this software is subject to change *
  14:  *   without notice and should not be construed as a commitment *
  15:  *   by  Digital  Equipment  Corporation.   Digital   makes  no *
  16:  *   representations about the suitability of this software for *
  17:  *   any purpose.  It is supplied "As Is" without expressed  or *
  18:  *   implied  warranty.                                         *
  19:  *                                                              *
  20:  *        If the Regents of the University of California or its *
  21:  *   licensees modify the software in a manner creating         *
  22:  *   diriviative copyright rights, appropriate copyright        *
  23:  *   legends may be placed on  the drivative work in addition   *
  24:  *   to that set forth above.                                   *
  25:  ***************************************************************/
  26: /*
  27:  * tmscp.c - TMSCP (TK50/TU81) standalone driver
  28:  */
  29: 
  30: # ifndef lint
  31: static char *sccsid = "@(#)tmscp.c	1.5	(ULTRIX)	4/18/86";
  32: # endif not lint
  33: 
  34: /* ------------------------------------------------------------------------
  35:  * Modification History: /sys/stand/tmscp.c
  36:  *
  37:  * 3-15-85  afd
  38:  *	Don't ask for an interrupt when commands are issued and
  39:  *	check ownership bit in the response descriptor to detect when a
  40:  *	command is complete.  Necessary due to the TU81's failure to set
  41:  *	the response interrupt field in the communications area.
  42:  *
  43:  * ------------------------------------------------------------------------
  44:  */
  45: 
  46: #include "../machine/pte.h"
  47: 
  48: #include "../h/param.h"
  49: #include "../h/gnode.h"
  50: #include "../h/devio.h"
  51: 
  52: #include "savax.h"
  53: 
  54: #include "saio.h"
  55: 
  56: /*
  57:  * Parameters for the communications area
  58:  * (Only 1 cmd & 1 rsp packet)
  59:  */
  60: #define NRSPL2  0
  61: #define NCMDL2  0
  62: #define NRSP    (1<<NRSPL2)
  63: #define NCMD    (1<<NCMDL2)
  64: 
  65: #include "../vaxuba/tmscpreg.h"
  66: #include "../vaxuba/ubareg.h"
  67: #include "../vax/tmscp.h"
  68: 
  69: u_short tmscpstd[] = { 0174500 };
  70: 
  71: struct iob  ctmscpbuf;
  72: 
  73: struct tmscpdevice *tmscpaddr = 0;
  74: 
  75: struct tmscp {
  76:     struct tmscpca  tmscp_ca;
  77:     struct mscp tmscp_rsp;
  78:     struct mscp tmscp_cmd;
  79:     } tmscp;
  80: 
  81: struct tmscp *tmscp_ubaddr;     /* Unibus address of tmscp structure */
  82: 
  83: struct mscp *tmscpcmd();
  84: 
  85: int tmscp_offline = 1;      /* Flag to prevent multiple STCON */
  86: int tms_offline[4] = {1,1,1,1}; /* Flag to prevent multiple ONLIN */
  87: 
  88: 
  89: /*
  90:  * Open a tmscp device. Initialize the controller and set the unit online.
  91:  */
  92: tmscpopen(io)
  93:     register struct iob *io;
  94: {
  95:     register struct mscp *mp;
  96:     int i;
  97: 
  98:     /*
  99: 	 * Have the tmscp controller characteristics already been set up
 100: 	 * (STCON)?
 101: 	 */
 102:     if (tmscp_offline)
 103:         {
 104:         if (tmscpaddr == 0)
 105:             tmscpaddr = (struct tmscpdevice *)ubamem(io->i_unit, tmscpstd[0]);
 106:         if (tmscp_ubaddr == 0)
 107:             {
 108:             ctmscpbuf.i_unit = io->i_unit;
 109:             ctmscpbuf.i_ma = (caddr_t)&tmscp;
 110:             ctmscpbuf.i_cc = sizeof(tmscp);
 111:             tmscp_ubaddr = (struct tmscp *)ubasetup(&ctmscpbuf, 2);
 112:             }
 113:         /*
 114: 		 * Initialize the tmscp device and wait for the 4 steps
 115: 		 * to complete.
 116: 		 */
 117:         tmscpaddr->tmscpip = 0;
 118:         while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
 119:             ;
 120:         tmscpaddr->tmscpsa =TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8);
 121: 
 122:         while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0)
 123:             ;
 124: #		define STEP1MASK 0174377
 125: #		define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2)
 126:         if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD)
 127:             printf("tmscpopen: step 1 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff);
 128:         tmscpaddr->tmscpsa = (short)&tmscp_ubaddr->tmscp_ca.ca_ringbase;
 129: 
 130:         while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)
 131:             ;
 132: #		define STEP2MASK 0174377
 133: #		define STEP2GOOD (TMSCP_STEP3)
 134:         if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD)
 135:             printf("tmscpopen: step 2 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff);
 136:         tmscpaddr->tmscpsa = (short)(((int)&tmscp_ubaddr->tmscp_ca.ca_ringbase) >> 16);
 137: 
 138:         while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)
 139:             ;
 140: #		define STEP3MASK 0174000
 141: #		define STEP3GOOD TMSCP_STEP4
 142:         if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
 143:             printf("tmscpopen: step 3 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff);
 144:         tmscpaddr->tmscpsa = TMSCP_GO;
 145: 
 146:         /*
 147: 		 * Init cmd & rsp area
 148: 		 */
 149:         tmscp.tmscp_ca.ca_cmddsc[0] = (long)&tmscp_ubaddr->tmscp_cmd.mscp_cmdref;
 150:         tmscp.tmscp_cmd.mscp_dscptr = tmscp.tmscp_ca.ca_cmddsc;
 151:         tmscp.tmscp_cmd.mscp_header.tmscp_vcid = 1; /* for tape */
 152: 
 153:         tmscp.tmscp_ca.ca_rspdsc[0] = (long)&tmscp_ubaddr->tmscp_rsp.mscp_cmdref;
 154:         tmscp.tmscp_rsp.mscp_dscptr = tmscp.tmscp_ca.ca_rspdsc;
 155:         tmscp.tmscp_cmd.mscp_cntflgs = 0;
 156:         if (tmscpcmd(M_OP_STCON, 0) == 0)
 157:             {
 158:             _stop("tms: open error, STCON");
 159:             return;
 160:             }
 161:         tmscp_offline = 0;
 162:         }
 163:     tmscp.tmscp_cmd.mscp_unit = io->i_unit&03;
 164:     /*
 165: 	 * Has this unit been issued an ONLIN?
 166: 	 */
 167:     if (tms_offline[tmscp.tmscp_cmd.mscp_unit])
 168:         {
 169:         if ((mp = tmscpcmd(M_OP_ONLIN, 0)) == 0)
 170:             {
 171:             _stop("tms: open error, ONLIN");
 172:             return;
 173:             }
 174:         tms_offline[tmscp.tmscp_cmd.mscp_unit] = 0;
 175:         }
 176:     if (io->i_boff < 0 || io->i_boff > 3)
 177:         _stop("tms: bad offset");
 178:     else if (io->i_boff > 0)
 179:         /*
 180: 		 * Skip forward the appropriate number of files on the tape.
 181: 		 */
 182:         {
 183:         tmscp.tmscp_cmd.mscp_tmkcnt = io->i_boff;
 184:         tmscpcmd(M_OP_REPOS, 0);
 185:         tmscp.tmscp_cmd.mscp_tmkcnt = 0;
 186:         }
 187: }
 188: 
 189: 
 190: /*
 191:  * Close the device (rewind it to BOT)
 192:  */
 193: tmscpclose(io)
 194:     register struct iob *io;
 195: {
 196:     tmscpcmd(M_OP_REPOS, M_MD_REWND);
 197: }
 198: 
 199: 
 200: /*
 201:  * Set up tmscp command packet.  Cause the controller to poll to pick up
 202:  * the command.
 203:  */
 204: struct mscp *
 205: tmscpcmd(op,mod)
 206:     int op, mod;            /* opcode and modifier (usu 0) */
 207: {
 208:     struct mscp *mp;        /* ptr to cmd packet */
 209:     int i;              /* read into to init polling */
 210: 
 211:     tmscp.tmscp_cmd.mscp_opcode = op;
 212:     tmscp.tmscp_cmd.mscp_modifier = mod;
 213:     tmscp.tmscp_cmd.mscp_header.tmscp_msglen = mscp_msglen;
 214:     tmscp.tmscp_ca.ca_cmddsc[0] |= TMSCP_OWN;   /* | TMSCP_INT */
 215:     tmscp.tmscp_rsp.mscp_header.tmscp_msglen = mscp_msglen;
 216:     tmscp.tmscp_ca.ca_rspdsc[0] |= TMSCP_OWN;   /* | TMSCP_INT */
 217: 
 218:     i = tmscpaddr->tmscpip;
 219:     for (;;)
 220:         {
 221:         if (tmscpaddr->tmscpsa & TMSCP_ERR)
 222:             {
 223:             printf("tmscpcmd: Fatal error sa=%o\n", tmscpaddr->tmscpsa & 0xffff);
 224:             return(0);
 225:             }
 226: 
 227:         if (tmscp.tmscp_ca.ca_cmdint)
 228:             tmscp.tmscp_ca.ca_cmdint = 0;
 229:         /*
 230: 		 * This is to handle the case of devices not setting the
 231: 		 * interrupt field in the communications area. Some
 232: 		 * devices (early TU81's) only clear the ownership field
 233: 		 * in the Response Descriptor.
 234: 		 */
 235: /*
 236: 		if (tmscp.tmscp_ca.ca_rspint)
 237: 			break;
 238: */
 239:         if (!(tmscp.tmscp_ca.ca_rspdsc[0] & (TMSCP_OWN)))
 240:             break;
 241:         }
 242:     tmscp.tmscp_ca.ca_rspint = 0;
 243:     mp = &tmscp.tmscp_rsp;
 244:     if (mp->mscp_opcode != (op|M_OP_END) ||
 245:        (mp->mscp_status&M_ST_MASK) != M_ST_SUCC)
 246:         {
 247:         /* Detect hitting tape mark.  This signifies the end of the
 248: 		 * tape mini-root file.  We don't want to return an error
 249: 		 * condition to the strategy routine.
 250: 		 */
 251:         if ((mp->mscp_status & M_ST_MASK) == M_ST_TAPEM)
 252:             return(mp);
 253:         return(0);
 254:         }
 255:     return(mp);
 256: }
 257: 
 258: 
 259: /*
 260:  * Set up to do reads and writes; call tmscpcmd to issue the cmd.
 261:  */
 262: tmscpstrategy(io, func)
 263:     register struct iob *io;
 264:     int func;
 265: {
 266:     register struct mscp *mp;
 267:     int ubinfo;
 268: 
 269:     ubinfo = ubasetup(io, 1);
 270:     mp = &tmscp.tmscp_cmd;
 271:     mp->mscp_lbn = io->i_bn;
 272:     mp->mscp_unit = io->i_unit&03;
 273:     mp->mscp_bytecnt = io->i_cc;
 274:     mp->mscp_buffer = (ubinfo & 0x3fffff) | (((ubinfo>>28)&0xf)<<24);
 275:     if ((mp = tmscpcmd(func == READ ? M_OP_READ : M_OP_WRITE, 0)) == 0)
 276:         {
 277:         ubafree(io, ubinfo);
 278:         printf("tms: I/O error\n");
 279:         return(-1);
 280:         }
 281:     ubafree(io, ubinfo);
 282:     /*
 283: 	 * Detect hitting tape mark so we do it gracefully and return a
 284: 	 * character count of 0 to signify end of copy.  Rewind the tape
 285: 	 * before returning.
 286: 	 */
 287:     if ((mp->mscp_status & M_ST_MASK) == M_ST_TAPEM)
 288:         return(0);
 289:     return(io->i_cc);
 290: }
 291: 
 292: /*ARGSUSED*/
 293: tmscpioctl(io, cmd, arg)
 294:     struct iob *io;
 295:     int cmd;
 296:     caddr_t arg;
 297: {
 298:     return (ECMD);
 299: }

Defined functions

tmscpclose defined in line 193; never used
tmscpcmd defined in line 204; used 6 times
tmscpioctl defined in line 293; never used
tmscpopen defined in line 92; never used
tmscpstrategy defined in line 262; never used

Defined variables

ctmscpbuf defined in line 71; used 4 times
sccsid defined in line 31; never used
tms_offline defined in line 86; used 2 times
tmscp defined in line 79; used 27 times
tmscp_offline defined in line 85; used 2 times
tmscp_ubaddr defined in line 81; used 6 times
tmscpaddr defined in line 73; used 20 times
tmscpstd defined in line 69; used 1 times

Defined struct's

tmscp defined in line 75; used 4 times

Defined macros

NCMD defined in line 63; never used
NCMDL2 defined in line 61; used 3 times
NRSP defined in line 62; never used
NRSPL2 defined in line 60; used 3 times
STEP1GOOD defined in line 125; used 1 times
STEP1MASK defined in line 124; used 1 times
STEP2GOOD defined in line 133; used 1 times
STEP2MASK defined in line 132; used 1 times
STEP3GOOD defined in line 141; used 1 times
STEP3MASK defined in line 140; used 1 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1357
Valid CSS Valid XHTML 1.0 Strict