1 /* $NetBSD: ts.c,v 1.3 2001/11/13 07:11:25 lukem Exp $ */ 2 3 /*- 4 * Copyright (c) 1991 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)tmscp.c 7.16 (Berkeley) 5/9/91 36 */ 37 38 /* 39 * sccsid = "@(#)tmscp.c 1.24 (ULTRIX) 1/21/86"; 40 */ 41 42 /************************************************************************ 43 * * 44 * Licensed from Digital Equipment Corporation * 45 * Copyright (c) * 46 * Digital Equipment Corporation * 47 * Maynard, Massachusetts * 48 * 1985, 1986 * 49 * All rights reserved. * 50 * * 51 * The Information in this software is subject to change * 52 * without notice and should not be construed as a commitment * 53 * by Digital Equipment Corporation. Digital makes no * 54 * representations about the suitability of this software for * 55 * any purpose. It is supplied "As Is" without expressed or * 56 * implied warranty. * 57 * * 58 * If the Regents of the University of California or its * 59 * licensees modify the software in a manner creating * 60 * derivative copyright rights, appropriate copyright * 61 * legends may be placed on the derivative work in addition * 62 * to that set forth above. * 63 * * 64 ************************************************************************/ 65 66 /* 67 * TSV05/TS05 device driver, written by Bertram Barth. 68 * 69 * should be TS11 compatible (untested) 70 */ 71 72 #include <sys/cdefs.h> 73 __KERNEL_RCSID(0, "$NetBSD: ts.c,v 1.3 2001/11/13 07:11:25 lukem Exp $"); 74 75 #undef TSDEBUG 76 77 /* 78 * TODO: 79 * 80 * Keep track of tape position so that lseek et al works. 81 * Use tprintf to inform the user, not the system console. 82 */ 83 84 85 #include <sys/param.h> 86 #include <sys/systm.h> 87 #include <sys/kernel.h> 88 #include <sys/buf.h> 89 #include <sys/conf.h> 90 #include <sys/errno.h> 91 #include <sys/file.h> 92 #include <sys/map.h> 93 #include <sys/syslog.h> 94 #include <sys/ioctl.h> 95 #include <sys/mtio.h> 96 #include <sys/uio.h> 97 #include <sys/proc.h> 98 99 #include <machine/bus.h> 100 101 #include <dev/qbus/ubareg.h> 102 #include <dev/qbus/ubavar.h> 103 104 #include <dev/qbus/tsreg.h> 105 106 #include "ioconf.h" 107 108 struct ts { 109 struct cmd cmd; /* command packet */ 110 struct chr chr; /* characteristics packet */ 111 struct status status; /* status packet */ 112 }; 113 114 /* 115 * Software status, per controller. 116 * also status per tape-unit, since only one unit per controller 117 * (thus we have no struct ts_info) 118 */ 119 struct ts_softc { 120 struct device sc_dev; /* Autoconf ... */ 121 struct uba_unit sc_unit; /* Struct common for UBA to talk */ 122 struct evcnt sc_intrcnt; /* Interrupt counting */ 123 struct ubinfo sc_ui; /* mapping info for struct ts */ 124 struct uba_unit sc_uu; /* Struct for UBA to communicate */ 125 bus_space_tag_t sc_iot; 126 bus_addr_t sc_ioh; 127 bus_dma_tag_t sc_dmat; 128 bus_dmamap_t sc_dmam; 129 volatile struct ts *sc_vts; /* Memory address of ts struct */ 130 struct ts *sc_bts; /* Unibus address of ts struct */ 131 int sc_type; /* TS11 or TS05? */ 132 short sc_waddr; /* Value to write to TSDB */ 133 struct buf_queue sc_bufq; /* pending I/O requests */ 134 135 short sc_mapped; /* Unibus map allocated ? */ 136 short sc_state; /* see below: ST_xxx */ 137 short sc_rtc; /* retry count for lcmd */ 138 short sc_openf; /* lock against multiple opens */ 139 short sc_liowf; /* last operation was write */ 140 struct buf ts_cbuf; /* internal cmd buffer (for ioctls) */ 141 }; 142 143 #define XNAME sc->sc_dev.dv_xname 144 145 #define TS_WCSR(csr, val) \ 146 bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val) 147 #define TS_RCSR(csr) \ 148 bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr) 149 150 #define LOWORD(x) ((int)(x) & 0xffff) 151 #define HIWORD(x) (((int)(x) >> 16) & 0x3f) 152 153 #define TYPE_TS11 0 154 #define TYPE_TS05 1 155 #define TYPE_TU80 2 156 157 #define TS_INVALID 0 158 #define TS_INIT 1 159 #define TS_RUNNING 2 160 #define TS_FASTREPOS 3 161 162 static void tsintr(void *); 163 static void tsinit(struct ts_softc *); 164 static void tscommand(struct ts_softc *, dev_t, int, int); 165 static int tsstart(struct ts_softc *, int); 166 static void tswchar(struct ts_softc *); 167 static int tsreset(struct ts_softc *); 168 static int tsmatch(struct device *, struct cfdata *, void *); 169 static void tsattach(struct device *, struct device *, void *); 170 static int tsready(struct uba_unit *); 171 172 cdev_decl(ts); 173 bdev_decl(ts); 174 175 struct cfattach ts_ca = { 176 sizeof(struct ts_softc), tsmatch, tsattach 177 }; 178 179 /* Bits in minor device */ 180 #define TS_UNIT(dev) (minor(dev)&03) 181 #define TS_HIDENSITY 010 182 183 #define TS_PRI LOG_INFO 184 185 186 /* 187 * Probe for device. If found, try to raise an interrupt. 188 */ 189 int 190 tsmatch(struct device *parent, struct cfdata *match, void *aux) 191 { 192 struct ts_softc ssc; 193 struct ts_softc *sc = &ssc; 194 struct uba_attach_args *ua = aux; 195 int i; 196 197 sc->sc_iot = ua->ua_iot; 198 sc->sc_ioh = ua->ua_ioh; 199 sc->sc_mapped = 0; 200 sc->sc_dev.dv_parent = parent; 201 strcpy(XNAME, "ts"); 202 203 /* Try to reset the device */ 204 for (i = 0; i < 3; i++) 205 if (tsreset(sc) == 1) 206 break; 207 208 if (i == 3) 209 return 0; 210 211 tsinit(sc); 212 tswchar(sc); /* write charact. to enable interrupts */ 213 /* completion of this will raise the intr. */ 214 215 DELAY(1000000); /* Wait for interrupt */ 216 ubmemfree((void *)parent, &sc->sc_ui); 217 return 1; 218 } 219 220 /* 221 */ 222 void 223 tsattach(struct device *parent, struct device *self, void *aux) 224 { 225 struct uba_softc *uh = (void *)parent; 226 struct ts_softc *sc = (void *)self; 227 struct uba_attach_args *ua = aux; 228 int error; 229 char *t; 230 231 sc->sc_iot = ua->ua_iot; 232 sc->sc_ioh = ua->ua_ioh; 233 sc->sc_dmat = ua->ua_dmat; 234 235 sc->sc_uu.uu_softc = sc; 236 sc->sc_uu.uu_ready = tsready; 237 238 tsinit(sc); /* reset and map */ 239 240 if ((error = bus_dmamap_create(sc->sc_dmat, (64*1024), 16, (64*1024), 241 0, BUS_DMA_NOWAIT, &sc->sc_dmam))) 242 return printf(": failed create DMA map %d\n", error); 243 244 BUFQ_INIT(&sc->sc_bufq); 245 246 /* 247 * write the characteristics (again) 248 */ 249 sc->sc_state = TS_INIT; /* tsintr() checks this ... */ 250 tswchar(sc); 251 if (tsleep(sc, PRIBIO, "tsattach", 100)) 252 return printf(": failed SET CHARACTERISTICS\n"); 253 254 sc->sc_state = TS_RUNNING; 255 if (uh->uh_type == UBA_UBA) { 256 if (sc->sc_vts->status.xst2 & TS_SF_TU80) { 257 sc->sc_type = TYPE_TU80; 258 t = "TU80"; 259 } else { 260 sc->sc_type = TYPE_TS11; 261 t = "TS11"; 262 } 263 } else { 264 sc->sc_type = TYPE_TS05; 265 t = "TS05"; 266 } 267 268 printf("\n%s: %s\n", XNAME, t); 269 printf("%s: rev %d, extended features %s, transport %s\n", 270 XNAME, (sc->sc_vts->status.xst2 & TS_SF_MCRL) >> 2, 271 (sc->sc_vts->status.xst2 & TS_SF_EFES ? "enabled" : "disabled"), 272 (TS_RCSR(TSSR) & TS_OFL ? "offline" : "online")); 273 274 uba_intr_establish(ua->ua_icookie, ua->ua_cvec, tsintr, 275 sc, &sc->sc_intrcnt); 276 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt, 277 sc->sc_dev.dv_xname, "intr"); 278 } 279 280 /* 281 * Initialize a TS device. Set up UBA mapping registers, 282 * initialize data structures, what else ??? 283 */ 284 void 285 tsinit(struct ts_softc *sc) 286 { 287 if (sc->sc_mapped == 0) { 288 289 /* 290 * Map the communications area and command and message 291 * buffer into Unibus address space. 292 */ 293 sc->sc_ui.ui_size = sizeof(struct ts); 294 if ((ubmemalloc((void *)sc->sc_dev.dv_parent, 295 &sc->sc_ui, UBA_CANTWAIT))) 296 return; 297 sc->sc_vts = (void *)sc->sc_ui.ui_vaddr; 298 sc->sc_bts = (void *)sc->sc_ui.ui_baddr; 299 sc->sc_waddr = sc->sc_ui.ui_baddr | 300 ((sc->sc_ui.ui_baddr >> 16) & 3); 301 sc->sc_mapped = 1; 302 } 303 tsreset(sc); 304 } 305 306 /* 307 * Execute a (ioctl) command on the tape drive a specified number of times. 308 * This routine sets up a buffer and calls the strategy routine which 309 * issues the command to the controller. 310 */ 311 void 312 tscommand(struct ts_softc *sc, dev_t dev, int cmd, int count) 313 { 314 struct buf *bp; 315 int s; 316 317 #ifdef TSDEBUG 318 printf("tscommand (%x, %d)\n", cmd, count); 319 #endif 320 321 bp = &sc->ts_cbuf; 322 323 s = splbio(); 324 while (bp->b_flags & B_BUSY) { 325 /* 326 * This special check is because B_BUSY never 327 * gets cleared in the non-waiting rewind case. ??? 328 */ 329 if (bp->b_bcount == 0 && (bp->b_flags & B_DONE)) 330 break; 331 bp->b_flags |= B_WANTED; 332 (void) tsleep(bp, PRIBIO, "tscmd", 0); 333 /* check MOT-flag !!! */ 334 } 335 bp->b_flags = B_BUSY | B_READ; 336 splx(s); 337 338 /* 339 * Load the buffer. The b_count field gets used to hold the command 340 * count. the b_resid field gets used to hold the command mneumonic. 341 * These 2 fields are "known" to be "safe" to use for this purpose. 342 * (Most other drivers also use these fields in this way.) 343 */ 344 bp->b_dev = dev; 345 bp->b_bcount = count; 346 bp->b_resid = cmd; 347 bp->b_blkno = 0; 348 tsstrategy(bp); 349 /* 350 * In case of rewind from close, don't wait. 351 * This is the only case where count can be 0. 352 */ 353 if (count == 0) 354 return; 355 biowait(bp); 356 if (bp->b_flags & B_WANTED) 357 wakeup((caddr_t)bp); 358 bp->b_flags &= B_ERROR; 359 } 360 361 /* 362 * Start an I/O operation on TS05 controller 363 */ 364 int 365 tsstart(struct ts_softc *sc, int isloaded) 366 { 367 struct buf *bp; 368 int cmd; 369 370 if (TAILQ_EMPTY(&sc->sc_bufq.bq_head)) 371 return 0; 372 373 bp = BUFQ_FIRST(&sc->sc_bufq); 374 #ifdef TSDEBUG 375 printf("buf: %p bcount %ld blkno %d\n", bp, bp->b_bcount, bp->b_blkno); 376 #endif 377 /* 378 * Check if command is an ioctl or not (ie. read or write). 379 * If it's an ioctl then just set the flags for later use; 380 * For other commands attempt to setup a buffer pointer. 381 */ 382 if (bp == &sc->ts_cbuf) { 383 switch ((int)bp->b_resid) { 384 case MTWEOF: 385 cmd = TS_CMD_WTM; 386 break; 387 case MTFSF: 388 cmd = TS_CMD_STMF; 389 sc->sc_vts->cmd.cw1 = bp->b_bcount; 390 break; 391 case MTBSF: 392 cmd = TS_CMD_STMR; 393 sc->sc_vts->cmd.cw1 = bp->b_bcount; 394 break; 395 case MTFSR: 396 cmd = TS_CMD_SRF; 397 sc->sc_vts->cmd.cw1 = bp->b_bcount; 398 break; 399 case MTBSR: 400 cmd = TS_CMD_SRR; 401 sc->sc_vts->cmd.cw1 = bp->b_bcount; 402 break; 403 case MTREW: 404 cmd = TS_CMD_RWND; 405 break; 406 case MTOFFL: 407 cmd = TS_CMD_RWUL; 408 break; 409 case MTNOP: 410 cmd = TS_CMD_STAT; 411 break; 412 default: 413 printf ("%s: bad ioctl %d\n", sc->sc_dev.dv_xname, 414 (int)bp->b_resid); 415 /* Need a no-op. get status */ 416 cmd = TS_CMD_STAT; 417 } /* end switch (bp->b_resid) */ 418 } else { 419 if (isloaded == 0) { 420 /* 421 * now we try to map the buffer into uba map space (???) 422 */ 423 if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmam, 424 bp->b_data, 425 bp->b_bcount, bp->b_proc, BUS_DMA_NOWAIT)) { 426 uba_enqueue(&sc->sc_uu); 427 return 0; 428 } 429 sc->sc_rtc = 0; 430 } 431 sc->sc_vts->cmd.cw1 = LOWORD(sc->sc_dmam->dm_segs[0].ds_addr); 432 sc->sc_vts->cmd.cw2 = HIWORD(sc->sc_dmam->dm_segs[0].ds_addr); 433 sc->sc_vts->cmd.cw3 = bp->b_bcount; 434 bp->b_error = 0; /* Used for error count */ 435 #ifdef TSDEBUG 436 printf("tsstart-1: err %d\n", bp->b_error); 437 #endif 438 if (bp->b_flags & B_READ) 439 cmd = TS_CMD_RNF; 440 else 441 cmd = TS_CMD_WD; 442 } 443 444 /* 445 * Now that the command-buffer is setup, give it to the controller 446 */ 447 sc->sc_vts->cmd.cmdr = TS_CF_ACK | TS_CF_IE | cmd; 448 #ifdef TSDEBUG 449 printf("tsstart: sending cmdr %x\n", sc->sc_vts->cmd.cmdr); 450 #endif 451 TS_WCSR(TSDB, sc->sc_waddr); 452 } 453 454 /* 455 * Called when there are free uba resources. 456 */ 457 int 458 tsready(struct uba_unit *uu) 459 { 460 struct ts_softc *sc = uu->uu_softc; 461 struct buf *bp = BUFQ_FIRST(&sc->sc_bufq); 462 463 if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmam, bp->b_data, 464 bp->b_bcount, bp->b_proc, BUS_DMA_NOWAIT)) 465 return 0; 466 467 tsstart(sc, 1); 468 return 1; 469 } 470 471 /* 472 * initialize the controller by sending WRITE CHARACTERISTICS command. 473 * contents of command- and message-buffer are assembled during this 474 * function. 475 */ 476 void 477 tswchar(struct ts_softc *sc) 478 { 479 /* 480 * assemble and send "WRITE CHARACTERISTICS" command 481 */ 482 483 sc->sc_vts->cmd.cmdr = TS_CF_ACK | TS_CF_IE | TS_CMD_WCHAR; 484 sc->sc_vts->cmd.cw1 = LOWORD(&sc->sc_bts->chr); 485 sc->sc_vts->cmd.cw2 = HIWORD(&sc->sc_bts->chr); 486 sc->sc_vts->cmd.cw3 = 010; /* size of charact.-data */ 487 488 sc->sc_vts->chr.sadrl = LOWORD(&sc->sc_bts->status); 489 sc->sc_vts->chr.sadrh = HIWORD(&sc->sc_bts->status); 490 sc->sc_vts->chr.onesix = (sc->sc_type == TYPE_TS05 ? 020 : 016); 491 sc->sc_vts->chr.chrw = TS_WC_ESS; 492 sc->sc_vts->chr.xchrw = TS_WCX_HSP|TS_WCX_RBUF|TS_WCX_WBUF; 493 494 TS_WCSR(TSDB, sc->sc_waddr); 495 } 496 497 /* 498 * Reset the TS11. Return 1 if failed, 0 if succeeded. 499 */ 500 int 501 tsreset(struct ts_softc *sc) 502 { 503 int timeout; 504 505 /* 506 * reset ctlr by writing into TSSR, then write characteristics 507 */ 508 timeout = 0; /* timeout in 10 seconds */ 509 TS_WCSR(TSSR, 0); /* start initialization */ 510 while ((TS_RCSR(TSSR) & TS_SSR) == 0) { 511 DELAY(10000); 512 if (timeout++ > 1000) 513 return 0; 514 } 515 return 1; 516 } 517 518 static void 519 prtstat(struct ts_softc *sc, int sr) 520 { 521 char buf[100]; 522 523 bitmask_snprintf(sr, TS_TSSR_BITS, buf, sizeof(buf)); 524 printf("%s: TSSR=%s\n", XNAME, buf); 525 bitmask_snprintf(sc->sc_vts->status.xst0,TS_XST0_BITS,buf,sizeof(buf)); 526 printf("%s: XST0=%s\n", XNAME, buf); 527 } 528 529 /* 530 * TSV05/TS05 interrupt routine 531 */ 532 static void 533 tsintr(void *arg) 534 { 535 struct ts_softc *sc = arg; 536 struct buf *bp; 537 538 unsigned short sr = TS_RCSR(TSSR); /* save TSSR */ 539 unsigned short mh = sc->sc_vts->status.hdr; /* and msg-header */ 540 /* clear the message header ??? */ 541 542 short ccode = sc->sc_vts->cmd.cmdr & TS_CF_CCODE; 543 544 #ifdef TSDEBUG 545 { 546 char buf[100]; 547 bitmask_snprintf(sr, TS_TSSR_BITS, buf, sizeof(buf)); 548 printf("tsintr: sr %x mh %x\n", sr, mh); 549 printf("srbits: %s\n", buf); 550 } 551 #endif 552 /* 553 * There are two different things which can (and should) be checked: 554 * the actual (internal) state and the device's result (tssr/msg.hdr) 555 * 556 * For each state there's only one "normal" interrupt. Anything else 557 * has to be checked more intensively. Thus in a first run according 558 * to the internal state the expected interrupt is checked/handled. 559 * 560 * In a second run the remaining (not yet handled) interrupts are 561 * checked according to the drive's result. 562 */ 563 switch (sc->sc_state) { 564 565 case TS_INVALID: 566 /* 567 * Ignore unsolicited interrupts. 568 */ 569 log(LOG_WARNING, "%s: stray intr [%x,%x]\n", 570 sc->sc_dev.dv_xname, sr, mh); 571 return; 572 573 case TS_INIT: 574 /* 575 * Init phase ready. 576 */ 577 wakeup(sc); 578 return; 579 580 case TS_RUNNING: 581 case TS_FASTREPOS: 582 /* 583 * Here we expect interrupts indicating the end of 584 * commands or indicating problems. 585 */ 586 /* 587 * Anything else is handled outside this switch ... 588 */ 589 break; 590 591 default: 592 printf ("%s: unexpected interrupt during state %d [%x,%x]\n", 593 sc->sc_dev.dv_xname, sc->sc_state, sr, mh); 594 return; 595 } 596 597 /* 598 * now we check the termination class. 599 */ 600 switch (sr & TS_TC) { 601 602 case TS_TC_NORM: 603 /* 604 * Normal termination -- The operation is completed 605 * witout incident. 606 */ 607 if (sc->sc_state == TS_FASTREPOS) { 608 #ifdef TSDEBUG 609 printf("Fast repos interrupt\n"); 610 #endif 611 /* Fast repos succeeded, start normal data xfer */ 612 sc->sc_state = TS_RUNNING; 613 tsstart(sc, 1); 614 return; 615 } 616 sc->sc_liowf = (ccode == TS_CC_WRITE); 617 break; 618 619 case TS_TC_ATTN: 620 /* 621 * Attention condition -- this code indicates that the 622 * drive has undergone a status change, such as going 623 * off-line or coming on-line. 624 * (Without EAI enabled, no Attention interrupts occur. 625 * drive status changes are signaled by the VCK flag.) 626 */ 627 return; 628 629 case TS_TC_TSA: 630 /* 631 * Tape Status Alert -- A status condition is encountered 632 * that may have significance to the program. Bits of 633 * interest in the extended status registers include 634 * TMK, EOT and RLL. 635 */ 636 #ifdef TSDEBUG 637 { 638 char buf[100]; 639 bitmask_snprintf(sc->sc_vts->status.xst0, 640 TS_XST0_BITS, buf, sizeof(buf)); 641 printf("TSA: sr %x bits %s\n", 642 sc->sc_vts->status.xst0, buf); 643 } 644 #endif 645 if (sc->sc_vts->status.xst0 & TS_SF_TMK) { 646 /* Read to end-of-file. No error. */ 647 break; 648 } 649 if (sc->sc_vts->status.xst0 & TS_SF_EOT) { 650 /* End of tape. Bad. */ 651 #ifdef TSDEBUG 652 printf("TS_TC_TSA: EOT\n"); 653 #endif 654 bp->b_flags |= B_ERROR; 655 bp->b_error = EIO; 656 break; 657 } 658 if (sc->sc_vts->status.xst0 & TS_SF_RLS) 659 break; 660 if (sc->sc_vts->status.xst0 & TS_SF_TMK) { 661 #ifdef TSDEBUG 662 printf(("Tape Mark detected")); 663 #endif 664 } 665 if (sc->sc_vts->status.xst0 & TS_SF_EOT) { 666 #ifdef TSDEBUG 667 printf(("End of Tape")); 668 #endif 669 } 670 #ifndef TSDEBUG 671 { 672 char buf[100]; 673 bitmask_snprintf(sc->sc_vts->status.xst0, 674 TS_XST0_BITS, buf, sizeof(buf)); 675 printf("TSA: sr %x bits %s\n", 676 sc->sc_vts->status.xst0, buf); 677 } 678 #endif 679 break; 680 681 case TS_TC_FR: 682 /* 683 * Function Reject -- The specified function was not 684 * initiated. Bits of interest include OFL, VCK, BOT, 685 * WLE, ILC and ILA. 686 */ 687 if (sr & TS_OFL) 688 printf("tape is off-line.\n"); 689 #ifdef TSDEBUG 690 { 691 char buf[100]; 692 bitmask_snprintf(sc->sc_vts->status.xst0, 693 TS_XST0_BITS, buf, sizeof(buf)); 694 printf("FR: sr %x bits %s\n", 695 sc->sc_vts->status.xst0, buf); 696 } 697 #endif 698 if (sc->sc_vts->status.xst0 & TS_SF_VCK) 699 printf("Volume check\n"); 700 if (sc->sc_vts->status.xst0 & TS_SF_BOT) 701 printf("Start of tape.\n"); 702 if (sc->sc_vts->status.xst0 & TS_SF_WLE) 703 printf("Write Lock Error\n"); 704 if (sc->sc_vts->status.xst0 & TS_SF_EOT) 705 printf("End of tape.\n"); 706 break; 707 708 case TS_TC_TPD: 709 /* 710 * Recoverable Error -- Tape position is a record beyond 711 * what its position was when the function was initiated. 712 * Suggested recovery procedure is to log the error and 713 * issue the appropriate retry command. 714 * 715 * Do a fast repositioning one record back. 716 */ 717 sc->sc_state = TS_FASTREPOS; 718 #ifdef TSDEBUG 719 printf("TS_TC_TPD: errcnt %d\n", sc->sc_rtc); 720 #endif 721 if (sc->sc_rtc++ == 8) { 722 printf("%s: failed 8 retries\n", XNAME); 723 prtstat(sc, sr); 724 bp->b_flags |= B_ERROR; 725 bp->b_error = EIO; 726 break; 727 } 728 sc->sc_vts->cmd.cmdr = TS_CF_ACK | TS_CF_IE | TS_CMD_SRR; 729 sc->sc_vts->cmd.cw1 = 1; 730 TS_WCSR(TSDB, sc->sc_waddr); 731 return; 732 733 break; 734 735 case TS_TC_TNM: 736 /* 737 * Recoverable Error -- Tape position has not changed. 738 * Suggested recovery procedure is to log the error and 739 * reissue the original command. 740 */ 741 if (sc->sc_rtc++ == 8) { 742 printf("%s: failed 8 retries\n", XNAME); 743 prtstat(sc, sr); 744 bp->b_flags |= B_ERROR; 745 bp->b_error = EIO; 746 break; 747 } 748 tsstart(sc, 1); 749 return; 750 751 case TS_TC_TPL: 752 /* 753 * Unrecoverable Error -- Tape position has been lost. 754 * No valid recovery procedures exist unless the tape 755 * has labels or sequence numbers. 756 */ 757 printf("Tape position lost\n"); 758 bp->b_flags |= B_ERROR; 759 bp->b_error = EIO; 760 break; 761 762 case TS_TC_FCE: 763 /* 764 * Fatal subsytem Error -- The subsytem is incapable 765 * of properly performing commands, or at least its 766 * integrity is seriously questionable. Refer to the 767 * fatal class code field in the TSSR register for 768 * additional information on the type of fatal error. 769 */ 770 printf ("Fatal Controller Error\n"); 771 prtstat(sc, sr); 772 break; 773 774 default: 775 printf ("%s: error 0x%x, resetting controller\n", 776 sc->sc_dev.dv_xname, sr & TS_TC); 777 tsreset(sc); 778 } 779 if ((bp = TAILQ_FIRST(&sc->sc_bufq.bq_head)) != NULL) { 780 BUFQ_REMOVE(&sc->sc_bufq, bp); 781 782 #ifdef TSDEBUG 783 printf("tsintr2: que %p\n", TAILQ_FIRST(&sc->sc_bufq.bq_head)); 784 #endif 785 if (bp != &sc->ts_cbuf) { /* no ioctl */ 786 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmam); 787 uba_done((void *)sc->sc_dev.dv_parent); 788 } 789 bp->b_resid = sc->sc_vts->status.rbpcr; 790 if ((bp->b_flags & B_ERROR) == 0) 791 bp->b_error = 0; 792 biodone (bp); 793 } 794 tsstart(sc, 0); 795 } 796 797 798 /* 799 * Open a ts device and set the unit online. If the controller is not 800 * in the run state, call init to initialize the ts controller first. 801 */ 802 int 803 tsopen(dev_t dev, int flag, int type, struct proc *p) 804 { 805 struct ts_softc *sc; 806 int unit = TS_UNIT(dev); 807 808 if (unit >= ts_cd.cd_ndevs) 809 return ENXIO; 810 811 sc = ts_cd.cd_devs[unit]; 812 if (sc == 0) 813 return ENXIO; 814 815 if (sc->sc_state < TS_RUNNING) 816 return ENXIO; 817 818 if (sc->sc_openf) 819 return EBUSY; 820 sc->sc_openf = 1; 821 822 /* 823 * check if transport is really online. 824 * (without attention-interrupts enabled, we really don't know 825 * the actual state of the transport. Thus we call get-status 826 * (ie. MTNOP) once and check the actual status.) 827 */ 828 if (TS_RCSR(TSSR) & TS_OFL) { 829 uprintf("%s: transport is offline.\n", XNAME); 830 sc->sc_openf = 0; 831 return EIO; /* transport is offline */ 832 } 833 tscommand(sc, dev, MTNOP, 1); 834 if ((flag & FWRITE) && (sc->sc_vts->status.xst0 & TS_SF_WLK)) { 835 uprintf("%s: no write ring.\n", XNAME); 836 sc->sc_openf = 0; 837 return EROFS; 838 } 839 if (sc->sc_vts->status.xst0 & TS_SF_VCK) { 840 sc->sc_vts->cmd.cmdr = TS_CF_CVC|TS_CF_ACK; 841 TS_WCSR(TSDB, sc->sc_waddr); 842 } 843 tscommand(sc, dev, MTNOP, 1); 844 #ifdef TSDEBUG 845 { 846 char buf[100]; 847 bitmask_snprintf(sc->sc_vts->status.xst0, 848 TS_XST0_BITS, buf, sizeof(buf)); 849 printf("tsopen: xst0 %s\n", buf); 850 } 851 #endif 852 sc->sc_liowf = 0; 853 return 0; 854 } 855 856 857 /* 858 * Close tape device. 859 * 860 * If tape was open for writing or last operation was 861 * a write, then write two EOF's and backspace over the last one. 862 * Unless this is a non-rewinding special file, rewind the tape. 863 * 864 * Make the tape available to others, by clearing openf flag. 865 */ 866 int 867 tsclose(dev_t dev, int flag, int type, struct proc *p) 868 { 869 struct ts_softc *sc = ts_cd.cd_devs[TS_UNIT(dev)]; 870 871 if (flag == FWRITE || ((flag & FWRITE) && sc->sc_liowf)) { 872 /* 873 * We are writing two tape marks (EOT), but place the tape 874 * before the second one, so that another write operation 875 * will overwrite the second one and leave and EOF-mark. 876 */ 877 tscommand(sc, dev, MTWEOF, 1); /* Write Tape Mark */ 878 tscommand(sc, dev, MTWEOF, 1); /* Write Tape Mark */ 879 tscommand(sc, dev, MTBSF, 1); /* Skip Tape Marks Reverse */ 880 } 881 882 if ((dev & T_NOREWIND) == 0) 883 tscommand(sc, dev, MTREW, 0); 884 885 sc->sc_openf = 0; 886 sc->sc_liowf = 0; 887 return 0; 888 } 889 890 891 /* 892 * Manage buffers and perform block mode read and write operations. 893 */ 894 void 895 tsstrategy(struct buf *bp) 896 { 897 register int unit = TS_UNIT(bp->b_dev); 898 struct ts_softc *sc = (void *)ts_cd.cd_devs[unit]; 899 int s, empty; 900 901 #ifdef TSDEBUG 902 printf("buf: %p bcount %ld blkno %d\n", bp, bp->b_bcount, bp->b_blkno); 903 #endif 904 s = splbio (); 905 empty = TAILQ_EMPTY(&sc->sc_bufq.bq_head); 906 BUFQ_INSERT_TAIL(&sc->sc_bufq, bp); 907 if (empty) 908 tsstart(sc, 0); 909 splx(s); 910 } 911 912 913 /* 914 * Catch ioctl commands, and call the "command" routine to do them. 915 */ 916 int 917 tsioctl(dev, cmd, data, flag, p) 918 dev_t dev; 919 u_long cmd; 920 caddr_t data; 921 int flag; 922 struct proc *p; 923 { 924 struct buf *bp; 925 struct ts_softc *sc; 926 struct mtop *mtop; /* mag tape cmd op to perform */ 927 struct mtget *mtget; /* mag tape struct to get info in */ 928 int callcount; /* number of times to call routine */ 929 int scount; /* number of files/records to space */ 930 int spaceop = 0; /* flag for skip/space operation */ 931 int error = 0; 932 933 #ifdef TSDEBUG 934 printf("tsioctl (%x, %lx, %p, %d)\n", dev, cmd, data, flag); 935 #endif 936 937 sc = ts_cd.cd_devs[TS_UNIT(dev)]; 938 bp = &sc->ts_cbuf; 939 940 switch (cmd) { 941 case MTIOCTOP: /* do a mag tape op */ 942 mtop = (struct mtop *)data; 943 switch (mtop->mt_op) { 944 case MTWEOF: /* write an end-of-file record */ 945 callcount = mtop->mt_count; 946 scount = 1; 947 break; 948 case MTFSR: /* forward space record */ 949 case MTBSR: /* backward space record */ 950 spaceop = 1; 951 case MTFSF: /* forward space file */ 952 case MTBSF: /* backward space file */ 953 callcount = 1; 954 scount = mtop->mt_count; 955 break; 956 case MTREW: /* rewind */ 957 case MTOFFL: /* rewind and put the drive offline */ 958 case MTNOP: /* no operation, sets status only */ 959 callcount = 1; 960 scount = 1; /* wait for this rewind */ 961 break; 962 case MTRETEN: /* retension */ 963 case MTERASE: /* erase entire tape */ 964 case MTEOM: /* forward to end of media */ 965 case MTNBSF: /* backward space to begin of file */ 966 case MTCACHE: /* enable controller cache */ 967 case MTNOCACHE: /* disable controller cache */ 968 case MTSETBSIZ: /* set block size; 0 for variable */ 969 case MTSETDNSTY: /* set density code for current mode */ 970 printf("ioctl %d not implemented.\n", mtop->mt_op); 971 return (ENXIO); 972 default: 973 #ifdef TSDEBUG 974 printf("invalid ioctl %d\n", mtop->mt_op); 975 #endif 976 return (ENXIO); 977 } /* switch (mtop->mt_op) */ 978 979 if (callcount <= 0 || scount <= 0) { 980 #ifdef TSDEBUG 981 printf("invalid values %d/%d\n", callcount, scount); 982 #endif 983 return (EINVAL); 984 } 985 do { 986 tscommand(sc, dev, mtop->mt_op, scount); 987 if (spaceop && bp->b_resid) { 988 #ifdef TSDEBUG 989 printf(("spaceop didn't complete\n")); 990 #endif 991 return (EIO); 992 } 993 if (bp->b_flags & B_ERROR) { 994 #ifdef TSDEBUG 995 printf("error in ioctl %d\n", mtop->mt_op); 996 #endif 997 break; 998 } 999 } while (--callcount > 0); 1000 if (bp->b_flags & B_ERROR) 1001 if ((error = bp->b_error) == 0) 1002 return (EIO); 1003 return (error); 1004 1005 case MTIOCGET: /* get tape status */ 1006 mtget = (struct mtget *)data; 1007 mtget->mt_type = MT_ISTS; 1008 mtget->mt_dsreg = TS_RCSR(TSSR); 1009 mtget->mt_erreg = sc->sc_vts->status.xst0; 1010 mtget->mt_resid = 0; /* ??? */ 1011 mtget->mt_density = 0; /* ??? */ 1012 break; 1013 1014 case MTIOCIEOT: /* ignore EOT error */ 1015 #ifdef TSDEBUG 1016 printf(("MTIOCIEOT not implemented.\n")); 1017 #endif 1018 return (ENXIO); 1019 1020 case MTIOCEEOT: /* enable EOT error */ 1021 #ifdef TSDEBUG 1022 printf(("MTIOCEEOT not implemented.\n")); 1023 #endif 1024 return (ENXIO); 1025 1026 default: 1027 #ifdef TSDEBUG 1028 printf("invalid ioctl cmd 0x%lx\n", cmd); 1029 #endif 1030 return (ENXIO); 1031 } 1032 1033 return (0); 1034 } 1035 1036 1037 /* 1038 * 1039 */ 1040 int 1041 tsread(dev_t dev, struct uio *uio, int flag) 1042 { 1043 return (physio (tsstrategy, NULL, dev, B_READ, minphys, uio)); 1044 } 1045 1046 /* 1047 * 1048 */ 1049 int 1050 tswrite(dev_t dev, struct uio *uio, int flag) 1051 { 1052 return (physio (tsstrategy, NULL, dev, B_WRITE, minphys, uio)); 1053 } 1054 1055 /* 1056 * 1057 */ 1058 int 1059 tsdump(dev, blkno, va, size) 1060 dev_t dev; 1061 daddr_t blkno; 1062 caddr_t va; 1063 size_t size; 1064 { 1065 return EIO; 1066 } 1067