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.8 (Berkeley) 03/22/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 #define MAXCTLR 1 /* all addresses must be specified */ 36 u_short udastd[MAXCTLR] = { 0772150 }; 37 38 struct udadevice *udaddr[MAXNUBA][MAXCTLR]; 39 40 struct uda1 { 41 struct uda1ca uda1_ca; /* communications area */ 42 struct mscp uda1_rsp; /* response packet */ 43 struct mscp uda1_cmd; /* command packet */ 44 } uda1; 45 46 /* Unibus address of uda structure */ 47 struct uda1 *ud_ubaddr[MAXNUBA][MAXCTLR]; 48 struct disklabel ralabel[MAXNUBA][MAXCTLR][NRA]; 49 static u_int ratype[MAXNUBA][MAXCTLR][NRA]; 50 char lbuf[SECTSIZ]; 51 52 raopen(io) 53 register struct iob *io; 54 { 55 register struct disklabel *lp, *dlp; 56 register struct udadevice *addr; 57 register struct uda1 *ubaddr; 58 register int uba, unit; 59 static int udainit[MAXNUBA][MAXCTLR]; 60 struct iob tio; 61 62 if ((u_int)io->i_ctlr >= MAXCTLR) 63 return (ECTLR); 64 unit = io->i_unit; 65 uba = io->i_adapt; 66 addr = udaddr[uba][io->i_ctlr] = 67 (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]); 68 if (badaddr((char *)addr, sizeof(short))) 69 return (ENXIO); 70 if (ud_ubaddr[uba][io->i_ctlr] == 0) { 71 tio = *io; 72 tio.i_ma = (caddr_t)&uda1; 73 tio.i_cc = sizeof(uda1); 74 ud_ubaddr[uba][io->i_ctlr] = (struct uda1 *)ubasetup(&tio, 2); 75 } 76 ubaddr = ud_ubaddr[uba][io->i_ctlr]; 77 if (udainit[uba][io->i_ctlr] == 0) { 78 addr->udaip = 0; 79 while ((addr->udasa & UDA_STEP1) == 0); 80 addr->udasa = UDA_ERR; 81 while ((addr->udasa & UDA_STEP2) == 0); 82 addr->udasa = (short)&ubaddr->uda1_ca.ca_rspdsc; 83 while ((addr->udasa & UDA_STEP3) == 0); 84 addr->udasa = 85 (short)(((int)&ubaddr->uda1_ca.ca_rspdsc) >> 16); 86 while ((addr->udasa & UDA_STEP4) == 0); 87 addr->udasa = UDA_GO; 88 uda1.uda1_ca.ca_rspdsc = (long)&ubaddr->uda1_rsp.mscp_cmdref; 89 uda1.uda1_ca.ca_cmddsc = (long)&ubaddr->uda1_cmd.mscp_cmdref; 90 /* uda1.uda1_cmd.mscp_cntflgs = 0; */ 91 if (udcmd(M_OP_SETCTLRC, io)) { 92 printf("ra: open error, SETCTLRC\n"); 93 return (ENXIO); 94 } 95 udainit[uba][io->i_ctlr] = 1; 96 } 97 lp = &ralabel[uba][io->i_ctlr][unit]; 98 if (ratype[uba][io->i_ctlr][unit] == 0) { 99 uda1.uda1_cmd.mscp_unit = unit; 100 if (udcmd(M_OP_ONLINE, io)) { 101 printf("ra: open error, ONLINE\n"); 102 return (ENXIO); 103 } 104 ratype[uba][io->i_ctlr][unit] = 105 uda1.uda1_rsp.mscp_onle.onle_drivetype; 106 tio = *io; 107 tio.i_bn = LABELSECTOR; 108 tio.i_ma = lbuf; 109 tio.i_cc = SECTSIZ; 110 tio.i_flgs |= F_RDDATA; 111 if (rastrategy(&tio, READ) != SECTSIZ) 112 return (ERDLAB); 113 *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 114 if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) 115 #ifdef COMPAT_42 116 { 117 printf("ra%d: unlabeled\n", unit); 118 ramaptype(io, lp); 119 } 120 #else 121 return (EUNLAB); 122 #endif 123 } 124 if ((u_int)io->i_part >= lp->d_npartitions || 125 (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 126 return (EPART); 127 return (0); 128 } 129 130 int 131 udcmd(op, io) 132 int op; 133 register struct iob *io; 134 { 135 register struct uda1 *u = &uda1; 136 register struct mscp *mp; 137 register int i; 138 139 u->uda1_cmd.mscp_opcode = op; 140 u->uda1_cmd.mscp_msglen = MSCP_MSGLEN; 141 u->uda1_rsp.mscp_msglen = MSCP_MSGLEN; 142 u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; 143 u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; 144 i = udaddr[io->i_adapt][io->i_ctlr]->udaip; /* start uda polling */ 145 mp = &u->uda1_rsp; 146 for (;;) { 147 if (u->uda1_ca.ca_cmdint) 148 u->uda1_ca.ca_cmdint = 0; 149 if (u->uda1_ca.ca_rspint == 0) 150 continue; 151 u->uda1_ca.ca_rspint = 0; 152 if (mp->mscp_opcode == (op | M_OP_END)) 153 break; 154 printf("unexpected rsp type %x op %x ignored\n", 155 MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 156 u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 157 } 158 if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS) 159 return (-1); 160 return (0); 161 } 162 163 rastrategy(io, func) 164 register struct iob *io; 165 { 166 register struct mscp *mp; 167 int ubinfo; 168 169 ubinfo = ubasetup(io, 1); 170 mp = &uda1.uda1_cmd; 171 mp->mscp_unit = io->i_unit; 172 mp->mscp_seq.seq_lbn = io->i_bn; 173 mp->mscp_seq.seq_bytecount = io->i_cc; 174 mp->mscp_seq.seq_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 175 if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) { 176 printf("ra: I/O error\n"); 177 ubafree(io, ubinfo); 178 return(-1); 179 } 180 ubafree(io, ubinfo); 181 return(io->i_cc); 182 } 183 184 #ifdef COMPAT_42 185 u_long ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 186 u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 187 u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 }; 188 u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 }; 189 u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 190 u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 191 #ifndef UCBRA 192 #ifdef RA_COMPAT 193 u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 }; 194 #else 195 u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 }; 196 #endif 197 #else 198 u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 }; 199 #endif 200 201 u_long *ra_off[] = { 202 0, /* 0 = unused */ 203 ra80_off, /* 1 = ra80 */ 204 ra25_off, /* 2 = rc25 removable */ 205 ra25_off, /* 3 = rc25 fixed */ 206 ra60_off, /* 4 = ra60 */ 207 ra81_off, /* 5 = ra81 */ 208 0, /* 6 = ? */ 209 rx50_off, /* 7 = rx50 */ 210 rd52_off, /* 8 = rd52 */ 211 rd53_off, /* 9 = rd53 */ 212 }; 213 214 #define NOFFS (sizeof(ra_off)/sizeof(ra_off[0])) 215 216 ramaptype(io, lp) 217 register struct iob *io; 218 register struct disklabel *lp; 219 { 220 register struct partition *pp; 221 register u_long *off; 222 register u_int i; 223 224 if ((i = ratype[io->i_adapt][io->i_ctlr][io->i_unit]) >= NOFFS || 225 (off = ra_off[i]) == 0) { 226 printf("ra%d: ra type %d unsupported\n", io->i_unit, i); 227 lp->d_npartitions = 0; 228 return; 229 } 230 lp->d_npartitions = 8; 231 for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 232 pp->p_offset = *off++; 233 } 234 #endif 235