1: /*	@(#)tmscp.c	7.1.5 (2.11BSD GTE) 1998/1/30 */
   2: 
   3: /****************************************************************
   4:  *        Licensed from Digital Equipment Corporation           *
   5:  *                       Copyright (c)                          *
   6:  *               Digital Equipment Corporation                  *
   7:  *                   Maynard, Massachusetts                     *
   8:  *                         1985, 1986                           *
   9:  *                    All rights reserved.                      *
  10:  *                                                              *
  11:  *        The Information in this software is subject to change *
  12:  *   without notice and should not be construed as a commitment *
  13:  *   by  Digital  Equipment  Corporation.   Digital   makes  no *
  14:  *   representations about the suitability of this software for *
  15:  *   any purpose.  It is supplied "As Is" without expressed  or *
  16:  *   implied  warranty.                                         *
  17:  *                                                              *
  18:  *        If the Regents of the University of California or its *
  19:  *   licensees modify the software in a manner creating         *
  20:  *   deriviative copyright rights, appropriate copyright        *
  21:  *   legends may be placed on  the drivative work in addition   *
  22:  *   to that set forth above.                                   *
  23:  ***************************************************************/
  24: /*
  25:  * tmscp.c - TMSCP (TK50/TU81) standalone driver
  26:  */
  27: 
  28: /* static char *sccsid = "@(#)tmscp.c	1.5	(ULTRIX) 4/18/86"; */
  29: 
  30: /* ------------------------------------------------------------------------
  31:  * Modification History: /sys/pdpstand/tmscp.c
  32:  *
  33:  * 5-30-95 sms - new iob structure.
  34:  * 4-20-91 sms - add multi controller and unit support (sms)
  35:  * 8-20-90 steven m. schultz (sms@wlv.iipo.gtegsc.com)
  36:  *	Port from 4.3BSD to 2.11BSD
  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 "../h/param.h"
  47: #include "saio.h"
  48: 
  49: /*
  50:  * Parameters for the communications area
  51:  * (Only 1 cmd & 1 rsp packet)
  52:  */
  53: #define NRSPL2  0           /* Define these before including */
  54: #define NCMDL2  0           /*   tmscpreg.h and tmscp.h below */
  55: 
  56: #include "sys/buf.h"
  57: #include "../pdpuba/tmscpreg.h"
  58: #include "../pdp/tmscp.h"
  59: 
  60: #define NTMS    2
  61: 
  62:     struct  tmscpdevice *TMScsr[NTMS + 1] =
  63:         {
  64:         (struct tmscpdevice *)0174500,
  65:         (struct tmscpdevice *)0,
  66:         (struct tmscpdevice *)-1
  67:         };
  68: 
  69: struct tmscp tmscp[NTMS];
  70: 
  71: u_char tmsoffline[NTMS] = {1, 1};   /* Flag to prevent multiple STCON */
  72: u_char tms_offline[NTMS][4] = {{1,1,1,1},
  73:                    {1,1,1,1}}; /* Flag to prevent multiple ONLIN */
  74: static char opnmsg[] = "tms%d: step %d failed sa=0%o\n";
  75: 
  76: extern int tapemark;        /* flag to indicate tapemark encountered
  77: 				   (see sys.c as to how it's used) */
  78: 
  79: /*
  80:  * Open a tmscp device. Initialize the controller and set the unit online.
  81:  */
  82: tmscpopen(io)
  83:     register struct iob *io;
  84: {
  85:     register struct tmscpdevice *tmscpaddr;
  86:     int ctlr = io->i_ctlr;
  87:     int unit = io->i_unit, bae, lo16;
  88:     register struct tmscp *tms = &tmscp[ctlr];
  89: 
  90:     if (genopen(NTMS, io) < 0)
  91:         return(-1);
  92:     io->i_flgs |= F_TAPE;
  93:     tmscpaddr = TMScsr[ctlr];
  94: 
  95:     /*
  96: 	 * Have the tmscp controller characteristics already been set up
  97: 	 * (STCON)?
  98: 	 */
  99:     if (tmsoffline[ctlr])
 100:         {
 101:         /*
 102: 		 * Initialize the tmscp device and wait for the 4 steps
 103: 		 * to complete.
 104: 		 */
 105:         tmscpaddr->tmscpip = 0;
 106:         while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
 107:             ;
 108:         tmscpaddr->tmscpsa =TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8);
 109: 
 110:         while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0)
 111:             ;
 112: #define STEP1MASK 0174377
 113: #define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2)
 114:         iomapadr(&tms->tmscp_ca.ca_ringbase, &bae, &lo16);
 115:         if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD)
 116:             printf(opnmsg, ctlr, 1, tmscpaddr->tmscpsa);
 117:         tmscpaddr->tmscpsa = lo16;
 118: 
 119:         while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)
 120:             ;
 121: #define STEP2MASK 0174377
 122: #define STEP2GOOD (TMSCP_STEP3)
 123:         if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD)
 124:             printf(opnmsg, ctlr, 2, tmscpaddr->tmscpsa);
 125:         tmscpaddr->tmscpsa = bae;
 126: 
 127:         while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)
 128:             ;
 129: #define STEP3MASK 0174000
 130: #define STEP3GOOD TMSCP_STEP4
 131:         if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
 132:             printf(opnmsg, ctlr, 3, tmscpaddr->tmscpsa);
 133:         tmscpaddr->tmscpsa = TMSCP_GO;
 134:         if (tmscpcmd(io, M_OP_STCON, 0) == 0)
 135:             {
 136:             printf("%s STCON", devname(io));
 137:             return(-1);
 138:             }
 139:         tmsoffline[ctlr] = 0;
 140:         }
 141:     tms->tmscp_cmd[0].mscp_unit = unit;
 142:     /*
 143: 	 * Has this unit been issued an ONLIN?
 144: 	 */
 145:     if (tms_offline[ctlr][unit])
 146:         {
 147:         if (tmscpcmd(io, M_OP_ONLIN, 0) == 0)
 148:             {
 149:             printf("%s ONLIN", devname(io));
 150:             return(-1);
 151:             }
 152:         tms_offline[ctlr][unit] = 0;
 153:         }
 154:     tmscpclose(io);     /* close just does a rewind */
 155:     if  (io->i_part > 0)
 156:         /*
 157: 		 * Skip forward the appropriate number of files on the tape.
 158: 		 */
 159:         {
 160:         tms->tmscp_cmd[0].mscp_tmkcnt = io->i_part;
 161:         tms->tmscp_cmd[0].mscp_buffer_h = 0;
 162:         tms->tmscp_cmd[0].mscp_bytecnt = 0;
 163:         tmscpcmd(io, M_OP_REPOS, 0);
 164:         tms->tmscp_cmd[0].mscp_tmkcnt = 0;
 165:         }
 166:     return(0);
 167: }
 168: 
 169: /*
 170:  * Close the device (rewind it to BOT)
 171:  */
 172: tmscpclose(io)
 173:     register struct iob *io;
 174: {
 175:     register struct tmscp *tms = &tmscp[io->i_ctlr];
 176: 
 177:     tms->tmscp_cmd[0].mscp_buffer_l = 0;    /* tmkcnt */
 178:     tms->tmscp_cmd[0].mscp_buffer_h = 0;
 179:     tms->tmscp_cmd[0].mscp_bytecnt = 0;
 180:     tms->tmscp_cmd[0].mscp_unit = io->i_unit;
 181:     tmscpcmd(io, M_OP_REPOS, M_MD_REWND | M_MD_CLSEX);
 182: }
 183: 
 184: /*
 185:  * Set up tmscp command packet.  Cause the controller to poll to pick up
 186:  * the command.
 187:  */
 188: tmscpcmd(io, op,mod)
 189:     struct  iob *io;
 190:     int op, mod;        /* opcode and modifier (usu 0) */
 191: {
 192:     int ctlr = io->i_ctlr;
 193:     register struct tmscp *tms = &tmscp[ctlr];
 194:     register struct mscp *mp;   /* ptr to cmd packet */
 195:     int i;              /* read into to init polling */
 196:     int bae, lo16;
 197: 
 198:     /*
 199: 	 * Init cmd & rsp area
 200: 	 */
 201:     iomapadr(&tms->tmscp_cmd[0].mscp_cmdref, &bae, &lo16);
 202:     tms->tmscp_ca.ca_cmddsc[0].lsh = lo16;
 203:     tms->tmscp_ca.ca_cmddsc[0].hsh = bae;
 204:     tms->tmscp_cmd[0].mscp_dscptr = (long *)tms->tmscp_ca.ca_cmddsc;
 205:     tms->tmscp_cmd[0].mscp_header.mscp_vcid = 1;    /* for tape */
 206: 
 207:     iomapadr(&tms->tmscp_rsp[0].mscp_cmdref, &bae, &lo16);
 208:     tms->tmscp_ca.ca_rspdsc[0].lsh = lo16;
 209:     tms->tmscp_ca.ca_rspdsc[0].hsh = bae;
 210:     tms->tmscp_rsp[0].mscp_dscptr = (long *)tms->tmscp_ca.ca_rspdsc;
 211:     tms->tmscp_cmd[0].mscp_cntflgs = 0;
 212: 
 213:     tms->tmscp_cmd[0].mscp_opcode = op;
 214:     tms->tmscp_cmd[0].mscp_modifier = mod;
 215:     tms->tmscp_cmd[0].mscp_header.mscp_msglen = sizeof (struct tmscp);
 216:     tms->tmscp_ca.ca_cmddsc[0].hsh |= TMSCP_OWN;    /* | TMSCP_INT */
 217:     tms->tmscp_rsp[0].mscp_header.mscp_msglen = sizeof (struct tmscp);
 218:     tms->tmscp_ca.ca_rspdsc[0].hsh |= TMSCP_OWN;    /* | TMSCP_INT */
 219:     tms->tmscp_cmd[0].mscp_zzz2 = 0;
 220: 
 221:     i = TMScsr[ctlr]->tmscpip;
 222:     for (;;)
 223:         {
 224:         if (TMScsr[ctlr]->tmscpsa & TMSCP_ERR) {
 225:             printf("%s Fatal err sa=%o\n",
 226:                 devname(io), TMScsr[ctlr]->tmscpsa);
 227:             return(0);
 228:         }
 229: 
 230:         if (tms->tmscp_ca.ca_cmdint)
 231:             tms->tmscp_ca.ca_cmdint = 0;
 232:         /*
 233: 		 * This is to handle the case of devices not setting the
 234: 		 * interrupt field in the communications area. Some
 235: 		 * devices (early TU81's) only clear the ownership field
 236: 		 * in the Response Descriptor.
 237: 		 */
 238: /*
 239: 		if (tms->tmscp_ca.ca_rspint)
 240: 			break;
 241: */
 242:         if (!(tms->tmscp_ca.ca_rspdsc[0].hsh & TMSCP_OWN))
 243:             break;
 244:         }
 245:     tms->tmscp_ca.ca_rspint = 0;
 246:     mp = &tms->tmscp_rsp[0];
 247:     if (mp->mscp_opcode != (op|M_OP_END) ||
 248:        (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) {
 249:         /* Detect hitting tape mark.  This signifies the end of the
 250: 		 * tape mini-root file.  We don't want to return an error
 251: 		 * condition to the strategy routine.  Set tapemark flag
 252: 		 * for sys.c
 253: 		 */
 254:         if ((mp->mscp_status & M_ST_MASK) == M_ST_TAPEM) {
 255:             tapemark = 1;
 256:             return(1);
 257:         }
 258:         printf("%s I/O err 0%o op=0%o mod=0%o\n", devname(io),
 259:             mp->mscp_status, op, mod);
 260:         return(0);
 261:     }
 262:     return(1);
 263: }
 264: 
 265: /*
 266:  * Set up to do reads and writes; call tmscpcmd to issue the cmd.
 267:  */
 268: tmscpstrategy(io, func)
 269:     register struct iob *io;
 270:     int func;
 271: {
 272:     int ctlr = io->i_ctlr, unit = io->i_unit;
 273:     int bae, lo16;
 274:     register struct tmscp *tms = &tmscp[ctlr];
 275:     register struct mscp *mp;
 276: 
 277:     mp = &tms->tmscp_cmd[0];
 278:     mp->mscp_lbn_l = loint(io->i_bn);
 279:     mp->mscp_lbn_h = hiint(io->i_bn);
 280:     mp->mscp_unit = unit;
 281:     mp->mscp_bytecnt = io->i_cc;
 282:     iomapadr(io->i_ma, &bae, &lo16);
 283:     mp->mscp_buffer_l = lo16;
 284:     mp->mscp_buffer_h = bae;
 285:     if  (tmscpcmd(io, func == READ ? M_OP_READ : M_OP_WRITE, 0) ==0)
 286:         return(-1);
 287:     /*
 288: 	 * Detect hitting tape mark so we do it gracefully and return a
 289: 	 * character count of 0 to signify end of copy.
 290: 	 */
 291:     if (tapemark)
 292:         return(0);
 293:     return(io->i_cc);
 294: }
 295: 
 296: tmscpseek(io, space)
 297:     register struct iob *io;
 298:     int space;
 299:     {
 300:     register struct tmscp *tms = &tmscp[io->i_ctlr];
 301:     int mod;
 302: 
 303:     if  (space == 0)
 304:         return(0);
 305:     if  (space < 0)
 306:         {
 307:         mod = M_MD_REVRS;
 308:         space = -space;
 309:         }
 310:     else
 311:         mod = 0;
 312:     tms->tmscp_cmd[0].mscp_buffer_l = 0;
 313:     tms->tmscp_cmd[0].mscp_buffer_h = 0;
 314:     tms->tmscp_cmd[0].mscp_unit = io->i_unit;
 315:     tms->tmscp_cmd[0].mscp_reccnt = space;
 316:     tmscpcmd(io, M_OP_REPOS, mod | M_MD_OBJCT);
 317:     return(0);
 318:     }

Defined functions

tmscpclose defined in line 172; used 3 times
tmscpcmd defined in line 188; used 6 times
tmscpopen defined in line 82; used 2 times
tmscpseek defined in line 296; used 2 times
tmscpstrategy defined in line 268; used 2 times

Defined variables

TMScsr defined in line 62; used 5 times
opnmsg defined in line 74; used 3 times
tms_offline defined in line 72; used 2 times
tmscp defined in line 69; used 5 times
tmsoffline defined in line 71; used 2 times

Defined macros

NCMDL2 defined in line 54; used 2 times
NRSPL2 defined in line 53; used 2 times
NTMS defined in line 60; used 5 times
STEP1GOOD defined in line 113; used 1 times
STEP1MASK defined in line 112; used 1 times
STEP2GOOD defined in line 122; used 1 times
STEP2MASK defined in line 121; used 1 times
STEP3GOOD defined in line 130; used 1 times
STEP3MASK defined in line 129; used 1 times
Last modified: 1998-01-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4096
Valid CSS Valid XHTML 1.0 Strict