|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1990 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms, with or without ! 6: * modification, are permitted provided that the following conditions ! 7: * are met: ! 8: * 1. Redistributions of source code must retain the above copyright ! 9: * notice, this list of conditions and the following disclaimer. ! 10: * 2. Redistributions in binary form must reproduce the above copyright ! 11: * notice, this list of conditions and the following disclaimer in the ! 12: * documentation and/or other materials provided with the distribution. ! 13: * 3. All advertising materials mentioning features or use of this software ! 14: * must display the following acknowledgement: ! 15: * This product includes software developed by the University of ! 16: * California, Berkeley and its contributors. ! 17: * 4. Neither the name of the University nor the names of its contributors ! 18: * may be used to endorse or promote products derived from this software ! 19: * without specific prior written permission. ! 20: * ! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 31: * SUCH DAMAGE. ! 32: * ! 33: * @(#)ct.c 7.3 (Berkeley) 5/5/91 ! 34: */ ! 35: ! 36: /* ! 37: * CS80 tape driver ! 38: */ ! 39: #include <sys/param.h> ! 40: #include "../dev/ctreg.h" ! 41: ! 42: #include "saio.h" ! 43: #include "samachdep.h" ! 44: ! 45: struct ct_iocmd ct_ioc; ! 46: struct ct_rscmd ct_rsc; ! 47: struct ct_stat ct_stat; ! 48: struct ct_ssmcmd ct_ssmc; ! 49: ! 50: struct ct_softc { ! 51: char sc_retry; ! 52: char sc_alive; ! 53: short sc_punit; ! 54: int sc_blkno; ! 55: } ct_softc[NCT]; ! 56: ! 57: #define CTRETRY 5 ! 58: #define MTFSF 10 ! 59: #define MTREW 11 ! 60: ! 61: struct ctinfo { ! 62: short hwid; ! 63: short punit; ! 64: } ctinfo[] = { ! 65: CT7946ID, 1, ! 66: CT7912PID, 1, ! 67: CT7914PID, 1, ! 68: CT9144ID, 0, ! 69: CT9145ID, 0, ! 70: }; ! 71: int nctinfo = sizeof(ctinfo) / sizeof(ctinfo[0]); ! 72: ! 73: ctinit(unit) ! 74: register int unit; ! 75: { ! 76: register struct ct_softc *rs = &ct_softc[unit]; ! 77: u_char stat; ! 78: register int type; ! 79: ! 80: if (hpibrecv(unit, C_QSTAT, &stat, 1) != 1 || stat) ! 81: return (0); ! 82: if (ctident(unit) < 0) ! 83: return (0); ! 84: ct_ssmc.unit = C_SUNIT(rs->sc_punit); ! 85: ct_ssmc.cmd = C_SSM; ! 86: ct_ssmc.fefm = FEF_MASK; ! 87: ct_ssmc.refm = REF_MASK; ! 88: ct_ssmc.aefm = AEF_MASK; ! 89: ct_ssmc.iefm = IEF_MASK; ! 90: hpibsend(unit, C_CMD, &ct_ssmc, sizeof(ct_ssmc)); ! 91: hpibswait(unit); ! 92: hpibrecv(unit, C_QSTAT, &stat, 1); ! 93: rs->sc_alive = 1; ! 94: return (1); ! 95: } ! 96: ! 97: ctident(unit) ! 98: int unit; ! 99: { ! 100: struct ct_describe desc; ! 101: u_char stat, cmd[3]; ! 102: char name[7]; ! 103: int id, i; ! 104: ! 105: id = hpibid(unit); ! 106: if ((id & 0x200) == 0) ! 107: return(-1); ! 108: for (i = 0; i < nctinfo; i++) ! 109: if (id == ctinfo[i].hwid) ! 110: break; ! 111: if (i == nctinfo) ! 112: return(-1); ! 113: ct_softc[unit].sc_punit = ctinfo[i].punit; ! 114: id = i; ! 115: ! 116: /* ! 117: * Collect device description. ! 118: * Right now we only need this to differentiate 7945 from 7946. ! 119: * Note that we always issue the describe command to unit 0. ! 120: */ ! 121: cmd[0] = C_SUNIT(0); ! 122: cmd[1] = C_SVOL(0); ! 123: cmd[2] = C_DESC; ! 124: hpibsend(unit, C_CMD, cmd, sizeof(cmd)); ! 125: hpibrecv(unit, C_EXEC, &desc, 37); ! 126: hpibrecv(unit, C_QSTAT, &stat, sizeof(stat)); ! 127: bzero(name, sizeof(name)); ! 128: if (!stat) { ! 129: register int n = desc.d_name; ! 130: for (i = 5; i >= 0; i--) { ! 131: name[i] = (n & 0xf) + '0'; ! 132: n >>= 4; ! 133: } ! 134: } ! 135: switch (ctinfo[id].hwid) { ! 136: case CT7946ID: ! 137: if (bcmp(name, "079450", 6) == 0) ! 138: id = -1; /* not really a 7946 */ ! 139: break; ! 140: default: ! 141: break; ! 142: } ! 143: return(id); ! 144: } ! 145: ! 146: ctopen(io) ! 147: struct iob *io; ! 148: { ! 149: register int unit = io->i_unit; ! 150: register struct ct_softc *rs = &ct_softc[unit]; ! 151: register int skip; ! 152: ! 153: if (hpibalive(unit) == 0) ! 154: _stop("ct controller not configured"); ! 155: if (rs->sc_alive == 0) ! 156: if (ctinit(unit) == 0) ! 157: _stop("ct init failed"); ! 158: ctstrategy(io, MTREW); ! 159: skip = io->i_boff; ! 160: while (skip--) ! 161: ctstrategy(io, MTFSF); ! 162: } ! 163: ! 164: ctclose(io) ! 165: struct iob *io; ! 166: { ! 167: ctstrategy(io, MTREW); ! 168: } ! 169: ! 170: ctstrategy(io, func) ! 171: register struct iob *io; ! 172: register int func; ! 173: { ! 174: register int unit = io->i_unit; ! 175: register struct ct_softc *rs = &ct_softc[unit]; ! 176: char stat; ! 177: ! 178: rs->sc_retry = 0; ! 179: ct_ioc.unit = C_SUNIT(rs->sc_punit); ! 180: ct_ioc.saddr = C_SADDR; ! 181: ct_ioc.nop2 = C_NOP; ! 182: ct_ioc.slen = C_SLEN; ! 183: ct_ioc.nop3 = C_NOP; ! 184: top: ! 185: if (func == F_READ) { ! 186: ct_ioc.cmd = C_READ; ! 187: ct_ioc.addr = rs->sc_blkno; ! 188: ct_ioc.len = io->i_cc; ! 189: } ! 190: else if (func == F_WRITE) { ! 191: ct_ioc.cmd = C_WRITE; ! 192: ct_ioc.addr = rs->sc_blkno; ! 193: ct_ioc.len = io->i_cc; ! 194: } ! 195: else if (func == MTFSF) { ! 196: ct_ioc.cmd = C_READ; ! 197: ct_ioc.addr = rs->sc_blkno; ! 198: ct_ioc.len = io->i_cc = MAXBSIZE; ! 199: io->i_ma = io->i_buf; ! 200: } ! 201: else { ! 202: ct_ioc.cmd = C_READ; ! 203: ct_ioc.addr = 0; ! 204: ct_ioc.len = 0; ! 205: rs->sc_blkno = 0; ! 206: io->i_cc = 0; ! 207: } ! 208: retry: ! 209: hpibsend(unit, C_CMD, &ct_ioc, sizeof(ct_ioc)); ! 210: if (func != MTREW) { ! 211: hpibswait(unit); ! 212: hpibgo(unit, C_EXEC, io->i_ma, io->i_cc, ! 213: func != F_WRITE ? F_READ : F_WRITE); ! 214: hpibswait(unit); ! 215: } ! 216: else { ! 217: while (hpibswait(unit) < 0) ! 218: ; ! 219: } ! 220: hpibrecv(unit, C_QSTAT, &stat, 1); ! 221: if (stat) { ! 222: stat = cterror(unit); ! 223: if (stat == 0) ! 224: return (-1); ! 225: if (stat == 2) ! 226: return (0); ! 227: if (++rs->sc_retry > CTRETRY) ! 228: return (-1); ! 229: else ! 230: goto retry; ! 231: } ! 232: rs->sc_blkno += CTBTOK(io->i_cc); ! 233: if (func == MTFSF) ! 234: goto top; ! 235: return (io->i_cc); ! 236: } ! 237: ! 238: cterror(unit) ! 239: register int unit; ! 240: { ! 241: register struct ct_softc *ct = &ct_softc[unit]; ! 242: char stat; ! 243: ! 244: ct_rsc.unit = C_SUNIT(ct->sc_punit); ! 245: ct_rsc.cmd = C_STATUS; ! 246: hpibsend(unit, C_CMD, &ct_rsc, sizeof(ct_rsc)); ! 247: hpibrecv(unit, C_EXEC, &ct_stat, sizeof(ct_stat)); ! 248: hpibrecv(unit, C_QSTAT, &stat, 1); ! 249: if (stat) { ! 250: printf("ct%d: request status fail %d\n", unit, stat); ! 251: return(0); ! 252: } ! 253: if (ct_stat.c_aef & AEF_EOF) { ! 254: /* 9145 drives don't increment block number at EOF */ ! 255: if ((ct_stat.c_blk - ct->sc_blkno) == 0) ! 256: ct->sc_blkno++; ! 257: else ! 258: ct->sc_blkno = ct_stat.c_blk; ! 259: return (2); ! 260: } ! 261: printf("ct%d err: vu 0x%x, pend 0x%x, bn%d", unit, ! 262: ct_stat.c_vu, ct_stat.c_pend, ct_stat.c_blk); ! 263: printf(", R 0x%x F 0x%x A 0x%x I 0x%x\n", ct_stat.c_ref, ! 264: ct_stat.c_fef, ct_stat.c_aef, ct_stat.c_ief); ! 265: return (1); ! 266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.