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