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