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