1: /*
   2:  *	SCCS id	@(#)rx3.c	2.1 (Berkeley)	8/5/83
   3:  */
   4: 
   5: /*
   6:  *
   7:  * Data Systems Design (DSD480) floppy disk drive
   8:  *
   9:  * Lauri Rathmann
  10:  * Tektronix
  11:  *
  12:  *
  13:  * Notes:
  14:  *	The drive is being used in MODE 3 (Extended IBM)
  15:  *	The ioctl mechanism is being used to determine
  16:  *	format, density, number of sectors, bytes per
  17:  *	sector and number of sides.
  18:  *
  19:  * History:
  20:  * August 1981
  21:  *	Written (for 2.8BSD UNIX)
  22:  *
  23:  * January 1982 Modified slightly to work for standard V7 UNIX
  24:  *	S. McGeady
  25:  *
  26:  * NOTE:
  27:  *	This is a block rx3device: the 'c.c' file should contain
  28:  *	lines that look like:
  29:  *
  30:  *	int	rx3open(), rx3close(), rx3strategy();
  31:  *	struct	buf	rx3tab;
  32:  *	...
  33:  *	in bdevsw:
  34:  *	rx3open, rx3close, rx3strategy, &rx3tab,
  35:  *
  36:  *	...
  37:  *	int	rx3ioctl();
  38:  *	...
  39:  *	in cdevsw:
  40:  *	nulldev, nulldev, nodev, nodev, rx3ioctl, nulldev, 0,
  41:  *
  42:  *	The block rx3device is used for all I/O, and the character rx3device
  43:  *	is used only for the IOCTL to set up the rx3device format parameters
  44:  */
  45: 
  46: #include "rx3.h"
  47: #if NRX3 > 0
  48: #include "param.h"
  49: #include <sys/systm.h>
  50: #include <sys/buf.h>
  51: #include <sys/conf.h>
  52: #include <sys/dir.h>
  53: #include <sys/user.h>
  54: #include <sys/map.h>
  55: #include <sys/rx2reg.h>
  56: 
  57: extern  struct  rx3device   *RX3ADDR;
  58: 
  59: #define RXUNIT(dev) (minor(dev)&07)
  60: 
  61: #define NSEC        4   /* Number of logical sections on a disk */
  62: #define MSEC        5   /* Maximum number of retrys */
  63: #define TTIME       (2 * hz)/* Timeout time in HZ */
  64: #define trwait()    while((rx3r->rx2cs & RX2_XREQ) == 0)
  65: 
  66: /*
  67:  * type of disk information.  The floppy is logically divided
  68:  * into four sections.  1) Track 0, side 0
  69:  *			2) Track 1-76, side 0
  70:  *			3) Track 0, side 1
  71:  *			4) Track 1-76, side 1
  72:  */
  73: struct  rx3info {
  74:     long    first_byte;     /* first byte of section */
  75:     long    no_bytes;       /* number of bytes in section */
  76:     char    first_track;        /* track offset for section */
  77:     char    no_track;       /* number of tracks in section */
  78:     char    sector_code;        /* Information about sectors */
  79:     char    interleave;     /* interleave factor */
  80:     char    secperrot;      /* sectors per rotation for track */
  81:     u_short skew;           /* skew factor */
  82:     char    side_code;      /* 0=side 0, 1=side 1; 2=either side */
  83: } rx3info[NRX3][NSEC] = {
  84:     0L,     252928L, 0, 77, 0, 2,  13, 6, 0,
  85:     0L, 0L,      0, 0,  0, 1,  0,  0, 0,
  86:     0L, 0L,      0, 0,  0, 1,  0,  0, 0,
  87:     0L,     252928L, 0, 77, 0, 1,  26, 0, 0
  88: };
  89: 
  90: struct secinfo {
  91:     char    no_sect;        /* number of sectors per cyclinder */
  92:     short   bytpersec;      /* number of bytes per sector */
  93:     char    density;        /* 0=single, 1=double */
  94:     short   bytpertrk;      /* number of bytes per track */
  95:     short   sect_size;      /* coded sector size */
  96: } secinfo[] = {
  97:     26, 128, 0, 26*128, 0,      /* 26  128 byte sect/trk */
  98:     26, 256, 1, 26*256, 0,
  99:     15, 256, 1, 15*256, 2,      /* 15 512 byte sectors/track */
 100:     15, 512, 1, 15*512, 2,
 101:     8,  512, 1, 8*512,  4,      /* 8 512 byte sectors/trakc */
 102:     8, 1024, 1, 8*1024, 4
 103:     };
 104: 
 105: struct  rx3stat {
 106:     char    rx3open;        /* open/closed status */
 107:     short   bytect;         /* remaining bytes */
 108:     char    com;            /* save current command */
 109:     char    sec_code;       /* pointer to sector data */
 110:     caddr_t addr;           /* address in memory */
 111:     short   xmem;           /* high order bits of memory */
 112:     off_t   seek;           /* current byte to begin operation */
 113:     short   uid;            /* current user's uid */
 114: } rx3stat[NRX3];
 115: 
 116: struct  rx3errs {
 117:     short   retries;        /* number of retries */
 118:     short   errs;           /* number of hard errors */
 119:     short   errreg;         /* Last error register */
 120:     short   stat1;          /* extended status location 1 */
 121:     short   stat2;          /* extended status location 2 */
 122:     short   stat3;          /* extended status location 3 */
 123:     short   stat4;          /* extended status location 4 */
 124: } rx3errs[NRX3];
 125: 
 126: struct  buf rx3tab; /* driver info */
 127: 
 128: /*
 129:  * ioctl commands for
 130:  * rx03 floppy
 131:  */
 132: #define RX3SET      ((('r') << 8) | 2)  /* set up parameters */
 133: #define RX3RD       ((('r') << 8) | 3)  /* read parameters */
 134: #define RX3STAT     ((('r') << 8) | 4)  /* read status */
 135: #define RX3ERR      ((('r') << 8) | 5)  /* give error information */
 136: 
 137: /*
 138:  * Commands.
 139:  */
 140: #define XINIT       01
 141: #define XREAD       02
 142: #define XWRITE      04
 143: #define XFILL       010
 144: #define XEMPTY      020
 145: #define XERR        040
 146: 
 147: /*
 148:  * States.
 149:  */
 150: #define NCRC        10      /* number of crc retries */
 151: #define NDEN        2       /* number of density retries */
 152: 
 153: #ifdef  RX3_TIMEOUT
 154: int rx3_wticks;     /* used to keep track of lost interrupts */
 155: int rx3wstart;
 156: int rx3watch();
 157: #endif	RX3_TIMEOUT
 158: 
 159: /*
 160:  * Open drive for use.
 161:  *
 162:  */
 163: /*ARGSUSED*/
 164: rx3open(dev, flag)
 165: register dev_t dev;
 166: {
 167:     register drv, result;
 168: 
 169:     drv = RXUNIT(dev);
 170: 
 171: 
 172:     /* Make sure drive is a valid one */
 173:     if (drv >= NRX3) {
 174:         u.u_error = ENXIO;
 175:         return;
 176:     };
 177: 
 178: #ifdef  RX3_TIMEOUT
 179:     /* Start timing for timeouts.  Set status to open */
 180:     if (rx3wstart==0)
 181:         timeout(rx3watch, (caddr_t) 0, TTIME);
 182:     rx3wstart++;
 183: #endif
 184: 
 185:     rx3stat[drv].rx3open++;
 186:     rx3stat[drv].uid = u.u_uid;
 187:     rx3errs[drv].retries = 0;
 188:     rx3errs[drv].errs = 0;
 189: }
 190: 
 191: /*
 192:  * Close drive. Simply need to turn off timeouts and
 193:  * set drive status to closed.
 194:  */
 195: /*ARGSUSED*/
 196: rx3close(dev, flag)
 197: register dev_t dev;
 198: {
 199:     register drv = RXUNIT(dev);
 200: 
 201: #ifdef  RX3_TIMEOUT
 202:     rx3wstart--;
 203: #endif	RX3_TIMEOUT
 204:     rx3stat[drv].rx3open--;
 205:     if (rx3stat[drv].rx3open < 0)
 206:         rx3stat[drv].rx3open = 0;
 207: }
 208: 
 209: rx3strategy(bp)
 210: register struct buf *bp;
 211: {
 212:     register opl;
 213:     int mdev,okay,i;
 214:     off_t seek;
 215: 
 216: #ifdef  UNIBUS_MAP
 217:     if (bp->b_flags & B_PHYS)
 218:         mapalloc(bp);
 219: #endif
 220:     /*
 221: 	 *  Make sure block number is within range.
 222: 	 */
 223:     okay = 0;
 224:     mdev = RXUNIT(bp->b_dev);
 225:     seek = (dbtofsb(bp->b_blkno) << BSHIFT) + bp->b_bcount;
 226:     for (i=0; i<NSEC;  i++)
 227:         if ((rx3info[mdev][i].no_bytes+rx3info[mdev][i].first_byte) >
 228:                                 seek) okay = 1;
 229:     if (!okay) {
 230:         bp->b_flags |= B_ERROR;
 231:         iodone(bp);
 232:         return;
 233:     };
 234: 
 235:     /*
 236: 	 * Link buffer into rx3device queue
 237: 	 */
 238:     bp->av_forw = (struct buf *) NULL;
 239:     opl = spl5();
 240:     if (rx3tab.b_actf == (struct buf *) NULL)
 241:         rx3tab.b_actf = bp;
 242:     else
 243:         rx3tab.b_actl->av_forw = bp;
 244:     rx3tab.b_actl = bp;
 245:     if (rx3tab.b_active == 0)
 246:         rx3start();
 247:     splx(opl);
 248: }
 249: 
 250: /*
 251:  *  Start processing command.
 252:  */
 253: rx3start()
 254: {
 255:     register struct buf *bp;
 256:     register int mdev;
 257: 
 258: 
 259:     if ((bp = rx3tab.b_actf) == (struct buf *) NULL)
 260:         return;
 261:     rx3tab.b_active++;
 262: 
 263:     /*
 264: 	 * get minor rx3device number from buffer
 265: 	 */
 266:     mdev = RXUNIT(bp->b_dev);
 267: 
 268:     /*
 269: 	 *  Set up status for current buffer
 270: 	 */
 271:     rx3stat[mdev].addr = bp->b_un.b_addr;
 272:     rx3stat[mdev].xmem = bp->b_xmem;
 273:     rx3stat[mdev].seek = dbtofsb(bp->b_blkno) << BSHIFT;
 274:     rx3stat[mdev].bytect = bp->b_bcount;
 275: 
 276:     /*
 277: 	 * if command is read, initiate the command
 278: 	 * if command is write, fill the rx3device buffer,
 279: 	 *   then initiate the write
 280: 	 */
 281:     if (bp->b_flags & B_READ)
 282:         rx3io(bp, XREAD);
 283:     else
 284:         rx3io(bp, XFILL);
 285: }
 286: 
 287: /*
 288:  * Do actual IO command.
 289:  */
 290: rx3io(bp, cmd)
 291: register struct buf *bp;
 292: register short cmd;
 293: {
 294:     register struct rx3device *rx3r;
 295:     int sect, code, trk, side, drv;
 296: 
 297: 
 298:     rx3r = RX3ADDR;
 299:     drv = RXUNIT(bp->b_dev);
 300:     rx3stat[drv].com = cmd;
 301:         rx3leave(bp,drv,&code,&sect,&trk,&side);
 302:     rx3stat[drv].sec_code = code;
 303: 
 304:     switch (cmd) {
 305:         case XINIT:  /* Read status */
 306:             cmd = RX2_GO|RX2_RDSTAT|RX2_IE|drv<<4;
 307:             rx3r->rx2cs = cmd;
 308:             break;
 309: 
 310:         case XREAD: /* Read Sector */
 311:             cmd = RX2_GO|RX2_RSECT|RX2_IE|(drv<<4)|(secinfo[code].density<<8)|
 312:                 (side<<9);
 313:             rx3r->rx2cs = cmd;
 314:             trwait();
 315:             rx3r->rx2sa = sect|(secinfo[code].sect_size<<5);
 316:             trwait();
 317:             rx3r->rx2ta = trk;
 318:             break;
 319: 
 320:         case XEMPTY:    /* Empty buffer */
 321:             /* no disk i/o; unit not needed */
 322:             cmd = RX2_GO|RX2_EMPTY|RX2_IE|(side<<9)|(secinfo[code].density<<8)|
 323:                 (drv<<4)|(rx3stat[drv].xmem<<12);
 324:             rx3r->rx2cs = cmd;
 325:             trwait();
 326:                 /* NOT 2's complement */
 327:             if (rx3stat[drv].bytect <= secinfo[code].bytpersec)
 328:                 rx3r->rx2wc = rx3stat[drv].bytect>>1;
 329:             else
 330:                 rx3r->rx2wc = secinfo[code].bytpersec>>1;
 331:             trwait();
 332:             rx3r->rx2ba = (int) rx3stat[drv].addr;
 333:             break;
 334: 
 335:         case XWRITE:        /* Write buffer to disk */
 336:             cmd = RX2_GO|RX2_WSECT|RX2_IE|(drv<<4)|(secinfo[code].density<<8)|
 337:                 (side<<9);
 338:             rx3r->rx2cs = cmd;
 339:             trwait();
 340:             rx3r->rx2sa = sect|(secinfo[code].sect_size<<5);
 341:             trwait();
 342:             rx3r->rx2ta = trk;
 343:             break;
 344: 
 345:         case XFILL:     /* Fill disk buffer */
 346:             /* no disk i/o; unit not needed */
 347:             cmd = RX2_GO|RX2_FILL|RX2_IE|(side<<9)|(secinfo[code].density<<8)|
 348:                 (drv<<4)|(rx3stat[drv].xmem<<12);
 349:             rx3r->rx2cs = cmd;
 350:             trwait();
 351:                 /* NOT 2's complement */
 352:             if (rx3stat[drv].bytect <= secinfo[code].bytpersec)
 353:                 rx3r->rx2wc = rx3stat[drv].bytect>>1;
 354:             else
 355:                 rx3r->rx2wc = secinfo[code].bytpersec>>1;
 356:             trwait();
 357:             rx3r->rx2ba = (int) rx3stat[drv].addr;
 358:             break;
 359: 
 360:         case XERR:  /* Read extended error status */
 361:             cmd = RX2_IE|RX2_RDEC;
 362:             rx3r->rx2cs = cmd;
 363:             trwait();
 364:             rx3r->rx2ba = (int) &rx3errs[drv].stat1;
 365:             break;
 366: 
 367:         default:
 368:             panic("rx3io");
 369:             break;
 370:     }
 371: }
 372: 
 373: /*
 374:  *	Process interrupt.
 375:  */
 376: rx3intr()
 377: {
 378:     register struct buf *bp;
 379:     register struct rx3device *rx3r;
 380:     int drv, code;
 381:     long paddr;
 382: 
 383: 
 384:     if (rx3tab.b_active == 0) {
 385:         printf("rx3:  stray interrupt\n");
 386:         return;
 387:     }
 388: 
 389:     bp = rx3tab.b_actf;
 390:     rx3r = RX3ADDR;
 391: #ifdef  RX3_TIMEOUT
 392:     rx3_wticks = 0;
 393: #endif	RX3_TIMEOUT
 394: 
 395:     if (rx3r->rx2cs < 0) {
 396:         rx3err(bp);
 397:         return;
 398:     }
 399: 
 400:     drv = RXUNIT(bp->b_dev);
 401: 
 402:     switch (rx3stat[drv].com) {
 403:         case XINIT:
 404:             rx3errs[drv].errreg = rx3r->rx2es;
 405:             rx3tab.b_active = 0;
 406:             rx3tab.b_errcnt = 0;
 407:             rx3stat[drv].bytect = 0;
 408:             iodone(bp);
 409:             break;
 410:         case XREAD:
 411:             rx3io(bp, XEMPTY);
 412:             break;
 413:         case XFILL:
 414:             rx3io(bp, XWRITE);
 415:             break;
 416:         case XWRITE:    /* Go on to next sector if should */
 417:         case XEMPTY:
 418:             code = rx3stat[drv].sec_code;
 419:             if (rx3stat[drv].bytect <= secinfo[code].bytpersec) {
 420:                 rx3stat[drv].bytect = 0;
 421:                 rx3tab.b_errcnt = 0;
 422:                 rx3tab.b_active = 0;
 423:                 rx3tab.b_actf = bp->av_forw;
 424:                 iodone(bp);
 425:                 rx3start();
 426:             }
 427:             else {
 428:                 rx3stat[drv].bytect -= secinfo[code].bytpersec;
 429:                 paddr = (long) rx3stat[drv].addr +
 430:                     (long) secinfo[code].bytpersec;
 431:                 rx3stat[drv].addr = (caddr_t) paddr;
 432:                 rx3stat[drv].xmem = rx3stat[drv].xmem +
 433:                     (int) (paddr>>16);
 434:                 rx3stat[drv].seek += secinfo[code].bytpersec;
 435:                 if (rx3stat[drv].com==XWRITE)
 436:                     rx3stat[drv].com=XFILL;
 437:                 else rx3stat[drv].com=XREAD;
 438:                 rx3io(bp,rx3stat[drv].com);
 439:             }
 440:             break;
 441:         case XERR:
 442:             break;
 443: 
 444:         default:
 445:             printf("rx3:  command %o\n", rx3stat[drv].com);
 446:             break;
 447:     }
 448: }
 449: 
 450: /*
 451:  * Handle an error condition.
 452:  * Crc errors and density errors get retries,
 453:  * only NDEN for density errors and NCRC for crc errors.
 454:  * All other errors are considered hard errors.
 455:  */
 456: rx3err(bp)
 457: register struct buf *bp;
 458: {
 459:     register struct rx3device *rx3r;
 460:     register int drv;
 461:     register int cmd;
 462: 
 463:     drv = minor(bp->b_dev);
 464: 
 465: 
 466:     rx3tab.b_active = 0;
 467:     rx3r = RX3ADDR;
 468:     rx3errs[drv].errreg = rx3r->rx2es;
 469: 
 470:     /*
 471: 	 * Crc error.
 472: 	 */
 473:     if (rx3r->rx2es & RX2ES_CRC) {
 474:         rx3errs[drv].retries++;
 475:         if (rx3tab.b_errcnt < NCRC) {
 476:             rx3tab.b_errcnt++;
 477:             rx3reset();
 478:             return;
 479:         }
 480:     }
 481: 
 482:     /*
 483: 	 * Density error.
 484: 	 */
 485:     if (rx3r->rx2es & RX2ES_DENSERR) {
 486:         rx3errs[drv].retries++;
 487:         if (rx3tab.b_errcnt < NDEN) {
 488:             rx3tab.b_errcnt++;
 489:             rx3reset();
 490:             return;
 491:         }
 492:     }
 493: 
 494:     rx3errs[drv].errs++;
 495:     bp->b_flags |= B_ERROR;
 496: #ifdef  UCB_DEVERR
 497:     harderr(bp, "rx3");
 498:     printf("cs=%b er=%b\n", rx3r->rx2cs, RX2_BITS, rx3r->rx2es, RX2ES_BITS);
 499: #else
 500:     deverror(bp, (rx3r->rx2es&0377), (rx3r->rx2cs));
 501: #endif	UCB_DEVERR
 502: 
 503:     rx3tab.b_active = 0;
 504:     rx3tab.b_errcnt = 0;
 505:     rx3tab.b_actf = bp->av_forw;
 506: 
 507:     iodone(bp);
 508:     rx3reset();
 509: }
 510: 
 511: /*
 512:  * Calculate the physical sector and physical track on the
 513:  * disk for a given logical sector.
 514:  *
 515:  */
 516: rx3leave(bp,drv,code,sect,trk,side)
 517: int *code,*sect,*trk,*side;
 518: register struct buf *bp;
 519: {
 520:     off_t seek, t0;
 521:     int t1,t2,t3;
 522:     int section;
 523: 
 524: 
 525:     /*
 526: 	 * Determine track by searching the rx3info table
 527: 	 * looking at first_byte and no_bytes.
 528: 	 *     first_byte <= seek < first_byte + no_bytes
 529: 	 */
 530:     seek = rx3stat[drv].seek;
 531:     section = 0;
 532:     *trk = 0;
 533:     while (section<NSEC && *trk==0) {
 534:         if (rx3info[drv][section].first_byte <= rx3stat[drv].seek) {
 535:             t0 = rx3info[drv][section].first_byte +
 536:                  rx3info[drv][section].no_bytes;
 537:             if (rx3stat[drv].seek < t0) *trk = 1;
 538:         }
 539:         if (!*trk) {
 540:             seek -= rx3info[drv][section].no_bytes;
 541:             section++;
 542:         }
 543:     }
 544:     if (!*trk) {
 545:         bp->b_flags |= B_ERROR;
 546:             rx3tab.b_active = 0;
 547:         iodone(bp);
 548:         return(1);
 549:     };
 550:     *code = rx3info[drv][section].sector_code;
 551:     t1 = secinfo[*code].bytpertrk;
 552:     t2 = t1 * (rx3info[drv][section].side_code==2 ? 2 : 1 );
 553:     *trk = seek/t2;     /* track offset */
 554: 
 555:     /*
 556: 	 * Determine side of disk.  Use section code.
 557:  	 */
 558:     t3 = seek % t2;         /* sector offset in track */
 559:     if (rx3info[drv][section].side_code==0) *side = 0;
 560:     else if (rx3info[drv][section].side_code==1) *side = 1;
 561:     else {
 562:         if (t3 < t1) *side = 0;
 563:         else {
 564:             t3 -= t1;
 565:             *side = 1;
 566:         }
 567:     };
 568: 
 569:     /*
 570: 	 * Determine physical sector.
 571: 	 */
 572:     t1 = t3 / secinfo[*code].bytpersec; /* logical sector */
 573:     t1 = t1 % secinfo[*code].no_sect;
 574:     t2 = t1 / rx3info[drv][section].secperrot;  /* logical rotation */
 575:     t3 = t1 % rx3info[drv][section].secperrot;  /* sector offset */
 576:     t3 = t3 * rx3info[drv][section].interleave;
 577:     t3 = t3 + (rx3info[drv][section].skew * *trk);
 578:     /* sector count begins with 1 */
 579:     *sect = (t3 + t2) % secinfo[*code].no_sect + 1;
 580:     *trk += rx3info[drv][section].first_track;  /* physical track */
 581:         return(0);
 582: }
 583: 
 584: rx3ioctl(dev, cmd, addr, flag)
 585: caddr_t addr;
 586: {
 587:     int drv;
 588:     register struct rx3device *rx3r;
 589: 
 590:     drv = RXUNIT(dev);
 591: 
 592: 
 593:     switch (cmd) {
 594:         case RX3SET:    /* Setup parameters for disk */
 595:             if (copyin(addr, (caddr_t)rx3info[drv],
 596:                         sizeof(struct rx3info)*NSEC)) {
 597:                 u.u_error = EFAULT;
 598:                 return;
 599:             };
 600:             break;
 601:         case RX3RD: /* return disk parameters */
 602:             if (copyout((caddr_t)rx3info[drv], addr,
 603:                         sizeof(struct rx3info)*NSEC)) {
 604:                 u.u_error = EFAULT;
 605:                 return;
 606:             }
 607:             break;
 608:         case RX3STAT:
 609:             break;
 610:         case RX3ERR:
 611:             if (copyout( (caddr_t)&rx3errs[drv], addr,
 612:                         sizeof(struct rx3errs))) {
 613:                 u.u_error = EFAULT;
 614:                 return;
 615:             }
 616:             break;
 617:         default:
 618:             u.u_error = ENOTTY;
 619:             break;
 620:     }
 621: }
 622: 
 623: /*
 624:  * reset drives and restart controller.
 625:  */
 626: rx3reset() {
 627:     register struct rx3device *rx3r;
 628:     register int i;
 629:     register short cmd;
 630: 
 631: 
 632:     rx3r = RX3ADDR;
 633: 
 634:     /*
 635: 	 * If any drive is in use
 636: 	 * then do an init.
 637: 	 */
 638:     for (i = 0; i < NRX3; i++) {
 639:         if (rx3stat[i].rx3open) {
 640:             rx3r->rx2cs = RX2_INIT;
 641:             while ((rx3r->rx2cs & RX2_DONE) == 0);
 642:             break;
 643:         }
 644:     }
 645: 
 646:     rx3start();
 647: }
 648: 
 649: #ifdef  RX3_TIMEOUT
 650: /*
 651:  * Wake up every second and if an interrupt is pending
 652:  * but nothing has happened increment wticks. If nothing
 653:  * happens for 60 seconds, reset the controller and begin
 654:  * anew.
 655:  */
 656: rx3watch()
 657: {
 658:     if (rx3wstart)
 659:         timeout(rx3watch, (caddr_t) 0, TTIME);
 660: 
 661:     if (rx3tab.b_active == 0) {
 662:         rx3_wticks = 0;     /* idling */
 663:         return;
 664:     }
 665: 
 666:     rx3_wticks++;
 667: 
 668:     if (rx3_wticks >= 60) {
 669:         rx3_wticks = 0;
 670:         printf("rx3:  lost interrupt\n");
 671:         rx3reset();
 672:     }
 673: }
 674: #endif	RX3_TIMEOUT
 675: #endif	NRX3

