|
|
1.1 ! root 1: ! 2: /* @(#)tmscp.c 7.3 (Berkeley) 3/4/88 */ ! 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 "param.h" ! 47: #include "inode.h" ! 48: #include "fs.h" ! 49: ! 50: #include "../vax/pte.h" ! 51: ! 52: #include "savax.h" ! 53: #include "saio.h" ! 54: ! 55: /* ! 56: * Parameters for the communications area ! 57: * (Only 1 cmd & 1 rsp packet) ! 58: */ ! 59: #define NRSPL2 0 ! 60: #define NCMDL2 0 ! 61: #define NRSP (1<<NRSPL2) ! 62: #define NCMD (1<<NCMDL2) ! 63: ! 64: #include "../vaxuba/tmscpreg.h" ! 65: #include "../vaxuba/ubareg.h" ! 66: #include "../vax/tmscp.h" ! 67: ! 68: #define MAXCTLR 1 /* all addresses must be specified */ ! 69: u_short tmscpstd[MAXCTLR] = { 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: * Open a tmscp device. Initialize the controller and set the unit online. ! 90: */ ! 91: tmscpopen(io) ! 92: register struct iob *io; ! 93: { ! 94: register struct mscp *mp; ! 95: int i; ! 96: ! 97: if ((u_int)io->i_ctlr >= MAXCTLR) ! 98: return (ECTLR); ! 99: /* ! 100: * Have the tmscp controller characteristics already been set up ! 101: * (STCON)? ! 102: */ ! 103: if (tmscp_offline) { ! 104: if (tmscpaddr == 0) ! 105: tmscpaddr = (struct tmscpdevice *)ubamem(io->i_adapt, tmscpstd[0]); ! 106: if (tmscp_ubaddr == 0) { ! 107: ctmscpbuf.i_unit = io->i_unit; ! 108: ctmscpbuf.i_ma = (caddr_t)&tmscp; ! 109: ctmscpbuf.i_cc = sizeof(tmscp); ! 110: tmscp_ubaddr = (struct tmscp *)ubasetup(&ctmscpbuf, 2); ! 111: } ! 112: /* ! 113: * Initialize the tmscp device and wait for the 4 steps ! 114: * to complete. ! 115: */ ! 116: tmscpaddr->tmscpip = 0; ! 117: while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0); ! 118: tmscpaddr->tmscpsa =TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8); ! 119: ! 120: while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0); ! 121: # define STEP1MASK 0174377 ! 122: # define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2) ! 123: if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD) ! 124: printf("tmscpopen: step 1 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff); ! 125: tmscpaddr->tmscpsa = (short)&tmscp_ubaddr->tmscp_ca.ca_ringbase; ! 126: ! 127: while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0); ! 128: # define STEP2MASK 0174377 ! 129: # define STEP2GOOD (TMSCP_STEP3) ! 130: if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD) ! 131: printf("tmscpopen: step 2 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff); ! 132: tmscpaddr->tmscpsa = (short)(((int)&tmscp_ubaddr->tmscp_ca.ca_ringbase) >> 16); ! 133: ! 134: while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0); ! 135: # define STEP3MASK 0174000 ! 136: # define STEP3GOOD TMSCP_STEP4 ! 137: if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD) ! 138: printf("tmscpopen: step 3 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff); ! 139: tmscpaddr->tmscpsa = TMSCP_GO; ! 140: ! 141: /* ! 142: * Init cmd & rsp area ! 143: */ ! 144: tmscp.tmscp_ca.ca_cmddsc[0] = (long)&tmscp_ubaddr->tmscp_cmd.mscp_cmdref; ! 145: tmscp.tmscp_cmd.mscp_dscptr = tmscp.tmscp_ca.ca_cmddsc; ! 146: tmscp.tmscp_cmd.mscp_header.tmscp_vcid = 1; /* for tape */ ! 147: ! 148: tmscp.tmscp_ca.ca_rspdsc[0] = (long)&tmscp_ubaddr->tmscp_rsp.mscp_cmdref; ! 149: tmscp.tmscp_rsp.mscp_dscptr = tmscp.tmscp_ca.ca_rspdsc; ! 150: tmscp.tmscp_cmd.mscp_cntflgs = 0; ! 151: if (tmscpcmd(M_OP_STCON, 0) == 0) { ! 152: printf("tms: open error, STCON\n"); ! 153: return (EIO); ! 154: } ! 155: tmscp_offline = 0; ! 156: } ! 157: tmscp.tmscp_cmd.mscp_unit = io->i_unit&03; ! 158: /* ! 159: * Has this unit been issued an ONLIN? ! 160: */ ! 161: if (tms_offline[tmscp.tmscp_cmd.mscp_unit]) { ! 162: if ((mp = tmscpcmd(M_OP_ONLIN, 0)) == 0) { ! 163: _stop("tms: open error, ONLIN\n"); ! 164: return (EIO); ! 165: } ! 166: tms_offline[tmscp.tmscp_cmd.mscp_unit] = 0; ! 167: } ! 168: /* ! 169: * This makes no sense, but I could be wrong... KB ! 170: * ! 171: * if ((u_int)io->i_part > 3) ! 172: * return (EPART); ! 173: */ ! 174: if (io->i_part) { ! 175: /* ! 176: * Skip forward the appropriate number of files on the tape. ! 177: */ ! 178: tmscp.tmscp_cmd.mscp_tmkcnt = io->i_part; ! 179: (void)tmscpcmd(M_OP_REPOS, 0); ! 180: tmscp.tmscp_cmd.mscp_tmkcnt = 0; ! 181: } ! 182: return (0); ! 183: } ! 184: ! 185: /* ! 186: * Close the device (rewind it to BOT) ! 187: */ ! 188: tmscpclose(io) ! 189: register struct iob *io; ! 190: { ! 191: (void)tmscpcmd(M_OP_REPOS, M_MD_REWND); ! 192: } ! 193: ! 194: /* ! 195: * Set up tmscp command packet. Cause the controller to poll to pick up ! 196: * the command. ! 197: */ ! 198: struct mscp * ! 199: tmscpcmd(op,mod) ! 200: int op, mod; /* opcode and modifier (usu 0) */ ! 201: { ! 202: struct mscp *mp; /* ptr to cmd packet */ ! 203: int i; /* read into to init polling */ ! 204: ! 205: tmscp.tmscp_cmd.mscp_opcode = op; ! 206: tmscp.tmscp_cmd.mscp_modifier = mod; ! 207: tmscp.tmscp_cmd.mscp_header.tmscp_msglen = mscp_msglen; ! 208: tmscp.tmscp_ca.ca_cmddsc[0] |= TMSCP_OWN; /* | TMSCP_INT */ ! 209: tmscp.tmscp_rsp.mscp_header.tmscp_msglen = mscp_msglen; ! 210: tmscp.tmscp_ca.ca_rspdsc[0] |= TMSCP_OWN; /* | TMSCP_INT */ ! 211: ! 212: i = tmscpaddr->tmscpip; ! 213: for (;;) { ! 214: if (tmscpaddr->tmscpsa & TMSCP_ERR) { ! 215: printf("tmscpcmd: Fatal error sa=%o\n", tmscpaddr->tmscpsa & 0xffff); ! 216: return(0); ! 217: } ! 218: ! 219: if (tmscp.tmscp_ca.ca_cmdint) ! 220: tmscp.tmscp_ca.ca_cmdint = 0; ! 221: /* ! 222: * This is to handle the case of devices not setting the ! 223: * interrupt field in the communications area. Some ! 224: * devices (early TU81's) only clear the ownership field ! 225: * in the Response Descriptor. ! 226: * ! 227: * ! 228: * if (tmscp.tmscp_ca.ca_rspint) ! 229: * break; ! 230: */ ! 231: if (!(tmscp.tmscp_ca.ca_rspdsc[0] & (TMSCP_OWN))) ! 232: break; ! 233: } ! 234: tmscp.tmscp_ca.ca_rspint = 0; ! 235: mp = &tmscp.tmscp_rsp; ! 236: if (mp->mscp_opcode != (op|M_OP_END) || ! 237: (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) { ! 238: /* ! 239: * Detect hitting tape mark. This signifies the end of the ! 240: * tape mini-root file. We don't want to return an error ! 241: * condition to the strategy routine. ! 242: */ ! 243: if ((mp->mscp_status & M_ST_MASK) != M_ST_TAPEM) ! 244: return(0); ! 245: } ! 246: return(mp); ! 247: } ! 248: ! 249: /* ! 250: * Set up to do reads and writes; call tmscpcmd to issue the cmd. ! 251: */ ! 252: tmscpstrategy(io, func) ! 253: register struct iob *io; ! 254: int func; ! 255: { ! 256: register struct mscp *mp; ! 257: int ubinfo; ! 258: ! 259: ubinfo = ubasetup(io, 1); ! 260: mp = &tmscp.tmscp_cmd; ! 261: mp->mscp_lbn = io->i_bn; ! 262: mp->mscp_unit = io->i_unit&03; ! 263: mp->mscp_bytecnt = io->i_cc; ! 264: mp->mscp_buffer = (ubinfo & 0x3fffff) | (((ubinfo>>28)&0xf)<<24); ! 265: if ((mp = tmscpcmd(func == READ ? M_OP_READ : M_OP_WRITE, 0)) == 0) { ! 266: ubafree(io, ubinfo); ! 267: printf("tms: I/O error\n"); ! 268: return(-1); ! 269: } ! 270: ubafree(io, ubinfo); ! 271: /* ! 272: * Detect hitting tape mark so we do it gracefully and return a ! 273: * character count of 0 to signify end of copy. Rewind the tape ! 274: * before returning. ! 275: */ ! 276: if ((mp->mscp_status & M_ST_MASK) == M_ST_TAPEM) ! 277: return(0); ! 278: return(io->i_cc); ! 279: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.