|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.