1 /* vd.c 7.3 86/07/16 */ 2 3 /* 4 * Stand alone driver for the VDDC controller 5 * TAHOE Version, Oct 1983. 6 */ 7 #include "../machine/mtpr.h" 8 9 #include "param.h" 10 #include "inode.h" 11 #include "fs.h" 12 #define VDGENDATA 1 13 #include "../tahoevba/vdreg.h" 14 #undef VDGENDATA 15 #include "../tahoevba/vbaparam.h" 16 #include "saio.h" 17 18 #define NVD 4 /* Max number of controllers */ 19 #define VDUNIT(x) (minor(x) & 0x3) 20 #define VDCTLR(x) (minor(x) >> 2) 21 22 fmt_mdcb mdcb; 23 fmt_dcb dcb; 24 25 /* 26 * Drive specific information. 27 */ 28 struct dkinfo { 29 char configured; 30 fs_tab info; 31 } dkinfo[NVD][16]; 32 33 /* 34 * Controller specific information. 35 */ 36 struct vdinfo { 37 u_short vd_flags; 38 #define VDF_INIT 0x1 /* controller initialized */ 39 #define VDF_BUSY 0x2 /* controller running */ 40 u_short vd_type; /* smd or smde */ 41 char *vd_name; 42 } vdinfo[NVD]; 43 44 static char junk[1024]; 45 46 #define VDADDR(ctlr) ((cdr *)(vddcaddr[(ctlr)]+VBIOBASE)) 47 48 vdopen(io) 49 register struct iob *io; 50 { 51 register int ctlr = VDCTLR(io->i_unit), unit = VDUNIT(io->i_unit); 52 struct vdinfo *vd; 53 register int i, j; 54 55 /* Make sure controller number is in range */ 56 if (ctlr >= NVD) { 57 printf( 58 "dk%d: invalid controller (only configured for %d vd's)\n", 59 io->i_unit, NVD); 60 _stop(""); 61 } 62 /* check file system for validity */ 63 if ((unsigned)io->i_boff > 5) { 64 printf("dk%d: invalid partition number (%d)\n", 65 io->i_unit, io->i_boff); 66 _stop(""); 67 } 68 vd = &vdinfo[ctlr]; 69 if ((vd->vd_flags&VDF_INIT) == 0) { 70 vdinit(io); /* initialize controller/drive */ 71 vd->vd_flags |= VDF_INIT; 72 for (j = 0; j < 16; j++) 73 dkinfo[ctlr][j].configured = 0; 74 } 75 if (!dkinfo[ctlr][unit].configured) { 76 vdconfigure_drive(io); 77 dkinfo[ctlr][unit].configured = 1; 78 } 79 io->i_boff = dkinfo[ctlr][unit].info.partition[io->i_boff].par_start; 80 } 81 82 vdinit(io) 83 register struct iob *io; 84 { 85 register int ctlr = VDCTLR(io->i_unit), unit = VDUNIT(io->i_unit); 86 register cdr *ctlr_addr = VDADDR(ctlr); 87 register struct vdinfo *vd = &vdinfo[ctlr]; 88 89 /* Check to see if controller is really there */ 90 if (badaddr(ctlr_addr, 2)) { 91 printf("dk%d: vd%d csr doesn't respond\n", io->i_unit, ctlr); 92 _stop(""); 93 } 94 /* Probe further to find what kind of controller it is */ 95 ctlr_addr->cdr_reset = 0xffffffff; 96 DELAY(1000000); 97 if (ctlr_addr->cdr_reset != 0xffffffff) { 98 vd->vd_type = SMDCTLR; 99 vd->vd_name = "smd"; 100 DELAY(1000000); 101 } else { 102 vd->vd_type = SMD_ECTLR; 103 vd->vd_name = "smde"; 104 ctlr_addr->cdr_reserved = 0x0; 105 DELAY(3000000); 106 } 107 if (vd->vd_type == SMD_ECTLR) { 108 ctlr_addr->cdr_csr = 0; 109 ctlr_addr->mdcb_tcf = AM_ENPDA; 110 ctlr_addr->dcb_tcf = AM_ENPDA; 111 ctlr_addr->trail_tcf = AM_ENPDA; 112 ctlr_addr->data_tcf = AM_ENPDA; 113 ctlr_addr->cdr_ccf = CCF_STS | XMD_32BIT | BSZ_16WRD | 114 CCF_ENP | CCF_EPE /* | CCF_EDE */ | CCF_ECE | CCF_ERR; 115 } 116 if (vdaccess_with_no_trailer(io, INIT, 8) & HRDERR) { 117 vdprint_error(io->i_unit, "init error", 118 dcb.operrsta,dcb.err_code); 119 _stop(""); 120 } 121 if (vdaccess_with_no_trailer(io, DIAG, 8) & HRDERR) { 122 vdprint_error(io->i_unit, "diagnostic error", 123 dcb.operrsta, dcb.err_code); 124 _stop(""); 125 } 126 } 127 128 vdconfigure_drive(io) 129 register struct iob *io; 130 { 131 register int ctlr = VDCTLR(io->i_unit), unit = VDUNIT(io->i_unit); 132 register fs_tab *file_sys; 133 register struct dkinfo *dk = &dkinfo[ctlr][unit]; 134 dskadr daddr; 135 register int i; 136 137 for (i = 0; i < nvddrv; i++) { 138 dk->info = vdst[i]; 139 if (vdinfo[ctlr].vd_type == SMDCTLR) 140 if (dk->info.nsec != 32) 141 continue; 142 vdconfigure(io, 0); 143 daddr.cylinder = dk->info.ncyl - 2; 144 daddr.track = dk->info.ntrak - 1; 145 daddr.sector = dk->info.nsec - 1; 146 io->i_ma = junk; 147 io->i_cc = dk->info.secsize; 148 if ((vdaccess(io, &daddr, RD) & HRDERR) == 0) 149 return; 150 } 151 printf("dk%d: unknown drive type\n", io->i_unit); 152 _stop(""); 153 } 154 155 vdstart_drive(io) 156 register struct iob *io; 157 { 158 register int ctlr = VDCTLR(io->i_unit), unit = VDUNIT(io->i_unit); 159 int ounit = io->i_unit; 160 161 if (vdinfo[ctlr].vd_flags&VDF_BUSY) { 162 DELAY(5500000); 163 return; 164 } 165 io->i_unit &= ~3; 166 if (vdaccess_with_no_trailer(io, VDSTART, ((unit * 6) + 62)) & HRDERR) { 167 vdprint_error(io->i_unit, "start error", 168 dcb.operrsta, dcb.err_code); 169 _stop(""); 170 } 171 vdinfo[ctlr].vd_flags |= VDF_BUSY; 172 io->i_unit = ounit; 173 DELAY((unit * 5500000) + 62000000); 174 } 175 176 /* 177 * This routine actually configures a particular drive. 178 * 179 * If the controller is an SMD/E controller then the number of sectors per 180 * track is loaded into the appropriate register, otherwise it is left 181 * alone because the old SMD controller requires a constant 32 sectors 182 * per track for it's drives. (an error would be returned if the value is 183 * loaded.) 184 */ 185 vdconfigure(io, pass) 186 register struct iob *io; 187 int pass; 188 { 189 register int ctlr = VDCTLR(io->i_unit), unit = VDUNIT(io->i_unit); 190 register cdr *ctlr_addr = VDADDR(ctlr); 191 192 dcb.opcode = RSTCFG; /* command */ 193 dcb.intflg = NOINT; 194 dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */ 195 dcb.operrsta = 0; 196 dcb.devselect = (char)unit; 197 dcb.trail.rstrail.ncyl = dkinfo[ctlr][unit].info.ncyl; 198 dcb.trail.rstrail.nsurfaces = dkinfo[ctlr][unit].info.ntrak; 199 if (vdinfo[ctlr].vd_type == SMD_ECTLR) { 200 dcb.trailcnt = (char)4; 201 dcb.trail.rstrail.nsectors = dkinfo[ctlr][unit].info.nsec; 202 dcb.trail.rstrail.slip_sec = dkinfo[ctlr][unit].info.nslip; 203 } else 204 dcb.trailcnt = (char)2; 205 mdcb.firstdcb = &dcb; 206 mdcb.vddcstat = 0; 207 VDDC_ATTENTION(ctlr_addr, &mdcb, vdinfo[ctlr].vd_type); 208 if (!vdpoll(ctlr_addr,&dcb,10,vdinfo[ctlr].vd_type)) 209 _stop(" during drive configuration.\n"); 210 if ((dcb.operrsta & (NOTCYLERR | DRVNRDY)) && !pass) { 211 vdstart_drive(io); 212 vdconfigure(io, 1); 213 } 214 if (dcb.operrsta & HRDERR) { 215 vdprint_error(io->i_unit, "configuration error", 216 dcb.operrsta, dcb.err_code); 217 _stop(""); 218 } 219 } 220 221 /* 222 * Strategy is called to do the actual I/O to the disk drives. 223 * 224 * Some simple checks are made to make sure we don't do anything rediculus, 225 * If everything is sane then the request is issued. 226 * 227 * If no errors occured then the original byte count is returned, 228 * otherwise -1 is returned to indicate an error occured. 229 */ 230 vdstrategy(io, func) 231 register struct iob *io; 232 register int func; 233 { 234 dskadr daddr; 235 register int ctlr = VDCTLR(io->i_unit), unit = VDUNIT(io->i_unit); 236 register fs_tab *u_info = &dkinfo[ctlr][unit].info; 237 register int op = (func == READ) ? RD : WD; 238 register int blk; 239 240 if (io->i_cc == 0 || io->i_cc > 65535) { 241 printf("dk%d: invalid transfer size %d\n", io->i_unit, 242 io->i_cc); 243 _stop(""); 244 } 245 blk = io->i_bn * DEV_BSIZE / u_info->secsize; 246 daddr.sector = blk % u_info->nsec; 247 daddr.track = (blk / u_info->nsec) % u_info->ntrak; 248 daddr.cylinder = (blk/u_info->nsec) / u_info->ntrak; 249 if (vdaccess(io, &daddr, op) & HRDERR) { 250 vdprint_error(io->i_unit, "i/o error", dcb.operrsta, 251 dcb.err_code); 252 return (-1); 253 } 254 mtpr(PADC, 0); 255 return (io->i_cc); 256 } 257 258 struct vdstatus { 259 int bit; 260 char *meaning; 261 } vdstatus[] = { 262 { DRVNRDY, "drive not ready" }, 263 { INVDADR, "invalid disk address" }, 264 { DNEMEM, "non-existent memory" }, 265 { PARERR, "parity error" }, 266 { OPABRT, "operation aborted" }, 267 { WPTERR, "drive write protect" }, 268 { DSEEKERR, "seek error" }, 269 { UCDATERR, "uncorrectable data error" }, 270 { CTLRERR, "controller error" }, 271 { NOTCYLERR, "not on cylinder" }, 272 { INVCMD, "invalid controller command" }, 273 { -1, "controller error" } 274 }; 275 #define NVDSTATUS (sizeof (vdstatus) / sizeof (vdstatus[0])) 276 277 vdprint_error(unit, str, status, smde_status) 278 int unit; 279 char *str; 280 u_long status; 281 u_long smde_status; 282 { 283 register struct vdstatus *sp; 284 285 printf("dk%d: %s; ", unit, str); 286 for (sp = vdstatus; sp < &vdstatus[NVDSTATUS]; sp++) 287 if (status & sp->bit) { 288 printf("%s. status %x", sp->meaning, status); 289 break; 290 } 291 if (smde_status) 292 printf(", code %x", smde_status); 293 printf("\n"); 294 } 295 296 vdaccess_with_no_trailer(io, function, time) 297 register struct iob *io; 298 register int function, time; 299 { 300 register int ctlr = VDCTLR(io->i_unit); 301 register cdr *ctlr_addr = VDADDR(ctlr); 302 303 dcb.opcode = function; /* command */ 304 dcb.intflg = NOINT; 305 dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */ 306 dcb.operrsta = 0; 307 dcb.devselect = (char)VDUNIT(io->i_unit); 308 dcb.trailcnt = (char)0; 309 mdcb.firstdcb = &dcb; 310 mdcb.vddcstat = 0; 311 VDDC_ATTENTION(ctlr_addr, &mdcb, vdinfo[ctlr].vd_type); 312 if (!vdpoll(ctlr_addr, &dcb, time, vdinfo[ctlr].vd_type)) 313 _stop(" during initialization operation.\n"); 314 return dcb.operrsta; 315 } 316 317 vdaccess(io, daddr, func) 318 register struct iob *io; 319 dskadr *daddr; 320 int func; 321 { 322 register int ctlr = VDCTLR(io->i_unit); 323 register cdr *ctlr_addr = VDADDR(ctlr); 324 325 dcb.opcode = (short)func; /* format sector command */ 326 dcb.intflg = NOINT; 327 dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */ 328 dcb.operrsta = 0; 329 dcb.devselect = (char)VDUNIT(io->i_unit); 330 dcb.trailcnt = (char)(sizeof(trrw) / 4); 331 dcb.trail.rwtrail.memadr = io->i_ma; 332 dcb.trail.rwtrail.wcount = ((io->i_cc + 1) / sizeof(short)); 333 dcb.trail.rwtrail.disk.cylinder = daddr->cylinder; 334 dcb.trail.rwtrail.disk.track = daddr->track; 335 dcb.trail.rwtrail.disk.sector = daddr->sector; 336 mdcb.firstdcb = &dcb; 337 mdcb.vddcstat = 0; 338 VDDC_ATTENTION(ctlr_addr, &mdcb, vdinfo[ctlr].vd_type); 339 if (!vdpoll(ctlr_addr, &dcb, 60, vdinfo[ctlr].vd_type)) 340 _stop(" during i/o operation.\n"); 341 return (dcb.operrsta); 342 } 343 344 /* 345 * Dump the MDCB and DCB for diagnostic purposes. This 346 * routine is called whenever a fatal error is encountered. 347 */ 348 vdprintdcb(ptr) 349 register long *ptr; 350 { 351 register long i, trailer_count; 352 353 printf("mdcb: %lx %lx %lx %lx\n", ptr[0], ptr[1], ptr[2], ptr[3]); 354 if (ptr = (long *)*ptr) { 355 printf("dcb:"); 356 trailer_count = ptr[3] & 0xff; 357 for (i=0; i<7+trailer_count; i++) { 358 uncache(&ptr[i]); 359 printf(" %lx", ptr[i]); 360 } 361 } 362 printf("\n"); 363 DELAY(5000000); 364 } 365 366 /* 367 * Poll controller until operation completes 368 * or timeout expires. 369 */ 370 vdpoll(addr, dcb, t, type) 371 register cdr *addr; 372 register fmt_dcb *dcb; 373 register int t, type; 374 { 375 376 t *= 1000; 377 uncache(&dcb->operrsta); 378 while ((dcb->operrsta&(DCBCMP|DCBABT)) == 0) { 379 DELAY(1000); 380 uncache(&dcb->operrsta); 381 if (--t <= 0) { 382 printf("vd: controller timeout"); 383 VDDC_ABORT(addr, type); 384 DELAY(30000); 385 uncache(&dcb->operrsta); 386 return (0); 387 } 388 } 389 if (type == SMD_ECTLR) { 390 uncache(&addr->cdr_csr); 391 while (addr->cdr_csr&CS_GO) { 392 DELAY(50); 393 uncache(&addr->cdr_csr); 394 } 395 DELAY(300); 396 } 397 DELAY(200); 398 uncache(&dcb->operrsta); 399 return (1); 400 } 401