1: #
   2: #define DK_N    2
   3: /*
   4:  * DV disk driver
   5:  *
   6:  * Adapted for Version 7 UNIX 8/21/79 - Bob Kridle
   7:  */
   8: 
   9: #include <sys/param.h>
  10: #include <sys/buf.h>
  11: #include <sys/conf.h>
  12: #include <sys/systm.h>
  13: #include <sys/dir.h>
  14: #include <sys/user.h>
  15: 
  16: #ifdef  UCB_SCCSID
  17: static  char sccs_id[] = "@(#)dv.c	3.1";
  18: #endif
  19: 
  20: 
  21: struct {
  22:     int dvcsr;
  23:     int dvdbr;
  24:     int dvmar;
  25:     int dvwcr;
  26:     int dvcbr;
  27:     int dvssr;
  28:     union
  29:     {
  30:         int i;
  31:         char    c[2];
  32:     } dvair;
  33:     int dvusr;
  34: };
  35: 
  36: #define DVADDR  ((struct device *) 0164000 )
  37: #define NDV 4
  38: 
  39: struct dv_sizes {
  40:     daddr_t nblocks;
  41:     int cyloff;
  42: } dv_sizes[] {
  43:     10080,  0,      /* cyl 0 thru 41	*/
  44:     10080,  42,     /* cyl 42 thru 83	*/
  45:     77280,  84,     /* cyl 84 thru 405	*/
  46:     97440,  0,      /* cyl 0 thru 405	*/
  47:     54000,  180,        /* cyl 180 thru 405	*/
  48:     65520,  0,      /* cyl 0 thru 272	*/
  49:     31680,  273,        /* cyl 273 thru 405	*/
  50:     2048,   123,        /* cyl 123 thru 132	*/
  51: };
  52: 
  53: struct {
  54:     int hd1;
  55:     int hd2;
  56:     int cksum;
  57:     unsigned int chadr;
  58: } dvhdr;
  59: int dv_unit -1, dv_cyl, dv_head, dv_sctr, dv_count;
  60: union
  61: {
  62:     long    l;
  63:     int in[2];
  64: } dv_addr;
  65: 
  66: int dv_debug    0;
  67: 
  68: int dv_wcheck, dv_sw 0;
  69: 
  70: 
  71: int wcwcnt[4];
  72: 
  73: struct  buf dvtab;
  74: struct  buf rdvbuf;
  75: 
  76: char    dvsecmap[] {
  77:     0, 4, 8,
  78:     1, 5, 9,
  79:     2, 6, 10,
  80:     3, 7, 11,
  81: };
  82: 
  83: 
  84: #define HTBCOM  000000
  85: #define CTBCOM  020000
  86: #define CNBCOM  030000
  87: #define     INCHD   01
  88: #define     RECAL   02
  89: #define     RESET   020
  90: #define     SEEK    040
  91: #define     CLRDA   0100
  92: #define CHRCOM  070000
  93: #define CHWCOM  0130000
  94: #define CHCD    071000
  95: #define LDSCOM  0140000
  96: #define CTLRST  0170000
  97: #define CHRDATA 060000
  98: #define CHWHEAD 0110000
  99: #define WENABL  0100000
 100: 
 101: #define DRVRDY  04000
 102: #define ATTN    0400
 103: #define DONE    0200
 104: #define IENABLE 0100
 105: #define GO  01
 106: 
 107: /*
 108:  * Use av_back to save sector,
 109:  * b_resid for cylinder+track.
 110:  */
 111: 
 112: #define dvsec   av_back
 113: #define cylhd   b_resid
 114: 
 115: dvstrategy(bp)
 116: register struct buf *bp;
 117: {
 118:     register unsigned trkno;
 119:     register struct dv_sizes *sptr;
 120: 
 121:     if(bp->b_flags&B_PHYS)
 122:         mapalloc(bp);
 123:     sptr = &dv_sizes[minor(bp->b_dev)&07];
 124:     if ((minor(bp->b_dev)&077) >= (NDV<<3) ||
 125:         bp->b_blkno >= sptr->nblocks) {
 126:         bp->b_flags =| B_ERROR;
 127:         iodone(bp);
 128:         return;
 129:     }
 130:     bp->av_forw = NULL;
 131:     trkno = bp->b_blkno/12;
 132:     bp->cylhd = ((sptr->cyloff+trkno/20)<<5)|(trkno%20);
 133:     bp->dvsec = bp->b_blkno%12;
 134:     spl5();
 135:     disksort(&dvtab,bp);
 136:     if (dvtab.b_active==0)
 137:         dvstart();
 138:     spl0();
 139: }
 140: 
 141: dvstart()
 142: {
 143:     register struct buf *bp;
 144: 
 145:     if ((bp = dvtab.b_actf) == 0) {
 146: /*
 147: 		dv_busy = 0;
 148: */
 149:         return;
 150:     }
 151:     dv_cyl = bp->cylhd>>5;
 152:     dv_head = bp->cylhd&037;
 153:     dv_sctr = bp->dvsec;
 154:     dv_count = -bp->b_bcount;
 155:     dv_addr.in[0] = bp->b_xmem & 03;
 156:     dv_addr.in[1] = bp->b_un.b_addr;
 157:     dvexec();
 158: }
 159: 
 160: dvexec()
 161: {
 162:     register struct buf *bp;
 163:     register sctr, minord;
 164:     int i, cnt;
 165: 
 166:     bp = dvtab.b_actf;
 167:     sctr = dv_sctr;
 168:     minord = minor(bp->b_dev);
 169:     if (minord&64)
 170:         sctr = dvsecmap[sctr];
 171:     dvtab.b_active++;
 172:     if (dv_unit!=((minord&077)>>3)) {   /* select unit */
 173:         dv_unit = (minord&077)>>3;
 174:         cnt = 0;
 175:         for (i = 0; i < 2; i++)
 176:             while((DVADDR->dvssr&DRVRDY) && --cnt) ;
 177:         DVADDR->dvcbr = LDSCOM | dv_unit;
 178:     }
 179:     if(dvrdy()) return;
 180:     DVADDR->dvcbr = CNBCOM | RESET | CLRDA; /* reset and clear */
 181:     if (dv_cyl != (~(DVADDR->dvssr|0177000))) { /* seek */
 182:         if(dvrdy()) return;
 183:         DVADDR->dvcbr = CTBCOM | dv_cyl;
 184:         if(dvrdy()) return;
 185:         DVADDR->dvcbr = CNBCOM | SEEK | RESET;
 186:         DVADDR->dvair.i = 1<<dv_unit;
 187:         DVADDR->dvcsr = DONE | IENABLE;
 188: 
 189:         /***** I/O monitoring stuff  *****/
 190: /*  Removed for V7 upgrade
 191:  *		if((minord == 64) && (bp->b_blkno >= swplo1)) dv_busy = 18;
 192:  *		else dv_busy = (((minord & 030) >> 2) | (minord & 01)) + 10;
 193:  *		dk_busy =| 1<<DK_N;
 194:  *		dv_numb[dv_busy] =+ 1;
 195:  */
 196:         /************************/
 197: 
 198:         return;
 199:     }
 200:     if(dvrdy()) return;
 201:     DVADDR->dvcbr = HTBCOM | dv_head;   /* select head */
 202:     if(dv_count <= -512)
 203:         DVADDR->dvwcr = -512; else
 204:         DVADDR->dvwcr = dv_count;
 205:     dvhdr.hd1 = (dv_head<<8)+dv_cyl;    /* set up header */
 206:     dvhdr.hd2 = 0170000|sctr;
 207:     dvhdr.cksum = -dvhdr.hd1-dvhdr.hd2;
 208:     dvhdr.chadr = dv_addr.in[1];
 209:     if(dvrdy()) return;
 210:     DVADDR->dvmar = &dvhdr;
 211:     if(dv_debug)
 212:         printf("ST,h1=%o,h2=%o,h4=%o,mar=%o,wc=%o,x=%o,\n",
 213:             dvhdr.hd1,
 214:             dvhdr.hd2,
 215:             dvhdr.chadr,
 216:             DVADDR->dvmar,
 217:             DVADDR->dvwcr,
 218:             dv_addr.in[0]
 219:         );
 220:     if (minord & 128) {
 221:         if (bp->b_flags & B_READ) {
 222:             dv_addr.in[0] = 0;
 223:             DVADDR->dvmar = dv_addr.in[1];
 224:             DVADDR->dvcbr = CHRDATA | (sctr<<1);
 225:         } else {
 226:             DVADDR->dvcbr = CHWHEAD | (sctr<<1);
 227:             DVADDR->dvair.i =| WENABL;
 228:         }
 229:     } else {
 230:         if (bp->b_flags & B_READ)
 231:             DVADDR->dvcbr = CHRCOM | (sctr<<1);
 232:         else
 233:             if (dv_wcheck)
 234:                 DVADDR->dvcbr = CHCD | (sctr<<1);
 235:             else
 236:                 DVADDR->dvcbr = CHWCOM | (sctr<<1);
 237:     }
 238:     DVADDR->dvcsr = IENABLE | GO | (dv_addr.in[0]<<4);
 239: 
 240:     /***** I/O monitoring stuff *****/
 241: /* Removed for v7 Upgrade
 242:  *	dk_busy =| 1<<DK_N;
 243:  *	dk_numb[DK_N] =+ 1;
 244:  *	dk_wds[DK_N] =+ 8;
 245:  *	if((minord == 64) && (bp->b_blkno >= swplo1)) dv_busy = 9;
 246:  *	else dv_busy = (((minord & 030) >> 2) | (minord & 01)) + 1;
 247:  *	if (dv_count >= -512)
 248:  *		dv_numb[dv_busy] =+ 1;
 249:  *	if(bp->b_flags & B_READ) dv_rwds[dv_busy] =+ 8;
 250:  *	else dv_wwds[dv_busy] =+ 8;
 251:  */
 252:     /*****************************/
 253: 
 254: }
 255: 
 256: int dv_tmp;
 257: int dv_errct;
 258: dvintr()
 259: {
 260:     register struct buf *bp;
 261:     register int csr,i;
 262: 
 263:     if (dvtab.b_active == 0)
 264:         return;
 265:     if(dv_debug)
 266:         printf("IN,mar=%o,wc=%o,cbr=%o,\n",
 267:             DVADDR->dvmar,
 268:             DVADDR->dvwcr,
 269:             DVADDR->dvcbr
 270:         );
 271: 
 272:     /***** I/O monitoring stuff *****/
 273: /* Removed for v7 Upgrade
 274:  *	dk_busy =& ~(1<<DK_N);
 275:  *	dv_busy = 19;
 276:  */
 277:     /*********************************/
 278: 
 279:     bp = dvtab.b_actf;
 280:     dvtab.b_active = 0;
 281:     csr = DVADDR->dvcsr;
 282:     DVADDR->dvcsr = DONE;
 283:     if (csr&ATTN) { /* seek complete */
 284:         dv_wcheck = 0;
 285:         DVADDR->dvair.c[0] = 0;
 286:         if(DVADDR->dvssr>0) { /* error */
 287:             printf("Seek error\n");
 288:             deverror(bp, DVADDR->dvssr, csr);
 289:             DVADDR->dvcbr = CNBCOM | RECAL | RESET;
 290:             dv_unit = -1;
 291:             if(dvrdy()) return;
 292:             DVADDR->dvcbr = CTLRST;
 293:             if (++dvtab.b_errcnt<=10) {
 294:                 dvexec();
 295:                 return;
 296:             }
 297:             dvherr(0);
 298:             return;
 299:         } else {
 300:             dvexec();
 301:             return;
 302:         }
 303:     } else {    /* r/w complete */
 304:         if (dv_count <= -512)
 305:             i = -512;
 306:         else    i = dv_count ;
 307:         if ((csr < 0 || dv_addr.in[1]-i != DVADDR->dvmar) &&
 308:             (minor(bp->b_dev)&128)==0) {
 309:             if (dv_addr.in[1]-i != DVADDR->dvmar) {
 310:                 printf("hdr/xfer err ");
 311:                 printf("%o %o %o\n", dv_addr.in[1], DVADDR->dvmar, csr);
 312:                 deverror(bp, DVADDR->dvssr, csr);
 313:                 dv_wcheck = 0;
 314:             }
 315:             dv_tmp = csr;
 316:             dv_errct++;
 317:             dv_unit = -1;
 318:             if (dv_wcheck) {
 319:                 printf("diva bad write\n");
 320:                 wcwcnt[(minor(bp->b_dev)&030) >> 3]++;
 321:                 deverror(bp, DVADDR->dvssr, csr);
 322:             }
 323:             dv_wcheck = 0;
 324:             if((dvtab.b_errcnt&03)==03) {
 325:                 deverror(bp, DVADDR->dvssr, csr);
 326:                 DVADDR->dvcbr = CNBCOM | RECAL | RESET;
 327:                 if(dvrdy()) return;
 328:             }
 329:             DVADDR->dvcbr = CTLRST;
 330:             if(++dvtab.b_errcnt<=12) {
 331:                 dvexec();
 332:                 return;
 333:             }
 334:             dvherr(0);
 335:             return;
 336:         } else {
 337:             if (dv_sw && (bp->b_flags&B_READ)==B_WRITE &&
 338:                 dv_wcheck==0 && dv_count==-512) {
 339:                 dv_wcheck = 1;
 340:                 dvexec();
 341:                 return;
 342:             }
 343:             dv_wcheck = 0;
 344:             if ((dv_count =+ 512)<0) { /* more to do */
 345:                 dv_addr.l += 512;
 346:             if (++dv_sctr>=12) {
 347:                 dv_sctr = 0;
 348:                 if (++dv_head>=20) {
 349:                     dv_head = 0;
 350:                     dv_cyl++;
 351:                 }
 352:             }
 353:             dvexec();
 354:             return;
 355:             }
 356:         }
 357:     }
 358:     if (csr < 0 && (minor(bp->b_dev)&128)) {
 359:         DVADDR->dvcbr = CTLRST;
 360:         dv_unit = -1;
 361:         dvrdy();
 362:         if (DVADDR->dvcsr < 0) {
 363:             DVADDR->dvcbr = CNBCOM | RECAL | RESET;
 364:             dvrdy();
 365:         }
 366:     }
 367:     dv_wcheck = 0;
 368:     dvtab.b_errcnt = 0;
 369:     dvtab.b_actf = bp->av_forw;
 370: /*  This is not right but a kludge for the moment */
 371:     bp->b_resid = 0;
 372:     iodone(bp);
 373:     dvstart();
 374: }
 375: 
 376: 
 377: dvrdy()
 378: {
 379:     register int cnt, i;
 380: 
 381:     if ((DVADDR->dvssr & DRVRDY) == 0)
 382:         return(0);
 383:     cnt = i = 0;
 384:     /*
 385: 	 *	waste a bit of time, max .7(approx) sec on a 70
 386: 	 */
 387:     for (; i < 2; i++)
 388:         while(--cnt && (DVADDR->dvssr&DRVRDY));
 389:     if (DVADDR->dvssr & DRVRDY) {
 390:         printf("diva not ready\n");
 391:         dvherr(1);
 392:         return(1);
 393:     }
 394:     return(0);
 395: }
 396: 
 397: dvherr(n)
 398: {
 399:     register struct buf *bp;
 400: 
 401:     bp = dvtab.b_actf;
 402:     printf("Hard error on diva\n");
 403:     deverror(bp, DVADDR->dvssr, DVADDR->dvcsr);
 404:     bp->b_flags =| B_ERROR;
 405:     dvtab.b_errcnt = 0;
 406:     dvtab.b_active = 0;
 407:     dvtab.b_actf = bp->av_forw;
 408:     iodone(bp);
 409:     if(n==0)
 410:         dvstart();
 411: }
 412: dvread(dev)
 413: {
 414: 
 415:     if(dvphys(dev))
 416:     physio(dvstrategy, &rdvbuf, dev, B_READ);
 417: }
 418: 
 419: dvwrite(dev)
 420: {
 421: 
 422:     if(dvphys(dev))
 423:     physio(dvstrategy, &rdvbuf, dev, B_WRITE);
 424: }
 425: 
 426: dvphys(dev)
 427: {
 428:     long c;
 429: 
 430:     c = u.u_offset >> 9;
 431:     c =+ (u.u_count+511) / 512;
 432:     if(c > dv_sizes[minor(dev) & 07].nblocks) {
 433:         u.u_error = ENXIO;
 434:         return(0);
 435:     }
 436:     return(1);
 437: }

