|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)uda.c 7.1 (Berkeley) 6/5/86 ! 7: */ ! 8: ! 9: /* ! 10: * UDA50/RAxx disk device driver ! 11: */ ! 12: #include "../machine/pte.h" ! 13: ! 14: #include "../h/param.h" ! 15: #include "../h/inode.h" ! 16: #include "../h/fs.h" ! 17: ! 18: #include "saio.h" ! 19: #include "savax.h" ! 20: ! 21: #define NRA 4 ! 22: /* ! 23: * Parameters for the communications area ! 24: */ ! 25: #define NRSPL2 0 ! 26: #define NCMDL2 0 ! 27: #define NRSP (1<<NRSPL2) ! 28: #define NCMD (1<<NCMDL2) ! 29: ! 30: #include "../vaxuba/udareg.h" ! 31: #include "../vaxuba/ubareg.h" ! 32: #include "../vax/mscp.h" ! 33: ! 34: u_short udastd[] = { 0772150 }; ! 35: ! 36: struct iob cudbuf; ! 37: ! 38: struct udadevice *udaddr = 0; ! 39: ! 40: struct uda { ! 41: struct udaca uda_ca; ! 42: struct mscp uda_rsp; ! 43: struct mscp uda_cmd; ! 44: } uda; ! 45: ! 46: struct uda *ud_ubaddr; /* Unibus address of uda structure */ ! 47: ! 48: int ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; ! 49: int ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; ! 50: int ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; ! 51: #ifndef UCBRA ! 52: #ifdef RA_COMPAT ! 53: int ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 }; ! 54: #else ! 55: int ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 }; ! 56: #endif ! 57: #else ! 58: int ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 }; ! 59: #endif ! 60: ! 61: struct mscp *udcmd(); ! 62: static int ratype[NRA]; ! 63: ! 64: raopen(io) ! 65: register struct iob *io; ! 66: { ! 67: register struct mscp *mp; ! 68: static int udainit, udadriveinit[NRA]; ! 69: int i; ! 70: daddr_t off; ! 71: ! 72: if (udaddr == 0) ! 73: udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]); ! 74: if (ud_ubaddr == 0) { ! 75: /* ! 76: * Initialise cudbuf.i_unit so that controllers ! 77: * on UNIBUSes other than 0 can be used. ! 78: */ ! 79: cudbuf.i_unit = io->i_unit; ! 80: cudbuf.i_ma = (caddr_t)&uda; ! 81: cudbuf.i_cc = sizeof(uda); ! 82: ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2); ! 83: } ! 84: if (udainit == 0) { ! 85: udaddr->udaip = 0; ! 86: while ((udaddr->udasa & UDA_STEP1) == 0) ! 87: ; ! 88: udaddr->udasa = UDA_ERR; ! 89: while ((udaddr->udasa & UDA_STEP2) == 0) ! 90: ; ! 91: udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase; ! 92: while ((udaddr->udasa & UDA_STEP3) == 0) ! 93: ; ! 94: udaddr->udasa = ! 95: (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16); ! 96: while ((udaddr->udasa & UDA_STEP4) == 0) ! 97: ; ! 98: udaddr->udasa = UDA_GO; ! 99: uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref; ! 100: uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref; ! 101: uda.uda_cmd.mscp_cntflgs = 0; ! 102: if (udcmd(M_OP_STCON) == 0) { ! 103: _stop("ra: open error, STCON"); ! 104: return; ! 105: } ! 106: } ! 107: i = io->i_unit & 7; ! 108: if (udadriveinit[i] == 0) { ! 109: uda.uda_cmd.mscp_unit = i; ! 110: if (udcmd(M_OP_ONLIN) == 0) { ! 111: _stop("ra: open error, ONLIN"); ! 112: return; ! 113: } ! 114: udainit = 1; ! 115: } ! 116: if (io->i_boff < 0 || io->i_boff > 7) ! 117: _stop("ra: bad unit"); ! 118: ! 119: switch (ratype[i]) { ! 120: case 25: ! 121: off = ra25_off[io->i_boff]; ! 122: break; ! 123: case 60: ! 124: off = ra60_off[io->i_boff]; ! 125: break; ! 126: case 80: ! 127: off = ra80_off[io->i_boff]; ! 128: break; ! 129: case 81: ! 130: off = ra81_off[io->i_boff]; ! 131: break; ! 132: default: ! 133: printf("uda%d: don't support ra%d's\n", i, ratype[i]); ! 134: off = -1; ! 135: break; ! 136: } ! 137: if (off == -1) ! 138: _stop("ra: bad partition"); ! 139: io->i_boff = off; ! 140: } ! 141: ! 142: struct mscp * ! 143: udcmd(op) ! 144: int op; ! 145: { ! 146: struct mscp *mp; ! 147: int i; ! 148: ! 149: uda.uda_cmd.mscp_opcode = op; ! 150: uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp); ! 151: uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp); ! 152: uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT; ! 153: uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT; ! 154: i = udaddr->udaip; ! 155: for (;;) { ! 156: if (uda.uda_ca.ca_cmdint) ! 157: uda.uda_ca.ca_cmdint = 0; ! 158: if (uda.uda_ca.ca_rspint) ! 159: break; ! 160: } ! 161: uda.uda_ca.ca_rspint = 0; ! 162: mp = &uda.uda_rsp; ! 163: if (mp->mscp_opcode != (op|M_OP_END) || ! 164: (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) ! 165: return(0); ! 166: if (mp->mscp_opcode == (M_OP_ONLIN|M_OP_END)) ! 167: ratype[uda.uda_cmd.mscp_unit] = mp->mscp_mediaid & 0x7f; ! 168: return(mp); ! 169: } ! 170: ! 171: rastrategy(io, func) ! 172: register struct iob *io; ! 173: { ! 174: register struct mscp *mp; ! 175: int ubinfo; ! 176: ! 177: ubinfo = ubasetup(io, 1); ! 178: mp = &uda.uda_cmd; ! 179: mp->mscp_lbn = io->i_bn; ! 180: mp->mscp_unit = io->i_unit&7; ! 181: mp->mscp_bytecnt = io->i_cc; ! 182: mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); ! 183: if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) { ! 184: printf("ra: I/O error\n"); ! 185: ubafree(io, ubinfo); ! 186: return(-1); ! 187: } ! 188: ubafree(io, ubinfo); ! 189: return(io->i_cc); ! 190: } ! 191: ! 192: /*ARGSUSED*/ ! 193: raioctl(io, cmd, arg) ! 194: struct iob *io; ! 195: int cmd; ! 196: caddr_t arg; ! 197: { ! 198: ! 199: return (ECMD); ! 200: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.