# 2.11BSD#431 - /usr/src/sys/pdpuba/br.c

##### Functions

    brattach          X
    brdump            X
    brintr            X
    bropen            X
    brroot            X
    brsize            X
    brstrategy        X

##### Variables

    Br_addr           X
    br_chars          X
    br_disk           X
    brtab             X

##### Macros

    BRADDR            X
    DBSIZE            X
    SECTRK            X
    TRKCYL            X
    brunit            X

##### struct's

    br_char           X
    br_dsz            X

       1: /*
       2:  * BR disk driver
       3:  * modified from the UNIX RP03 driver for BR disk drive -JM
       4:  * 11/11/84 - Added dump routine for taking 2.9 crash dumps in swap. -SMS
       5:  * 9/28/85  - Use brreg.h so as to look more like a 2.9 disk handler. -SMS
       6:  * 2/16/86  - Rewrite!  Drop the bropen, brclose and brgch functions.  Do
       7:  *	      initialization on a per drive basis rather than controller.
       8:  *	      The bropen and brclose functions were only used to perform
       9:  *	      the init'ing of a drive, and there was a problem in single
      10:  *	      user mode where a 'umount' could close the device before all
      11:  *	      data for that filesystem was written out thereby giving offline
      12:  *	      errors and causing corruption of the disc.  Also defined a
      13:  *	      disc slice that encompassed the whole drive for ease in copying,
      14:  *	      several other mods made because this was done.  Overall, several
      15:  *	      pages of code were removed. -SMS
      16:  *	      Just discovered that bropen() and brclose() were defined as
      17:  *	      nulldev() in c.c!  Wasted code all this time!  The offline errors
      18:  *	      observed were a result of entry into brstrategy() during a
      19:  *	      'umount' when bropen() had never been called in the first place!!!
      20:  * 12/6/87  - Changes to run under 2.10bsd.  Still single controller only.
      21:  *	      Considering we don't make the controller any more that's fairly
      22:  *	      safe to assume.  Partitions drastically changed to allow room
      23:  *	      on T300 and T200 to hold the source distribution.
      24:  *	      Autoconfigure logic finally added though. -SMS
      25:  * 2/17/89  - For 2.10.1BSD added old 2.9BSD /usr,/userfiles, and /minkie
      26:  *	      partitions as partitions 'e', 'f', and 'g' as an aid in
      27:  *	      converting the systems.  BE CAREFUL!  For T300 only.
      28:  * 8/4/89   - Use the log() function to record soft errors.
      29:  * 9/22/91  - remove read and write entry - use common raw read/write routine.
      30:  * 12/23/92 - add the partition size routine.
      31:  * 1/2/93   - remove unibus map ifdefs, the run time check using 'ubmap' is
      32:  *	      sufficient and does the right thing.
      33:  * 1995/04/13 - change reference to dkunit.
      34:  */
      35:
      36: #include "br.h"
      37: #if NBR > 0
      38:
      39: #include "param.h"
      40: #include "../machine/seg.h"
      41:
      42: #include "systm.h"
      43: #include "buf.h"
      44: #include "conf.h"
      45: #include "user.h"
      46: #include "brreg.h"
      47: #include "dk.h"
      48: #include "disklabel.h"
      49: #include "disk.h"
      50: #include "syslog.h"
      51: #include "map.h"
      52: #include "uba.h"
      53:
      54: #define BRADDR ((struct brdevice *) 0176710)
      55: #define brunit(dev) ((dev >> 3) & 7)
      56: #define SECTRK  brc->sectrk
      57: #define TRKCYL  brc->trkcyl
      58:
      59: struct br_char {
      60:     struct br_dsz {
      61:         daddr_t nblocks;
      62:         int cyloff;
      63:     } br_sizes[8];
      64:     int sectrk, trkcyl;
      65: } br_chars[] =
      66: {               /* T300 */
      67:     18240,   0,     /* cyl 000 - 029 */
      68:     12160,  30,     /* cyl 030 - 049 */
      69:     232256, 50,     /* cyl 050 - 431 */
      70:     232256, 432,        /* cyl 432 - 813 */
      71:     154432,  50,        /* 'e' is old 2.9 'c' partition */
      72:     154432,  304,       /* 'f' is old 2.9 'd' partition */
      73:     154432,  558,       /* 'g' is old 2.9 'e' partition */
      74:     495520,  0,     /* cyl 000 - 814 */
      75:     32,  19,        /* 32 sectrk, 19 trkcyl */
      76:  /* T200 */
      77:     18392,  0,      /* cyl 000 - 043 */
      78:     12122,  43,     /* cyl 044 - 072 */
      79:     231990, 73,     /* cyl 073 - 627 */
      80:     78166,  443,            /* cyl 628 - 814 */
      81:     0,  0,
      82:     0,  0,
      83:     0,      0,
      84:     340670, 0,      /* cyl 000 - 814  */
      85:     22,     19,     /* 22 sectrk, 19 trkcyl */
      86: /* T80 */
      87:     18400,    0,        /* cyl 000 - 114 */
      88:     12320,  115,        /* cyl 115 - 190 */
      89:     99840,  191,        /* cyl 191 - 814 */
      90:     0,    0,
      91:     0,    0,
      92:     0,    0,
      93:     0,    0,
      94:     130300,   0,
      95:     32,   5,        /* 32 sectrk, 5 trkcyl */
      96: /* T50 */
      97:     18260,    0,        /* cyl 000 - 165 */
      98:     12210,  166,        /* cyl 166 - 276 */
      99:     59180,  277,        /* cyl 277 - 814 */
     100:     0,    0,
     101:     0,    0,
     102:     0,    0,
     103:     0,    0,
     104:     89650,    0,
     105:     22,   5,        /* 22 sectrk, 5 trkcyl */
     106: };
     107:
     108: /*
     109:  * Define the recovery strobes and offsets in br_da
     110:  */
     111: static int br_offs[] = {
     112:     0,      0,      0,      STBE,
     113:     STBE,       STBL,       STBL,       OFFP+STBL,
     114:     OFFP+STBL,  OFFP,       OFFP,       OFFP+STBE,
     115:     OFFP+STBE,  OFFM+STBE,  OFFM+STBE,  OFFP,
     116:     OFFP,       OFFP+STBL,  OFFP+STBL,  0
     117: };
     118:
     119: #ifdef UCB_METER
     120: static int br_dkn = -1;
     121: #endif
     122: struct buf brtab;
     123: struct br_char *br_disk[NBR];
     124: struct brdevice *Br_addr;
     125:
     126: brroot()
     127: {
     128:     brattach((struct brdevice *)BRADDR, 0);
     129: }
     130:
     131: brattach(braddr, unit)
     132:     register struct brdevice *braddr;
     133:     int unit;
     134: {
     135:
     136: #ifdef UCB_METER
     137:     if (br_dkn < 0)
     138:         dk_alloc(&br_dkn, NBR, "br", 0L);
     139: #endif
     140:     if (unit >= NBR)
     141:         return(0);
     142:     if (braddr && (fioword(braddr) != -1)) {
     143:         Br_addr = braddr;
     144:         return(1);
     145:     }
     146:     return(0);
     147: }
     148:
     149: bropen(dev, flag)
     150:     dev_t   dev;
     151:     int flag;
     152: {
     153:     register int dn = brunit(dev);
     154:
     155:     if  (dn >= NBR || !Br_addr)
     156:         return(ENXIO);
     157:     if  (!br_disk[dn])
     158:         brinit(dn);
     159:     if  (!br_disk[dn])
     160:         return(EIO);
     161:     return(0);
     162: }
     163:
     164: brstrategy(bp)
     165:     register struct buf *bp;
     166: {
     167:     register struct buf *dp;
     168:     register int unit;
     169:     struct br_char *brc;
     170:     struct br_dsz *brz;
     171:     long sz;
     172:     int drive, s;
     173:
     174:     unit = bp->b_dev & 07;
     175:     drive = brunit(bp->b_dev);
     176:     if  (!(brc = br_disk[drive])) {
     177:         brinit(drive);
     178:         if (!(brc = br_disk[drive])) {
     179:             bp->b_error = ENODEV;
     180:             bp->b_flags |= B_ERROR;
     181:             iodone(bp);
     182:             return;
     183:         }
     184:     }
     185:     brz = &brc->br_sizes[unit];
     186:     sz = (bp->b_bcount + 511L) >> 9;
     187:     if (bp->b_blkno == brz->nblocks) {
     188:         bp->b_resid = bp->b_bcount;
     189:         iodone(bp);
     190:         return;
     191:     }
     192:     if (bp->b_blkno + sz > brz->nblocks) {
     193:         bp->b_error = EINVAL;
     194:         bp->b_flags |= B_ERROR;
     195:         iodone(bp);
     196:         return;
     197:     }
     198:     if (Br_addr->brae >= 0)
     199:         mapalloc(bp);
     200:     bp->b_cylin = bp->b_blkno/(SECTRK*TRKCYL) + brz->cyloff;
     201:     s = splbio();
     202:     dp = &brtab;
     203:     disksort(dp, bp);
     204:     if (dp->b_active == NULL)
     205:         brstart();
     206:     splx(s);
     207: }
     208:
     209: static
     210: brstart()
     211: {
     212:     register struct buf *bp;
     213:     register int unit;
     214:     int com,cn,tn,sn,dn;
     215:     daddr_t bn;
     216:     struct br_char *brc;
     217:     struct br_dsz *brz;
     218:
     219:     if ((bp = brtab.b_actf) == NULL)
     220:         return;
     221:     Br_addr->brds = -1;
     222:     brtab.b_active++;
     223:     if (!(Br_addr->brcs.w & BR_RDY)) {
     224:         timeout(brstart, 0, 4);
     225:         return;
     226:     }
     227:     unit = bp->b_dev & 07;
     228:     dn = brunit(bp->b_dev);
     229:     if (!(brc = br_disk[dn])) {
     230:         brinit(dn);
     231:         if (!(brc = br_disk[dn])) {
     232:             bp->b_flags |= B_ERROR;
     233:             brdone(bp);
     234:             return;
     235:         }
     236:     }
     237:     brz = &brc->br_sizes[unit];
     238:     bn = bp->b_blkno;
     239:     cn = bn/(SECTRK*TRKCYL) + brz->cyloff;
     240:     sn = bn%(SECTRK*TRKCYL);
     241:     tn = sn/SECTRK;
     242:     sn = sn%SECTRK;
     243:     if (Br_addr->brae < 0)
     244:         Br_addr->brae = bp->b_xmem;
     245:     Br_addr->brcs.w = (dn<<8);
     246:     Br_addr->brda = (tn<<8) | sn;
     247:     cn |= br_offs[brtab.b_errcnt];
     248:     Br_addr->brca = cn;
     249:     Br_addr->brba = bp->b_un.b_addr;
     250:     Br_addr->brwc = -(bp->b_bcount>>1);
     251:     com = ((bp->b_xmem&3)<<4) | BR_IDE | BR_GO;
     252:     if (bp->b_flags & B_READ)
     253:         com |= BR_RCOM;
     254:     else
     255:         com |= BR_WCOM;
     256:     Br_addr->brcs.w |= com;
     257: #ifdef UCB_METER
     258:     if (br_dkn >= 0) {
     259:         dk_busy |= 1 << (br_dkn + dn);
     260:         dk_xfer[br_dkn + dn]++;
     261:         dk_seek[br_dkn + dn]++;
     262:         dk_wds[br_dkn + dn] += (bp->b_bcount >> 6);
     263:     }
     264: #endif
     265: }
     266:
     267: static
     268: brinit(drive)
     269:     register int drive;
     270: {
     271:     register int ctr = 0;
     272:     register struct br_char **br = &br_disk[drive];
     273:
     274:     /*
     275: 	 * Clear the drive's entry in br_disk.  Select the unit.  If the
     276: 	 * unit exists, switch on the spindle type. and set the br_disk
     277: 	 * table entry
     278: 	 */
     279:     *br = (struct br_char *)NULL;
     280:     do {
     281:         Br_addr->brcs.w = (drive << 8) | BR_HSEEK | BR_GO;
     282:         while ((Br_addr->brcs.w & BR_RDY) == 0 && --ctr) ;
     283:     } while (Br_addr->brer & BRER_SUBUSY);
     284:     if ((Br_addr->brcs.w & BR_HE) == 0) {
     285:         switch (Br_addr->brae & AE_DTYP) {
     286:         case AE_T300:
     287:             *br = &br_chars[0];
     288:             break;
     289:         case AE_T200:
     290:             *br = &br_chars[1];
     291:             break;
     292:         case AE_T80:
     293:             *br = &br_chars[2];
     294:             break;
     295:         case AE_T50:
     296:             *br = &br_chars[3];
     297:             break;
     298:         }
     299: #ifdef UCB_METER
     300:         if (br_dkn >= 0)
     301:             dk_wps[br_dkn + drive] =
     302:                 (long)(*br)->sectrk * (60L * 256L);
     303: #endif
     304:     }
     305: }
     306:
     307: brintr(dev)
     308:     int dev;
     309: {
     310:     register struct buf *bp;
     311:     register int ctr = 0;
     312:     struct brdevice brsave;
     313:
     314:     if (brtab.b_active == NULL)
     315:         return;
     316:     brsave = *Br_addr;
     317:     bp = brtab.b_actf;
     318:     if (!(brsave.brcs.w & BR_RDY))
     319:         return;
     320: #ifdef UCB_METER
     321:     if (br_dkn >= 0)
     322:         dk_busy &= ~(1<<(br_dkn + dev));
     323: #endif
     324:     if (brsave.brcs.w < 0) {
     325:         if (brsave.brer & BRER_SUBUSY) {
     326:             timeout(brstart, 0, 5);
     327:             return;
     328:         }
     329:         if (brsave.brds & (BRDS_SUFU|BRDS_SUSI|BRDS_HNF)) {
     330:             Br_addr->brcs.c[0] = BR_HSEEK|BR_GO;
     331:             while (((Br_addr->brds&BRDS_SURDY) == 0) && --ctr);
     332:         }
     333:         Br_addr->brcs.w = BR_IDLE|BR_GO;
     334:         ctr = 0;
     335:         while (((Br_addr->brcs.w&BR_RDY) == 0) && --ctr) ;
     336:         if (brtab.b_errcnt == 0) {
     337:             log(LOG_WARNING,"br%d%c ds:%b er:%b cs:%b wc:%o ba:%o ca:%o da:%o bae:%o\n",
     338:                 dkunit(bp->b_dev), 'a'+ dkpart(bp->b_dev),
     339:                 brsave.brds, BRDS_BITS, brsave.brer, BRER_BITS,
     340:                 brsave.brcs.w, BR_BITS, brsave.brwc,brsave.brba,
     341:                 brsave.brca, brsave.brda, brsave.brae);
     342:         }
     343:         brtab.b_errcnt++;
     344:         if (brtab.b_errcnt < 20) {
     345:             brstart();
     346:             return;
     347:         }
     348:         harderr(bp,"br");
     349:         bp->b_flags |= B_ERROR;
     350:     }
     351:     brdone(bp);
     352: }
     353:
     354: static
     355: brdone (bp)
     356:     register struct buf *bp;
     357: {
     358:     brtab.b_active = NULL;
     359:     brtab.b_errcnt = 0;
     360:     brtab.b_actf = bp->av_forw;
     361:     bp->b_resid = 0;
     362:     iodone(bp);
     363:     brstart();
     364: }
     365:
     366: #ifdef BR_DUMP
     367: /*
     368:  * Dump routine.  Dumps from dumplo to end of memory/end of disk section for
     369:  * minor(dev).
     370:  */
     371: #define DBSIZE  16          /* unit of transfer, same number */
     372:
     373: brdump(dev)
     374:     dev_t dev;
     375: {
     376:     struct br_char *brc;
     377:     struct ubmap *ubp;
     378:     daddr_t bn, dumpsize;
     379:     long paddr;
     380:     int count, cyl, dn, cn, tn, sn, unit, com;
     381:
     382:     unit = dev & 07;
     383:     dn = brunit(dev);
     384:     if ((bdevsw[major(dev)].d_strategy != brstrategy) || dn >= NBR)
     385:         return(EINVAL);
     386:     if (!Br_addr || !(brc = br_disk[dn]))
     387:         return(ENXIO);
     388:     dumpsize = brc->br_sizes[unit].nblocks;
     389:     cyl = brc->br_sizes[unit].cyloff;
     390:     if ((dumplo < 0) || (dumplo >= dumpsize))
     391:         return(EINVAL);
     392:     dumpsize -= dumplo;
     393:     while (!(Br_addr->brcs.w & BR_RDY));
     394:     ubp = &UBMAP[0];
     395:     for (paddr = 0L; dumpsize > 0; dumpsize -= count) {
     396:         count = dumpsize > DBSIZE ? DBSIZE : dumpsize;
     397:         bn = dumplo + (paddr >> PGSHIFT);
     398:         cn = (bn / (SECTRK * TRKCYL)) + cyl;
     399:         sn = bn % (SECTRK * TRKCYL);
     400:         tn = sn / SECTRK;
     401:         sn = sn % SECTRK;
     402:         Br_addr->brca = cn;
     403:         Br_addr->brda = (tn << 8) | sn;
     404:         Br_addr->brwc = -(count << (PGSHIFT-1));
     405:         com = (dn << 8) | BR_GO | BR_WCOM;
     406:         if (ubmap && Br_addr->brae >= 0) {
     407:             ubp->ub_lo = loint(paddr);
     408:             ubp->ub_hi = hiint(paddr);
     409:             Br_addr->brba = 0;
     410:         }
     411:         else {
     412:             Br_addr->brba = (caddr_t)loint(paddr);
     413:             Br_addr->brae = hiint(paddr);
     414:             com |= ((hiint(paddr) & 3) << 4);
     415:         }
     416:         Br_addr->brcs.w = com;
     417:         while (!(Br_addr->brcs.w & BR_RDY));
     418:         if (Br_addr->brcs.w < 0) {
     419:             if (Br_addr->brer & BRER_NXME)
     420:                 return(0);  /* end of memory */
     421:             return(EIO);
     422:         }
     423:         paddr += (DBSIZE << PGSHIFT);
     424:     }
     425:     return(0);              /* filled disk */
     426: }
     427: #endif /* BR_DUMP */
     428:
     429: /*
     430:  * Assumes the 'open' entry point has been called to validate the unit
     431:  * number and fill in the drive type structure.
     432: */
     433: daddr_t
     434: brsize(dev)
     435:     register dev_t dev;
     436:     {
     437:     register struct br_char *brc;
     438:
     439:     brc = br_disk[brunit(dev)];
     440:     return(brc->br_sizes[dev & 7].nblocks);
     441:     }
     442: #endif /* NBR */

