1 /* vd.c 7.4 86/11/04 */ 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 > 8) { 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(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)5; 201 dcb.trail.rstrail.nsectors = dkinfo[ctlr][unit].info.nsec; 202 dcb.trail.rstrail.slip_sec = dkinfo[ctlr][unit].info.nslip; 203 dcb.trail.rstrail.recovery = 0x18f; 204 } else 205 dcb.trailcnt = (char)2; 206 mdcb.firstdcb = &dcb; 207 mdcb.vddcstat = 0; 208 VDDC_ATTENTION(ctlr_addr, &mdcb, vdinfo[ctlr].vd_type); 209 if (!vdpoll(ctlr_addr,&dcb,10,vdinfo[ctlr].vd_type)) { 210 if (pass == 0) { 211 VDDC_RESET(ctlr_addr, vdinfo[ctlr].vd_type); 212 vdconfigure(io, 1); 213 } else 214 _stop(" during drive configuration.\n"); 215 } 216 if ((dcb.operrsta & (NOTCYLERR | DRVNRDY)) && !pass) { 217 vdstart_drive(io); 218 vdconfigure(io, 1); 219 } 220 if (dcb.operrsta & HRDERR) { 221 vdprint_error(io->i_unit, "configuration error", 222 dcb.operrsta, dcb.err_code); 223 _stop(""); 224 } 225 } 226 227 /* 228 * Strategy is called to do the actual I/O to the disk drives. 229 * 230 * Some simple checks are made to make sure we don't do anything rediculous, 231 * If everything is sane then the request is issued. 232 * 233 * If no errors occured then the original byte count is returned, 234 * otherwise -1 is returned to indicate an error occured. 235 */ 236 vdstrategy(io, func) 237 register struct iob *io; 238 register int func; 239 { 240 dskadr daddr; 241 register int ctlr = VDCTLR(io->i_unit), unit = VDUNIT(io->i_unit); 242 register fs_tab *u_info = &dkinfo[ctlr][unit].info; 243 register int op = (func == READ) ? RD : WD; 244 register int blk; 245 246 if (io->i_cc == 0 || io->i_cc > 65535) { 247 printf("dk%d: invalid transfer size %d\n", io->i_unit, 248 io->i_cc); 249 _stop(""); 250 } 251 blk = io->i_bn * DEV_BSIZE / u_info->secsize; 252 daddr.sector = blk % u_info->nsec; 253 daddr.track = (blk / u_info->nsec) % u_info->ntrak; 254 daddr.cylinder = (blk/u_info->nsec) / u_info->ntrak; 255 if (vdaccess(io, &daddr, op) & HRDERR) { 256 vdprint_error(io->i_unit, "i/o error", dcb.operrsta, 257 dcb.err_code); 258 return (-1); 259 } 260 mtpr(PADC, 0); 261 return (io->i_cc); 262 } 263 264 struct vdstatus { 265 int bit; 266 char *meaning; 267 } vdstatus[] = { 268 { DRVNRDY, "drive not ready" }, 269 { INVDADR, "invalid disk address" }, 270 { DNEMEM, "non-existent memory" }, 271 { PARERR, "parity error" }, 272 { OPABRT, "operation aborted" }, 273 { WPTERR, "drive write protect" }, 274 { DSEEKERR, "seek error" }, 275 { UCDATERR, "uncorrectable data error" }, 276 { CTLRERR, "controller error" }, 277 { NOTCYLERR, "not on cylinder" }, 278 { INVCMD, "invalid controller command" }, 279 { -1, "controller error" } 280 }; 281 #define NVDSTATUS (sizeof (vdstatus) / sizeof (vdstatus[0])) 282 283 vdprint_error(unit, str, status, smde_status) 284 int unit; 285 char *str; 286 u_long status; 287 u_long smde_status; 288 { 289 register struct vdstatus *sp; 290 291 printf("dk%d: %s; ", unit, str); 292 for (sp = vdstatus; sp < &vdstatus[NVDSTATUS]; sp++) 293 if (status & sp->bit) { 294 printf("%s. status %x", sp->meaning, status); 295 break; 296 } 297 if (smde_status) 298 printf(", code %x", smde_status); 299 printf("\n"); 300 } 301 302 vdaccess_with_no_trailer(io, function, time) 303 register struct iob *io; 304 register int function, time; 305 { 306 register int ctlr = VDCTLR(io->i_unit); 307 register cdr *ctlr_addr = VDADDR(ctlr); 308 309 dcb.opcode = function; /* command */ 310 dcb.intflg = NOINT; 311 dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */ 312 dcb.operrsta = 0; 313 dcb.devselect = (char)VDUNIT(io->i_unit); 314 dcb.trailcnt = (char)0; 315 mdcb.firstdcb = &dcb; 316 mdcb.vddcstat = 0; 317 VDDC_ATTENTION(ctlr_addr, &mdcb, vdinfo[ctlr].vd_type); 318 if (!vdpoll(ctlr_addr, &dcb, time, vdinfo[ctlr].vd_type)) 319 _stop(" during initialization operation.\n"); 320 return dcb.operrsta; 321 } 322 323 vdaccess(io, daddr, func) 324 register struct iob *io; 325 dskadr *daddr; 326 int func; 327 { 328 register int ctlr = VDCTLR(io->i_unit); 329 register cdr *ctlr_addr = VDADDR(ctlr); 330 331 dcb.opcode = (short)func; /* format sector command */ 332 dcb.intflg = NOINT; 333 dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */ 334 dcb.operrsta = 0; 335 dcb.devselect = (char)VDUNIT(io->i_unit); 336 dcb.trailcnt = (char)(sizeof(trrw) / 4); 337 dcb.trail.rwtrail.memadr = io->i_ma; 338 dcb.trail.rwtrail.wcount = ((io->i_cc + 1) / sizeof(short)); 339 dcb.trail.rwtrail.disk.cylinder = daddr->cylinder; 340 dcb.trail.rwtrail.disk.track = daddr->track; 341 dcb.trail.rwtrail.disk.sector = daddr->sector; 342 mdcb.firstdcb = &dcb; 343 mdcb.vddcstat = 0; 344 VDDC_ATTENTION(ctlr_addr, &mdcb, vdinfo[ctlr].vd_type); 345 if (!vdpoll(ctlr_addr, &dcb, 60, vdinfo[ctlr].vd_type)) 346 _stop(" during i/o operation.\n"); 347 return (dcb.operrsta); 348 } 349 350 /* 351 * Dump the MDCB and DCB for diagnostic purposes. This 352 * routine is called whenever a fatal error is encountered. 353 */ 354 vdprintdcb(ptr) 355 register long *ptr; 356 { 357 register long i, trailer_count; 358 359 printf("mdcb: %lx %lx %lx %lx\n", ptr[0], ptr[1], ptr[2], ptr[3]); 360 if (ptr = (long *)*ptr) { 361 printf("dcb:"); 362 trailer_count = ptr[3] & 0xff; 363 for (i=0; i<7+trailer_count; i++) { 364 uncache(&ptr[i]); 365 printf(" %lx", ptr[i]); 366 } 367 } 368 printf("\n"); 369 DELAY(5000000); 370 } 371 372 /* 373 * Poll controller until operation completes 374 * or timeout expires. 375 */ 376 vdpoll(addr, dcb, t, type) 377 register cdr *addr; 378 register fmt_dcb *dcb; 379 register int t, type; 380 { 381 382 t *= 1000; 383 uncache(&dcb->operrsta); 384 while ((dcb->operrsta&(DCBCMP|DCBABT)) == 0) { 385 DELAY(1000); 386 uncache(&dcb->operrsta); 387 if (--t <= 0) { 388 printf("vd: controller timeout"); 389 VDDC_ABORT(addr, type); 390 DELAY(30000); 391 uncache(&dcb->operrsta); 392 return (0); 393 } 394 } 395 if (type == SMD_ECTLR) { 396 uncache(&addr->cdr_csr); 397 while (addr->cdr_csr&CS_GO) { 398 DELAY(50); 399 uncache(&addr->cdr_csr); 400 } 401 DELAY(300); 402 uncache(&dcb->err_code); 403 } 404 DELAY(200); 405 uncache(&dcb->operrsta); 406 return (1); 407 } 408