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