BSD 4_3_Reno release
[unix-history] / usr / src / sys / vaxuba / rk.c
index 45c258c..1df9019 100644 (file)
@@ -1,4 +1,10 @@
-/*     rk.c    6.2     83/10/11        */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)rk.c        7.8 (Berkeley) 2/17/90
+ */
 
 #include "rk.h"
 #if NHK > 0
 
 #include "rk.h"
 #if NHK > 0
@@ -18,26 +24,28 @@ int rkbdebug;
  * TODO:
  *     Learn why we lose an interrupt sometime when spinning drives down
  */
  * TODO:
  *     Learn why we lose an interrupt sometime when spinning drives down
  */
-#include "../machine/pte.h"
-
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/buf.h"
-#include "../h/conf.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/map.h"
-#include "../h/vm.h"
-#include "../h/dk.h"
-#include "../h/cmap.h"
-#include "../h/dkbad.h"
-#include "../h/uio.h"
-#include "../h/kernel.h"
+#include "machine/pte.h"
+
+#include "param.h"
+#include "systm.h"
+#include "buf.h"
+#include "conf.h"
+#include "user.h"
+#include "map.h"
+#include "vm.h"
+#include "dkstat.h"
+#include "cmap.h"
+#include "dkbad.h"
+#include "ioctl.h"
+#include "disklabel.h"
+#include "uio.h"
+#include "kernel.h"
+#include "syslog.h"
 
 #include "../vax/cpu.h"
 
 #include "../vax/cpu.h"
-#include "../vaxuba/ubareg.h"
-#include "../vaxuba/ubavar.h"
-#include "../vaxuba/rkreg.h"
+#include "ubareg.h"
+#include "ubavar.h"
+#include "rkreg.h"
 
 struct rk_softc {
        int     sc_softas;
 
 struct rk_softc {
        int     sc_softas;
@@ -46,18 +54,20 @@ struct      rk_softc {
        int     sc_recal;
 } rk_softc[NHK];
 
        int     sc_recal;
 } rk_softc[NHK];
 
+#define rkunit(dev)    (minor(dev) >> 3)
+
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 struct size {
        daddr_t nblocks;
        int     cyloff;
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 struct size {
        daddr_t nblocks;
        int     cyloff;
-} rk7_sizes[8] ={
+} rk7_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 240 */
        10032,  241,            /* B=cyl 241 thru 392 */
        53790,  0,              /* C=cyl 0 thru 814 */
        15884,  0,              /* A=cyl 0 thru 240 */
        10032,  241,            /* B=cyl 241 thru 392 */
        53790,  0,              /* C=cyl 0 thru 814 */
+       15884,  393,            /* D=cyl 393 thru 633 */
        0,      0,
        0,      0,
-       0,      0,
-       0,      0,
-       27786,  393,            /* G=cyl 393 thru 813 */
+       11792,  634,            /* F=cyl 634 thru 814 */
+       27786,  393,            /* G=cyl 393 thru 814, should be 27698 */
        0,      0,
 }, rk6_sizes[8] ={
        15884,  0,              /* A=cyl 0 thru 240 */
        0,      0,
 }, rk6_sizes[8] ={
        15884,  0,              /* A=cyl 0 thru 240 */
@@ -102,14 +112,8 @@ u_char     rk_offset[16] =
     RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0
   };
 
     RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0
   };
 
-struct buf rrkbuf[NRK];
-
 #define        b_cylin b_resid
 
 #define        b_cylin b_resid
 
-#ifdef INTRLVE
-daddr_t        dkblock();
-#endif
-
 int    rkwstart, rkwatch();
 
 rkprobe(reg)
 int    rkwstart, rkwatch();
 
 rkprobe(reg)
@@ -159,7 +163,7 @@ rkattach(ui)
                rkwstart++;
        }
        if (ui->ui_dk >= 0)
                rkwstart++;
        }
        if (ui->ui_dk >= 0)
-               dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256);
+               dk_wpms[ui->ui_dk] = (60 * NRKSECT * 256);
        rkip[ui->ui_ctlr][ui->ui_slave] = ui;
        rk_softc[ui->ui_ctlr].sc_ndrive++;
        rkcyl[ui->ui_unit] = -1;
        rkip[ui->ui_ctlr][ui->ui_slave] = ui;
        rk_softc[ui->ui_ctlr].sc_ndrive++;
        rkcyl[ui->ui_unit] = -1;
@@ -169,7 +173,7 @@ rkattach(ui)
 rkopen(dev)
        dev_t dev;
 {
 rkopen(dev)
        dev_t dev;
 {
-       register int unit = minor(dev) >> 3;
+       register int unit = rkunit(dev);
        register struct uba_device *ui;
 
        if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0)
        register struct uba_device *ui;
 
        if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0)
