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.6 (Berkeley) 01/28/88 7 */ 8 9 /* 10 * UDA50/RAxx disk device driver 11 */ 12 #include "../machine/pte.h" 13 14 #include "param.h" 15 #include "inode.h" 16 #include "fs.h" 17 #include "disklabel.h" 18 19 #include "saio.h" 20 #include "savax.h" 21 22 #define NRA 8 /* max. unit number on controller */ 23 #define SECTSIZ 512 /* sector size in bytes */ 24 25 /* 26 * Unused, but needed in udareg.h 27 */ 28 #define NRSP 1 29 #define NCMD 1 30 31 #include "../vaxuba/udareg.h" 32 #include "../vaxuba/ubareg.h" 33 #include "../vax/mscp.h" 34 35 u_short udastd[] = { 0772150 }; 36 37 struct iob cudbuf; 38 39 /* 40 * Per-controller structures use dimension MAXNUBA, 41 * as only one controller per UNIBUS is supported. 42 */ 43 struct udadevice *udaddr[MAXNUBA]; 44 45 struct uda1 { 46 struct uda1ca uda1_ca; /* communications area */ 47 struct mscp uda1_rsp; /* response packet */ 48 struct mscp uda1_cmd; /* command packet */ 49 } uda1; 50 51 struct uda1 *ud_ubaddr[MAXNUBA]; /* Unibus address of uda structure */ 52 struct disklabel ralabel[MAXNUBA * NRA]; 53 static u_int ratype[MAXNUBA * NRA]; 54 char lbuf[SECTSIZ]; 55 56 raopen(io) 57 register struct iob *io; 58 { 59 register struct mscp *mp; 60 register struct disklabel *lp, *dlp; 61 register struct udadevice *addr; 62 register struct uda1 *ubaddr; 63 register unit; 64 static int udainit[MAXNUBA]; 65 int uba; 66 67 unit = io->i_unit; 68 uba = UNITTOUBA(unit); 69 if (udaddr[uba] == 0) 70 udaddr[uba] = (struct udadevice *)ubamem(unit, udastd[0]); 71 addr = udaddr[uba]; 72 if (badaddr((char *)addr, sizeof(short))) { 73 printf("nonexistent device\n"); 74 return (ENXIO); 75 } 76 if (ud_ubaddr[uba] == 0) { 77 /* 78 * Initialize cudbuf.i_unit so that controllers 79 * on UNIBUSes other than 0 can be used. 80 */ 81 cudbuf.i_unit = unit; 82 cudbuf.i_ma = (caddr_t)&uda1; 83 cudbuf.i_cc = sizeof(uda1); 84 ud_ubaddr[uba] = (struct uda1 *)ubasetup(&cudbuf, 2); 85 } 86 ubaddr = ud_ubaddr[uba]; 87 if (udainit[uba] == 0) { 88 addr->udaip = 0; 89 while ((addr->udasa & UDA_STEP1) == 0) 90 ; 91 addr->udasa = UDA_ERR; 92 while ((addr->udasa & UDA_STEP2) == 0) 93 ; 94 addr->udasa = (short)&ubaddr->uda1_ca.ca_rspdsc; 95 while ((addr->udasa & UDA_STEP3) == 0) 96 ; 97 addr->udasa = 98 (short)(((int)&ubaddr->uda1_ca.ca_rspdsc) >> 16); 99 while ((addr->udasa & UDA_STEP4) == 0) 100 ; 101 addr->udasa = UDA_GO; 102 uda1.uda1_ca.ca_rspdsc = (long)&ubaddr->uda1_rsp.mscp_cmdref; 103 uda1.uda1_ca.ca_cmddsc = (long)&ubaddr->uda1_cmd.mscp_cmdref; 104 /* uda1.uda1_cmd.mscp_cntflgs = 0; */ 105 if (udcmd(M_OP_SETCTLRC, io)) { 106 printf("ra: open error, SETCTLRC\n"); 107 return (EIO); 108 } 109 udainit[uba] = 1; 110 } 111 lp = &ralabel[unit]; 112 if (ratype[unit] == 0) { 113 struct iob tio; 114 115 uda1.uda1_cmd.mscp_unit = UNITTODRIVE(unit); 116 if (udcmd(M_OP_ONLINE, io)) { 117 printf("ra: open error, ONLINE\n"); 118 return (EIO); 119 } 120 ratype[unit] = uda1.uda1_rsp.mscp_onle.onle_drivetype; 121 tio = *io; 122 tio.i_bn = LABELSECTOR; 123 tio.i_ma = lbuf; 124 tio.i_cc = SECTSIZ; 125 tio.i_flgs |= F_RDDATA; 126 if (rastrategy(&tio, READ) != SECTSIZ) { 127 printf("can't read disk label\n"); 128 return (EIO); 129 } 130 *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 131 if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 132 printf("ra%d: unlabeled\n", unit); 133 #ifdef COMPAT_42 134 ramaptype(io, lp); 135 #else 136 return (ENXIO); 137 #endif 138 } 139 } 140 if ((unsigned)io->i_boff >= lp->d_npartitions || 141 (io->i_boff = lp->d_partitions[io->i_boff].p_offset) == -1) { 142 printf("ra: bad partition\n"); 143 return (EUNIT); 144 } 145 return (0); 146 } 147 148 int 149 udcmd(op, io) 150 int op; 151 register struct iob *io; 152 { 153 register struct uda1 *u = &uda1; 154 register struct mscp *mp; 155 int i; 156 157 u->uda1_cmd.mscp_opcode = op; 158 u->uda1_cmd.mscp_msglen = MSCP_MSGLEN; 159 u->uda1_rsp.mscp_msglen = MSCP_MSGLEN; 160 u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; 161 u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; 162 i = udaddr[UNITTOUBA(io->i_unit)]->udaip; 163 mp = &u->uda1_rsp; 164 for (;;) { 165 if (u->uda1_ca.ca_cmdint) 166 u->uda1_ca.ca_cmdint = 0; 167 if (u->uda1_ca.ca_rspint == 0) 168 continue; 169 u->uda1_ca.ca_rspint = 0; 170 if (mp->mscp_opcode == (op | M_OP_END)) 171 break; 172 printf("unexpected rsp type %x op %x ignored\n", 173 MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 174 u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 175 } 176 if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS) 177 return (-1); 178 return (0); 179 } 180 181 rastrategy(io, func) 182 register struct iob *io; 183 { 184 register struct mscp *mp; 185 int ubinfo; 186 187 ubinfo = ubasetup(io, 1); 188 mp = &uda1.uda1_cmd; 189 mp->mscp_unit = UNITTODRIVE(io->i_unit); 190 mp->mscp_seq.seq_lbn = io->i_bn; 191 mp->mscp_seq.seq_bytecount = io->i_cc; 192 mp->mscp_seq.seq_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 193 if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) { 194 printf("ra: I/O error\n"); 195 ubafree(io, ubinfo); 196 return(-1); 197 } 198 ubafree(io, ubinfo); 199 return(io->i_cc); 200 } 201 202 /*ARGSUSED*/ 203 raioctl(io, cmd, arg) 204 struct iob *io; 205 int cmd; 206 caddr_t arg; 207 { 208 209 return (ECMD); 210 } 211 212 #ifdef COMPAT_42 213 u_long ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 214 u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 215 u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 }; 216 u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 }; 217 u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 218 u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 219 #ifndef UCBRA 220 #ifdef RA_COMPAT 221 u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 }; 222 #else 223 u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 }; 224 #endif 225 #else 226 u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 }; 227 #endif 228 229 u_long *ra_off[] = { 230 0, /* 0 = unused */ 231 ra80_off, /* 1 = ra80 */ 232 ra25_off, /* 2 = rc25 removable */ 233 ra25_off, /* 3 = rc25 fixed */ 234 ra60_off, /* 4 = ra60 */ 235 ra81_off, /* 5 = ra81 */ 236 0, /* 6 = ? */ 237 rx50_off, /* 7 = rx50 */ 238 rd52_off, /* 8 = rd52 */ 239 rd53_off, /* 9 = rd53 */ 240 }; 241 242 #define NOFFS (sizeof(ra_off)/sizeof(ra_off[0])) 243 244 ramaptype(io, lp) 245 register struct iob *io; 246 register struct disklabel *lp; 247 { 248 register struct partition *pp; 249 register u_int i; 250 register u_long *off; 251 252 if ((i = ratype[io->i_unit]) >= NOFFS || (off = ra_off[i]) == 0) { 253 printf("ra%d: ra type %d unsupported\n", io->i_unit, i); 254 lp->d_npartitions = 0; 255 return; 256 } 257 lp->d_npartitions = 8; 258 for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 259 pp->p_offset = *off++; 260 } 261 #endif 262