|
|
1.1 ! root 1: /* ! 2: * DSA disk class driver ! 3: * drives RA-class disks ! 4: * hooked up through an MSCP port ! 5: */ ! 6: ! 7: #include "sys/param.h" ! 8: #include "sys/buf.h" ! 9: #include "sys/udaioc.h" ! 10: #include "sys/diskio.h" ! 11: #include "sys/ra.h" ! 12: #include "sys/mscp.h" ! 13: #include "sys/user.h" ! 14: #include "sys/file.h" ! 15: #include "sys/conf.h" ! 16: ! 17: extern struct msaddr raaddr[]; ! 18: extern struct radisk radisk[]; ! 19: extern int racnt; ! 20: static long rarefno; /* ref seq num */ ! 21: extern struct buf rabuf[]; ! 22: static struct buf rctbuf; /* for reading replacement table */ ! 23: ! 24: static rareplace(), raonline(), rasonl(), racinit(); ! 25: ! 26: int raopen(), raread(), rawrite(), raioctl(), rastrategy(), raclose(); ! 27: struct bdevsw rabdev = bdinit(raopen, raclose, rastrategy, 0); ! 28: struct cdevsw racdev = cdinit(raopen, raclose, raread, rawrite, raioctl); ! 29: ! 30: /* ! 31: * UNIT(d) == logical unit number; ! 32: * the physical unit number is in raaddr[UNIT(d)].unit ! 33: * ! 34: * 0100 in the minor device is (temporarily?) ! 35: * usurped to indicate bitmapped file systems ! 36: * quietly ignore it for now ! 37: * when things improve, change the UNIT mask to 037 ! 38: */ ! 39: #define UNIT(dev) (((dev)>>3) & 027) ! 40: #define PART(dev) ((dev)&07) ! 41: #define HUGE 0x7fffffff /* very large 32-bit number */ ! 42: ! 43: /* ! 44: * default partition sizes ! 45: */ ! 46: static struct size { ! 47: daddr_t nblocks; ! 48: daddr_t blkoff; ! 49: ! 50: } ra_sizes[NRAPART] = { ! 51: 11*960, 0*960, /* 0 = cyl 0 thru 10 ! 52: 21*960, 11*960, /* 1 = cyl 11 thru 31 ! 53: 242*960 32*960, /* 2 = cyl 32 thru 273 ! 54: 242*960 274*960, /* 3 = cyl 274 thru 515 ! 55: 242*960 516*960, /* 4 = cyl 516 thru 757 ! 56: 84*960 758*960, /* 5 = cyl 758 thru 841 ! 57: 842*960 0*960, /* 6 = all cyl 0 thru 841 ! 58: }; ! 59: ! 60: /* ! 61: *} ra_sizes[NRAPART] = { ! 62: * 11*960, 0*960, /* A = cyl 0 thru 10 for / */ ! 63: * 22*960, 11*960, /* B = cyl 11 thru 32 for swap */ ! 64: * 842*960, 0*960, /* C = all cyl 0 thru 841 for testing */ ! 65: * 16*960, 33*960, /* D = cyl 33 thru 48 for /usr/guest */ ! 66: * 66*960, 49*960, /* E = cyl 49 thru 114 for /usr/src */ ! 67: * 242*960,115*960, /* F = cyl 115 thru 356 nearly 1/3 */ ! 68: * 242*960,357*960, /* G = cyl 357 thru 598 nearly 1/3 */ ! 69: * 242*960,599*960, /* H = cyl 599 thru 840 nearly 1/3 */ ! 70: *}; ! 71: */ ! 72: ! 73: /* ! 74: * reused bits of buf/iobuf struct ! 75: */ ! 76: ! 77: #define b_next av_forw /* next buffer in queue */ ! 78: #define b_pkt av_back /* pointer to mscp command */ ! 79: #define b_crf b_resid /* saved refno for pending command */ ! 80: ! 81: /* ! 82: * flags in radisk.flags ! 83: */ ! 84: ! 85: #define ONLINE 01 /* drive is online */ ! 86: #define WONLINE 02 /* waiting for online */ ! 87: #define GOTDI 04 /* got unit info */ ! 88: #define RPLOCK 010 /* replacement in progress */ ! 89: #define RPWANT 020 /* want RPLOCK */ ! 90: #define RPDONE 040 /* replacement done */ ! 91: #define SPDOWN 0100 /* spin down on last close */ ! 92: ! 93: /* ! 94: * random numbers ! 95: */ ! 96: ! 97: #define PRIONL (PZERO-1) ! 98: #define SECTOR 512 /* size of an MSCP sector */ ! 99: #define IDRA 0 /* connection ID for MSCP */ ! 100: ! 101: /* ! 102: * open a drive, if necessary ! 103: */ ! 104: ! 105: int raseql(), radg(); ! 106: ! 107: raopen(dev, flag) ! 108: dev_t dev; ! 109: { ! 110: register int unit; ! 111: register struct radisk *ra; ! 112: register struct msaddr *rp; ! 113: register int part; ! 114: ! 115: unit = UNIT(dev); ! 116: if (unit >= racnt) { ! 117: u.u_error = ENXIO; ! 118: return; ! 119: } ! 120: ra = &radisk[unit]; ! 121: rp = &raaddr[unit]; ! 122: if (ra->open == 0) { ! 123: if (rp->ctype < 0 || rp->ctype >= nmsport ! 124: || (ra->port = msportsw[rp->ctype]) == NULL) { ! 125: u.u_error = ENXIO; ! 126: return; ! 127: } ! 128: ra->di.radsize = HUGE; ! 129: if ((*ra->port->mp_init)(rp->ctl, rp->ctype, 0, IDRA, raseql, radg) == 0) { ! 130: u.u_error = ENXIO; ! 131: return; ! 132: } ! 133: racinit(ra, rp); ! 134: } ! 135: part = PART(dev); ! 136: if ((ra->pinit & (1<<part)) == 0) { ! 137: ra->nblocks[part] = ra_sizes[part].nblocks; ! 138: ra->blkoff[part] = ra_sizes[part].blkoff; ! 139: ra->pinit |= (1<<part); ! 140: } ! 141: ra->open |= 1<<part; ! 142: spl6(); ! 143: if ((ra->flags & ONLINE) == 0) ! 144: raonline(ra, rp); ! 145: spl0(); ! 146: if ((ra->flags & ONLINE) == 0) ! 147: u.u_error = ENXIO; ! 148: } ! 149: ! 150: raclose(dev) ! 151: { ! 152: register struct radisk *ra; ! 153: register struct msaddr *rp; ! 154: register struct mscmd *mp; ! 155: ! 156: ra = &radisk[UNIT(dev)]; ! 157: rp = &raaddr[UNIT(dev)]; ! 158: ra->open &=~ (1<<PART(dev)); ! 159: if (ra->open || (ra->flags & ONLINE) == 0) ! 160: return; ! 161: mp = (*ra->port->mp_get)(rp->ctl); ! 162: mp->m_crf = ++rarefno; ! 163: mp->m_unit = rp->unit; ! 164: mp->m_opcd = OPAVL; /* put it offline */ ! 165: if ((ra->flags & SPDOWN) == 0) ! 166: mp->m_mod = 0; ! 167: else { ! 168: mp->m_mod = MDSPD; ! 169: ra->flags &=~ SPDOWN; ! 170: } ! 171: mp->m_unfl = 0; ! 172: mp->m_dvpm = 0; /* ? */ ! 173: ra->flags &=~ ONLINE; ! 174: (*ra->port->mp_send)(rp->ctl, IDRA, mp); ! 175: } ! 176: ! 177: int rastrategy(); ! 178: ! 179: raread(dev) ! 180: { ! 181: physio(rastrategy, &rabuf[UNIT(dev)], dev, B_READ, minphys); ! 182: } ! 183: ! 184: rawrite(dev) ! 185: { ! 186: physio(rastrategy, &rabuf[UNIT(dev)], dev, B_WRITE, minphys); ! 187: } ! 188: ! 189: /* ! 190: * strategy routine; ! 191: * used as strategy by all port drivers ! 192: * send the packet right away ! 193: */ ! 194: ! 195: rastrategy(bp) ! 196: register struct buf *bp; ! 197: { ! 198: register struct radisk *ra; ! 199: register struct mscmd *mp; ! 200: register int unit; ! 201: register int part; ! 202: register struct msaddr *rp; ! 203: int count; ! 204: daddr_t limit; ! 205: ! 206: unit = UNIT(minor(bp->b_dev)); ! 207: part = PART(minor(bp->b_dev)); ! 208: ra = &radisk[unit]; ! 209: rp = &raaddr[unit]; ! 210: limit = ra->di.radsize - ra->blkoff[part]; ! 211: if (limit > ra->nblocks[part]) ! 212: limit = ra->nblocks[part]; ! 213: if (bp->b_blkno >= limit && bp != &rctbuf) { ! 214: if (bp->b_blkno == ra->nblocks[part]) ! 215: bp->b_resid = bp->b_bcount; ! 216: else { ! 217: bp->b_error = ENOSPC; ! 218: bp->b_flags |= B_ERROR; ! 219: } ! 220: iodone(bp); ! 221: return; ! 222: } ! 223: count = bp->b_bcount; ! 224: if (count/SECTOR + bp->b_blkno > limit && bp != &rctbuf) ! 225: count = (limit - bp->b_blkno) * SECTOR; ! 226: spl6(); ! 227: if ((ra->flags & ONLINE) == 0 && raonline(ra, rp) == 0) { ! 228: bp->b_flags |= B_ERROR; ! 229: iodone(bp); ! 230: spl0(); ! 231: return; ! 232: } ! 233: mp = (*ra->port->mp_get)(rp->ctl); ! 234: mp->m_crf = ++rarefno; ! 235: mp->m_unit = rp->unit; ! 236: mp->m_opcd = (bp->b_flags & B_READ) ? OPRD : OPWR; ! 237: mp->m_mod = 0; ! 238: mp->m_bcnt = count; ! 239: mp->m_lbn = bp->b_blkno + ra->blkoff[part]; ! 240: (*ra->port->mp_map)(rp->ctl, mp, bp); ! 241: bp->b_pkt = (struct buf *)mp; ! 242: bp->b_crf = mp->m_crf; ! 243: bp->b_next = NULL; ! 244: if (ra->actf) ! 245: ra->actl->b_next = bp; ! 246: else ! 247: ra->actf = bp; ! 248: ra->actl = bp; ! 249: (*ra->port->mp_send)(rp->ctl, IDRA, mp); ! 250: spl0(); ! 251: } ! 252: ! 253: /* ! 254: * ioctl ! 255: * principally for bad block replacement ! 256: */ ! 257: ! 258: raioctl(dev, cmd, addr, flag) ! 259: dev_t dev; ! 260: caddr_t addr; ! 261: { ! 262: register union arg { ! 263: struct ud_rctbuf r; ! 264: struct ud_repl b; ! 265: } *uap; ! 266: register struct radisk *ra; ! 267: register int i; ! 268: long parts[2]; ! 269: ! 270: ra = &radisk[UNIT(dev)]; ! 271: if ((ra->flags & (ONLINE|GOTDI)) != (ONLINE|GOTDI)) { ! 272: /* should bring it online here */ ! 273: u.u_error = EIO; ! 274: return; ! 275: } ! 276: uap = (union arg *)addr; ! 277: switch(cmd) { ! 278: default: ! 279: u.u_error = ENOTTY; ! 280: return; ! 281: ! 282: case DIOSSIZ: ! 283: if ((flag & FWRITE) == 0) { ! 284: u.u_error = EBADF; ! 285: return; ! 286: } ! 287: if (copyin(addr, (caddr_t)parts, sizeof(parts)) < 0) { ! 288: u.u_error = EFAULT; ! 289: return; ! 290: } ! 291: ra->blkoff[PART(dev)] = parts[0]; ! 292: ra->nblocks[PART(dev)] = parts[1]; ! 293: return; ! 294: ! 295: case DIOGSIZ: ! 296: parts[0] = ra->blkoff[PART(dev)]; ! 297: parts[1] = ra->nblocks[PART(dev)]; ! 298: if (copyout((caddr_t)parts, addr, sizeof(parts)) < 0) ! 299: u.u_error = EFAULT; ! 300: return; ! 301: ! 302: case UIOCHAR: ! 303: if (copyout((caddr_t)&ra->di, addr, sizeof(struct ud_unit))) ! 304: u.u_error = EFAULT; ! 305: return; ! 306: ! 307: case UIORRCT: ! 308: if(uap->r.lbn < 0 || uap->r.lbn > ra->di.rctsize) { ! 309: u.u_error = EIO; ! 310: return; ! 311: } ! 312: /* ! 313: * try different copies until one works ! 314: */ ! 315: for (i = 0; i < ra->di.copies; i++) { ! 316: u.u_count = SECTOR; /* block size on disk */ ! 317: u.u_offset = ltoL((uap->r.lbn + ra->di.radsize) * SECTOR); ! 318: u.u_offset = Lladd(u.u_offset,i * ra->di.rctsize * SECTOR); ! 319: u.u_base = uap->r.buf; ! 320: u.u_segflg = SEGUDATA; ! 321: u.u_error = 0; ! 322: physio(rastrategy, &rctbuf, dev, B_READ, minphys); ! 323: if (u.u_error == 0) ! 324: break; ! 325: } ! 326: return; ! 327: ! 328: case UIOWRCT: ! 329: if ((flag & FWRITE) == 0) { ! 330: u.u_error = EBADF; ! 331: return; ! 332: } ! 333: if(uap->r.lbn < 0 || uap->r.lbn > ra->di.rctsize) { ! 334: u.u_error = EIO; ! 335: return; ! 336: } ! 337: /* ! 338: * write every copy we can ! 339: * should do read-after-write ! 340: */ ! 341: for (i = 0; i < ra->di.copies; i++) { ! 342: u.u_count = SECTOR; /* block size on disk */ ! 343: u.u_offset = ltoL((uap->r.lbn + ra->di.radsize) * SECTOR); ! 344: u.u_offset = Lladd(u.u_offset, i * ra->di.rctsize * SECTOR); ! 345: u.u_base = uap->r.buf; ! 346: u.u_segflg = SEGUDATA; ! 347: physio(rastrategy, &rctbuf, dev, B_WRITE, minphys); ! 348: u.u_error = 0; ! 349: } ! 350: return; ! 351: ! 352: case UIOREPL: ! 353: if ((flag & FWRITE) == 0) { ! 354: u.u_error = EBADF; ! 355: return; ! 356: } ! 357: rareplace(dev, uap->b.lbn, uap->b.replbn, uap->b.prim); ! 358: return; ! 359: ! 360: case UIOSPDW: ! 361: ra->flags |= SPDOWN; ! 362: return; ! 363: ! 364: case UIORST: ! 365: (*ra->port->mp_init)(raaddr[UNIT(dev)].ctl, raaddr[UNIT(dev)].ctype, 1, IDRA, raseql, radg); ! 366: return; ! 367: } ! 368: ! 369: } ! 370: ! 371: static ! 372: rareplace(dev, badlbn, replbn, prim) ! 373: int dev; ! 374: daddr_t badlbn; ! 375: daddr_t replbn; ! 376: int prim; ! 377: { ! 378: register struct mscmd *mp; ! 379: register struct radisk *ra; ! 380: register struct msaddr *rp; ! 381: register int unit; ! 382: ! 383: unit = UNIT(minor(dev)); ! 384: ra = &radisk[unit]; ! 385: rp = &raaddr[unit]; ! 386: spl6(); ! 387: while (ra->flags & RPLOCK) { ! 388: ra->flags |= RPWANT; ! 389: sleep((caddr_t)&ra->flags, PZERO + 1); ! 390: } ! 391: ra->flags |= RPLOCK; ! 392: printf("ra%d replace %D with %D\n", unit, badlbn, replbn); ! 393: mp = (*ra->port->mp_get)(rp->ctl); ! 394: bzero((caddr_t)mp, sizeof(struct mscmd)); /* clear reserved fields */ ! 395: mp->m_crf = ++rarefno; ! 396: mp->m_unit = rp->unit; ! 397: mp->m_opcd = OPRPL; ! 398: mp->m_rbn = replbn; ! 399: mp->m_lbn = badlbn; ! 400: mp->m_mod = prim ? MDPRI : 0; ! 401: ra->cmdcrf = mp->m_crf; ! 402: ra->cmdopc = OPRPL; ! 403: (*ra->port->mp_send)(rp->ctl, IDRA, mp); ! 404: while ((ra->flags & RPDONE) == 0) ! 405: sleep((caddr_t)&ra->rplret, PZERO); ! 406: u.u_error = ra->rplret; ! 407: if (ra->flags & RPWANT) ! 408: wakeup((caddr_t)&ra->flags); ! 409: ra->flags &=~ (RPWANT|RPLOCK|RPDONE); ! 410: spl0(); ! 411: ! 412: } ! 413: ! 414: /* ! 415: * here when the port gets a sequential message ! 416: */ ! 417: raseql(ctl, type, ep) ! 418: int ctl, type; ! 419: register struct msend *ep; ! 420: { ! 421: register struct buf *bp; ! 422: register struct radisk *ra; ! 423: register int unit; ! 424: register struct buf *obp; ! 425: int sts; ! 426: ! 427: if (ep->m_opcd == 0 && ep->m_sts == STRST) { ! 428: rareset(ctl); ! 429: return; ! 430: } ! 431: for (unit = 0; unit < racnt; unit++) ! 432: if (raaddr[unit].ctl == ctl ! 433: && raaddr[unit].ctype == type ! 434: && raaddr[unit].unit == ep->m_unit) ! 435: break; ! 436: if (unit >= racnt) { ! 437: printf("ra%d ctl%d typ%d: stray mscp packet sts x%x opcode %o\n", ! 438: ep->m_unit, ctl, type, ep->m_sts, ep->m_opcd); ! 439: return; ! 440: } ! 441: ra = &radisk[unit]; ! 442: sts = ep->m_sts & STMSK; ! 443: if (sts == STAVL || sts == STOFL) ! 444: ra->flags &=~ ONLINE; /* help! */ ! 445: illcmd: ! 446: switch (ep->m_opcd & 0377) { ! 447: case OPEND: /* eg invalid command */ ! 448: if (ep->m_crf == ra->cmdcrf) { ! 449: ep->m_opcd = ra->cmdopc | OPEND; ! 450: goto illcmd; ! 451: } ! 452: /* else check for pending read or write */ ! 453: case OPRD|OPEND: ! 454: case OPWR|OPEND: ! 455: for (bp = ra->actf, obp = NULL; bp; obp = bp, bp = bp->b_next) ! 456: if (ep->m_crf == bp->b_crf) ! 457: break; ! 458: if (bp == NULL) { ! 459: printf("ra%d stray end: crf %d sts x%x opcode 0%o\n", ! 460: unit, ep->m_crf, ep->m_sts, ep->m_opcd & 0377); ! 461: return; ! 462: } ! 463: if (((struct mscmd *)(bp->b_pkt))->m_crf != ep->m_crf) ! 464: printf("ra%d sent %d got %d crf; flg %x dev %x\n", ! 465: unit, ((struct mscmd *)(bp->b_pkt))->m_crf, ! 466: ep->m_crf, bp->b_flags, bp->b_dev); ! 467: if (obp) ! 468: obp->b_next = bp->b_next; ! 469: else ! 470: ra->actf = bp->b_next; ! 471: if (bp == ra->actl) ! 472: ra->actl = obp; ! 473: bp->b_resid = bp->b_bcount - ep->m_bcnt; ! 474: if (sts != STSUC) { ! 475: bp->b_flags |= B_ERROR; ! 476: if (ep->m_sts == STBCK || ep->m_sts == STBK2) /* optical disk blank check */ ! 477: bp->b_error = ENXIO; ! 478: else ! 479: printf("err on ra%d block %D: sts x%x\n", unit, bp->b_blkno, ep->m_sts); ! 480: } ! 481: (*ra->port->mp_unmap)(ctl, (struct mscmd *)bp->b_pkt); ! 482: iodone(bp); ! 483: return; ! 484: ! 485: case OPONL|OPEND: ! 486: rasonl(ra, ep); ! 487: return; ! 488: ! 489: case OPAVL|OPEND: ! 490: ra->flags &=~ ONLINE; ! 491: return; ! 492: ! 493: case OPGUS|OPEND: ! 494: if (sts != STSUC) { ! 495: printf("ra%d: can't get unit sts x%x\n", unit, ep->m_sts); ! 496: return; ! 497: } ! 498: ra->di.medium = ep->m_medi; ! 499: ra->di.tracksz = ep->m_trck; ! 500: ra->di.groupsz = ep->m_grp; ! 501: ra->di.cylsz = ep->m_cyl; ! 502: ra->di.rctsize = ep->m_rcts; ! 503: ra->di.rbns = ep->m_rbns; ! 504: ra->di.copies = ep->m_rctc; ! 505: ra->flags |= GOTDI; ! 506: return; ! 507: ! 508: case OPSCC|OPEND: ! 509: if (sts != STSUC) ! 510: printf("ra ctl%d typ%d: bad init\n", ctl, type); ! 511: return; ! 512: ! 513: case OPRPL|OPEND: ! 514: ra->rplret = 0; ! 515: if (sts != STSUC) { ! 516: printf("ra%d: rpl sts x%x\n", unit, ep->m_sts); ! 517: ra->rplret = EIO; ! 518: } ! 519: ra->flags |= RPDONE; ! 520: wakeup((caddr_t)&ra->rplret); ! 521: return; ! 522: ! 523: default: ! 524: printf("ra%d ctl%d typ%d: stray mscp msg opcd 0%o sts x%x\n", ! 525: ep->m_unit, ctl, type, ep->m_opcd&0377, ep->m_sts); ! 526: return; ! 527: } ! 528: } ! 529: ! 530: /* ! 531: * controller was reset ! 532: * discard all pending io, ! 533: * awake all sleepers, ! 534: * mark everything offline ! 535: */ ! 536: ! 537: rareset(ctl) ! 538: int ctl; ! 539: { ! 540: register int unit; ! 541: register struct radisk *ra; ! 542: register struct buf *bp, *nbp; ! 543: ! 544: for (unit = 0; unit < racnt; unit++) { ! 545: if (raaddr[unit].ctl != ctl) ! 546: continue; ! 547: ra = &radisk[unit]; ! 548: for (bp = ra->actf; bp; bp = nbp) { ! 549: nbp = bp->b_next; ! 550: (*ra->port->mp_unmap)(ctl, (struct mscmd *)bp->b_pkt); ! 551: bp->b_flags |= B_ERROR; ! 552: iodone(bp); ! 553: } ! 554: ra->actf = ra->actl = NULL; ! 555: ra->flags &=~ (ONLINE|WONLINE); ! 556: wakeup((caddr_t)ra); ! 557: } ! 558: } ! 559: ! 560: /* ! 561: * here with a datagram message ! 562: * explanations really shouldn't be in the driver ! 563: * ! 564: * the hack for event 8 ignores error packets from ! 565: * the US Design optical disk controller ! 566: * that really mean `read a blank spot on the disk ! 567: */ ! 568: ! 569: static char *raevents[] = { ! 570: "ok", ! 571: "inv cmd", ! 572: "op aborted", ! 573: "offline", ! 574: "available", ! 575: "med fmt", ! 576: "write prot", ! 577: "comp err", ! 578: "data err", ! 579: "host buf access err", ! 580: "cntl err", ! 581: "drive err", ! 582: }; ! 583: #define MAXEVT 0xb ! 584: ! 585: radg(ctl, type, ep) ! 586: int ctl, type; ! 587: register struct mserl *ep; ! 588: { ! 589: register u_short *sp; /* for sdi crap */ ! 590: register int i; /* for useless design crap */ ! 591: register unsigned char *cp; /* for useless design crap */ ! 592: ! 593: if (ep->l_fmt == FMDSK && ep->l_evnt == STBCK && ep->l_flgs == 0) ! 594: return; ! 595: printf("ra%d ctl%d typ%d seq %d: %s err; fmt x%x ev x%x fl x%x\n", ! 596: ep->l_unit, ctl, type, ep->l_seq, /* phys unit, not log */ ! 597: ep->l_flgs&(LFSUC|LFCON) ? "soft" : "hard", ! 598: ep->l_fmt, ep->l_evnt, ep->l_flgs&0377); ! 599: if ((ep->l_evnt & STMSK) <= MAXEVT) ! 600: printf("%s; ", raevents[ep->l_evnt & STMSK]); ! 601: switch (ep->l_fmt) { ! 602: case FMCNT: ! 603: /* now the thing should be marked disastrously bad */ ! 604: printf("oops\n"); ! 605: break; ! 606: ! 607: case FMBAD: ! 608: printf("host mem access; addr x%x\n", ep->l_badr); ! 609: break; ! 610: ! 611: case FMDSK: ! 612: printf("%sbn %d; lev x%x, retry x%x\n", ! 613: (ep->l_hdcd & 0xf0000000) == 0 ? "l" : "r", ! 614: ep->l_hdcd & 0x0fffffff, ep->l_lvl, ep->l_rtry); ! 615: break; ! 616: ! 617: case FMSDI: ! 618: printf("%sbn %d;", ! 619: (ep->l_hdcd & 0xf0000000) == 0 ? "l" : "r", ! 620: ep->l_hdcd & 0x0fffffff); ! 621: /* ! 622: * print the bytes in the same order used ! 623: * by the dec diagnostics ! 624: */ ! 625: sp = (u_short *)&ep->l_sdi[3]; ! 626: while (sp > (u_short *)ep->l_sdi) ! 627: printf(" %x", *--sp); ! 628: printf(" xx\n"); ! 629: break; ! 630: ! 631: case FMSMD: ! 632: printf("cyl %d\n", ep->l_sdi[1]); ! 633: break; ! 634: ! 635: case 0x40: /* hack for useless design */ ! 636: printf("scsi:"); ! 637: cp = (unsigned char *)ep->l_sdi; ! 638: for(i = 0; i < 10; i++) ! 639: printf(" %x", *cp++); ! 640: printf(" [%x %x]\n", cp[0], cp[1]); ! 641: break; ! 642: ! 643: default: ! 644: printf("\n"); ! 645: break; ! 646: } ! 647: } ! 648: ! 649: /* ! 650: * unit is believed offline ! 651: * try to bring it on ! 652: */ ! 653: ! 654: static ! 655: raonline(ra, rp) ! 656: register struct radisk *ra; ! 657: register struct msaddr *rp; ! 658: { ! 659: register struct mscmd *mp; ! 660: int s; ! 661: ! 662: s = spl6(); ! 663: if ((ra->flags & WONLINE) == 0) { ! 664: ra->flags &=~ GOTDI; ! 665: mp = (*ra->port->mp_get)(rp->ctl); ! 666: bzero((caddr_t)mp, sizeof(struct mscmd)); /* clear reserved fields */ ! 667: mp->m_crf = ++rarefno; ! 668: mp->m_unit = rp->unit; ! 669: mp->m_opcd = OPONL; ! 670: ra->cmdcrf = mp->m_crf; ! 671: ra->cmdopc = OPONL; ! 672: (*ra->port->mp_send)(rp->ctl, IDRA, mp); ! 673: ra->flags |= WONLINE; ! 674: } ! 675: while (ra->flags & WONLINE) ! 676: tsleep((caddr_t)ra, PRIONL, 60); ! 677: if ((ra->flags & ONLINE) == 0) ! 678: return (0); ! 679: if ((ra->flags & GOTDI) == 0) { ! 680: mp = (*ra->port->mp_get)(rp->ctl); ! 681: mp->m_crf = ++rarefno; ! 682: mp->m_unit = rp->unit; ! 683: mp->m_opcd = OPGUS; ! 684: mp->m_mod = 0; ! 685: mp->m_unfl = 0; ! 686: mp->m_dvpm = 0; /* ? */ ! 687: (*ra->port->mp_send)(rp->ctl, IDRA, mp); ! 688: } ! 689: splx(s); ! 690: return (1); ! 691: } ! 692: ! 693: static ! 694: rasonl(ra, ep) ! 695: register struct radisk *ra; ! 696: register struct msend *ep; ! 697: { ! 698: ! 699: if (ra->flags & WONLINE) { ! 700: ra->flags &=~ WONLINE; ! 701: wakeup((caddr_t)ra); ! 702: } ! 703: if ((ep->m_sts & STMSK) != STSUC) ! 704: return; ! 705: ra->flags |= ONLINE; ! 706: if (ra->di.radsize != HUGE && ra->di.radsize != ep->m_unsz) ! 707: printf("ra%d: changed size %d to %d\n", ra-radisk, ra->di.radsize, ep->m_unsz); ! 708: ra->di.radsize = ep->m_unsz; ! 709: } ! 710: ! 711: /* ! 712: * controller init ! 713: * set characteristics to turn off host timeouts ! 714: */ ! 715: ! 716: static ! 717: racinit(ra, rp) ! 718: struct radisk *ra; ! 719: struct msaddr *rp; ! 720: { ! 721: register struct mscmd *mp; ! 722: register int s; ! 723: ! 724: mp = (*ra->port->mp_get)(rp->ctl); ! 725: mp->m_crf = ++rarefno; ! 726: mp->m_unit = rp->unit; ! 727: mp->m_opcd = OPSCC; ! 728: mp->m_mod = 0; ! 729: mp->m_cntf = CFMSC | CFTHS; ! 730: mp->m_vrsn = MSCPVER; ! 731: mp->m_htmo = 0; /* no timeout */ ! 732: mp->m_time[0] = mp->m_time[1] = 0L; ! 733: s = spl6(); ! 734: (*ra->port->mp_send)(rp->ctl, IDRA, mp); ! 735: splx(s); ! 736: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.