Annotation of 42BSD/sys/vaxuba/rl.c, revision 1.1.1.1

1.1       root        1: /*     rl.c    6.1     83/07/29        */
                      2: 
                      3: #include "rl.h"
                      4: #if NRL > 0
                      5: /*
                      6:  * UNIBUS RL02 disk driver
                      7:  */
                      8: #include "../machine/pte.h"
                      9: 
                     10: #include "../h/param.h"
                     11: #include "../h/systm.h"
                     12: #include "../h/dk.h"
                     13: #include "../h/dkbad.h"
                     14: #include "../h/buf.h"
                     15: #include "../h/conf.h"
                     16: #include "../h/dir.h"
                     17: #include "../h/user.h"
                     18: #include "../h/map.h"
                     19: #include "../h/vm.h"
                     20: #include "../h/cmap.h"
                     21: #include "../h/uio.h"
                     22: #include "../h/kernel.h"
                     23: 
                     24: #include "../vax/cpu.h"
                     25: #include "../vax/nexus.h"
                     26: #include "../vaxuba/ubavar.h"
                     27: #include "../vaxuba/ubareg.h"
                     28: #include "../vaxuba/rlreg.h"
                     29: 
                     30: /* Pending Controller items and statistics */
                     31: struct rl_softc {
                     32:        int     rl_softas;      /* Attention sumary, (seeks pending) */
                     33:        int     rl_ndrive;      /* Number of drives on controller */
                     34:        int     rl_wticks;      /* Monitor time for function */
                     35: } rl_softc[NHL];
                     36: 
                     37: /* 
                     38:  * State of controller from last transfer.
                     39:  * Since only one transfer can be done at a time per
                     40:  * controller, only allocate one for each controller.
                     41:  */
                     42: struct rl_stat {
                     43:        short   rl_cyl[4];      /* Current cylinder for each drive */
                     44:        short   rl_dn;          /* drive number currently transferring */
                     45:        short   rl_cylnhd;      /* current cylinder and head of transfer */
                     46:        u_short rl_bleft;       /* bytes left to transfer */
                     47:        u_short rl_bpart;       /* bytes transferred */
                     48: } rl_stat[NHL];
                     49: 
                     50: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
                     51: /* Last cylinder not used. Saved for Bad Sector File */
                     52: struct size {
                     53:        daddr_t nblocks;
                     54:        int     cyloff;
                     55: } rl02_sizes[8] = {
                     56:        15884,          0,              /* A=cyl   0 thru 397 */
                     57:         4520,          398,            /* B=cyl 398 thru 510 */
                     58:           -1,          0,              /* C=cyl   0 thru 511 */
                     59:         4520,          398,            /* D=cyl 398 thru 510 */
                     60:            0,          0,              /* F= Not Defined     */
                     61:        20440,          0,              /* G=cyl   0 thru 510 */
                     62:            0,          0,              /* H= Not Defined     */
                     63: };
                     64: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
                     65: 
                     66: int    rlprobe(), rlslave(), rlattach(), rldgo(), rlintr();
                     67: struct uba_ctlr        *rlminfo[NHL];
                     68: struct uba_device      *rldinfo[NRL];
                     69: struct uba_device      *rlip[NHL][4];
                     70: 
                     71: /* RL02 driver structure */
                     72: u_short        rlstd[] = { 0174400 };
                     73: struct uba_driver hldriver =
                     74:     { rlprobe, rlslave, rlattach, rldgo, rlstd, "rl", rldinfo, "hl", rlminfo };
                     75: 
                     76: /* User table per controller */
                     77: struct buf     rlutab[NRL];
                     78: 
                     79: /* RL02 drive structure */
                     80: struct RL02 {
                     81:        short   nbpt;           /* Number of 512 byte blocks/track */
                     82:        short   ntrak;
                     83:        short   nbpc;           /* Number of 512 byte blocks/cylinder */
                     84:        short   ncyl;
                     85:        short   btrak;          /* Number of bytes/track */
                     86:        struct  size *sizes;
                     87: } rl02 = {
                     88:        20,     2,      40,     512,    20*512, rl02_sizes /* rl02/DEC*/
                     89: };
                     90: 
                     91: struct buf     rrlbuf[NRL];
                     92: 
                     93: #define        b_cylin b_resid         /* Last seek as CYL<<1 | HD */
                     94: 
                     95: #ifdef INTRLVE
                     96: daddr_t dkblock();
                     97: #endif
                     98: 
                     99: int    rlwstart, rlwatch();            /* Have started guardian */
                    100: 
                    101: /* Check that controller exists */
                    102: /*ARGSUSED*/
                    103: rlprobe(reg)
                    104:        caddr_t reg;
                    105: {
                    106:        register int br, cvec;
                    107: 
                    108: #ifdef lint    
                    109:        br = 0; cvec = br; br = cvec;
                    110:        rlintr(0);
                    111: #endif
                    112:        ((struct rldevice *)reg)->rlcs = RL_IE | RL_NOOP;
                    113:        DELAY(10);
                    114:        ((struct rldevice *)reg)->rlcs &= ~RL_IE;
                    115:        return (sizeof (struct rldevice));
                    116: }
                    117: 
                    118: rlslave(ui, reg)
                    119:        struct uba_device *ui;
                    120:        caddr_t reg;
                    121: {
                    122:        register struct rldevice *rladdr = (struct rldevice *)reg;
                    123:        short ctr = 0;
                    124: 
                    125:        /*
                    126:         * DEC reports that:
                    127:         * For some unknown reason the RL02 (seems to be only drive 1)
                    128:         * does not return a valid drive status the first time that a
                    129:         * GET STATUS request is issued for the drive, in fact it can
                    130:         * take up to three or more GET STATUS requests to obtain the
                    131:         * correct status.
                    132:         * In order to overcome this, the driver has been modified to
                    133:         * issue a GET STATUS request and validate the drive status
                    134:         * returned.  If a valid status is not returned after eight
                    135:         * attempts, then an error message is printed.
                    136:         */
                    137:        do {
                    138:                rladdr->rlda.getstat = RL_RESET;
                    139:                rladdr->rlcs = (ui->ui_slave <<8) | RL_GETSTAT; /* Get status*/
                    140:                rlwait(rladdr);
                    141:        } while ((rladdr->rlmp.getstat&RLMP_STATUS) != RLMP_STATOK && ++ctr<8);
                    142:        if ((rladdr->rlcs & RL_DE) || (ctr >= 8))
                    143:                return (0);
                    144:        if ((rladdr->rlmp.getstat & RLMP_DT) == 0 ) {
                    145:                printf("rl%d: rl01's not supported\n", ui->ui_slave);
                    146:                return(0);
                    147:        }
                    148:        return (1);
                    149: }
                    150: 
                    151: rlattach(ui)
                    152:        register struct uba_device *ui;
                    153: {
                    154:        register struct rldevice *rladdr;
                    155: 
                    156:        if (rlwstart == 0) {
                    157:                timeout(rlwatch, (caddr_t)0, hz);
                    158:                rlwstart++;
                    159:        }
                    160:        /* Initialize iostat values */
                    161:        if (ui->ui_dk >= 0)
                    162:                dk_mspw[ui->ui_dk] = .000003906;   /* 16bit transfer time? */
                    163:        rlip[ui->ui_ctlr][ui->ui_slave] = ui;
                    164:        rl_softc[ui->ui_ctlr].rl_ndrive++;
                    165:        rladdr = (struct rldevice *)ui->ui_addr;
                    166:        /* reset controller */
                    167:        rladdr->rlda.getstat = RL_RESET;        /* SHOULD BE REPEATED? */
                    168:        rladdr->rlcs = (ui->ui_slave << 8) | RL_GETSTAT; /* Reset DE bit */
                    169:        rlwait(rladdr);
                    170:        /* determine disk posistion */
                    171:        rladdr->rlcs = (ui->ui_slave << 8) | RL_RHDR;
                    172:        rlwait(rladdr);
                    173:        /* save disk drive posistion */
                    174:        rl_stat[ui->ui_ctlr].rl_cyl[ui->ui_slave] =
                    175:             (rladdr->rlmp.readhdr & 0177700) >> 6;
                    176:        rl_stat[ui->ui_ctlr].rl_dn = -1;
                    177: }
                    178:  
                    179: rlopen(dev)
                    180:        dev_t dev;
                    181: {
                    182:        register int unit = minor(dev) >> 3;
                    183:        register struct uba_device *ui;
                    184: 
                    185:        if (unit >= NRL || (ui = rldinfo[unit]) == 0 || ui->ui_alive == 0)
                    186:                return (ENXIO);
                    187:        return (0);
                    188: }
                    189: 
                    190: rlstrategy(bp)
                    191:        register struct buf *bp;
                    192: {
                    193:        register struct uba_device *ui;
                    194:        register int drive;
                    195:        register struct buf *dp;
                    196:        int partition = minor(bp->b_dev) & 07, s;
                    197:        long bn, sz;
                    198: 
                    199:        sz = (bp->b_bcount+511) >> 9;
                    200:        drive = dkunit(bp);
                    201:        if (drive >= NRL)
                    202:                goto bad;
                    203:        ui = rldinfo[drive];
                    204:        if (ui == 0 || ui->ui_alive == 0)
                    205:                goto bad;
                    206:        if (bp->b_blkno < 0 ||
                    207:            (bn = dkblock(bp))+sz > rl02.sizes[partition].nblocks)
                    208:                goto bad;
                    209:        /* bn is in 512 byte block size */
                    210:        bp->b_cylin = bn/rl02.nbpc + rl02.sizes[partition].cyloff;
                    211:        s = spl5();
                    212:        dp = &rlutab[ui->ui_unit];
                    213:        disksort(dp, bp);
                    214:        if (dp->b_active == 0) {
                    215:                rlustart(ui);
                    216:                bp = &ui->ui_mi->um_tab;
                    217:                if (bp->b_actf && bp->b_active == 0)
                    218:                        rlstart(ui->ui_mi);
                    219:        }
                    220:        splx(s);
                    221:        return;
                    222: 
                    223: bad:
                    224:        bp->b_flags |= B_ERROR;
                    225:        iodone(bp);
                    226:        return;
                    227: }
                    228: 
                    229: /*
                    230:  * Unit start routine.
                    231:  * Seek the drive to be where the data is
                    232:  * and then generate another interrupt
                    233:  * to actually start the transfer.
                    234:  */
                    235: rlustart(ui)
                    236:        register struct uba_device *ui;
                    237: {
                    238:        register struct buf *bp, *dp;
                    239:        register struct uba_ctlr *um;
                    240:        register struct rldevice *rladdr;
                    241:        daddr_t bn;
                    242:        short hd, diff;
                    243: 
                    244:        if (ui == 0)
                    245:                return;
                    246:        um = ui->ui_mi;
                    247:        dk_busy &= ~(1 << ui->ui_dk);
                    248:        dp = &rlutab[ui->ui_unit];
                    249:        if ((bp = dp->b_actf) == NULL)
                    250:                return;
                    251:        /*
                    252:         * If the controller is active, just remember
                    253:         * that this device has to be positioned...
                    254:         */
                    255:        if (um->um_tab.b_active) {
                    256:                rl_softc[um->um_ctlr].rl_softas |=  1<<ui->ui_slave;
                    257:                return;
                    258:        }
                    259:        /*
                    260:         * If we have already positioned this drive,
                    261:         * then just put it on the ready queue.
                    262:         */
                    263:        if (dp->b_active)
                    264:                goto done;
                    265:        dp->b_active = 1;       /* positioning drive */
                    266:        rladdr = (struct rldevice *)um->um_addr;
                    267: 
                    268:        /*
                    269:         * Figure out where this transfer is going to
                    270:         * and see if we are seeked correctly.
                    271:         */
                    272:        bn = dkblock(bp);               /* Block # desired */
                    273:        /*
                    274:         * Map 512 byte logical disk blocks
                    275:         * to 256 byte sectors (rl02's are stupid).
                    276:         */
                    277:        hd = (bn / rl02.nbpt) & 1;      /* Get head required */
                    278:        diff = (rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] >> 1) - bp->b_cylin;
                    279:        if ( diff == 0 && (rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] & 1) == hd)
                    280:                goto done;              /* on cylinder and head */
                    281:        /*
                    282:         * Not at correct position.
                    283:         */
                    284:        rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] = (bp->b_cylin << 1) | hd;
                    285:        if (diff < 0)
                    286:                rladdr->rlda.seek = -diff << 7 | RLDA_HGH | hd << 4;
                    287:        else
                    288:                rladdr->rlda.seek = diff << 7 | RLDA_LOW | hd << 4;
                    289:        rladdr->rlcs = (ui->ui_slave << 8) | RL_SEEK;
                    290: 
                    291:        /*
                    292:         * Mark unit busy for iostat.
                    293:         */
                    294:        if (ui->ui_dk >= 0) {
                    295:                dk_busy |= 1<<ui->ui_dk;
                    296:                dk_seek[ui->ui_dk]++;
                    297:        }
                    298:        rlwait(rladdr);
                    299: done:
                    300:        /*
                    301:         * Device is ready to go.
                    302:         * Put it on the ready queue for the controller
                    303:         * (unless its already there.)
                    304:         */
                    305:        if (dp->b_active != 2) {
                    306:                dp->b_forw = NULL;
                    307:                if (um->um_tab.b_actf == NULL)
                    308:                        um->um_tab.b_actf = dp;
                    309:                else
                    310:                        um->um_tab.b_actl->b_forw = dp;
                    311:                um->um_tab.b_actl = dp;
                    312:                dp->b_active = 2;       /* Request on ready queue */
                    313:        }
                    314: }
                    315: 
                    316: /*
                    317:  * Start up a transfer on a drive.
                    318:  */
                    319: rlstart(um)
                    320:        register struct uba_ctlr *um;
                    321: {
                    322:        register struct buf *bp, *dp;
                    323:        register struct uba_device *ui;
                    324:        register struct rldevice *rladdr;
                    325:        register struct rl_stat *st = &rl_stat[um->um_ctlr];
                    326:        daddr_t bn;
                    327:        short sn, cyl, cmd;
                    328: 
                    329: loop:
                    330:        if ((dp = um->um_tab.b_actf) == NULL) {
                    331:                st->rl_dn = -1;
                    332:                st->rl_cylnhd = 0;
                    333:                st->rl_bleft = 0;
                    334:                st->rl_bpart = 0;
                    335:                return;
                    336:        }
                    337:        if ((bp = dp->b_actf) == NULL) {
                    338:                um->um_tab.b_actf = dp->b_forw;
                    339:                goto loop;
                    340:        }
                    341:        /*
                    342:         * Mark controller busy, and
                    343:         * determine destination.
                    344:         */
                    345:        um->um_tab.b_active++;
                    346:        ui = rldinfo[dkunit(bp)];               /* Controller */
                    347:        bn = dkblock(bp);                       /* 512 byte Block number */
                    348:        cyl = bp->b_cylin << 1;                 /* Cylinder */
                    349:        cyl |= (bn / rl02.nbpt) & 1;            /* Get head required */
                    350:        sn = (bn % rl02.nbpt) << 1;             /* Sector number */
                    351:        rladdr = (struct rldevice *)ui->ui_addr;
                    352:        rlwait(rladdr);
                    353:        rladdr->rlda.rw = cyl<<6 | sn;
                    354:        /* save away current transfers drive status */
                    355:        st->rl_dn = ui->ui_slave;
                    356:        st->rl_cylnhd = cyl;
                    357:        st->rl_bleft = bp->b_bcount;
                    358:        st->rl_bpart = rl02.btrak - (sn * NRLBPSC);
                    359:        /*
                    360:         * RL02 must seek between cylinders and between tracks,
                    361:         * determine maximum data transfer at this time.
                    362:         */
                    363:        if (st->rl_bleft < st->rl_bpart)
                    364:                st->rl_bpart = st->rl_bleft;
                    365:        rladdr->rlmp.rw = -(st->rl_bpart >> 1);
                    366:        if (bp->b_flags & B_READ)
                    367:                cmd = RL_IE | RL_READ | (ui->ui_slave << 8);
                    368:        else
                    369:                cmd = RL_IE | RL_WRITE | (ui->ui_slave << 8);
                    370:        um->um_cmd = cmd;
                    371:        (void) ubago(ui);
                    372: }
                    373: 
                    374: rldgo(um)
                    375:        register struct uba_ctlr *um;
                    376: {
                    377:        register struct rldevice *rladdr = (struct rldevice *)um->um_addr;
                    378: 
                    379:        rladdr->rlba = um->um_ubinfo;
                    380:        rladdr->rlcs = um->um_cmd|((um->um_ubinfo>>12)&RL_BAE);
                    381: }
                    382: 
                    383: /*
                    384:  * Handle a disk interrupt.
                    385:  */
                    386: rlintr(rl21)
                    387:        register rl21;
                    388: {
                    389:        register struct buf *bp, *dp;
                    390:        register struct uba_ctlr *um = rlminfo[rl21];
                    391:        register struct uba_device *ui;
                    392:        register struct rldevice *rladdr = (struct rldevice *)um->um_addr;
                    393:        register unit;
                    394:        struct rl_softc *rl = &rl_softc[um->um_ctlr];
                    395:        struct rl_stat *st = &rl_stat[um->um_ctlr];
                    396:        int as = rl->rl_softas, status;
                    397: 
                    398:        rl->rl_wticks = 0;
                    399:        rl->rl_softas = 0;
                    400:        dp = um->um_tab.b_actf;
                    401:        bp = dp->b_actf;
                    402:        ui = rldinfo[dkunit(bp)];
                    403:        dk_busy &= ~(1 << ui->ui_dk);
                    404: 
                    405:        /*
                    406:         * Check for and process errors on
                    407:         * either the drive or the controller.
                    408:         */
                    409:        if (rladdr->rlcs & RL_ERR) {
                    410:                u_short err;
                    411:                rlwait(rladdr);
                    412:                err = rladdr->rlcs;
                    413:                /* get staus and reset controller */
                    414:                rladdr->rlda.getstat = RL_GSTAT;
                    415:                rladdr->rlcs = (ui->ui_slave << 8) | RL_GETSTAT;
                    416:                rlwait(rladdr);
                    417:                status = rladdr->rlmp.getstat;
                    418:                /* reset drive */
                    419:                rladdr->rlda.getstat = RL_RESET;
                    420:                rladdr->rlcs = (ui->ui_slave <<8) | RL_GETSTAT; /* Get status*/
                    421:                rlwait(rladdr);
                    422:                if ((status & RLMP_WL) == RLMP_WL) {
                    423:                        /*
                    424:                         * Give up on write protected devices
                    425:                         * immediately.
                    426:                         */
                    427:                        printf("rl%d: write protected\n", dkunit(bp));
                    428:                        bp->b_flags |= B_ERROR;
                    429:                } else if (++um->um_tab.b_errcnt > 10) {
                    430:                        /*
                    431:                         * After 10 retries give up.
                    432:                         */
                    433:                        harderr(bp, "rl");
                    434:                        printf("cs=%b mp=%b\n", err, RLCS_BITS,
                    435:                            status, RLER_BITS);
                    436:                        bp->b_flags |= B_ERROR;
                    437:                } else
                    438:                        um->um_tab.b_active = 0;         /* force retry */
                    439:                /* determine disk position */
                    440:                rladdr->rlcs = (ui->ui_slave << 8) | RL_RHDR;
                    441:                rlwait(rladdr);
                    442:                /* save disk drive position */
                    443:                st->rl_cyl[ui->ui_slave] =
                    444:                    (rladdr->rlmp.readhdr & 0177700) >> 6;
                    445:        }
                    446:        /*
                    447:         * If still ``active'', then don't need any more retries.
                    448:         */
                    449:        if (um->um_tab.b_active) {
                    450:                /* RL02 check if more data from previous request */
                    451:                if ((bp->b_flags & B_ERROR) == 0 &&
                    452:                     (int)(st->rl_bleft -= st->rl_bpart) > 0) {
                    453:                        /*
                    454:                         * The following code was modeled from the rk07
                    455:                         * driver when an ECC error occured.  It has to
                    456:                         * fix the bits then restart the transfer which is
                    457:                         * what we have to do (restart transfer).
                    458:                         */
                    459:                        int reg, npf, o, cmd, ubaddr, diff, head;
                    460: 
                    461:                        /* seek to next head/track */
                    462:                        /* increment head and/or cylinder */
                    463:                        st->rl_cylnhd++;
                    464:                        diff = (st->rl_cyl[ui->ui_slave] >> 1) -
                    465:                                (st->rl_cylnhd >> 1);
                    466:                        st->rl_cyl[ui->ui_slave] = st->rl_cylnhd;
                    467:                        head = st->rl_cylnhd & 1;
                    468:                        rlwait(rladdr);
                    469:                        if (diff < 0)
                    470:                                rladdr->rlda.seek =
                    471:                                    -diff << 7 | RLDA_HGH | head << 4;
                    472:                        else
                    473:                                rladdr->rlda.seek =
                    474:                                    diff << 7 | RLDA_LOW | head << 4;
                    475:                        rladdr->rlcs = (ui->ui_slave << 8) | RL_SEEK;
                    476:                        npf = btop( bp->b_bcount - st->rl_bleft );
                    477:                        reg = btop(um->um_ubinfo&0x3ffff) + npf;
                    478:                        o = (int)bp->b_un.b_addr & PGOFSET;
                    479:                        ubapurge(um);
                    480:                        um->um_tab.b_active++;
                    481:                        rlwait(rladdr);
                    482:                        rladdr->rlda.rw = st->rl_cylnhd << 6;
                    483:                        if (st->rl_bleft < (st->rl_bpart = rl02.btrak))
                    484:                                st->rl_bpart = st->rl_bleft;
                    485:                        rladdr->rlmp.rw = -(st->rl_bpart >> 1);
                    486:                        cmd = (bp->b_flags&B_READ ? RL_READ : RL_WRITE) |
                    487:                            RL_IE | (ui->ui_slave << 8);
                    488:                        ubaddr = (int)ptob(reg) + o;
                    489:                        cmd |= ((ubaddr >> 12) & RL_BAE);
                    490:                        rladdr->rlba = ubaddr;
                    491:                        rladdr->rlcs = cmd;
                    492:                        return;
                    493:                }
                    494:                um->um_tab.b_active = 0;
                    495:                um->um_tab.b_errcnt = 0;
                    496:                dp->b_active = 0;
                    497:                dp->b_errcnt = 0;
                    498:                /* "b_resid" words remaining after error */
                    499:                bp->b_resid = st->rl_bleft;
                    500:                um->um_tab.b_actf = dp->b_forw;
                    501:                dp->b_actf = bp->av_forw;
                    502:                st->rl_dn = -1;
                    503:                st->rl_bpart = st->rl_bleft = 0;
                    504:                iodone(bp);
                    505:                /*
                    506:                 * If this unit has more work to do,
                    507:                 * then start it up right away.
                    508:                 */
                    509:                if (dp->b_actf)
                    510:                        rlustart(ui);
                    511:                as &= ~(1<<ui->ui_slave);
                    512:        } else
                    513:                as |= (1<<ui->ui_slave);
                    514:        ubadone(um);
                    515:        /* reset state info */
                    516:        st->rl_dn = -1;
                    517:        st->rl_cylnhd = st->rl_bpart = st->rl_bleft = 0;
                    518:        /*
                    519:         * Process other units which need attention.
                    520:         * For each unit which needs attention, call
                    521:         * the unit start routine to place the slave
                    522:         * on the controller device queue.
                    523:         */
                    524:        while (unit = ffs(as)) {
                    525:                unit--;         /* was 1 origin */
                    526:                as &= ~(1<<unit);
                    527:                rlustart(rlip[rl21][unit]);
                    528:        }
                    529:        /*
                    530:         * If the controller is not transferring, but
                    531:         * there are devices ready to transfer, start
                    532:         * the controller.
                    533:         */
                    534:        if (um->um_tab.b_actf && um->um_tab.b_active == 0)
                    535:                rlstart(um);
                    536: }
                    537: 
                    538: rlwait(rladdr)
                    539:        register struct rldevice *rladdr;
                    540: {
                    541: 
                    542:        while ((rladdr->rlcs & RL_CRDY) == 0)
                    543:                ;
                    544: }
                    545: 
                    546: rlread(dev, uio)
                    547:        dev_t dev;
                    548:        struct uio *uio;
                    549: {
                    550:        register int unit = minor(dev) >> 3;
                    551: 
                    552:        if (unit >= NRL)
                    553:                return (ENXIO);
                    554:        return (physio(rlstrategy, &rrlbuf[unit], dev, B_READ, minphys, uio));
                    555: }
                    556: 
                    557: rlwrite(dev, uio)
                    558:        dev_t dev;
                    559:        struct uio *uio;
                    560: {
                    561:        register int unit = minor(dev) >> 3;
                    562: 
                    563:        if (unit >= NRL)
                    564:                return (ENXIO);
                    565:        return (physio(rlstrategy, &rrlbuf[unit], dev, B_WRITE, minphys, uio));
                    566: }
                    567: 
                    568: /*
                    569:  * Reset driver after UBA init.
                    570:  * Cancel software state of all pending transfers
                    571:  * and restart all units and the controller.
                    572:  */
                    573: rlreset(uban)
                    574:        int uban;
                    575: {
                    576:        register struct uba_ctlr *um;
                    577:        register struct uba_device *ui;
                    578:        register struct rldevice *rladdr;
                    579:        register struct rl_stat *st;
                    580:        register int rl21, unit;
                    581: 
                    582:        for (rl21 = 0; rl21 < NHL; rl21++) {
                    583:                if ((um = rlminfo[rl21]) == 0 || um->um_ubanum != uban ||
                    584:                    um->um_alive == 0)
                    585:                        continue;
                    586:                printf(" hl%d", rl21);
                    587:                rladdr = (struct rldevice *)um->um_addr;
                    588:                st = &rl_stat[rl21];
                    589:                um->um_tab.b_active = 0;
                    590:                um->um_tab.b_actf = um->um_tab.b_actl = 0;
                    591:                if (um->um_ubinfo) {
                    592:                        printf("<%d>", (um->um_ubinfo>>28)&0xf);
                    593:                        um->um_ubinfo = 0;
                    594:                }
                    595:                /* reset controller */
                    596:                st->rl_dn = -1;
                    597:                st->rl_cylnhd = 0;
                    598:                st->rl_bleft = 0;
                    599:                st->rl_bpart = 0;
                    600:                rlwait(rladdr);
                    601:                for (unit = 0; unit < NRL; unit++) {
                    602:                        rladdr->rlcs = (unit << 8) | RL_GETSTAT;
                    603:                        rlwait(rladdr);
                    604:                        /* Determine disk posistion */
                    605:                        rladdr->rlcs = (unit << 8) | RL_RHDR;
                    606:                        rlwait(rladdr);
                    607:                        /* save disk drive posistion */
                    608:                        st->rl_cyl[unit] =
                    609:                                (rladdr->rlmp.readhdr & 0177700) >> 6;
                    610:                        if ((ui = rldinfo[unit]) == 0)
                    611:                                continue;
                    612:                        if (ui->ui_alive == 0 || ui->ui_mi != um)
                    613:                                continue;
                    614:                        rlutab[unit].b_active = 0;
                    615:                        rlustart(ui);
                    616:                }
                    617:                rlstart(um);
                    618:        }
                    619: }
                    620: 
                    621: /*
                    622:  * Wake up every second and if an interrupt is pending
                    623:  * but nothing has happened increment a counter.
                    624:  * If nothing happens for 20 seconds, reset the UNIBUS
                    625:  * and begin anew.
                    626:  */
                    627: rlwatch()
                    628: {
                    629:        register struct uba_ctlr *um;
                    630:        register rl21, unit;
                    631:        register struct rl_softc *rl;
                    632: 
                    633:        timeout(rlwatch, (caddr_t)0, hz);
                    634:        for (rl21 = 0; rl21 < NHL; rl21++) {
                    635:                um = rlminfo[rl21];
                    636:                if (um == 0 || um->um_alive == 0)
                    637:                        continue;
                    638:                rl = &rl_softc[rl21];
                    639:                if (um->um_tab.b_active == 0) {
                    640:                        for (unit = 0; unit < NRL; unit++)
                    641:                                if (rlutab[unit].b_active &&
                    642:                                    rldinfo[unit]->ui_mi == um)
                    643:                                        goto active;
                    644:                        rl->rl_wticks = 0;
                    645:                        continue;
                    646:                }
                    647: active:
                    648:                rl->rl_wticks++;
                    649:                if (rl->rl_wticks >= 20) {
                    650:                        rl->rl_wticks = 0;
                    651:                        printf("hl%d: lost interrupt\n", rl21);
                    652:                        ubareset(um->um_ubanum);
                    653:                }
                    654:        }
                    655: }
                    656: 
                    657: /*ARGSUSED*/
                    658: rldump(dev)
                    659:        dev_t dev;
                    660: {
                    661: 
                    662:        /* don't think there is room on swap for it anyway. */
                    663: }
                    664: 
                    665: rlsize(dev)
                    666:        dev_t dev;
                    667: {
                    668:        register int unit = minor(dev) >> 3;
                    669:        register struct uba_device *ui;
                    670: 
                    671:        if (unit >= NRL || (ui = rldinfo[unit]) == 0 || ui->ui_alive == 0)
                    672:                return (-1);
                    673:        return (rl02.sizes[minor(dev) & 07].nblocks);
                    674: }
                    675: #endif

unix.superglobalmegacorp.com

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