#### Defined functions

brattach defined in line 131; used 1 times

- in line 128

brdone defined in line 354; used 2 times

- in line 233, 351

brdump defined in line 373; never used
brinit defined in line 267; used 3 times

- in line 158, 177, 230

brintr defined in line 307; used 1 times

- in /usr/src/sys/pdp/scb.s line 356

bropen defined in line 149; never used
brroot defined in line 126; never used
brsize defined in line 433; never used
brstart defined in line 209; used 5 times

- in line 205, 224, 326, 345, 363

brstrategy defined in line 164; used 1 times

- in line 384

#### Defined variables

Br_addr defined in line 124; used 36 times

- in line 143, 155, 198, 221-223(2), 243-250(7), 256, 281-285(5), 316, 330-335(4), 386, 393, 402-419(11)

br_chars defined in line 65; used 4 times

- in line 287-296(4)

br_disk defined in line 123; used 9 times

- in line 157-159(2), 176-178(2), 229-231(2), 272, 386, 439

br_dkn defined in line 120; used 11 times

- in line 137-138(2), 258-262(5), 300-301(2), 321-322(2)

br_offs defined in line 111; used 1 times

- in line 247

brtab defined in line 122; used 12 times

- in line 202, 219-222(2), 247, 314-317(2), 336, 343-344(2), 358-360(3)

#### Defined struct's

br_char defined in line 59; used 14 times

- in line 123(2), 169(2), 216(2), 272(2), 279(2), 376(2), 437(2)

br_dsz defined in line 60; used 4 times

- in line 170(2), 217(2)

#### Defined macros

BRADDR defined in line 54; used 1 times

- in line 128

DBSIZE defined in line 371; used 3 times

- in line 396(2), 423

SECTRK defined in line 56; used 9 times

- in line 200, 239-242(4), 398-401(4)

TRKCYL defined in line 57; used 5 times

- in line 200, 239-240(2), 398-399(2)

brunit defined in line 55; used 5 times

- in line 153, 175, 228, 383, 439

Last modified: 1995-04-14 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1412 |