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