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