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

unix.superglobalmegacorp.com

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