@@ -189,16 +193,26 @@ rkstrategy(bp)
        int s;
 
        sz = (bp->b_bcount+511) >> 9;
        int s;
 
        sz = (bp->b_bcount+511) >> 9;
-       unit = dkunit(bp);
-       if (unit >= NRK)
+       unit = rkunit(bp->b_dev);
+       if (unit >= NRK) {
+               bp->b_error = ENXIO;
                goto bad;
                goto bad;
+       }
        ui = rkdinfo[unit];
        ui = rkdinfo[unit];
-       if (ui == 0 || ui->ui_alive == 0)
+       if (ui == 0 || ui->ui_alive == 0) {
+               bp->b_error = ENXIO;
                goto bad;
                goto bad;
+       }
        st = &rkst[ui->ui_type];
        if (bp->b_blkno < 0 ||
        st = &rkst[ui->ui_type];
        if (bp->b_blkno < 0 ||
-           (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
+           (bn = bp->b_blkno)+sz > st->sizes[xunit].nblocks) {
+               if (bp->b_blkno == st->sizes[xunit].nblocks) {
+                   bp->b_resid = bp->b_bcount;
+                   goto done;
+               }
+               bp->b_error = EINVAL;
                goto bad;
                goto bad;
+       }
        bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
        s = spl5();
        dp = &rkutab[ui->ui_unit];
        bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
        s = spl5();
        dp = &rkutab[ui->ui_unit];
@@ -214,6 +228,7 @@ rkstrategy(bp)
 
 bad:
        bp->b_flags |= B_ERROR;
 
 bad:
        bp->b_flags |= B_ERROR;
+done:
        iodone(bp);
        return;
 }
        iodone(bp);
        return;
 }
@@ -308,8 +323,8 @@ loop:
                goto loop;
        }
        um->um_tab.b_active++;
                goto loop;
        }
        um->um_tab.b_active++;
-       ui = rkdinfo[dkunit(bp)];
-       bn = dkblock(bp);
+       ui = rkdinfo[rkunit(bp->b_dev)];
+       bn = bp->b_blkno;
        st = &rkst[ui->ui_type];
        sn = bn%st->nspc;
        tn = sn/st->nsect;
        st = &rkst[ui->ui_type];
        sn = bn%st->nspc;
        tn = sn/st->nsect;
@@ -329,7 +344,7 @@ retry:
                goto retry;
        }
        if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
                goto retry;
        }
        if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
-               printf("rk%d: not ready", dkunit(bp));
+               printf("rk%d: not ready", rkunit(bp->b_dev));
                if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
                        printf("\n");
                        rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
                if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
                        printf("\n");
                        rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
@@ -386,7 +401,7 @@ rkintr(rk11)
                um->um_tab.b_active = 1;
                dp = um->um_tab.b_actf;
                bp = dp->b_actf;
                um->um_tab.b_active = 1;
                dp = um->um_tab.b_actf;
                bp = dp->b_actf;
-               ui = rkdinfo[dkunit(bp)];
+               ui = rkdinfo[rkunit(bp->b_dev)];
                dk_busy &= ~(1 << ui->ui_dk);
                if (bp->b_flags&B_BAD)
                        if (rkecc(ui, CONT))
                dk_busy &= ~(1 << ui->ui_dk);
                if (bp->b_flags&B_BAD)
                        if (rkecc(ui, CONT))
@@ -404,13 +419,15 @@ rkintr(rk11)
                        }
 #endif
                        if (er & RKER_WLE) {
                        }
 #endif
                        if (er & RKER_WLE) {
-                               printf("rk%d: write locked\n", dkunit(bp));
+                               printf("rk%d: write locked\n",
+                                       rkunit(bp->b_dev));
                                bp->b_flags |= B_ERROR;
                        } else if (++um->um_tab.b_errcnt > 28 ||
                            ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) {
 hard:
                                bp->b_flags |= B_ERROR;
                        } else if (++um->um_tab.b_errcnt > 28 ||
                            ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) {
 hard:
-                               harderr(bp, "rk");
-                               printf("cs2=%b ds=%b er=%b\n",
+                               diskerr(bp, "rk", "hard error", LOG_PRINTF, -1,
+                                   (struct disklabel *)0);
+                               printf(" cs2=%b ds=%b er=%b\n",
                                    cs2, RKCS2_BITS, ds, 
                                    RKDS_BITS, er, RKER_BITS);
                                bp->b_flags |= B_ERROR;
                                    cs2, RKCS2_BITS, ds, 
                                    RKDS_BITS, er, RKER_BITS);
                                bp->b_flags |= B_ERROR;
@@ -514,28 +531,6 @@ rkwait(addr)
                ;
 }
 
                ;
 }
 
