1 /* 2 * Copyright (c) 1982 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 6.4 (Berkeley) 04/14/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 } 201