Annotation of 43BSDTahoe/sys/vaxuba/rl.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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