Defined functions

dvexec defined in line 160; used 6 times
dvherr defined in line 397; used 3 times
dvintr defined in line 258; never used
dvphys defined in line 426; used 2 times
dvrdy defined in line 377; used 9 times
dvread defined in line 412; never used
dvstart defined in line 141; used 3 times
dvstrategy defined in line 115; used 2 times
dvwrite defined in line 419; never used

Defined variables

dv_count defined in line 59; used 7 times
dv_cyl defined in line 59; used 5 times
dv_debug defined in line 66; used 2 times
dv_errct defined in line 257; used 1 times
dv_head defined in line 59; used 5 times
dv_sctr defined in line 59; used 4 times
dv_sizes defined in line 42; used 2 times
dv_sw defined in line 68; used 1 times
dv_tmp defined in line 256; used 1 times
dv_unit defined in line 59; used 7 times
dv_wcheck defined in line 68; used 9 times
dvsecmap defined in line 76; used 1 times
dvtab defined in line 73; used 17 times
rdvbuf defined in line 74; used 2 times
sccs_id defined in line 17; never used
wcwcnt defined in line 71; used 1 times

Defined struct's

dv_sizes defined in line 39; used 2 times
  • in line 119(2)

Defined macros

ATTN defined in line 102; used 1 times
CHCD defined in line 94; used 1 times
CHRCOM defined in line 92; used 1 times
CHRDATA defined in line 97; used 1 times
CHWCOM defined in line 93; used 1 times
CHWHEAD defined in line 98; used 1 times
CLRDA defined in line 91; used 1 times
CNBCOM defined in line 86; used 5 times
CTBCOM defined in line 85; used 1 times
CTLRST defined in line 96; used 3 times
DK_N defined in line 2; never used
DONE defined in line 103; used 2 times
DRVRDY defined in line 101; used 4 times
DVADDR defined in line 36; used 48 times
GO defined in line 105; used 1 times
HTBCOM defined in line 84; used 1 times
IENABLE defined in line 104; used 2 times
INCHD defined in line 87; never used
LDSCOM defined in line 95; used 1 times
NDV defined in line 37; used 1 times
RECAL defined in line 88; used 3 times
RESET defined in line 89; used 5 times
SEEK defined in line 90; used 1 times
WENABL defined in line 99; used 1 times
cylhd defined in line 113; used 3 times
dvsec defined in line 112; used 2 times
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1407
Valid CSS Valid XHTML 1.0 Strict