Annotation of 40BSD/sys/newdev/hk.c, revision 1.1.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.