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: }