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:  *	@(#)ts.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "ts.h"
  10: #if NTS > 0
  11: /*
  12:  * TS11 tape driver
  13:  *
  14:  * TODO:
  15:  *	write dump code
  16:  */
  17: #include "../machine/pte.h"
  18: 
  19: #include "param.h"
  20: #include "systm.h"
  21: #include "buf.h"
  22: #include "dir.h"
  23: #include "conf.h"
  24: #include "user.h"
  25: #include "file.h"
  26: #include "map.h"
  27: #include "vm.h"
  28: #include "ioctl.h"
  29: #include "mtio.h"
  30: #include "cmap.h"
  31: #include "uio.h"
  32: #include "tty.h"
  33: 
  34: #include "../vax/cpu.h"
  35: #include "ubareg.h"
  36: #include "ubavar.h"
  37: #include "tsreg.h"
  38: 
  39: /*
  40:  * There is a ctsbuf per tape controller.
  41:  * It is used as the token to pass to the internal routines
  42:  * to execute tape ioctls.
  43:  * In particular, when the tape is rewinding on close we release
  44:  * the user process but any further attempts to use the tape drive
  45:  * before the rewind completes will hang waiting for ctsbuf.
  46:  */
  47: struct  buf ctsbuf[NTS];
  48: 
  49: /*
  50:  * Raw tape operations use rtsbuf.  The driver
  51:  * notices when rtsbuf is being used and allows the user
  52:  * program to continue after errors and read records
  53:  * not of the standard length (BSIZE).
  54:  */
  55: struct  buf rtsbuf[NTS];
  56: 
  57: /*
  58:  * Driver unibus interface routines and variables.
  59:  */
  60: int tsprobe(), tsslave(), tsattach(), tsdgo(), tsintr();
  61: struct  uba_ctlr *tsminfo[NTS];
  62: struct  uba_device *tsdinfo[NTS];
  63: struct buf  tsutab[NTS];
  64: u_short tsstd[] = { 0772520, 0 };
  65: /*** PROBABLY DON'T NEED ALL THESE SINCE CONTROLLER == DRIVE ***/
  66: struct  uba_driver zsdriver =
  67:  { tsprobe, tsslave, tsattach, tsdgo, tsstd, "ts", tsdinfo, "zs", tsminfo, 0 };
  68: 
  69: /* bits in minor device */
  70: #define TSUNIT(dev) (minor(dev)&03)
  71: #define T_NOREWIND  04
  72: 
  73: #define INF (daddr_t)1000000L
  74: 
  75: /*
  76:  * Software state per tape transport.
  77:  * Also contains hardware state in message packets.
  78:  *
  79:  * 1. A tape drive is a unique-open device; we refuse opens when it is already.
  80:  * 2. We keep track of the current position on a block tape and seek
  81:  *    before operations by forward/back spacing if necessary.
  82:  * 3. We remember if the last operation was a write on a tape, so if a tape
  83:  *    is open read write and the last thing done is a write we can
  84:  *    write a standard end of tape mark (two eofs).
  85:  * 4. We remember the status registers after the last command, using
  86:  *    then internally and returning them to the SENSE ioctl.
  87:  */
  88: struct  ts_softc {
  89:     char    sc_openf;   /* lock against multiple opens */
  90:     char    sc_lastiow; /* last op was a write */
  91:     short   sc_resid;   /* copy of last bc */
  92:     daddr_t sc_blkno;   /* block number, for block device tape */
  93:     daddr_t sc_nxrec;   /* position of end of tape, if known */
  94:     struct  ts_cmd sc_cmd;  /* the command packet */
  95:     struct  ts_sts sc_sts;  /* status packet, for returned status */
  96:     struct  ts_char sc_char; /* characteristics packet */
  97:     struct  ts_softc *sc_ubaddr; /* Unibus address of ts_softc structure */
  98:     u_short sc_uba;     /* Unibus addr of cmd pkt for tsdb */
  99:     short   sc_mapped;  /* is ts_sfotc mapped in Unibus space? */
 100:     struct  tty *sc_ttyp;   /* record user's tty for errors */
 101: } ts_softc[NTS];
 102: 
 103: /*
 104:  * States for um->um_tab.b_active, the per controller state flag.
 105:  * This is used to sequence control in the driver.
 106:  */
 107: #define SSEEK   1       /* seeking */
 108: #define SIO 2       /* doing seq i/o */
 109: #define SCOM    3       /* sending control command */
 110: #define SREW    4       /* sending a drive rewind */
 111: 
 112: /*
 113:  * Determine if there is a controller for
 114:  * a ts at address reg.  Our goal is to make the
 115:  * device interrupt.
 116:  */
 117: /*ARGSUSED*/
 118: tsprobe(reg)
 119:     caddr_t reg;
 120: {
 121:     register int br, cvec;      /* must be r11,r10; value-result */
 122: 
 123: #ifdef lint
 124:     br = 0; cvec = br; br = cvec;
 125:     tsintr(0);
 126: #endif
 127:     ((struct tsdevice *)reg)->tssr = 0;
 128:     DELAY(100);
 129:     if ((((struct tsdevice *)reg)->tssr & TS_NBA) == 0)
 130:         return(0);
 131:     /* IT'S TOO HARD TO MAKE THIS THING INTERRUPT JUST TO FIND ITS VECTOR */
 132:     cvec = ((unsigned)reg) & 07 ? 0260 : 0224;
 133:     br = 0x15;
 134:     return (sizeof (struct tsdevice));
 135: }
 136: 
 137: /*
 138:  * TS11 only supports one drive per controller;
 139:  * check for ui_slave == 0.
 140:  *
 141:  * DO WE REALLY NEED THIS ROUTINE???
 142:  */
 143: /*ARGSUSED*/
 144: tsslave(ui, reg)
 145:     struct uba_device *ui;
 146:     caddr_t reg;
 147: {
 148: 
 149:     if (ui->ui_slave)   /* non-zero slave not allowed */
 150:         return(0);
 151:     return (1);
 152: }
 153: 
 154: /*
 155:  * Record attachment of the unit to the controller.
 156:  *
 157:  * SHOULD THIS ROUTINE DO ANYTHING???
 158:  */
 159: /*ARGSUSED*/
 160: tsattach(ui)
 161:     struct uba_device *ui;
 162: {
 163: 
 164: }
 165: 
 166: /*
 167:  * Open the device.  Tapes are unique open
 168:  * devices, so we refuse if it is already open.
 169:  * We also check that a tape is available, and
 170:  * don't block waiting here; if you want to wait
 171:  * for a tape you should timeout in user code.
 172:  */
 173: tsopen(dev, flag)
 174:     dev_t dev;
 175:     int flag;
 176: {
 177:     register int tsunit;
 178:     register struct uba_device *ui;
 179:     register struct ts_softc *sc;
 180: 
 181:     tsunit = TSUNIT(dev);
 182:     if (tsunit>=NTS || (ui = tsdinfo[tsunit]) == 0 || ui->ui_alive == 0)
 183:         return (ENXIO);
 184:     if ((sc = &ts_softc[tsunit])->sc_openf)
 185:         return (EBUSY);
 186:     if (tsinit(tsunit))
 187:         return (ENXIO);
 188:     tscommand(dev, TS_SENSE, 1);
 189:     if ((sc->sc_sts.s_xs0&TS_ONL) == 0) {
 190:         uprintf("ts%d: not online\n", tsunit);
 191:         return (EIO);
 192:     }
 193:     if ((flag&FWRITE) && (sc->sc_sts.s_xs0&TS_WLK)) {
 194:         uprintf("ts%d: no write ring\n", tsunit);
 195:         return (EIO);
 196:     }
 197:     sc->sc_openf = 1;
 198:     sc->sc_blkno = (daddr_t)0;
 199:     sc->sc_nxrec = INF;
 200:     sc->sc_lastiow = 0;
 201:     sc->sc_ttyp = u.u_ttyp;
 202:     return (0);
 203: }
 204: 
 205: /*
 206:  * Close tape device.
 207:  *
 208:  * If tape was open for writing or last operation was
 209:  * a write, then write two EOF's and backspace over the last one.
 210:  * Unless this is a non-rewinding special file, rewind the tape.
 211:  * Make the tape available to others.
 212:  */
 213: tsclose(dev, flag)
 214:     register dev_t dev;
 215:     register flag;
 216: {
 217:     register struct ts_softc *sc = &ts_softc[TSUNIT(dev)];
 218: 
 219:     if (flag == FWRITE || (flag&FWRITE) && sc->sc_lastiow) {
 220:         tscommand(dev, TS_WEOF, 1);
 221:         tscommand(dev, TS_WEOF, 1);
 222:         tscommand(dev, TS_SREV, 1);
 223:     }
 224:     if ((minor(dev)&T_NOREWIND) == 0)
 225:         /*
 226: 		 * 0 count means don't hang waiting for rewind complete
 227: 		 * rather ctsbuf stays busy until the operation completes
 228: 		 * preventing further opens from completing by
 229: 		 * preventing a TS_SENSE from completing.
 230: 		 */
 231:         tscommand(dev, TS_REW, 0);
 232:     sc->sc_openf = 0;
 233: }
 234: 
 235: /*
 236:  * Initialize the TS11.  Set up Unibus mapping for command
 237:  * packets and set device characteristics.
 238:  */
 239: tsinit(unit)
 240:     register int unit;
 241: {
 242:     register struct ts_softc *sc = &ts_softc[unit];
 243:     register struct uba_ctlr *um = tsminfo[unit];
 244:     register struct tsdevice *addr = (struct tsdevice *)um->um_addr;
 245:     register int i;
 246: 
 247:     /*
 248: 	 * Map the command and message packets into Unibus
 249: 	 * address space.  We do all the command and message
 250: 	 * packets at once to minimize the amount of Unibus
 251: 	 * mapping necessary.
 252: 	 */
 253:     if (sc->sc_mapped == 0) {
 254:         ctsbuf[unit].b_un.b_addr = (caddr_t)sc;
 255:         ctsbuf[unit].b_bcount = sizeof(*sc);
 256:         i = ubasetup(um->um_ubanum, &ctsbuf[unit], 0);
 257:         i &= 0777777;
 258:         sc->sc_ubaddr = (struct ts_softc *)i;
 259:         sc->sc_mapped++;
 260:     }
 261:     /*
 262: 	 * Now initialize the TS11 controller.
 263: 	 * Set the characteristics.
 264: 	 */
 265:     if (addr->tssr & (TS_NBA|TS_OFL)) {
 266:         addr->tssr = 0;     /* subsystem initialize */
 267:         tswait(addr);
 268:         i = (int)&sc->sc_ubaddr->sc_cmd;    /* Unibus addr of cmd */
 269:         sc->sc_uba = (u_short)(i + ((i>>16)&3));
 270:         sc->sc_char.char_addr = (int)&sc->sc_ubaddr->sc_sts;
 271:         sc->sc_char.char_size = sizeof(struct ts_sts);
 272:         sc->sc_char.char_mode = TS_ESS;
 273:         sc->sc_cmd.c_cmd = TS_ACK | TS_SETCHR;
 274:         i = (int)&sc->sc_ubaddr->sc_char;
 275:         sc->sc_cmd.c_loba = i;
 276:         sc->sc_cmd.c_hiba = (i>>16)&3;
 277:         sc->sc_cmd.c_size = sizeof(struct ts_char);
 278:         addr->tsdb = sc->sc_uba;
 279:         tswait(addr);
 280:         if (addr->tssr & TS_NBA)
 281:             return(1);
 282:     }
 283:     return(0);
 284: }
 285: 
 286: /*
 287:  * Execute a command on the tape drive
 288:  * a specified number of times.
 289:  */
 290: tscommand(dev, com, count)
 291:     dev_t dev;
 292:     int com, count;
 293: {
 294:     register struct buf *bp;
 295:     register int s;
 296: 
 297:     bp = &ctsbuf[TSUNIT(dev)];
 298:     s = spl5();
 299:     while (bp->b_flags&B_BUSY) {
 300:         /*
 301: 		 * This special check is because B_BUSY never
 302: 		 * gets cleared in the non-waiting rewind case.
 303: 		 */
 304:         if (bp->b_repcnt == 0 && (bp->b_flags&B_DONE))
 305:             break;
 306:         bp->b_flags |= B_WANTED;
 307:         sleep((caddr_t)bp, PRIBIO);
 308:     }
 309:     bp->b_flags = B_BUSY|B_READ;
 310:     splx(s);
 311:     bp->b_dev = dev;
 312:     bp->b_repcnt = count;
 313:     bp->b_command = com;
 314:     bp->b_blkno = 0;
 315:     tsstrategy(bp);
 316:     /*
 317: 	 * In case of rewind from close, don't wait.
 318: 	 * This is the only case where count can be 0.
 319: 	 */
 320:     if (count == 0)
 321:         return;
 322:     iowait(bp);
 323:     if (bp->b_flags&B_WANTED)
 324:         wakeup((caddr_t)bp);
 325:     bp->b_flags &= B_ERROR;
 326: }
 327: 
 328: /*
 329:  * Queue a tape operation.
 330:  */
 331: tsstrategy(bp)
 332:     register struct buf *bp;
 333: {
 334:     int tsunit = TSUNIT(bp->b_dev);
 335:     register struct uba_ctlr *um;
 336:     register struct buf *dp;
 337:     register int s;
 338: 
 339:     /*
 340: 	 * Put transfer at end of controller queue
 341: 	 */
 342:     bp->av_forw = NULL;
 343:     um = tsdinfo[tsunit]->ui_mi;
 344:     s = spl5();
 345:     dp = &tsutab[tsunit];
 346:     if (dp->b_actf == NULL)
 347:         dp->b_actf = bp;
 348:     else
 349:         dp->b_actl->av_forw = bp;
 350:     dp->b_actl = bp;
 351:     um->um_tab.b_actf = um->um_tab.b_actl = dp;
 352:     /*
 353: 	 * If the controller is not busy, get
 354: 	 * it going.
 355: 	 */
 356:     if (um->um_tab.b_active == 0)
 357:         tsstart(um);
 358:     splx(s);
 359: }
 360: 
 361: /*
 362:  * Start activity on a ts controller.
 363:  */
 364: tsstart(um)
 365:     register struct uba_ctlr *um;
 366: {
 367:     register struct buf *bp;
 368:     register struct tsdevice *addr = (struct tsdevice *)um->um_addr;
 369:     register struct ts_softc *sc;
 370:     register struct ts_cmd *tc;
 371:     register struct uba_device *ui;
 372:     int tsunit, cmd;
 373:     daddr_t blkno;
 374: 
 375:     /*
 376: 	 * Start the controller if there is something for it to do.
 377: 	 */
 378: loop:
 379:     if ((bp = um->um_tab.b_actf->b_actf) == NULL)
 380:         return;
 381:     tsunit = TSUNIT(bp->b_dev);
 382:     ui = tsdinfo[tsunit];
 383:     sc = &ts_softc[tsunit];
 384:     tc = &sc->sc_cmd;
 385:     /*
 386: 	 * Default is that last command was NOT a write command;
 387: 	 * if we do a write command we will notice this in tsintr().
 388: 	 */
 389:     sc->sc_lastiow = 0;
 390:     if (sc->sc_openf < 0 || (addr->tssr&TS_OFL)) {
 391:         /*
 392: 		 * Have had a hard error on a non-raw tape
 393: 		 * or the tape unit is now unavailable
 394: 		 * (e.g. taken off line).
 395: 		 */
 396:         bp->b_flags |= B_ERROR;
 397:         goto next;
 398:     }
 399:     if (bp == &ctsbuf[TSUNIT(bp->b_dev)]) {
 400:         /*
 401: 		 * Execute control operation with the specified count.
 402: 		 */
 403:         um->um_tab.b_active =
 404:             bp->b_command == TS_REW ? SREW : SCOM;
 405:         tc->c_repcnt = bp->b_repcnt;
 406:         goto dobpcmd;
 407:     }
 408:     /*
 409: 	 * The following checks handle boundary cases for operation
 410: 	 * on non-raw tapes.  On raw tapes the initialization of
 411: 	 * sc->sc_nxrec by tsphys causes them to be skipped normally
 412: 	 * (except in the case of retries).
 413: 	 */
 414:     if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
 415:         /*
 416: 		 * Can't read past known end-of-file.
 417: 		 */
 418:         bp->b_flags |= B_ERROR;
 419:         bp->b_error = ENXIO;
 420:         goto next;
 421:     }
 422:     if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec &&
 423:         bp->b_flags&B_READ) {
 424:         /*
 425: 		 * Reading at end of file returns 0 bytes.
 426: 		 */
 427:         bp->b_resid = bp->b_bcount;
 428:         clrbuf(bp);
 429:         goto next;
 430:     }
 431:     if ((bp->b_flags&B_READ) == 0)
 432:         /*
 433: 		 * Writing sets EOF
 434: 		 */
 435:         sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1;
 436:     /*
 437: 	 * If the data transfer command is in the correct place,
 438: 	 * set up all the registers except the csr, and give
 439: 	 * control over to the UNIBUS adapter routines, to
 440: 	 * wait for resources to start the i/o.
 441: 	 */
 442:     if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) {
 443:         tc->c_size = bp->b_bcount;
 444:         if ((bp->b_flags&B_READ) == 0)
 445:             cmd = TS_WCOM;
 446:         else
 447:             cmd = TS_RCOM;
 448:         if (um->um_tab.b_errcnt)
 449:             cmd |= TS_RETRY;
 450:         um->um_tab.b_active = SIO;
 451:         tc->c_cmd = TS_ACK | TS_CVC | TS_IE | cmd;
 452:         (void) ubago(ui);
 453:         return;
 454:     }
 455:     /*
 456: 	 * Tape positioned incorrectly;
 457: 	 * set to seek forwards or backwards to the correct spot.
 458: 	 * This happens for raw tapes only on error retries.
 459: 	 */
 460:     um->um_tab.b_active = SSEEK;
 461:     if (blkno < bdbtofsb(bp->b_blkno)) {
 462:         bp->b_command = TS_SFORW;
 463:         tc->c_repcnt = bdbtofsb(bp->b_blkno) - blkno;
 464:     } else {
 465:         bp->b_command = TS_SREV;
 466:         tc->c_repcnt = blkno - bdbtofsb(bp->b_blkno);
 467:     }
 468: dobpcmd:
 469:     /*
 470: 	 * Do the command in bp.
 471: 	 */
 472:     tc->c_cmd = TS_ACK | TS_CVC | TS_IE | bp->b_command;
 473:     addr->tsdb = sc->sc_uba;
 474:     return;
 475: 
 476: next:
 477:     /*
 478: 	 * Done with this operation due to error or
 479: 	 * the fact that it doesn't do anything.
 480: 	 * Release UBA resources (if any), dequeue
 481: 	 * the transfer and continue processing this slave.
 482: 	 */
 483:     if (um->um_ubinfo)
 484:         ubadone(um);
 485:     um->um_tab.b_errcnt = 0;
 486:     um->um_tab.b_actf->b_actf = bp->av_forw;
 487:     iodone(bp);
 488:     goto loop;
 489: }
 490: 
 491: /*
 492:  * The UNIBUS resources we needed have been
 493:  * allocated to us; start the device.
 494:  */
 495: tsdgo(um)
 496:     register struct uba_ctlr *um;
 497: {
 498:     register struct tsdevice *addr = (struct tsdevice *)um->um_addr;
 499:     register struct ts_softc *sc = &ts_softc[um->um_ctlr];
 500:     register int i;
 501: 
 502:     /*
 503: 	 * The uba code uses byte-offset mode if using bdp;
 504: 	 * mask off the low bit here.
 505: 	 */
 506:     i = um->um_ubinfo & 0777777;
 507:     if (UBAI_BDP(um->um_ubinfo))
 508:         i &= ~1;
 509:     sc->sc_cmd.c_loba = i;
 510:     sc->sc_cmd.c_hiba = (i>>16)&3;
 511:     addr->tsdb = sc->sc_uba;
 512: }
 513: 
 514: /*
 515:  * Ts interrupt routine.
 516:  */
 517: /*ARGSUSED*/
 518: tsintr(ts11)
 519:     int ts11;
 520: {
 521:     register struct buf *bp;
 522:     register struct uba_ctlr *um = tsminfo[ts11];
 523:     register struct tsdevice *addr;
 524:     register struct ts_softc *sc;
 525:     int tsunit;
 526:     register state;
 527: #if VAX630
 528:     spl5();
 529: #endif
 530:     if ((bp = um->um_tab.b_actf->b_actf) == NULL)
 531:         return;
 532:     tsunit = TSUNIT(bp->b_dev);
 533:     addr = (struct tsdevice *)tsdinfo[tsunit]->ui_addr;
 534:     /*
 535: 	 * If last command was a rewind, and tape is still
 536: 	 * rewinding, wait for the rewind complete interrupt.
 537: 	 *
 538: 	 * SHOULD NEVER GET AN INTERRUPT IN THIS STATE.
 539: 	 */
 540:     if (um->um_tab.b_active == SREW) {
 541:         um->um_tab.b_active = SCOM;
 542:         if ((addr->tssr&TS_SSR) == 0)
 543:             return;
 544:     }
 545:     /*
 546: 	 * An operation completed... record status
 547: 	 */
 548:     sc = &ts_softc[tsunit];
 549:     if ((bp->b_flags & B_READ) == 0)
 550:         sc->sc_lastiow = 1;
 551:     state = um->um_tab.b_active;
 552:     um->um_tab.b_active = 0;
 553:     /*
 554: 	 * Check for errors.
 555: 	 */
 556:     if (addr->tssr&TS_SC) {
 557:         switch (addr->tssr & TS_TC) {
 558:         case TS_UNREC:      /* unrecoverable */
 559:         case TS_FATAL:      /* fatal error */
 560:         case TS_ATTN:       /* attention (shouldn't happen) */
 561:         case TS_RECNM:      /* recoverable, no motion */
 562:             break;
 563: 
 564:         case TS_SUCC:       /* success termination */
 565:             printf("ts%d: success\n", TSUNIT(minor(bp->b_dev)));
 566:             goto ignoreerr;
 567: 
 568:         case TS_ALERT:      /* tape status alert */
 569:             /*
 570: 			 * If we hit the end of the tape file,
 571: 			 * update our position.
 572: 			 */
 573:             if (sc->sc_sts.s_xs0 & (TS_TMK|TS_EOT)) {
 574:                 tsseteof(bp);       /* set blkno and nxrec */
 575:                 state = SCOM;       /* force completion */
 576:                 /*
 577: 				 * Stuff bc so it will be unstuffed correctly
 578: 				 * later to get resid.
 579: 				 */
 580:                 sc->sc_sts.s_rbpcr = bp->b_bcount;
 581:                 goto opdone;
 582:             }
 583:             /*
 584: 			 * If we were reading raw tape and the record was too long
 585: 			 * or too short, then we don't consider this an error.
 586: 			 */
 587:             if (bp == &rtsbuf[TSUNIT(bp->b_dev)] && (bp->b_flags&B_READ) &&
 588:                 sc->sc_sts.s_xs0&(TS_RLS|TS_RLL))
 589:                 goto ignoreerr;
 590:         case TS_RECOV:      /* recoverable, tape moved */
 591:             /*
 592: 			 * If this was an i/o operation retry up to 8 times.
 593: 			 */
 594:             if (state==SIO) {
 595:                 if (++um->um_tab.b_errcnt < 7) {
 596:                     ubadone(um);
 597:                     goto opcont;
 598:                 } else
 599:                     sc->sc_blkno++;
 600:             } else {
 601:                 /*
 602: 				 * Non-i/o errors on non-raw tape
 603: 				 * cause it to close.
 604: 				 */
 605:                 if (sc->sc_openf>0 && bp != &rtsbuf[TSUNIT(bp->b_dev)])
 606:                     sc->sc_openf = -1;
 607:             }
 608:             break;
 609: 
 610:         case TS_REJECT:     /* function reject */
 611:             if (state == SIO && sc->sc_sts.s_xs0 & TS_WLE)
 612:                 tprintf(sc->sc_ttyp, "ts%d: write locked\n",
 613:                     TSUNIT(bp->b_dev));
 614:             if ((sc->sc_sts.s_xs0 & TS_ONL) == 0)
 615:                 tprintf(sc->sc_ttyp, "ts%d: offline\n",
 616:                     TSUNIT(bp->b_dev));
 617:             break;
 618:         }
 619:         /*
 620: 		 * Couldn't recover error
 621: 		 */
 622:         tprintf(sc->sc_ttyp, "ts%d: hard error bn%d xs0=%b",
 623:             TSUNIT(bp->b_dev), bp->b_blkno, sc->sc_sts.s_xs0, TSXS0_BITS);
 624:         if (sc->sc_sts.s_xs1)
 625:             tprintf(sc->sc_ttyp, " xs1=%b", sc->sc_sts.s_xs1,
 626:                 TSXS1_BITS);
 627:         if (sc->sc_sts.s_xs2)
 628:             tprintf(sc->sc_ttyp, " xs2=%b", sc->sc_sts.s_xs2,
 629:                 TSXS2_BITS);
 630:         if (sc->sc_sts.s_xs3)
 631:             tprintf(sc->sc_ttyp, " xs3=%b", sc->sc_sts.s_xs3,
 632:                 TSXS3_BITS);
 633:         tprintf(sc->sc_ttyp, "\n");
 634:         bp->b_flags |= B_ERROR;
 635:         goto opdone;
 636:     }
 637:     /*
 638: 	 * Advance tape control FSM.
 639: 	 */
 640: ignoreerr:
 641:     switch (state) {
 642: 
 643:     case SIO:
 644:         /*
 645: 		 * Read/write increments tape block number
 646: 		 */
 647:         sc->sc_blkno++;
 648:         goto opdone;
 649: 
 650:     case SCOM:
 651:         /*
 652: 		 * For forward/backward space record update current position.
 653: 		 */
 654:         if (bp == &ctsbuf[TSUNIT(bp->b_dev)])
 655:         switch ((int)bp->b_command) {
 656: 
 657:         case TS_SFORW:
 658:             sc->sc_blkno += bp->b_repcnt;
 659:             break;
 660: 
 661:         case TS_SREV:
 662:             sc->sc_blkno -= bp->b_repcnt;
 663:             break;
 664:         }
 665:         goto opdone;
 666: 
 667:     case SSEEK:
 668:         sc->sc_blkno = bdbtofsb(bp->b_blkno);
 669:         goto opcont;
 670: 
 671:     default:
 672:         panic("tsintr");
 673:     }
 674: opdone:
 675:     /*
 676: 	 * Reset error count and remove
 677: 	 * from device queue.
 678: 	 */
 679:     um->um_tab.b_errcnt = 0;
 680:     um->um_tab.b_actf->b_actf = bp->av_forw;
 681:     bp->b_resid = sc->sc_sts.s_rbpcr;
 682:     ubadone(um);
 683:     iodone(bp);
 684:     if (um->um_tab.b_actf->b_actf == 0)
 685:         return;
 686: opcont:
 687:     tsstart(um);
 688: }
 689: 
 690: tsseteof(bp)
 691:     register struct buf *bp;
 692: {
 693:     register int tsunit = TSUNIT(bp->b_dev);
 694:     register struct ts_softc *sc = &ts_softc[tsunit];
 695: 
 696:     if (bp == &ctsbuf[TSUNIT(bp->b_dev)]) {
 697:         if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) {
 698:             /* reversing */
 699:             sc->sc_nxrec = bdbtofsb(bp->b_blkno) - sc->sc_sts.s_rbpcr;
 700:             sc->sc_blkno = sc->sc_nxrec;
 701:         } else {
 702:             /* spacing forward */
 703:             sc->sc_blkno = bdbtofsb(bp->b_blkno) + sc->sc_sts.s_rbpcr;
 704:             sc->sc_nxrec = sc->sc_blkno - 1;
 705:         }
 706:         return;
 707:     }
 708:     /* eof on read */
 709:     sc->sc_nxrec = bdbtofsb(bp->b_blkno);
 710: }
 711: 
 712: tsread(dev, uio)
 713:     dev_t dev;
 714:     struct uio *uio;
 715: {
 716:     int errno;
 717: 
 718:     errno = tsphys(dev, uio);
 719:     if (errno)
 720:         return (errno);
 721:     return (physio(tsstrategy, &rtsbuf[TSUNIT(dev)], dev, B_READ, minphys, uio));
 722: }
 723: 
 724: tswrite(dev, uio)
 725:     dev_t dev;
 726:     struct uio *uio;
 727: {
 728:     int errno;
 729: 
 730:     errno = tsphys(dev, uio);
 731:     if (errno)
 732:         return (errno);
 733:     return (physio(tsstrategy, &rtsbuf[TSUNIT(dev)], dev, B_WRITE, minphys, uio));
 734: }
 735: 
 736: /*
 737:  * Check that a raw device exists.
 738:  * If it does, set up sc_blkno and sc_nxrec
 739:  * so that the tape will appear positioned correctly.
 740:  */
 741: tsphys(dev, uio)
 742:     dev_t dev;
 743:     struct uio *uio;
 744: {
 745:     register int tsunit = TSUNIT(dev);
 746:     register daddr_t a;
 747:     register struct ts_softc *sc;
 748:     register struct uba_device *ui;
 749: 
 750:     if (tsunit >= NTS || (ui=tsdinfo[tsunit]) == 0 || ui->ui_alive == 0)
 751:         return (ENXIO);
 752:     sc = &ts_softc[tsunit];
 753:     a = bdbtofsb(uio->uio_offset >> 9);
 754:     sc->sc_blkno = a;
 755:     sc->sc_nxrec = a + 1;
 756:     return (0);
 757: }
 758: 
 759: tsreset(uban)
 760:     int uban;
 761: {
 762:     register struct uba_ctlr *um;
 763:     register struct uba_device *ui;
 764:     register struct buf *dp;
 765:     register ts11;
 766: 
 767:     for (ts11 = 0; ts11 < NTS; ts11++) {
 768:         if ((um = tsminfo[ts11]) == 0 || um->um_alive == 0 ||
 769:            um->um_ubanum != uban)
 770:             continue;
 771:         printf(" ts%d", ts11);
 772:         um->um_tab.b_active = 0;
 773:         um->um_tab.b_actf = um->um_tab.b_actl = 0;
 774:         if (ts_softc[ts11].sc_openf > 0)
 775:             ts_softc[ts11].sc_openf = -1;
 776:         if (um->um_ubinfo) {
 777:             printf("<%d>", (um->um_ubinfo>>28)&0xf);
 778:             um->um_ubinfo = 0;
 779:         }
 780:         if ((ui = tsdinfo[ts11]) && ui->ui_mi == um && ui->ui_alive) {
 781:             dp = &tsutab[ts11];
 782:             dp->b_active = 0;
 783:             dp->b_forw = 0;
 784:             if (um->um_tab.b_actf == NULL)
 785:                 um->um_tab.b_actf = dp;
 786:             else
 787:                 um->um_tab.b_actl->b_forw = dp;
 788:             um->um_tab.b_actl = dp;
 789:         }
 790:         ts_softc[ts11].sc_mapped = 0;
 791:         (void) tsinit(ts11);
 792:         tsstart(um);
 793:     }
 794: }
 795: 
 796: /*ARGSUSED*/
 797: tsioctl(dev, cmd, data, flag)
 798:     caddr_t data;
 799:     dev_t dev;
 800: {
 801:     int tsunit = TSUNIT(dev);
 802:     register struct ts_softc *sc = &ts_softc[tsunit];
 803:     register struct buf *bp = &ctsbuf[TSUNIT(dev)];
 804:     register callcount;
 805:     int fcount;
 806:     struct mtop *mtop;
 807:     struct mtget *mtget;
 808:     /* we depend of the values and order of the MT codes here */
 809:     static tsops[] =
 810:      {TS_WEOF,TS_SFORWF,TS_SREVF,TS_SFORW,TS_SREV,TS_REW,TS_OFFL,TS_SENSE};
 811: 
 812:     switch (cmd) {
 813: 
 814:     case MTIOCTOP:  /* tape operation */
 815:         mtop = (struct mtop *)data;
 816:         switch (mtop->mt_op) {
 817: 
 818:         case MTWEOF:
 819:             callcount = mtop->mt_count;
 820:             fcount = 1;
 821:             break;
 822: 
 823:         case MTFSF: case MTBSF:
 824:         case MTFSR: case MTBSR:
 825:             callcount = 1;
 826:             fcount = mtop->mt_count;
 827:             break;
 828: 
 829:         case MTREW: case MTOFFL: case MTNOP:
 830:             callcount = 1;
 831:             fcount = 1;
 832:             break;
 833: 
 834:         default:
 835:             return (ENXIO);
 836:         }
 837:         if (callcount <= 0 || fcount <= 0)
 838:             return (EINVAL);
 839:         while (--callcount >= 0) {
 840:             tscommand(dev, tsops[mtop->mt_op], fcount);
 841:             if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) &&
 842:                 bp->b_resid)
 843:                 return (EIO);
 844:             if ((bp->b_flags&B_ERROR) || sc->sc_sts.s_xs0&TS_BOT)
 845:                 break;
 846:         }
 847:         return (geterror(bp));
 848: 
 849:     case MTIOCGET:
 850:         mtget = (struct mtget *)data;
 851:         mtget->mt_dsreg = 0;
 852:         mtget->mt_erreg = sc->sc_sts.s_xs0;
 853:         mtget->mt_resid = sc->sc_resid;
 854:         mtget->mt_type = MT_ISTS;
 855:         break;
 856: 
 857:     default:
 858:         return (ENXIO);
 859:     }
 860:     return (0);
 861: }
 862: 
 863: #define DBSIZE  20
 864: 
 865: tsdump()
 866: {
 867:     register struct uba_device *ui;
 868:     register struct uba_regs *up;
 869:     register struct tsdevice *addr;
 870:     int blk, num;
 871:     int start;
 872: 
 873:     start = 0;
 874:     num = maxfree;
 875: #define phys(a,b)   ((b)((int)(a)&0x7fffffff))
 876:     if (tsdinfo[0] == 0)
 877:         return (ENXIO);
 878:     ui = phys(tsdinfo[0], struct uba_device *);
 879:     up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
 880:     ubainit(up);
 881:     DELAY(1000000);
 882:     addr = (struct tsdevice *)ui->ui_physaddr;
 883:     addr->tssr = 0;
 884:     tswait(addr);
 885:     while (num > 0) {
 886:         blk = num > DBSIZE ? DBSIZE : num;
 887:         tsdwrite(start, blk, addr, up);
 888:         start += blk;
 889:         num -= blk;
 890:     }
 891:     tseof(addr);
 892:     tseof(addr);
 893:     tswait(addr);
 894:     if (addr->tssr&TS_SC)
 895:         return (EIO);
 896:     addr->tssr = 0;
 897:     tswait(addr);
 898:     return (0);
 899: }
 900: 
 901: tsdwrite(dbuf, num, addr, up)
 902:     register int dbuf, num;
 903:     register struct tsdevice *addr;
 904:     struct uba_regs *up;
 905: {
 906:     register struct pte *io;
 907:     register int npf;
 908: 
 909:     tswait(addr);
 910:     io = up->uba_map;
 911:     npf = num+1;
 912:     while (--npf != 0)
 913:          *(int *)io++ = (dbuf++ | (1<<UBAMR_DPSHIFT) | UBAMR_MRV);
 914:     *(int *)io = 0;
 915: #ifdef notyet
 916:     addr->tsbc = -(num*NBPG);
 917:     addr->tsba = 0;
 918:     addr->tscs = TS_WCOM | TM_GO;
 919: #endif
 920: }
 921: 
 922: tswait(addr)
 923:     register struct tsdevice *addr;
 924: {
 925:     register s;
 926: 
 927:     do
 928:         s = addr->tssr;
 929:     while ((s & TS_SSR) == 0);
 930: }
 931: 
 932: tseof(addr)
 933:     struct tsdevice *addr;
 934: {
 935: 
 936:     tswait(addr);
 937: #ifdef notyet
 938:     addr->tscs = TS_WEOF | TM_GO;
 939: #endif
 940: }
 941: #endif

