Annotation of 41BSD/sys/newdev/hk.c, revision 1.1

1.1     ! root        1: static char *sccsid = "@(#)hk.c        1.1 (Berkeley) 10/10/80";
        !             2: 
        !             3: /*
        !             4:  * RK07 disk driver with bad-sector forwarding
        !             5:  *
        !             6:  *  This driver, revised from a UCSB RK07 driver, is modeled
        !             7:  * after the Stanford SI 9500 driver with bad-sector forwarding.
        !             8:  * The bad-sector information on the last track of each pack is
        !             9:  * used to patch up transfers by forwarding accesses to bad sectors
        !            10:  * to spares on the last cylinder.  The last cylinder is otherwise
        !            11:  * write-protected.
        !            12:  *  The bad-sector table is read when a minor device is first
        !            13:  * opened after a close.  No Volume-Valid checking is done;
        !            14:  * hamfists beware.  To be correct, the open routine needs a
        !            15:  * mechanism for reading drive status and for doing a PACKACK.
        !            16:  *  A pack is 1 minor device; there is no pack mapping.
        !            17:  *  No attempt at ECC logic is included.  Be my guest.
        !            18:  *
        !            19:  *  BUGS:  The same bomb is planted here as in most UBA DMA drivers,
        !            20:  * to wit, ubasetup is called from the interrupt level.  Ubasetup
        !            21:  * will sleep if it cannot allocate; ka-boom!
        !            22:  *
        !            23:  * Author: Rob Mathews, EE Information Systems Lab, Stanford 4/80
        !            24:  */
        !            25: 
        !            26: /*
        !            27:  * Debug control
        !            28:  *
        !            29:  *  1 - open/close
        !            30:  *  2 - strategy
        !            31:  *  4 - intr entry/exit
        !            32:  *  8 - intr detail
        !            33:  * 16 - intr sector mapping
        !            34:  * 32 - strat errors/lock-opens
        !            35:  * 64 - bst reading
        !            36:  *1024 - loop after errors
        !            37:  */
        !            38: 
        !            39: #define debug(bit)     if (rk7debug & (bit)) printf
        !            40: int rk7debug = (0);
        !            41: 
        !            42: #include "../h/param.h"
        !            43: #include "../h/systm.h"
        !            44: #include "../h/buf.h"
        !            45: #include "../h/conf.h"
        !            46: #include "../h/dir.h"
        !            47: #include "../h/user.h"
        !            48: #include "../h/map.h"
        !            49: #include "../h/pte.h"
        !            50: #include "../h/uba.h"
        !            51: 
        !            52: /*
        !            53:  * Disk parameters
        !            54:  */
        !            55: 
        !            56: #define        NRK7    8
        !            57: #define NCYLS  815
        !            58: #define NTRKS  3
        !            59: #define NSECTS 22
        !            60: #define NBYTES 512
        !            61: #define        NBLKS   (NCYLS*NTRKS*NSECTS)
        !            62: #define BSCYL  (NCYLS-1)               /* bad-sector repair cylinder */
        !            63: #define BSBASE (BSCYL*NTRKS*NSECTS)    /*  track 0,1 - repair pool */
        !            64: #define BSTBLK (BSBASE + 2*NSECTS)     /*  track 2 - bad-sector table */
        !            65: #define MAXBB  10                      /* max tolerable bad sectors */
        !            66: 
        !            67: /*
        !            68:  * Register definitions
        !            69:  */
        !            70: 
        !            71: #define        RK7ADDR ((struct rk7_regs *)(UBA0_DEV + 0177440))
        !            72: 
        !            73: struct rk7_regs
        !            74: {
        !            75:        short rkcs1, rkwc;
        !            76:        unsigned short rkba;
        !            77:        short rkda, rkcs2, rkds, rker, rkasof, rkdc, rknull, rkdb, rkmr1;
        !            78:        short rkecps, rkecpt, rkmr2, rkmr3;
        !            79: };
        !            80: 
        !            81: /*
        !            82:  * Register bits, per RK07 manual
        !            83:  */
        !            84: 
        !            85: #define GO     01      /* cs1 */
        !            86: #define DRCLR  04
        !            87: #define        READ    020
        !            88: #define        WRITE   022
        !            89: #define        PACKACK 02
        !            90: #define        IE      0100
        !            91: #define        RDY     0200
        !            92: #define BA1617 01400
        !            93: #define CDT    02000
        !            94: #define CERR   0100000
        !            95: #define CCLR   0100000
        !            96: #define SCLR   040     /* cs2 */
        !            97: #define SVAL   0100000 /* ds */
        !            98: #define DRDY   0200
        !            99: #define VV     0100
        !           100: #define DRA    01
        !           101: #define DCK    0100000 /* er */
        !           102: #define BSE    0200
        !           103: #define NXF    04
        !           104: 
        !           105: #define Error  ((RK7ADDR->rkcs1 & CERR) != 0)
        !           106: 
        !           107: /*
        !           108:  * Driver parameters, data, and definitions
        !           109:  */
        !           110: 
        !           111: #define RETRIES        10
        !           112: 
        !           113: #define IDLE   0
        !           114: #define NORMAL 1
        !           115: #define MAPPED 2
        !           116: #define RESTART        3
        !           117: 
        !           118: struct buf rk7tab, rk7bsbuf, rrk7buf;
        !           119: 
        !           120: struct rk7
        !           121:   {
        !           122:        long access;
        !           123:        short retries, errors, mapped, spurious;
        !           124:        int ubinfo, rwcommand;
        !           125:        short unsigned errer, errcs2, errds;
        !           126:        short cylnow, trksecnow;
        !           127:        unsigned short wcnow;
        !           128:        long manow;
        !           129:   }
        !           130:  rk7;
        !           131: 
        !           132: struct bb
        !           133:   {
        !           134:        short serial, zeros[2], alignpack;
        !           135:        struct bbtbl
        !           136:          {
        !           137:                short bbtcyl, bbtts;
        !           138:          }
        !           139:         bbt[MAXBB];
        !           140:   }
        !           141:  rk7bb[NRK7];
        !           142: #define OPENF  bbt[MAXBB-1].bbtcyl
        !           143: #define LOCKF  zeros[0]
        !           144: 
        !           145: #define b_trksec av_back
        !           146: #define b_cylin         b_resid
        !           147: #define nsects(x) x/NBYTES
        !           148: 
        !           149: /*
        !           150:  */
        !           151: 
        !           152: rk7open (dev, flag)
        !           153:   {
        !           154:        register struct bb *bbp;
        !           155:        register m;
        !           156: 
        !           157:        if ((m = minor (dev)) >= NRK7)
        !           158:          {
        !           159:                u.u_error = ENXIO;
        !           160:                return;
        !           161:          }
        !           162:        bbp = &rk7bb[m];
        !           163:        debug (1) ("open\n");
        !           164:        if (bbp->OPENF != -1)
        !           165:          {
        !           166:                bbp->OPENF = 1;
        !           167:                debug (1|64) ("bs read\n");
        !           168: 
        !           169:                rk7bsbuf.b_flags = B_BUSY | B_READ;
        !           170:                rk7bsbuf.b_dev = minor (dev);  /* major better not matter ! */
        !           171:                rk7bsbuf.b_bcount = sizeof (struct bb);
        !           172:                rk7bsbuf.b_un.b_addr = (caddr_t) bbp;
        !           173:                rk7bsbuf.b_blkno = BSTBLK;
        !           174:                rk7bsbuf.b_error = 0;
        !           175:                rk7strategy (&rk7bsbuf);
        !           176:                iowait (&rk7bsbuf);
        !           177: 
        !           178:                if (rk7bsbuf.b_flags & B_ERROR)
        !           179:                  {
        !           180:                        printf ("rk7: error reading bad sector table!\n");
        !           181:                  }
        !           182:                 else if (bbp->OPENF != -1)
        !           183:                  {
        !           184:                    printf ("rk7: too many bad sectors, drive %d\n", m);
        !           185:                    bbp->OPENF = -1;
        !           186:                  }
        !           187:                wakeup (&bbp->OPENF);
        !           188:                debug (1|64) ("bs read done\n");
        !           189:          }
        !           190:         else
        !           191:          while (bbp->OPENF != -1)
        !           192:            sleep (&bbp->OPENF, PSWP);
        !           193:   }
        !           194: 
        !           195: rk7close (dev, flag)
        !           196:   {
        !           197:        debug (1) ("close\n");
        !           198:        if (!rk7bb[minor (dev)].LOCKF)
        !           199:          rk7bb[minor (dev)].OPENF = 0;
        !           200:   }
        !           201: 
        !           202: rk7strategy (bp)
        !           203: register struct buf *bp;
        !           204:   {
        !           205:        debug (2) ("strat %s ", bp->b_flags & B_READ ? "r" : "w");
        !           206:        if (rk7bb[minor (bp->b_dev)].OPENF == 0)
        !           207:          {
        !           208:                rk7open (bp->b_dev, 0); /* in case root or swap is here */
        !           209:                rk7bb[minor (bp->b_dev)].LOCKF++;
        !           210:                debug (32) ("lock-open\n");
        !           211:          }
        !           212: 
        !           213:        if (bp->b_blkno + nsects (bp->b_bcount)
        !           214:              > (bp->b_flags & B_READ ? NBLKS : BSBASE))
        !           215:          {
        !           216:                debug (2|32) ("error, blk %d, dev %d\n",
        !           217:                                bp->b_blkno, minor (bp->b_dev));
        !           218:                bp->b_flags |= B_ERROR;
        !           219:                iodone(bp);
        !           220:                return;
        !           221:          }
        !           222:        
        !           223:        debug (2) ("queue ");
        !           224:        bp->b_cylin = bp->b_blkno / (NTRKS*NSECTS);
        !           225:        bp->b_trksec = (struct buf *) ((((bp->b_blkno / NSECTS) % NTRKS) << 8)
        !           226:                                        + (bp->b_blkno % NSECTS));
        !           227:        
        !           228:        spl5();
        !           229:        disksort (&rk7tab, bp);
        !           230: 
        !           231:        if(rk7tab.b_active == IDLE)
        !           232:          rk7intr();
        !           233:        spl0();
        !           234:        debug (2) ("end\n");
        !           235:   }
        !           236: 
        !           237: /*
        !           238: disksort (tabp, bp)
        !           239: register struct buf *tabp, bp;
        !           240:   {
        !           241:        bp->av_forw = (struct buf *)NULL;
        !           242:        if(tabp->b_actf == NULL)
        !           243:          tabp->b_actf = bp;
        !           244:         else
        !           245:          tabp->b_actl->av_forw = bp;
        !           246:        tabp->b_actl = bp;
        !           247:   }
        !           248:  */
        !           249: 
        !           250: /*
        !           251:  * Interrupt (co)routine
        !           252:  */
        !           253: 
        !           254: #define iwait(x)       rk7tab.b_active = x; return; case x:
        !           255: rk7intr()
        !           256:   {
        !           257:    register struct buf *bp;
        !           258: 
        !           259:    bp = rk7tab.b_actf;
        !           260:    switch (rk7tab.b_active)
        !           261:     {
        !           262:       case IDLE:
        !           263:        debug (4) ("intr ");
        !           264:        if (bp == NULL)
        !           265:          {
        !           266:                rk7.spurious++;
        !           267:                return;
        !           268:          }
        !           269:        
        !           270:        do { /* empty the queue */
        !           271: 
        !           272:                rk7.access++;
        !           273:                rk7tab.b_errcnt = 0;
        !           274: 
        !           275:                do { /* transfer */
        !           276:                     register short s;
        !           277:                     short rk7map (), ms;
        !           278: 
        !           279:                     rk7.rwcommand = bp->b_flags & B_READ
        !           280:                                        ? (READ|IE|CDT|GO)
        !           281:                                        : (WRITE|IE|CDT|GO);
        !           282:                     if (Error)
        !           283:                      {
        !           284:                        debug (8) ("clear ");
        !           285:                        rk7clear ();
        !           286:                      }
        !           287: 
        !           288:                     RK7ADDR->rkcs2 = minor (bp->b_dev);
        !           289:                     RK7ADDR->rkcs1 = PACKACK|CDT|GO;
        !           290:                     while (RK7ADDR->rkcs1 & GO);
        !           291: 
        !           292:                     debug (8) ("setup ");
        !           293:                     rk7.ubinfo = ubasetup (bp, 1);
        !           294:                     rk7start ( rk7.rwcommand,
        !           295:                                (short) bp->b_cylin, (short)(long) bp->b_trksec,
        !           296:                                (long) rk7.ubinfo,
        !           297:                                (short) (-(bp->b_bcount>>1)));
        !           298:                     debug (8) ("started ");
        !           299:                     iwait (NORMAL);
        !           300: 
        !           301:                     debug (8) ("NORMAL ");
        !           302:                     while (RK7ADDR->rker == BSE && (ms = rk7map ()) != -1)
        !           303:                      { /* forwarding */
        !           304:                        rk7.mapped++;
        !           305:                        debug (8|16) ("mapping ");
        !           306: 
        !           307:                        rk7clear ();
        !           308: 
        !           309:                        rk7start (rk7.rwcommand,
        !           310:                                  (short) BSCYL, (short) ms, (long) rk7.manow,
        !           311:                                  (short) (-(rk7.wcnow > NBYTES/2
        !           312:                                                ? NBYTES/2 : rk7.wcnow)));
        !           313:                        iwait (MAPPED);
        !           314: 
        !           315:                        debug (8|16) ("mapped\n");
        !           316:                        if (!Error && rk7.wcnow > NBYTES/2)
        !           317:                          {
        !           318:                                debug (8|16) ("restarting ");
        !           319:                                rk7restart ();
        !           320:                                iwait (RESTART);
        !           321:                                debug (8|16) ("restarted\n");
        !           322:                          }
        !           323:                      } /* forwarding */
        !           324: 
        !           325:                     if (Error)
        !           326:                      {
        !           327:                        rk7.errer = RK7ADDR->rker;
        !           328:                        rk7.errcs2 = RK7ADDR->rkcs2;
        !           329:                        rk7.errds = RK7ADDR->rkds;
        !           330:                      }
        !           331:                     debug (8) (Error ? "error\n" : "free ");
        !           332:                     ubafree (rk7.ubinfo);
        !           333:                   } /* transfer */
        !           334:                 while (Error && ++rk7tab.b_errcnt != RETRIES);
        !           335: 
        !           336:                if (rk7tab.b_errcnt != 0)
        !           337:                  rk7errs (bp);
        !           338: 
        !           339:                debug (8) ("next\n");
        !           340:                bp->b_resid = 0;
        !           341:                rk7tab.b_actf = bp->av_forw;
        !           342:                iodone (bp);
        !           343: 
        !           344:           } /* empty the queue */
        !           345:         while ((bp = rk7tab.b_actf) != NULL);
        !           346: 
        !           347:         rk7tab.b_active = IDLE;
        !           348:         debug (4) ("exit\n");
        !           349:         return;
        !           350:     }
        !           351:   }
        !           352: 
        !           353: rk7clear ()
        !           354:   {
        !           355:        register drive;
        !           356: 
        !           357:        drive = RK7ADDR->rkcs2 & 07;
        !           358:        RK7ADDR->rkcs1 = CCLR;
        !           359:        RK7ADDR->rkcs2 = drive;
        !           360:        RK7ADDR->rkcs1 = DRCLR|CDT|GO;
        !           361:        while ((RK7ADDR->rkcs1 & RDY) == 0);
        !           362:   }
        !           363: 
        !           364: rk7start (rwcommand, cyl, tsect, mem, wc)
        !           365: short cyl, tsect, wc;
        !           366: long mem;
        !           367:   {
        !           368:        RK7ADDR->rkdc = cyl;
        !           369:        RK7ADDR->rkda = tsect;
        !           370:        RK7ADDR->rkba = mem;
        !           371:        RK7ADDR->rkwc = wc;
        !           372:        RK7ADDR->rkcs1 = ((mem >> 8) & BA1617) | rwcommand;
        !           373:   }
        !           374: 
        !           375: short rk7map ()
        !           376:   {
        !           377:        register struct bbtbl *bbp;
        !           378:        register i;
        !           379: 
        !           380:        rk7.wcnow = -RK7ADDR->rkwc;
        !           381:        rk7.cylnow = RK7ADDR->rkdc;
        !           382:        rk7.trksecnow = RK7ADDR->rkda;
        !           383:        rk7.manow = (((long)(RK7ADDR->rkcs1 & BA1617)) << 8) + RK7ADDR->rkba;
        !           384: 
        !           385:        for (bbp = rk7bb[RK7ADDR->rkcs2 & 07].bbt, i = 0;
        !           386:             bbp->bbtcyl != -1 &&
        !           387:               (bbp->bbtcyl != rk7.cylnow || bbp->bbtts != rk7.trksecnow);
        !           388:             bbp++, i++);
        !           389:        return (bbp->bbtcyl == -1 ? -1 : i /* trk & sec */);
        !           390:   }
        !           391: 
        !           392: rk7restart ()
        !           393:   {
        !           394:        register short ts;
        !           395: 
        !           396:        ts = rk7.trksecnow;
        !           397:        if ((++ts & 0377) == NSECTS)
        !           398:          if (((ts += (1<<8) - NSECTS) >> 8) == NTRKS)
        !           399:            {
        !           400:                ts = 0;
        !           401:                rk7.cylnow++;
        !           402:            }
        !           403:        rk7start (rk7.rwcommand, (short) rk7.cylnow, (short) ts,
        !           404:                  (long) rk7.manow + NBYTES, (short) (-(rk7.wcnow - NBYTES/2)));
        !           405:   }
        !           406: 
        !           407: rk7errs (bp)
        !           408: register struct buf *bp;
        !           409:   {
        !           410:        register nerr;
        !           411: 
        !           412:        nerr = rk7tab.b_errcnt;
        !           413:        rk7.retries += nerr;
        !           414:        if (nerr == RETRIES)
        !           415:          {
        !           416:                bp->b_flags |= B_ERROR;
        !           417:                rk7.errors++;
        !           418:                printf ("Hard rk7 ");
        !           419:          }
        !           420:         else
        !           421:          printf ("%d * rk7 ", nerr);
        !           422:        deverror (bp, rk7.errer, rk7.errcs2);
        !           423:        printf ("ds %X\n", rk7.errds);
        !           424:        while (nerr == RETRIES && (rk7debug & 1024));
        !           425:   }
        !           426: 
        !           427: rk7read(dev)
        !           428: dev_t dev;
        !           429: {
        !           430: 
        !           431:        physio(rk7strategy, &rrk7buf, dev, B_READ, minphys);
        !           432: }
        !           433: 
        !           434: rk7write(dev)
        !           435: dev_t dev;
        !           436: {
        !           437: 
        !           438:        physio(rk7strategy, &rrk7buf, dev, B_WRITE, minphys);
        !           439: }

unix.superglobalmegacorp.com

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