1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)tm.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "te.h"
  10: #include "ts.h"
  11: #if NTE > 0
  12: /*
  13:  * TM11/TE10 tape driver
  14:  *
  15:  * TODO:
  16:  *	test driver with more than one slave
  17:  *	test driver with more than one controller
  18:  *	test reset code
  19:  *	what happens if you offline tape during rewind?
  20:  *	test using file system on tape
  21:  */
  22: #include "../machine/pte.h"
  23: 
  24: #include "param.h"
  25: #include "systm.h"
  26: #include "buf.h"
  27: #include "dir.h"
  28: #include "conf.h"
  29: #include "user.h"
  30: #include "file.h"
  31: #include "map.h"
  32: #include "vm.h"
  33: #include "ioctl.h"
  34: #include "mtio.h"
  35: #include "cmap.h"
  36: #include "uio.h"
  37: #include "kernel.h"
  38: #include "tty.h"
  39: 
  40: #include "../vax/cpu.h"
  41: #include "ubareg.h"
  42: #include "ubavar.h"
  43: #include "tmreg.h"
  44: 
  45: /*
  46:  * There is a ctmbuf per tape controller.
  47:  * It is used as the token to pass to the internal routines
  48:  * to execute tape ioctls, and also acts as a lock on the slaves
  49:  * on the controller, since there is only one per controller.
  50:  * In particular, when the tape is rewinding on close we release
  51:  * the user process but any further attempts to use the tape drive
  52:  * before the rewind completes will hang waiting for ctmbuf.
  53:  */
  54: struct  buf ctmbuf[NTM];
  55: 
  56: /*
  57:  * Raw tape operations use rtmbuf.  The driver
  58:  * notices when rtmbuf is being used and allows the user
  59:  * program to continue after errors and read records
  60:  * not of the standard length (BSIZE).
  61:  */
  62: struct  buf rtmbuf[NTM];
  63: 
  64: /*
  65:  * Driver unibus interface routines and variables.
  66:  */
  67: int tmprobe(), tmslave(), tmattach(), tmdgo(), tmintr();
  68: struct  uba_ctlr *tmminfo[NTM];
  69: struct  uba_device *tedinfo[NTE];
  70: struct  buf teutab[NTE];
  71: short   tetotm[NTE];
  72: u_short tmstd[] = { 0772520, 0 };
  73: struct  uba_driver tmdriver =
  74:  { tmprobe, tmslave, tmattach, tmdgo, tmstd, "te", tedinfo, "tm", tmminfo, 0 };
  75: 
  76: /* bits in minor device */
  77: #define TEUNIT(dev) (minor(dev)&03)
  78: #define TMUNIT(dev) (tetotm[TEUNIT(dev)])
  79: #define T_NOREWIND  04
  80: #define T_1600BPI   0x8
  81: 
  82: #define INF (daddr_t)1000000L
  83: 
  84: /*
  85:  * Software state per tape transport.
  86:  *
  87:  * 1. A tape drive is a unique-open device; we refuse opens when it is already.
  88:  * 2. We keep track of the current position on a block tape and seek
  89:  *    before operations by forward/back spacing if necessary.
  90:  * 3. We remember if the last operation was a write on a tape, so if a tape
  91:  *    is open read write and the last thing done is a write we can
  92:  *    write a standard end of tape mark (two eofs).
  93:  * 4. We remember the status registers after the last command, using
  94:  *    then internally and returning them to the SENSE ioctl.
  95:  * 5. We remember the last density the tape was used at.  If it is
  96:  *    not a BOT when we start using it and we are writing, we don't
  97:  *    let the density be changed.
  98:  */
  99: struct  te_softc {
 100:     char    sc_openf;   /* lock against multiple opens */
 101:     char    sc_lastiow; /* last op was a write */
 102:     daddr_t sc_blkno;   /* block number, for block device tape */
 103:     daddr_t sc_nxrec;   /* position of end of tape, if known */
 104:     u_short sc_erreg;   /* copy of last erreg */
 105:     u_short sc_dsreg;   /* copy of last dsreg */
 106:     short   sc_resid;   /* copy of last bc */
 107: #ifdef unneeded
 108:     short   sc_lastcmd; /* last command to handle direction changes */
 109: #endif
 110:     u_short sc_dens;    /* prototype command with density info */
 111:     short   sc_tact;    /* timeout is active */
 112:     daddr_t sc_timo;    /* time until timeout expires */
 113:     struct  tty *sc_ttyp;   /* record user's tty for errors */
 114: } te_softc[NTE];
 115: #ifdef unneeded
 116: int tmgapsdcnt;     /* DEBUG */
 117: #endif
 118: 
 119: /*
 120:  * States for um->um_tab.b_active, the per controller state flag.
 121:  * This is used to sequence control in the driver.
 122:  */
 123: #define SSEEK   1       /* seeking */
 124: #define SIO 2       /* doing seq i/o */
 125: #define SCOM    3       /* sending control command */
 126: #define SREW    4       /* sending a drive rewind */
 127: 
 128: /*
 129:  * Determine if there is a controller for
 130:  * a tm at address reg.  Our goal is to make the
 131:  * device interrupt.
 132:  */
 133: tmprobe(reg)
 134:     caddr_t reg;
 135: {
 136:     register int br, cvec;      /* must be r11,r10; value-result */
 137: 
 138: #ifdef lint
 139:     br = 0; cvec = br; br = cvec;
 140:     tmintr(0);
 141: #endif
 142:     ((struct tmdevice *)reg)->tmcs = TM_IE;
 143:     /*
 144: 	 * If this is a tm11, it ought to have interrupted
 145: 	 * by now, if it isn't (ie: it is a ts04) then we just
 146: 	 * hope that it didn't interrupt, so autoconf will ignore it.
 147: 	 * Just in case, we will reference one
 148: 	 * of the more distant registers, and hope for a machine
 149: 	 * check, or similar disaster if this is a ts.
 150: 	 *
 151: 	 * Note: on an 11/780, badaddr will just generate
 152: 	 * a uba error for a ts; but our caller will notice that
 153: 	 * so we won't check for it.
 154: 	 */
 155:     if (badaddr((caddr_t)&((struct tmdevice *)reg)->tmrd, 2))
 156:         return (0);
 157:     return (sizeof (struct tmdevice));
 158: }
 159: 
 160: /*
 161:  * Due to a design flaw, we cannot ascertain if the tape
 162:  * exists or not unless it is on line - ie: unless a tape is
 163:  * mounted. This is too servere a restriction to bear,
 164:  * so all units are assumed to exist.
 165:  */
 166: /*ARGSUSED*/
 167: tmslave(ui, reg)
 168:     struct uba_device *ui;
 169:     caddr_t reg;
 170: {
 171: 
 172:     return (1);
 173: }
 174: 
 175: /*
 176:  * Record attachment of the unit to the controller.
 177:  */
 178: /*ARGSUSED*/
 179: tmattach(ui)
 180:     struct uba_device *ui;
 181: {
 182:     /*
 183: 	 * Tetotm is used in TMUNIT to index the ctmbuf and rtmbuf
 184: 	 * arrays given a te unit number.
 185: 	 */
 186:     tetotm[ui->ui_unit] = ui->ui_mi->um_ctlr;
 187: }
 188: 
 189: int tmtimer();
 190: /*
 191:  * Open the device.  Tapes are unique open
 192:  * devices, so we refuse if it is already open.
 193:  * We also check that a tape is available, and
 194:  * don't block waiting here; if you want to wait
 195:  * for a tape you should timeout in user code.
 196:  */
 197: 
 198: #ifdef AVIV
 199: int tmdens[4] = { 0x6000, 0x0000, 0x2000, 0 };
 200: int tmdiag;
 201: #endif AVIV
 202: 
 203: tmopen(dev, flag)
 204:     dev_t dev;
 205:     int flag;
 206: {
 207:     register int teunit;
 208:     register struct uba_device *ui;
 209:     register struct te_softc *sc;
 210:     int olddens, dens;
 211:     int s;
 212: 
 213:     teunit = TEUNIT(dev);
 214:     if (teunit>=NTE || (ui = tedinfo[teunit]) == 0 || ui->ui_alive == 0)
 215:         return (ENXIO);
 216:     if ((sc = &te_softc[teunit])->sc_openf)
 217:         return (EBUSY);
 218:     olddens = sc->sc_dens;
 219:     dens = TM_IE | TM_GO | (ui->ui_slave << 8);
 220: #ifndef AVIV
 221:     if ((minor(dev) & T_1600BPI) == 0)
 222:         dens |= TM_D800;
 223: #else AVIV
 224:     dens |= tmdens[(minor(dev)>>3)&03];
 225: #endif AVIV
 226:     sc->sc_dens = dens;
 227: get:
 228:     tmcommand(dev, TM_SENSE, 1);
 229:     if (sc->sc_erreg&TMER_SDWN) {
 230:         sleep((caddr_t)&lbolt, PZERO+1);
 231:         goto get;
 232:     }
 233:     sc->sc_dens = olddens;
 234:     if ((sc->sc_erreg&(TMER_SELR|TMER_TUR)) != (TMER_SELR|TMER_TUR)) {
 235:         uprintf("te%d: not online\n", teunit);
 236:         return (EIO);
 237:     }
 238:     if ((flag&FWRITE) && (sc->sc_erreg&TMER_WRL)) {
 239:         uprintf("te%d: no write ring\n", teunit);
 240:         return (EIO);
 241:     }
 242:     if ((sc->sc_erreg&TMER_BOT) == 0 && (flag&FWRITE) &&
 243:         dens != sc->sc_dens) {
 244:         uprintf("te%d: can't change density in mid-tape\n", teunit);
 245:         return (EIO);
 246:     }
 247:     sc->sc_openf = 1;
 248:     sc->sc_blkno = (daddr_t)0;
 249:     sc->sc_nxrec = INF;
 250:     sc->sc_lastiow = 0;
 251:     sc->sc_dens = dens;
 252:     sc->sc_ttyp = u.u_ttyp;
 253:     s = splclock();
 254:     if (sc->sc_tact == 0) {
 255:         sc->sc_timo = INF;
 256:         sc->sc_tact = 1;
 257:         timeout(tmtimer, (caddr_t)dev, 5*hz);
 258:     }
 259:     splx(s);
 260:     return (0);
 261: }
 262: 
 263: /*
 264:  * Close tape device.
 265:  *
 266:  * If tape was open for writing or last operation was
 267:  * a write, then write two EOF's and backspace over the last one.
 268:  * Unless this is a non-rewinding special file, rewind the tape.
 269:  * Make the tape available to others.
 270:  */
 271: tmclose(dev, flag)
 272:     register dev_t dev;
 273:     register flag;
 274: {
 275:     register struct te_softc *sc = &te_softc[TEUNIT(dev)];
 276: 
 277:     if (flag == FWRITE || (flag&FWRITE) && sc->sc_lastiow) {
 278:         tmcommand(dev, TM_WEOF, 1);
 279:         tmcommand(dev, TM_WEOF, 1);
 280:         tmcommand(dev, TM_SREV, 1);
 281:     }
 282:     if ((minor(dev)&T_NOREWIND) == 0)
 283:         /*
 284: 		 * 0 count means don't hang waiting for rewind complete
 285: 		 * rather ctmbuf stays busy until the operation completes
 286: 		 * preventing further opens from completing by
 287: 		 * preventing a TM_SENSE from completing.
 288: 		 */
 289:         tmcommand(dev, TM_REW, 0);
 290:     sc->sc_openf = 0;
 291: }
 292: 
 293: /*
 294:  * Execute a command on the tape drive
 295:  * a specified number of times.
 296:  */
 297: tmcommand(dev, com, count)
 298:     dev_t dev;
 299:     int com, count;
 300: {
 301:     register struct buf *bp;
 302:     register int s;
 303: 
 304:     bp = &ctmbuf[TMUNIT(dev)];
 305:     s = spl5();
 306:     while (bp->b_flags&B_BUSY) {
 307:         /*
 308: 		 * This special check is because B_BUSY never
 309: 		 * gets cleared in the non-waiting rewind case.
 310: 		 */
 311:         if (bp->b_repcnt == 0 && (bp->b_flags&B_DONE))
 312:             break;
 313:         bp->b_flags |= B_WANTED;
 314:         sleep((caddr_t)bp, PRIBIO);
 315:     }
 316:     bp->b_flags = B_BUSY|B_READ;
 317:     splx(s);
 318:     bp->b_dev = dev;
 319:     bp->b_repcnt = -count;
 320:     bp->b_command = com;
 321:     bp->b_blkno = 0;
 322:     tmstrategy(bp);
 323:     /*
 324: 	 * In case of rewind from close, don't wait.
 325: 	 * This is the only case where count can be 0.
 326: 	 */
 327:     if (count == 0)
 328:         return;
 329:     iowait(bp);
 330:     if (bp->b_flags&B_WANTED)
 331:         wakeup((caddr_t)bp);
 332:     bp->b_flags &= B_ERROR;
 333: }
 334: 
 335: /*
 336:  * Queue a tape operation.
 337:  */
 338: tmstrategy(bp)
 339:     register struct buf *bp;
 340: {
 341:     int teunit = TEUNIT(bp->b_dev);
 342:     register struct uba_ctlr *um;
 343:     register struct buf *dp;
 344:     int s;
 345: 
 346:     /*
 347: 	 * Put transfer at end of unit queue
 348: 	 */
 349:     dp = &teutab[teunit];
 350:     bp->av_forw = NULL;
 351:     s = spl5();
 352:     um = tedinfo[teunit]->ui_mi;
 353:     if (dp->b_actf == NULL) {
 354:         dp->b_actf = bp;
 355:         /*
 356: 		 * Transport not already active...
 357: 		 * put at end of controller queue.
 358: 		 */
 359:         dp->b_forw = NULL;
 360:         if (um->um_tab.b_actf == NULL)
 361:             um->um_tab.b_actf = dp;
 362:         else
 363:             um->um_tab.b_actl->b_forw = dp;
 364:         um->um_tab.b_actl = dp;
 365:     } else
 366:         dp->b_actl->av_forw = bp;
 367:     dp->b_actl = bp;
 368:     /*
 369: 	 * If the controller is not busy, get
 370: 	 * it going.
 371: 	 */
 372:     if (um->um_tab.b_active == 0)
 373:         tmstart(um);
 374:     splx(s);
 375: }
 376: 
 377: /*
 378:  * Start activity on a tm controller.
 379:  */
 380: tmstart(um)
 381:     register struct uba_ctlr *um;
 382: {
 383:     register struct buf *bp, *dp;
 384:     register struct tmdevice *addr = (struct tmdevice *)um->um_addr;
 385:     register struct te_softc *sc;
 386:     register struct uba_device *ui;
 387:     int teunit, cmd;
 388:     daddr_t blkno;
 389: 
 390:     /*
 391: 	 * Look for an idle transport on the controller.
 392: 	 */
 393: loop:
 394:     if ((dp = um->um_tab.b_actf) == NULL)
 395:         return;
 396:     if ((bp = dp->b_actf) == NULL) {
 397:         um->um_tab.b_actf = dp->b_forw;
 398:         goto loop;
 399:     }
 400:     teunit = TEUNIT(bp->b_dev);
 401:     ui = tedinfo[teunit];
 402:     /*
 403: 	 * Record pre-transfer status (e.g. for TM_SENSE)
 404: 	 */
 405:     sc = &te_softc[teunit];
 406:     addr = (struct tmdevice *)um->um_addr;
 407:     addr->tmcs = (ui->ui_slave << 8);
 408:     sc->sc_dsreg = addr->tmcs;
 409:     sc->sc_erreg = addr->tmer;
 410:     sc->sc_resid = addr->tmbc;
 411:     /*
 412: 	 * Default is that last command was NOT a write command;
 413: 	 * if we do a write command we will notice this in tmintr().
 414: 	 */
 415:     sc->sc_lastiow = 0;
 416:     if (sc->sc_openf < 0 || (addr->tmcs&TM_CUR) == 0) {
 417:         /*
 418: 		 * Have had a hard error on a non-raw tape
 419: 		 * or the tape unit is now unavailable
 420: 		 * (e.g. taken off line).
 421: 		 */
 422:         bp->b_flags |= B_ERROR;
 423:         goto next;
 424:     }
 425:     if (bp == &ctmbuf[TMUNIT(bp->b_dev)]) {
 426:         /*
 427: 		 * Execute control operation with the specified count.
 428: 		 */
 429:         if (bp->b_command == TM_SENSE)
 430:             goto next;
 431:         /*
 432: 		 * Set next state; give 5 minutes to complete
 433: 		 * rewind, or 10 seconds per iteration (minimum 60
 434: 		 * seconds and max 5 minutes) to complete other ops.
 435: 		 */
 436:         if (bp->b_command == TM_REW) {
 437:             um->um_tab.b_active = SREW;
 438:             sc->sc_timo = 5 * 60;
 439:         } else {
 440:             um->um_tab.b_active = SCOM;
 441:             sc->sc_timo =
 442:                 imin(imax(10*(int)-bp->b_repcnt,60),5*60);
 443:         }
 444:         if (bp->b_command == TM_SFORW || bp->b_command == TM_SREV)
 445:             addr->tmbc = bp->b_repcnt;
 446:         goto dobpcmd;
 447:     }
 448:     /*
 449: 	 * The following checks handle boundary cases for operation
 450: 	 * on non-raw tapes.  On raw tapes the initialization of
 451: 	 * sc->sc_nxrec by tmphys causes them to be skipped normally
 452: 	 * (except in the case of retries).
 453: 	 */
 454:     if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
 455:         /*
 456: 		 * Can't read past known end-of-file.
 457: 		 */
 458:         bp->b_flags |= B_ERROR;
 459:         bp->b_error = ENXIO;
 460:         goto next;
 461:     }
 462:     if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec &&
 463:         bp->b_flags&B_READ) {
 464:         /*
 465: 		 * Reading at end of file returns 0 bytes.
 466: 		 */
 467:         bp->b_resid = bp->b_bcount;
 468:         clrbuf(bp);
 469:         goto next;
 470:     }
 471:     if ((bp->b_flags&B_READ) == 0)
 472:         /*
 473: 		 * Writing sets EOF
 474: 		 */
 475:         sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1;
 476:     /*
 477: 	 * If the data transfer command is in the correct place,
 478: 	 * set up all the registers except the csr, and give
 479: 	 * control over to the UNIBUS adapter routines, to
 480: 	 * wait for resources to start the i/o.
 481: 	 */
 482:     if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) {
 483:         addr->tmbc = -bp->b_bcount;
 484:         if ((bp->b_flags&B_READ) == 0) {
 485:             if (um->um_tab.b_errcnt)
 486:                 cmd = TM_WIRG;
 487:             else
 488:                 cmd = TM_WCOM;
 489:         } else
 490:             cmd = TM_RCOM;
 491:         um->um_tab.b_active = SIO;
 492:         um->um_cmd = sc->sc_dens|cmd;
 493: #ifdef notdef
 494:         if (tmreverseop(sc->sc_lastcmd))
 495:             while (addr->tmer & TMER_SDWN)
 496:                 DELAY(10),tmgapsdcnt++;
 497:         sc->sc_lastcmd = TM_RCOM;       /* will serve */
 498: #endif
 499:         sc->sc_timo = 60;   /* premature, but should serve */
 500:         (void) ubago(ui);
 501:         return;
 502:     }
 503:     /*
 504: 	 * Tape positioned incorrectly;
 505: 	 * set to seek forwards or backwards to the correct spot.
 506: 	 * This happens for raw tapes only on error retries.
 507: 	 */
 508:     um->um_tab.b_active = SSEEK;
 509:     if (blkno < bdbtofsb(bp->b_blkno)) {
 510:         bp->b_command = TM_SFORW;
 511:         addr->tmbc = blkno - bdbtofsb(bp->b_blkno);
 512:     } else {
 513:         bp->b_command = TM_SREV;
 514:         addr->tmbc = bdbtofsb(bp->b_blkno) - blkno;
 515:     }
 516:     sc->sc_timo = imin(imax(10 * -addr->tmbc, 60), 5 * 60);
 517: dobpcmd:
 518: #ifdef notdef
 519:     /*
 520: 	 * It is strictly necessary to wait for the tape
 521: 	 * to stop before changing directions, but the TC11
 522: 	 * handles this for us.
 523: 	 */
 524:     if (tmreverseop(sc->sc_lastcmd) != tmreverseop(bp->b_command))
 525:         while (addr->tmer & TM_SDWN)
 526:             DELAY(10),tmgapsdcnt++;
 527:     sc->sc_lastcmd = bp->b_command;
 528: #endif
 529:     /*
 530: 	 * Do the command in bp.
 531: 	 */
 532:     addr->tmcs = (sc->sc_dens | bp->b_command);
 533:     return;
 534: 
 535: next:
 536:     /*
 537: 	 * Done with this operation due to error or
 538: 	 * the fact that it doesn't do anything.
 539: 	 * Release UBA resources (if any), dequeue
 540: 	 * the transfer and continue processing this slave.
 541: 	 */
 542:     if (um->um_ubinfo)
 543:         ubadone(um);
 544:     um->um_tab.b_errcnt = 0;
 545:     dp->b_actf = bp->av_forw;
 546:     iodone(bp);
 547:     goto loop;
 548: }
 549: 
 550: /*
 551:  * The UNIBUS resources we needed have been
 552:  * allocated to us; start the device.
 553:  */
 554: tmdgo(um)
 555:     register struct uba_ctlr *um;
 556: {
 557:     register struct tmdevice *addr = (struct tmdevice *)um->um_addr;
 558: 
 559:     addr->tmba = um->um_ubinfo;
 560:     addr->tmcs = um->um_cmd | ((um->um_ubinfo >> 12) & 0x30);
 561: }
 562: 
 563: /*
 564:  * Tm interrupt routine.
 565:  */
 566: /*ARGSUSED*/
 567: tmintr(tm11)
 568:     int tm11;
 569: {
 570:     struct buf *dp;
 571:     register struct buf *bp;
 572:     register struct uba_ctlr *um = tmminfo[tm11];
 573:     register struct tmdevice *addr;
 574:     register struct te_softc *sc;
 575:     int teunit;
 576:     register state;
 577: 
 578:     if ((dp = um->um_tab.b_actf) == NULL)
 579:         return;
 580:     bp = dp->b_actf;
 581:     teunit = TEUNIT(bp->b_dev);
 582:     addr = (struct tmdevice *)tedinfo[teunit]->ui_addr;
 583:     sc = &te_softc[teunit];
 584:     /*
 585: 	 * If last command was a rewind, and tape is still
 586: 	 * rewinding, wait for the rewind complete interrupt.
 587: 	 */
 588:     if (um->um_tab.b_active == SREW) {
 589:         um->um_tab.b_active = SCOM;
 590:         if (addr->tmer&TMER_RWS) {
 591:             sc->sc_timo = 5*60;     /* 5 minutes */
 592:             return;
 593:         }
 594:     }
 595:     /*
 596: 	 * An operation completed... record status
 597: 	 */
 598:     sc->sc_timo = INF;
 599:     sc->sc_dsreg = addr->tmcs;
 600:     sc->sc_erreg = addr->tmer;
 601:     sc->sc_resid = addr->tmbc;
 602:     if ((bp->b_flags & B_READ) == 0)
 603:         sc->sc_lastiow = 1;
 604:     state = um->um_tab.b_active;
 605:     um->um_tab.b_active = 0;
 606:     /*
 607: 	 * Check for errors.
 608: 	 */
 609:     if (addr->tmcs&TM_ERR) {
 610:         while (addr->tmer & TMER_SDWN)
 611:             DELAY(10);          /* await settle down */
 612:         /*
 613: 		 * If we hit the end of the tape file, update our position.
 614: 		 */
 615:         if (addr->tmer&TMER_EOF) {
 616:             tmseteof(bp);       /* set blkno and nxrec */
 617:             state = SCOM;       /* force completion */
 618:             /*
 619: 			 * Stuff bc so it will be unstuffed correctly
 620: 			 * later to get resid.
 621: 			 */
 622:             addr->tmbc = -bp->b_bcount;
 623:             goto opdone;
 624:         }
 625:         /*
 626: 		 * If we were reading raw tape and the only error was that the
 627: 		 * record was too long, then we don't consider this an error.
 628: 		 */
 629:         if (bp == &rtmbuf[TMUNIT(bp->b_dev)] && (bp->b_flags&B_READ) &&
 630:             (addr->tmer&(TMER_HARD|TMER_SOFT)) == TMER_RLE)
 631:             goto ignoreerr;
 632:         /*
 633: 		 * If error is not hard, and this was an i/o operation
 634: 		 * retry up to 8 times.
 635: 		 */
 636:         if ((addr->tmer&TMER_HARD)==0 && state==SIO) {
 637:             if (++um->um_tab.b_errcnt < 7) {
 638:                 sc->sc_blkno++;
 639:                 ubadone(um);
 640:                 goto opcont;
 641:             }
 642:         } else
 643:             /*
 644: 			 * Hard or non-i/o errors on non-raw tape
 645: 			 * cause it to close.
 646: 			 */
 647:             if (sc->sc_openf>0 && bp != &rtmbuf[TMUNIT(bp->b_dev)])
 648:                 sc->sc_openf = -1;
 649:         /*
 650: 		 * Couldn't recover error
 651: 		 */
 652:         tprintf(sc->sc_ttyp,
 653:             "te%d: hard error bn%d er=%b\n", minor(bp->b_dev)&03,
 654:             bp->b_blkno, sc->sc_erreg, TMER_BITS);
 655: #ifdef  AVIV
 656:         if (tmdiag) {
 657:             addr->tmmr = DAB;
 658:             printf("reject code 0%o", addr->tmmr & DAB_MASK);
 659:             addr->tmmr = DTS;
 660:             if (addr->tmmr & DTS_MASK)
 661:                 printf(", dead track 0%o", addr->tmmr & DTS_MASK);
 662:             addr->tmmr = RWERR;
 663:             printf(", read/write errors %b\n",
 664:                 addr->tmmr & RWERR_MASK,
 665:                 RWERR_BITS);
 666:             addr->tmmr = DRSENSE;
 667:             printf("drive sense %b, ", addr->tmmr & DRSENSE_MASK,
 668:                 DRSENSE_BITS);
 669:             printf("fsr %b\n", addr->tmfsr, FSR_BITS);
 670:         }
 671: #endif AVIV
 672:         bp->b_flags |= B_ERROR;
 673:         goto opdone;
 674:     }
 675:     /*
 676: 	 * Advance tape control FSM.
 677: 	 */
 678: ignoreerr:
 679:     switch (state) {
 680: 
 681:     case SIO:
 682:         /*
 683: 		 * Read/write increments tape block number
 684: 		 */
 685:         sc->sc_blkno++;
 686:         goto opdone;
 687: 
 688:     case SCOM:
 689:         /*
 690: 		 * For forward/backward space record update current position.
 691: 		 */
 692:         if (bp == &ctmbuf[TMUNIT(bp->b_dev)])
 693:         switch ((int)bp->b_command) {
 694: 
 695:         case TM_SFORW:
 696:             sc->sc_blkno -= bp->b_repcnt;
 697:             break;
 698: 
 699:         case TM_SREV:
 700:             sc->sc_blkno += bp->b_repcnt;
 701:             break;
 702:         }
 703:         goto opdone;
 704: 
 705:     case SSEEK:
 706:         sc->sc_blkno = bdbtofsb(bp->b_blkno);
 707:         goto opcont;
 708: 
 709:     default:
 710:         panic("tmintr");
 711:     }
 712: opdone:
 713:     /*
 714: 	 * Reset error count and remove
 715: 	 * from device queue.
 716: 	 */
 717:     um->um_tab.b_errcnt = 0;
 718:     dp->b_actf = bp->av_forw;
 719:     /*
 720: 	 * Check resid; watch out for resid >32767 (tmbc not negative).
 721: 	 */
 722:     bp->b_resid = ((int) -addr->tmbc) & 0xffff;
 723:     ubadone(um);
 724:     iodone(bp);
 725:     /*
 726: 	 * Circulate slave to end of controller
 727: 	 * queue to give other slaves a chance.
 728: 	 */
 729:     um->um_tab.b_actf = dp->b_forw;
 730:     if (dp->b_actf) {
 731:         dp->b_forw = NULL;
 732:         if (um->um_tab.b_actf == NULL)
 733:             um->um_tab.b_actf = dp;
 734:         else
 735:             um->um_tab.b_actl->b_forw = dp;
 736:         um->um_tab.b_actl = dp;
 737:     }
 738:     if (um->um_tab.b_actf == 0)
 739:         return;
 740: opcont:
 741:     tmstart(um);
 742: }
 743: 
 744: tmtimer(dev)
 745:     int dev;
 746: {
 747:     register struct te_softc *sc = &te_softc[TEUNIT(dev)];
 748:     register short x;
 749: 
 750:     if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) {
 751:         printf("te%d: lost interrupt\n", TEUNIT(dev));
 752:         sc->sc_timo = INF;
 753:         x = spl5();
 754:         tmintr(TMUNIT(dev));
 755:         (void) splx(x);
 756:     }
 757:     timeout(tmtimer, (caddr_t)dev, 5*hz);
 758: }
 759: 
 760: tmseteof(bp)
 761:     register struct buf *bp;
 762: {
 763:     register int teunit = TEUNIT(bp->b_dev);
 764:     register struct tmdevice *addr =
 765:         (struct tmdevice *)tedinfo[teunit]->ui_addr;
 766:     register struct te_softc *sc = &te_softc[teunit];
 767: 
 768:     if (bp == &ctmbuf[TMUNIT(bp->b_dev)]) {
 769:         if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) {
 770:             /* reversing */
 771:             sc->sc_nxrec = bdbtofsb(bp->b_blkno) - addr->tmbc;
 772:             sc->sc_blkno = sc->sc_nxrec;
 773:         } else {
 774:             /* spacing forward */
 775:             sc->sc_blkno = bdbtofsb(bp->b_blkno) + addr->tmbc;
 776:             sc->sc_nxrec = sc->sc_blkno - 1;
 777:         }
 778:         return;
 779:     }
 780:     /* eof on read */
 781:     sc->sc_nxrec = bdbtofsb(bp->b_blkno);
 782: }
 783: 
 784: tmread(dev, uio)
 785:     dev_t dev;
 786:     struct uio *uio;
 787: {
 788:     int errno;
 789: 
 790:     errno = tmphys(dev, uio);
 791:     if (errno)
 792:         return (errno);
 793:     return (physio(tmstrategy, &rtmbuf[TMUNIT(dev)], dev, B_READ, minphys, uio));
 794: }
 795: 
 796: tmwrite(dev, uio)
 797:     dev_t dev;
 798:     struct uio *uio;
 799: {
 800:     int errno;
 801: 
 802:     errno = tmphys(dev, uio);
 803:     if (errno)
 804:         return (errno);
 805:     return (physio(tmstrategy, &rtmbuf[TMUNIT(dev)], dev, B_WRITE, minphys, uio));
 806: }
 807: 
 808: /*
 809:  * Check that a raw device exists.
 810:  * If it does, set up sc_blkno and sc_nxrec
 811:  * so that the tape will appear positioned correctly.
 812:  */
 813: tmphys(dev, uio)
 814:     dev_t dev;
 815:     struct uio *uio;
 816: {
 817:     register int teunit = TEUNIT(dev);
 818:     register daddr_t a;
 819:     register struct te_softc *sc;
 820:     register struct uba_device *ui;
 821: 
 822:     if (teunit >= NTE || (ui=tedinfo[teunit]) == 0 || ui->ui_alive == 0)
 823:         return (ENXIO);
 824:     sc = &te_softc[teunit];
 825:     a = bdbtofsb(uio->uio_offset >> 9);
 826:     sc->sc_blkno = a;
 827:     sc->sc_nxrec = a + 1;
 828:     return (0);
 829: }
 830: 
 831: tmreset(uban)
 832:     int uban;
 833: {
 834:     register struct uba_ctlr *um;
 835:     register tm11, teunit;
 836:     register struct uba_device *ui;
 837:     register struct buf *dp;
 838: 
 839:     for (tm11 = 0; tm11 < NTM; tm11++) {
 840:         if ((um = tmminfo[tm11]) == 0 || um->um_alive == 0 ||
 841:            um->um_ubanum != uban)
 842:             continue;
 843:         printf(" tm%d", tm11);
 844:         um->um_tab.b_active = 0;
 845:         um->um_tab.b_actf = um->um_tab.b_actl = 0;
 846:         if (um->um_ubinfo) {
 847:             printf("<%d>", (um->um_ubinfo>>28)&0xf);
 848:             um->um_ubinfo = 0;
 849:         }
 850:         ((struct tmdevice *)(um->um_addr))->tmcs = TM_DCLR;
 851:         for (teunit = 0; teunit < NTE; teunit++) {
 852:             if ((ui = tedinfo[teunit]) == 0 || ui->ui_mi != um ||
 853:                 ui->ui_alive == 0)
 854:                 continue;
 855:             dp = &teutab[teunit];
 856:             dp->b_active = 0;
 857:             dp->b_forw = 0;
 858:             if (um->um_tab.b_actf == NULL)
 859:                 um->um_tab.b_actf = dp;
 860:             else
 861:                 um->um_tab.b_actl->b_forw = dp;
 862:             um->um_tab.b_actl = dp;
 863:             if (te_softc[teunit].sc_openf > 0)
 864:                 te_softc[teunit].sc_openf = -1;
 865:         }
 866:         tmstart(um);
 867:     }
 868: }
 869: 
 870: /*ARGSUSED*/
 871: tmioctl(dev, cmd, data, flag)
 872:     caddr_t data;
 873:     dev_t dev;
 874: {
 875:     int teunit = TEUNIT(dev);
 876:     register struct te_softc *sc = &te_softc[teunit];
 877:     register struct buf *bp = &ctmbuf[TMUNIT(dev)];
 878:     register callcount;
 879:     int fcount;
 880:     struct mtop *mtop;
 881:     struct mtget *mtget;
 882:     /* we depend of the values and order of the MT codes here */
 883:     static tmops[] =
 884:        {TM_WEOF,TM_SFORW,TM_SREV,TM_SFORW,TM_SREV,TM_REW,TM_OFFL,TM_SENSE};
 885: 
 886:     switch (cmd) {
 887: 
 888:     case MTIOCTOP:  /* tape operation */
 889:         mtop = (struct mtop *)data;
 890:         switch (mtop->mt_op) {
 891: 
 892:         case MTWEOF:
 893:             callcount = mtop->mt_count;
 894:             fcount = 1;
 895:             break;
 896: 
 897:         case MTFSF: case MTBSF:
 898:             callcount = mtop->mt_count;
 899:             fcount = INF;
 900:             break;
 901: 
 902:         case MTFSR: case MTBSR:
 903:             callcount = 1;
 904:             fcount = mtop->mt_count;
 905:             break;
 906: 
 907:         case MTREW: case MTOFFL: case MTNOP:
 908:             callcount = 1;
 909:             fcount = 1;
 910:             break;
 911: 
 912:         default:
 913:             return (ENXIO);
 914:         }
 915:         if (callcount <= 0 || fcount <= 0)
 916:             return (EINVAL);
 917:         while (--callcount >= 0) {
 918:             tmcommand(dev, tmops[mtop->mt_op], fcount);
 919:             if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) &&
 920:                 bp->b_resid)
 921:                 return (EIO);
 922:             if ((bp->b_flags&B_ERROR) || sc->sc_erreg&TMER_BOT)
 923:                 break;
 924:         }
 925:         return (geterror(bp));
 926: 
 927:     case MTIOCGET:
 928:         mtget = (struct mtget *)data;
 929:         mtget->mt_dsreg = sc->sc_dsreg;
 930:         mtget->mt_erreg = sc->sc_erreg;
 931:         mtget->mt_resid = sc->sc_resid;
 932:         mtget->mt_type = MT_ISTM;
 933:         break;
 934: 
 935:     default:
 936:         return (ENXIO);
 937:     }
 938:     return (0);
 939: }
 940: 
 941: #define DBSIZE  20
 942: 
 943: tmdump()
 944: {
 945:     register struct uba_device *ui;
 946:     register struct uba_regs *up;
 947:     register struct tmdevice *addr;
 948:     int blk, num;
 949:     int start;
 950: 
 951:     start = 0;
 952:     num = maxfree;
 953: #define phys(a,b)   ((b)((int)(a)&0x7fffffff))
 954:     if (tedinfo[0] == 0)
 955:         return (ENXIO);
 956:     ui = phys(tedinfo[0], struct uba_device *);
 957:     up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
 958:     ubainit(up);
 959:     DELAY(1000000);
 960:     addr = (struct tmdevice *)ui->ui_physaddr;
 961:     tmwait(addr);
 962:     addr->tmcs = TM_DCLR | TM_GO;
 963:     while (num > 0) {
 964:         blk = num > DBSIZE ? DBSIZE : num;
 965:         tmdwrite(start, blk, addr, up);
 966:         start += blk;
 967:         num -= blk;
 968:     }
 969:     tmeof(addr);
 970:     tmeof(addr);
 971:     tmwait(addr);
 972:     if (addr->tmcs&TM_ERR)
 973:         return (EIO);
 974:     addr->tmcs = TM_REW | TM_GO;
 975:     tmwait(addr);
 976:     return (0);
 977: }
 978: 
 979: tmdwrite(dbuf, num, addr, up)
 980:     register dbuf, num;
 981:     register struct tmdevice *addr;
 982:     struct uba_regs *up;
 983: {
 984:     register struct pte *io;
 985:     register int npf;
 986: 
 987:     tmwait(addr);
 988:     io = up->uba_map;
 989:     npf = num+1;
 990:     while (--npf != 0)
 991:          *(int *)io++ = (dbuf++ | (1<<UBAMR_DPSHIFT) | UBAMR_MRV);
 992:     *(int *)io = 0;
 993:     addr->tmbc = -(num*NBPG);
 994:     addr->tmba = 0;
 995:     addr->tmcs = TM_WCOM | TM_GO;
 996: }
 997: 
 998: tmwait(addr)
 999:     register struct tmdevice *addr;