Defined functions

tsattach defined in line 160; used 2 times
tsclose defined in line 213; never used
tscommand defined in line 290; used 6 times
tsdgo defined in line 495; used 2 times
tsdump defined in line 865; never used
tsdwrite defined in line 901; used 1 times
tseof defined in line 932; used 2 times
tsinit defined in line 239; used 2 times
tsintr defined in line 518; used 3 times
tsioctl defined in line 797; never used
tsopen defined in line 173; never used
tsphys defined in line 741; used 2 times
tsprobe defined in line 118; used 2 times
tsread defined in line 712; never used
tsreset defined in line 759; never used
tsseteof defined in line 690; used 1 times
tsslave defined in line 144; used 2 times
tsstart defined in line 364; used 3 times
tsstrategy defined in line 331; used 3 times
tswait defined in line 922; used 7 times
tswrite defined in line 724; never used

Defined variables

ctsbuf defined in line 47; used 8 times
rtsbuf defined in line 55; used 4 times
ts_softc defined in line 101; used 12 times
tsdinfo defined in line 62; used 9 times
tsminfo defined in line 61; used 4 times
tsstd defined in line 64; used 1 times
  • in line 67
tsutab defined in line 63; used 2 times
zsdriver defined in line 66; used 2 times

Defined struct's

ts_softc defined in line 88; used 22 times

Defined macros

DBSIZE defined in line 863; used 2 times
  • in line 886(2)
INF defined in line 73; used 1 times
SCOM defined in line 109; used 3 times
SIO defined in line 108; used 3 times
SREW defined in line 110; used 2 times
SSEEK defined in line 107; used 1 times
TSUNIT defined in line 70; used 21 times
T_NOREWIND defined in line 71; used 1 times
phys defined in line 875; used 2 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2513
Valid CSS Valid XHTML 1.0 Strict