Defined functions

rx3close defined in line 196; never used
rx3err defined in line 456; used 1 times
rx3intr defined in line 376; never used
rx3io defined in line 290; used 5 times
rx3ioctl defined in line 584; never used
rx3leave defined in line 516; used 1 times
rx3open defined in line 164; used 6 times
rx3reset defined in line 626; used 4 times
rx3start defined in line 253; used 3 times
rx3strategy defined in line 209; never used
rx3watch defined in line 656; used 3 times

Defined variables

rx3_wticks defined in line 154; used 5 times
rx3errs defined in line 124; used 9 times
rx3info defined in line 83; used 17 times
rx3stat defined in line 114; used 39 times
rx3tab defined in line 126; used 24 times
rx3wstart defined in line 155; used 4 times
secinfo defined in line 96; used 18 times

Defined struct's

rx3errs defined in line 116; used 2 times
  • in line 612(2)
rx3info defined in line 73; used 4 times
rx3stat defined in line 105; never used
secinfo defined in line 90; never used

Defined macros

MSEC defined in line 62; never used
NCRC defined in line 150; used 1 times
NDEN defined in line 151; used 1 times
NSEC defined in line 61; used 5 times
RX3ERR defined in line 135; never used
RX3RD defined in line 133; never used
RX3SET defined in line 132; never used
RX3STAT defined in line 134; never used
RXUNIT defined in line 59; used 7 times
TTIME defined in line 63; used 2 times
XEMPTY defined in line 144; used 1 times
XERR defined in line 145; never used
XFILL defined in line 143; used 2 times
XINIT defined in line 140; never used
XREAD defined in line 141; used 2 times
XWRITE defined in line 142; used 2 times
trwait defined in line 64; used 9 times
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1299
Valid CSS Valid XHTML 1.0 Strict