1000: {
1001:     register s;
1002: 
1003:     do
1004:         s = addr->tmcs;
1005:     while ((s & TM_CUR) == 0);
1006: }
1007: 
1008: tmeof(addr)
1009:     struct tmdevice *addr;
1010: {
1011: 
1012:     tmwait(addr);
1013:     addr->tmcs = TM_WEOF | TM_GO;
1014: }
1015: #endif

Defined functions

tmattach defined in line 179; used 2 times
tmclose defined in line 271; never used
tmcommand defined in line 297; used 6 times
tmdgo defined in line 554; used 2 times
tmdump defined in line 943; never used
tmdwrite defined in line 979; used 1 times
tmeof defined in line 1008; used 2 times
tmintr defined in line 567; used 4 times
tmioctl defined in line 871; never used
tmopen defined in line 203; never used
tmphys defined in line 813; used 2 times
tmprobe defined in line 133; used 2 times
tmread defined in line 784; never used
tmreset defined in line 831; never used
tmseteof defined in line 760; used 1 times
tmslave defined in line 167; used 2 times
tmstart defined in line 380; used 3 times
tmstrategy defined in line 338; used 3 times
tmtimer defined in line 744; used 3 times
tmwait defined in line 998; used 5 times
tmwrite defined in line 796; never used

Defined variables

ctmbuf defined in line 54; used 5 times
rtmbuf defined in line 62; used 4 times
te_softc defined in line 114; used 10 times
tedinfo defined in line 69; used 10 times
tetotm defined in line 71; used 2 times
teutab defined in line 70; used 2 times
tmdens defined in line 199; used 1 times
tmdiag defined in line 200; used 1 times
tmdriver defined in line 73; used 3 times
tmgapsdcnt defined in line 116; used 2 times
tmminfo defined in line 68; used 3 times
tmstd defined in line 72; used 1 times
  • in line 74

Defined struct's

te_softc defined in line 99; used 16 times

Defined macros

DBSIZE defined in line 941; used 2 times
  • in line 964(2)
INF defined in line 82; used 6 times
SCOM defined in line 125; used 3 times
SIO defined in line 124; used 2 times
SREW defined in line 126; used 2 times
SSEEK defined in line 123; used 1 times
TEUNIT defined in line 77; used 11 times
TMUNIT defined in line 78; used 10 times
T_1600BPI defined in line 80; used 1 times
T_NOREWIND defined in line 79; used 1 times
phys defined in line 953; used 2 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2507
Valid CSS Valid XHTML 1.0 Strict