1 /* 2 * Copyright (c) 1982, 1986, 1988 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.9 (Berkeley) 07/09/88 7 */ 8 9 /* 10 * UDA50/RAxx disk device driver 11 */ 12 13 #include "param.h" 14 #include "inode.h" 15 #include "buf.h" 16 #include "fs.h" 17 #include "disklabel.h" 18 19 #include "../vax/pte.h" 20 21 #include "saio.h" 22 #include "savax.h" 23 24 /* 25 * Unused, but needed in udareg.h 26 */ 27 #define NRSP 1 28 #define NCMD 1 29 30 #include "../vaxuba/udareg.h" 31 #include "../vaxuba/ubareg.h" 32 #include "../vaxuba/ubavar.h" 33 #include "../vax/mscp.h" 34 35 #define NRA 8 /* max. unit number on controller */ 36 #define SECTSIZ 512 /* sector size in bytes */ 37 38 #define MAXCTLR 1 /* all addresses must be specified */ 39 u_short udastd[MAXCTLR] = { 0772150 }; 40 41 struct udadevice *udaddr[MAXNUBA][MAXCTLR]; 42 43 struct uda1 { 44 struct uda1ca uda1_ca; /* communications area */ 45 struct mscp uda1_rsp; /* response packet */ 46 struct mscp uda1_cmd; /* command packet */ 47 } uda1; 48 49 /* Unibus address of uda structure */ 50 struct uda1 *ud_ubaddr[MAXNUBA][MAXCTLR]; 51 struct disklabel ralabel[MAXNUBA][MAXCTLR][NRA]; 52 static u_long ramedia[MAXNUBA][MAXCTLR][NRA]; 53 char lbuf[SECTSIZ]; 54 55 raopen(io) 56 register struct iob *io; 57 { 58 register struct disklabel *lp; 59 register struct udadevice *addr; 60 register struct uda1 *ubaaddr; 61 register int uba, unit; 62 static int udainit[MAXNUBA][MAXCTLR]; 63 struct iob tio; 64 65 if ((u_int)(uba = io->i_adapt) >= nuba) 66 return (EADAPT); 67 if ((u_int)io->i_ctlr >= MAXCTLR) 68 return (ECTLR); 69 if ((u_int)(unit = io->i_unit) >= NRA) 70 return (EUNIT); 71 addr = udaddr[uba][io->i_ctlr] = 72 (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]); 73 if (badaddr((char *)addr, sizeof(short))) 74 return (ENXIO); 75 if ((ubaaddr = ud_ubaddr[uba][io->i_ctlr]) == 0) { 76 tio = *io; 77 tio.i_ma = (caddr_t)&uda1; 78 tio.i_cc = sizeof(uda1); 79 ud_ubaddr[uba][io->i_ctlr] = ubaaddr = 80 (struct uda1 *)ubasetup(&tio, 2); 81 } 82 if (udainit[uba][io->i_ctlr] == 0) { 83 addr->udaip = 0; 84 while ((addr->udasa & UDA_STEP1) == 0); 85 addr->udasa = UDA_ERR; 86 while ((addr->udasa & UDA_STEP2) == 0); 87 addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc; 88 while ((addr->udasa & UDA_STEP3) == 0); 89 addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc >> 16; 90 while ((addr->udasa & UDA_STEP4) == 0); 91 addr->udasa = UDA_GO; 92 uda1.uda1_ca.ca_rspdsc = (long)&ubaaddr->uda1_rsp.mscp_cmdref; 93 uda1.uda1_ca.ca_cmddsc = (long)&ubaaddr->uda1_cmd.mscp_cmdref; 94 /* uda1.uda1_cmd.mscp_cntflgs = 0; */ 95 if (udcmd(M_OP_SETCTLRC, io)) { 96 printf("ra: open error, SETCTLRC\n"); 97 return (ENXIO); 98 } 99 udainit[uba][io->i_ctlr] = 1; 100 } 101 lp = &ralabel[uba][io->i_ctlr][unit]; 102 if (ramedia[uba][io->i_ctlr][unit] == 0) { 103 uda1.uda1_cmd.mscp_unit = unit; 104 if (udcmd(M_OP_ONLINE, io)) { 105 printf("ra: open error, ONLINE\n"); 106 return (ENXIO); 107 } 108 ramedia[uba][io->i_ctlr][unit] = 109 uda1.uda1_rsp.mscp_onle.onle_mediaid; 110 tio = *io; 111 tio.i_bn = LABELSECTOR; 112 tio.i_ma = lbuf; 113 tio.i_cc = SECTSIZ; 114 tio.i_flgs |= F_RDDATA; 115 if (rastrategy(&tio, READ) != SECTSIZ) 116 return (ERDLAB); 117 *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 118 if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 119 #ifdef COMPAT_42 120 printf("ra%d: unlabeled\n", unit); 121 ramaptype(io, lp); 122 #else 123 return (EUNLAB); 124 #endif 125 } 126 } 127 if ((u_int)io->i_part >= lp->d_npartitions || 128 (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 129 return (EPART); 130 return (0); 131 } 132 133 int 134 udcmd(op, io) 135 int op; 136 register struct iob *io; 137 { 138 register struct uda1 *u = &uda1; 139 register struct mscp *mp; 140 register int i; 141 142 u->uda1_cmd.mscp_opcode = op; 143 u->uda1_cmd.mscp_msglen = MSCP_MSGLEN; 144 u->uda1_rsp.mscp_msglen = MSCP_MSGLEN; 145 u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; 146 u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; 147 i = udaddr[io->i_adapt][io->i_ctlr]->udaip; /* start uda polling */ 148 #ifdef lint 149 i = i; 150 #endif 151 mp = &u->uda1_rsp; 152 for (;;) { 153 if (u->uda1_ca.ca_cmdint) 154 u->uda1_ca.ca_cmdint = 0; 155 if (u->uda1_ca.ca_rspint == 0) 156 continue; 157 u->uda1_ca.ca_rspint = 0; 158 if (mp->mscp_opcode == (op | M_OP_END)) 159 break; 160 printf("unexpected rsp type %x op %x ignored\n", 161 MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 162 u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 163 } 164 if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS) 165 return (-1); 166 return (0); 167 } 168 169 rastrategy(io, func) 170 register struct iob *io; 171 int func; 172 { 173 register struct mscp *mp; 174 register int ubinfo; 175 176 ubinfo = ubasetup(io, 1); 177 mp = &uda1.uda1_cmd; 178 mp->mscp_unit = io->i_unit; 179 mp->mscp_seq.seq_lbn = io->i_bn; 180 mp->mscp_seq.seq_bytecount = io->i_cc; 181 mp->mscp_seq.seq_buffer = UBAI_ADDR(ubinfo) | (UBAI_BDP(ubinfo) << 24); 182 if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) { 183 printf("ra: I/O error\n"); 184 ubafree(io, ubinfo); 185 return (-1); 186 } 187 ubafree(io, ubinfo); 188 return (io->i_cc); 189 } 190 191 #ifdef COMPAT_42 192 u_long rc25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 193 u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 194 u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 }; 195 u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 }; 196 u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 197 #define ra70_off ra60_off 198 u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 199 #ifndef UCBRA 200 #ifdef RA_COMPAT 201 u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 }; 202 #else 203 u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 }; 204 #endif 205 #else 206 u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 }; 207 #endif 208 u_long ra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 }; 209 210 struct mediamap { 211 u_long id; /* media ID */ 212 u_long *off; /* offsets */ 213 } ra_map[] = { 214 { MSCP_MKDRIVE2('R', 'A', 60), ra60_off }, 215 { MSCP_MKDRIVE2('R', 'A', 70), ra70_off }, 216 { MSCP_MKDRIVE2('R', 'A', 80), ra80_off }, 217 { MSCP_MKDRIVE2('R', 'A', 81), ra81_off }, 218 { MSCP_MKDRIVE2('R', 'A', 82), ra82_off }, 219 { MSCP_MKDRIVE2('R', 'C', 25), rc25_off }, 220 { MSCP_MKDRIVE3('R', 'C', 'F', 25), rc25_off }, 221 { MSCP_MKDRIVE2('R', 'D', 52), rd52_off }, 222 { MSCP_MKDRIVE2('R', 'D', 53), rd53_off }, 223 { MSCP_MKDRIVE2('R', 'X', 50), rx50_off }, 224 0 225 }; 226 227 ramaptype(io, lp) 228 register struct iob *io; 229 register struct disklabel *lp; 230 { 231 register struct partition *pp; 232 register u_long i; 233 register struct mediamap *map; 234 235 i = MSCP_MEDIA_DRIVE(ramedia[io->i_adapt][io->i_ctlr][io->i_unit]); 236 for (map = ra_map; map->id != 0; map++) { 237 if (map->id == i) { 238 lp->d_npartitions = 8; 239 for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 240 pp->p_offset = map->off[i]; 241 return; 242 } 243 } 244 printf("ra%d: media type 0x%x unsupported\n", io->i_unit, i); 245 lp->d_npartitions = 0; 246 } 247 #endif 248