-rkread(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       register int unit = minor(dev) >> 3;
-
-       if (unit >= NRK)
-               return (ENXIO);
-       return (physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio));
-}
-
-rkwrite(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       register int unit = minor(dev) >> 3;
-
-       if (unit >= NRK)
-               return (ENXIO);
-       return (physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys, uio));
-}
-
 rkecc(ui, flag)
        register struct uba_device *ui;
 {
 rkecc(ui, flag)
        register struct uba_device *ui;
 {
@@ -551,10 +546,10 @@ rkecc(ui, flag)
        if (flag == CONT)
                npf = bp->b_error;
        else
        if (flag == CONT)
                npf = bp->b_error;
        else
-               npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount);
-       reg = btop(um->um_ubinfo&0x3ffff) + npf;
+               npf = btodb(bp->b_bcount + (rk->rkwc * sizeof(short)) + 511);
+       reg = btop(UBAI_ADDR(um->um_ubinfo)) + npf;
        o = (int)bp->b_un.b_addr & PGOFSET;
        o = (int)bp->b_un.b_addr & PGOFSET;
-       bn = dkblock(bp);
+       bn = bp->b_blkno;
        st = &rkst[ui->ui_type];
        cn = bp->b_cylin;
        sn = bn%st->nspc + npf;
        st = &rkst[ui->ui_type];
        cn = bp->b_cylin;
        sn = bn%st->nspc + npf;
@@ -571,14 +566,15 @@ rkecc(ui, flag)
 
                npf--;
                reg--;
 
                npf--;
                reg--;
-               printf("rk%d%c: soft ecc sn%d\n", dkunit(bp),
-                   'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
+               diskerr(bp, "rk", "soft ecc", LOG_WARNING, npf,
+                   (struct disklabel *)0);
+               addlog("\n");
                mask = rk->rkec2;
                i = rk->rkec1 - 1;              /* -1 makes 0 origin */
                bit = i&07;
                i = (i&~07)>>3;
                byte = i + o;
                mask = rk->rkec2;
                i = rk->rkec1 - 1;              /* -1 makes 0 origin */
                bit = i&07;
                i = (i&~07)>>3;
                byte = i + o;
-               while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
+               while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) {
                        addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
                            (byte & PGOFSET);
                        putmemc(addr, getmemc(addr)^(mask<<bit));
                        addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
                            (byte & PGOFSET);
                        putmemc(addr, getmemc(addr)^(mask<<bit));
@@ -622,9 +618,9 @@ rkecc(ui, flag)
        printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);
 #endif
                bp->b_flags &= ~B_BAD;
        printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);
 #endif
                bp->b_flags &= ~B_BAD;
-               rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short));
-               if (rk->rkwc == 0)
+               if ((int)dbtob(npf) >= bp->b_bcount)
                        return (0);
                        return (0);
+               rk->rkwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof (short));
                break;
        }
        rk->rkcs1 = RK_CCLR;
                break;
        }
        rk->rkcs1 = RK_CCLR;
@@ -720,7 +716,7 @@ rkdump(dev)
        register short *rp;
        struct rkst *st;
 
        register short *rp;
        struct rkst *st;
 
-       unit = minor(dev) >> 3;
+       unit = rkunit(dev);
        if (unit >= NRK)
                return (ENXIO);
 #define        phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
        if (unit >= NRK)
                return (ENXIO);
 #define        phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
@@ -742,8 +738,10 @@ rkdump(dev)
        }
        st = &rkst[ui->ui_type];
        sizes = phys(struct size *, st->sizes);
        }
        st = &rkst[ui->ui_type];
        sizes = phys(struct size *, st->sizes);
-       if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks)
+       if (dumplo < 0)
                return (EINVAL);
                return (EINVAL);
+       if (dumplo + num >= sizes[minor(dev)&07].nblocks)
+               num = sizes[minor(dev)&07].nblocks - dumplo;
        while (num > 0) {
                register struct pte *io;
                register int i;
        while (num > 0) {
                register struct pte *io;
                register int i;
@@ -778,7 +776,7 @@ rkdump(dev)
 rksize(dev)
        dev_t dev;
 {
 rksize(dev)
        dev_t dev;
 {
-       int unit = minor(dev) >> 3;
+       int unit = rkunit(dev);
        struct uba_device *ui;
        struct rkst *st;
 
        struct uba_device *ui;
        struct rkst *st;