Annotation of researchv10no/sys/io/ra.c, revision 1.1.1.1

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: } ra_sizes[NRAPART] = {
                     50:        10240,  0,
                     51:        20480,  10240,
                     52:        249848, 30720,
                     53:        249848, 280568,
                     54:        249848, 530416,
                     55:        HUGE,   780264,
                     56:        749544, 30720,          /* slices 2,3,4 */
                     57:        HUGE,   0,              /* whole drive */
                     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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.