1 /* $NetBSD: wt.c,v 1.66 2005/12/11 12:22:03 christos Exp $ */ 2 3 /* 4 * Streamer tape driver. 5 * Supports Archive and Wangtek compatible QIC-02/QIC-36 boards. 6 * 7 * Copyright (C) 1993 by: 8 * Sergey Ryzhkov <sir@kiae.su> 9 * Serge Vakulenko <vak@zebub.msk.su> 10 * 11 * This software is distributed with NO WARRANTIES, not even the implied 12 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 * 14 * Authors grant any other persons or organisations permission to use 15 * or modify this software as long as this message is kept with the software, 16 * all derivative works or modified versions. 17 * 18 * This driver is derived from the old 386bsd Wangtek streamer tape driver, 19 * made by Robert Baron at CMU, based on Intel sources. 20 */ 21 22 /* 23 * Copyright (c) 1989 Carnegie-Mellon University. 24 * All rights reserved. 25 * 26 * Authors: Robert Baron 27 * 28 * Permission to use, copy, modify and distribute this software and 29 * its documentation is hereby granted, provided that both the copyright 30 * notice and this permission notice appear in all copies of the 31 * software, derivative works or modified versions, and any portions 32 * thereof, and that both notices appear in supporting documentation. 33 * 34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 36 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 37 * 38 * Carnegie Mellon requests users of this software to return to 39 * 40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 41 * School of Computer Science 42 * Carnegie Mellon University 43 * Pittsburgh PA 15213-3890 44 * 45 * any improvements or extensions that they make and grant Carnegie the 46 * rights to redistribute these changes. 47 */ 48 49 /* 50 * Copyright 1988, 1989 by Intel Corporation 51 */ 52 53 #include <sys/cdefs.h> 54 __KERNEL_RCSID(0, "$NetBSD: wt.c,v 1.66 2005/12/11 12:22:03 christos Exp $"); 55 56 #include <sys/param.h> 57 #include <sys/systm.h> 58 #include <sys/callout.h> 59 #include <sys/kernel.h> 60 #include <sys/buf.h> 61 #include <sys/fcntl.h> 62 #include <sys/malloc.h> 63 #include <sys/ioctl.h> 64 #include <sys/mtio.h> 65 #include <sys/device.h> 66 #include <sys/proc.h> 67 #include <sys/conf.h> 68 69 #include <machine/intr.h> 70 #include <machine/bus.h> 71 #include <machine/pio.h> 72 73 #include <dev/isa/isavar.h> 74 #include <dev/isa/isadmavar.h> 75 #include <dev/isa/wtreg.h> 76 77 /* 78 * Uncomment this to enable internal device tracing. 79 */ 80 #define WTDBPRINT(x) /* printf x */ 81 82 #define WTPRI (PZERO+10) /* sleep priority */ 83 84 #define WT_NPORT 2 /* 2 i/o ports */ 85 #define AV_NPORT 4 /* 4 i/o ports */ 86 87 enum wttype { 88 UNKNOWN = 0, /* unknown type, driver disabled */ 89 ARCHIVE, /* Archive Viper SC499, SC402 etc */ 90 WANGTEK, /* Wangtek */ 91 }; 92 93 static struct wtregs { 94 /* controller ports */ 95 int DATAPORT, /* data, read only */ 96 CMDPORT, /* command, write only */ 97 STATPORT, /* status, read only */ 98 CTLPORT, /* control, write only */ 99 SDMAPORT, /* start DMA */ 100 RDMAPORT; /* reset DMA */ 101 /* status port bits */ 102 u_char BUSY, /* not ready bit define */ 103 NOEXCEP, /* no exception bit define */ 104 RESETMASK, /* to check after reset */ 105 RESETVAL, /* state after reset */ 106 /* control port bits */ 107 ONLINE, /* device selected */ 108 RESET, /* reset command */ 109 REQUEST, /* request command */ 110 IEN; /* enable interrupts */ 111 } wtregs = { 112 1, 1, 0, 0, 0, 0, 113 0x01, 0x02, 0x07, 0x05, 114 0x01, 0x02, 0x04, 0x08 115 }, avregs = { 116 0, 0, 1, 1, 2, 3, 117 0x40, 0x20, 0xf8, 0x50, 118 0, 0x80, 0x40, 0x20 119 }; 120 121 struct wt_softc { 122 struct device sc_dev; 123 void *sc_ih; 124 125 bus_space_tag_t sc_iot; 126 bus_space_handle_t sc_ioh; 127 isa_chipset_tag_t sc_ic; 128 129 struct callout sc_timer_ch; 130 131 enum wttype type; /* type of controller */ 132 int chan; /* DMA channel number, 1..3 */ 133 int flags; /* state of tape drive */ 134 unsigned dens; /* tape density */ 135 int bsize; /* tape block size */ 136 void *buf; /* internal i/o buffer */ 137 138 void *dmavaddr; /* virtual address of DMA i/o buffer */ 139 size_t dmatotal; /* size of i/o buffer */ 140 int dmaflags; /* i/o direction */ 141 size_t dmacount; /* resulting length of DMA i/o */ 142 143 u_short error; /* code for error encountered */ 144 u_short ercnt; /* number of error blocks */ 145 u_short urcnt; /* number of underruns */ 146 147 struct wtregs regs; 148 }; 149 150 dev_type_open(wtopen); 151 dev_type_close(wtclose); 152 dev_type_read(wtread); 153 dev_type_write(wtwrite); 154 dev_type_ioctl(wtioctl); 155 dev_type_strategy(wtstrategy); 156 dev_type_dump(wtdump); 157 dev_type_size(wtsize); 158 159 const struct bdevsw wt_bdevsw = { 160 wtopen, wtclose, wtstrategy, wtioctl, wtdump, wtsize, D_TAPE 161 }; 162 163 const struct cdevsw wt_cdevsw = { 164 wtopen, wtclose, wtread, wtwrite, wtioctl, 165 nostop, notty, nopoll, nommap, nokqfilter, D_TAPE 166 }; 167 168 int wtwait(struct wt_softc *sc, int catch, char *msg); 169 int wtcmd(struct wt_softc *sc, int cmd); 170 int wtstart(struct wt_softc *sc, int flag, void *vaddr, size_t len); 171 void wtdma(struct wt_softc *sc); 172 void wttimer(void *arg); 173 void wtclock(struct wt_softc *sc); 174 int wtreset(bus_space_tag_t, bus_space_handle_t, struct wtregs *); 175 int wtsense(struct wt_softc *sc, int verbose, int ignore); 176 int wtstatus(struct wt_softc *sc); 177 void wtrewind(struct wt_softc *sc); 178 int wtreadfm(struct wt_softc *sc); 179 int wtwritefm(struct wt_softc *sc); 180 u_char wtsoft(struct wt_softc *sc, int mask, int bits); 181 182 int wtprobe(struct device *, struct cfdata *, void *); 183 void wtattach(struct device *, struct device *, void *); 184 int wtintr(void *sc); 185 186 CFATTACH_DECL(wt, sizeof(struct wt_softc), 187 wtprobe, wtattach, NULL, NULL); 188 189 extern struct cfdriver wt_cd; 190 191 /* 192 * Probe for the presence of the device. 193 */ 194 int 195 wtprobe(parent, match, aux) 196 struct device *parent; 197 struct cfdata *match; 198 void *aux; 199 { 200 struct isa_attach_args *ia = aux; 201 bus_space_tag_t iot = ia->ia_iot; 202 bus_space_handle_t ioh; 203 int rv = 0, iosize; 204 205 if (ia->ia_nio < 1) 206 return (0); 207 if (ia->ia_nirq < 1) 208 return (0); 209 if (ia->ia_ndrq < 1) 210 return (0); 211 212 /* Disallow wildcarded i/o address. */ 213 if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) 214 return (0); 215 if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) 216 return (0); 217 218 if (ia->ia_drq[0].ir_drq < 1 || ia->ia_drq[0].ir_drq > 3) { 219 printf("wtprobe: Bad drq=%d, should be 1..3\n", 220 ia->ia_drq[0].ir_drq); 221 return (0); 222 } 223 224 iosize = AV_NPORT; 225 226 /* Map i/o space */ 227 if (bus_space_map(iot, ia->ia_io[0].ir_addr, iosize, 0, &ioh)) 228 return 0; 229 230 /* Try Wangtek. */ 231 if (wtreset(iot, ioh, &wtregs)) { 232 iosize = WT_NPORT; /* XXX misleading */ 233 rv = 1; 234 goto done; 235 } 236 237 /* Try Archive. */ 238 if (wtreset(iot, ioh, &avregs)) { 239 iosize = AV_NPORT; 240 rv = 1; 241 goto done; 242 } 243 244 done: 245 if (rv) { 246 ia->ia_nio = 1; 247 ia->ia_io[0].ir_size = iosize; 248 249 ia->ia_nirq = 1; 250 ia->ia_ndrq = 1; 251 252 ia->ia_niomem = 0; 253 } 254 bus_space_unmap(iot, ioh, AV_NPORT); 255 return rv; 256 } 257 258 /* 259 * Device is found, configure it. 260 */ 261 void 262 wtattach(parent, self, aux) 263 struct device *parent, *self; 264 void *aux; 265 { 266 struct wt_softc *sc = (void *)self; 267 struct isa_attach_args *ia = aux; 268 bus_space_tag_t iot = ia->ia_iot; 269 bus_space_handle_t ioh; 270 bus_size_t maxsize; 271 272 /* Map i/o space */ 273 if (bus_space_map(iot, ia->ia_io[0].ir_addr, AV_NPORT, 0, &ioh)) { 274 printf(": can't map i/o space\n"); 275 return; 276 } 277 278 sc->sc_iot = iot; 279 sc->sc_ioh = ioh; 280 sc->sc_ic = ia->ia_ic; 281 282 callout_init(&sc->sc_timer_ch); 283 284 /* Try Wangtek. */ 285 if (wtreset(iot, ioh, &wtregs)) { 286 sc->type = WANGTEK; 287 memcpy(&sc->regs, &wtregs, sizeof(sc->regs)); 288 printf(": type <Wangtek>\n"); 289 goto ok; 290 } 291 292 /* Try Archive. */ 293 if (wtreset(iot, ioh, &avregs)) { 294 sc->type = ARCHIVE; 295 memcpy(&sc->regs, &avregs, sizeof(sc->regs)); 296 printf(": type <Archive>\n"); 297 /* Reset DMA. */ 298 bus_space_write_1(iot, ioh, sc->regs.RDMAPORT, 0); 299 goto ok; 300 } 301 302 /* what happened? */ 303 printf("%s: lost controller\n", self->dv_xname); 304 return; 305 306 ok: 307 sc->flags = TPSTART; /* tape is rewound */ 308 sc->dens = -1; /* unknown density */ 309 310 sc->chan = ia->ia_drq[0].ir_drq; 311 312 if ((maxsize = isa_dmamaxsize(sc->sc_ic, sc->chan)) < MAXPHYS) { 313 printf("%s: max DMA size %lu is less than required %d\n", 314 sc->sc_dev.dv_xname, (u_long)maxsize, MAXPHYS); 315 return; 316 } 317 318 if (isa_drq_alloc(sc->sc_ic, sc->chan) != 0) { 319 printf("%s: can't reserve drq %d\n", 320 sc->sc_dev.dv_xname, sc->chan); 321 return; 322 } 323 324 if (isa_dmamap_create(sc->sc_ic, sc->chan, MAXPHYS, 325 BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 326 printf("%s: can't set up ISA DMA map\n", 327 sc->sc_dev.dv_xname); 328 return; 329 } 330 331 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, 332 IST_EDGE, IPL_BIO, wtintr, sc); 333 } 334 335 int 336 wtdump(dev, blkno, va, size) 337 dev_t dev; 338 daddr_t blkno; 339 caddr_t va; 340 size_t size; 341 { 342 343 /* Not implemented. */ 344 return ENXIO; 345 } 346 347 int 348 wtsize(dev) 349 dev_t dev; 350 { 351 352 /* Not implemented. */ 353 return -1; 354 } 355 356 /* 357 * Open routine, called on every device open. 358 */ 359 int 360 wtopen(dev, flag, mode, p) 361 dev_t dev; 362 int flag; 363 int mode; 364 struct proc *p; 365 { 366 int unit = minor(dev) & T_UNIT; 367 struct wt_softc *sc; 368 int error; 369 370 sc = device_lookup(&wt_cd, unit); 371 if (sc == NULL) 372 return (ENXIO); 373 374 /* Check that device is not in use */ 375 if (sc->flags & TPINUSE) 376 return EBUSY; 377 378 /* If the tape is in rewound state, check the status and set density. */ 379 if (sc->flags & TPSTART) { 380 /* If rewind is going on, wait */ 381 if ((error = wtwait(sc, PCATCH, "wtrew")) != 0) 382 return error; 383 384 /* Check the controller status */ 385 if (!wtsense(sc, 0, (flag & FWRITE) ? 0 : TP_WRP)) { 386 /* Bad status, reset the controller. */ 387 if (!wtreset(sc->sc_iot, sc->sc_ioh, &sc->regs)) 388 return EIO; 389 if (!wtsense(sc, 1, (flag & FWRITE) ? 0 : TP_WRP)) 390 return EIO; 391 } 392 393 /* Set up tape density. */ 394 if (sc->dens != (minor(dev) & WT_DENSEL)) { 395 int d = 0; 396 397 switch (minor(dev) & WT_DENSEL) { 398 case WT_DENSDFLT: 399 default: 400 break; /* default density */ 401 case WT_QIC11: 402 d = QIC_FMT11; break; /* minor 010 */ 403 case WT_QIC24: 404 d = QIC_FMT24; break; /* minor 020 */ 405 case WT_QIC120: 406 d = QIC_FMT120; break; /* minor 030 */ 407 case WT_QIC150: 408 d = QIC_FMT150; break; /* minor 040 */ 409 case WT_QIC300: 410 d = QIC_FMT300; break; /* minor 050 */ 411 case WT_QIC600: 412 d = QIC_FMT600; break; /* minor 060 */ 413 } 414 if (d) { 415 /* Change tape density. */ 416 if (!wtcmd(sc, d)) 417 return EIO; 418 if (!wtsense(sc, 1, TP_WRP | TP_ILL)) 419 return EIO; 420 421 /* Check the status of the controller. */ 422 if (sc->error & TP_ILL) { 423 printf("%s: invalid tape density\n", 424 sc->sc_dev.dv_xname); 425 return ENODEV; 426 } 427 } 428 sc->dens = minor(dev) & WT_DENSEL; 429 } 430 sc->flags &= ~TPSTART; 431 } else if (sc->dens != (minor(dev) & WT_DENSEL)) 432 return ENXIO; 433 434 sc->bsize = (minor(dev) & WT_BSIZE) ? 1024 : 512; 435 sc->buf = malloc(sc->bsize, M_TEMP, M_WAITOK); 436 437 sc->flags = TPINUSE; 438 if (flag & FREAD) 439 sc->flags |= TPREAD; 440 if (flag & FWRITE) 441 sc->flags |= TPWRITE; 442 return 0; 443 } 444 445 /* 446 * Close routine, called on last device close. 447 */ 448 int 449 wtclose(dev, flags, mode, p) 450 dev_t dev; 451 int flags; 452 int mode; 453 struct proc *p; 454 { 455 struct wt_softc *sc = device_lookup(&wt_cd, minor(dev) & T_UNIT); 456 457 /* If rewind is pending, do nothing */ 458 if (sc->flags & TPREW) 459 goto done; 460 461 /* If seek forward is pending and no rewind on close, do nothing */ 462 if (sc->flags & TPRMARK) { 463 if (minor(dev) & T_NOREWIND) 464 goto done; 465 466 /* If read file mark is going on, wait */ 467 wtwait(sc, 0, "wtrfm"); 468 } 469 470 if (sc->flags & TPWANY) { 471 /* Tape was written. Write file mark. */ 472 wtwritefm(sc); 473 } 474 475 if ((minor(dev) & T_NOREWIND) == 0) { 476 /* Rewind to beginning of tape. */ 477 /* Don't wait until rewind, though. */ 478 wtrewind(sc); 479 goto done; 480 } 481 if ((sc->flags & TPRANY) && (sc->flags & (TPVOL | TPWANY)) == 0) { 482 /* Space forward to after next file mark if no writing done. */ 483 /* Don't wait for completion. */ 484 wtreadfm(sc); 485 } 486 487 done: 488 sc->flags &= TPREW | TPRMARK | TPSTART | TPTIMER; 489 free(sc->buf, M_TEMP); 490 return 0; 491 } 492 493 /* 494 * Ioctl routine. Compatible with BSD ioctls. 495 * Direct QIC-02 commands ERASE and RETENSION added. 496 * There are three possible ioctls: 497 * ioctl(int fd, MTIOCGET, struct mtget *buf) -- get status 498 * ioctl(int fd, MTIOCTOP, struct mtop *buf) -- do BSD-like op 499 * ioctl(int fd, WTQICMD, int qicop) -- do QIC op 500 */ 501 int 502 wtioctl(dev, cmd, addr, flag, p) 503 dev_t dev; 504 u_long cmd; 505 caddr_t addr; 506 int flag; 507 struct proc *p; 508 { 509 struct wt_softc *sc = device_lookup(&wt_cd, minor(dev) & T_UNIT); 510 int error, count, op; 511 512 switch (cmd) { 513 default: 514 return EINVAL; 515 case WTQICMD: /* direct QIC command */ 516 op = *(int *)addr; 517 switch (op) { 518 default: 519 return EINVAL; 520 case QIC_ERASE: /* erase the whole tape */ 521 if ((sc->flags & TPWRITE) == 0 || (sc->flags & TPWP)) 522 return EACCES; 523 if ((error = wtwait(sc, PCATCH, "wterase")) != 0) 524 return error; 525 break; 526 case QIC_RETENS: /* retension the tape */ 527 if ((error = wtwait(sc, PCATCH, "wtretens")) != 0) 528 return error; 529 break; 530 } 531 /* Both ERASE and RETENS operations work like REWIND. */ 532 /* Simulate the rewind operation here. */ 533 sc->flags &= ~(TPRO | TPWO | TPVOL); 534 if (!wtcmd(sc, op)) 535 return EIO; 536 sc->flags |= TPSTART | TPREW; 537 if (op == QIC_ERASE) 538 sc->flags |= TPWANY; 539 wtclock(sc); 540 return 0; 541 case MTIOCIEOT: /* ignore EOT errors */ 542 case MTIOCEEOT: /* enable EOT errors */ 543 return 0; 544 case MTIOCGET: 545 ((struct mtget*)addr)->mt_type = 546 sc->type == ARCHIVE ? MT_ISVIPER1 : 0x11; 547 ((struct mtget*)addr)->mt_dsreg = sc->flags; /* status */ 548 ((struct mtget*)addr)->mt_erreg = sc->error; /* errors */ 549 ((struct mtget*)addr)->mt_resid = 0; 550 ((struct mtget*)addr)->mt_fileno = 0; /* file */ 551 ((struct mtget*)addr)->mt_blkno = 0; /* block */ 552 return 0; 553 case MTIOCTOP: 554 break; 555 } 556 557 switch ((short)((struct mtop*)addr)->mt_op) { 558 default: 559 #if 0 560 case MTFSR: /* forward space record */ 561 case MTBSR: /* backward space record */ 562 case MTBSF: /* backward space file */ 563 #endif 564 return EINVAL; 565 case MTNOP: /* no operation, sets status only */ 566 case MTCACHE: /* enable controller cache */ 567 case MTNOCACHE: /* disable controller cache */ 568 return 0; 569 case MTREW: /* rewind */ 570 case MTOFFL: /* rewind and put the drive offline */ 571 if (sc->flags & TPREW) /* rewind is running */ 572 return 0; 573 if ((error = wtwait(sc, PCATCH, "wtorew")) != 0) 574 return error; 575 wtrewind(sc); 576 return 0; 577 case MTFSF: /* forward space file */ 578 for (count = ((struct mtop*)addr)->mt_count; count > 0; 579 --count) { 580 if ((error = wtwait(sc, PCATCH, "wtorfm")) != 0) 581 return error; 582 if ((error = wtreadfm(sc)) != 0) 583 return error; 584 } 585 return 0; 586 case MTWEOF: /* write an end-of-file record */ 587 if ((sc->flags & TPWRITE) == 0 || (sc->flags & TPWP)) 588 return EACCES; 589 if ((error = wtwait(sc, PCATCH, "wtowfm")) != 0) 590 return error; 591 if ((error = wtwritefm(sc)) != 0) 592 return error; 593 return 0; 594 } 595 596 #ifdef DIAGNOSTIC 597 panic("wtioctl: impossible"); 598 #endif 599 } 600 601 /* 602 * Strategy routine. 603 */ 604 void 605 wtstrategy(bp) 606 struct buf *bp; 607 { 608 struct wt_softc *sc = device_lookup(&wt_cd, minor(bp->b_dev) & T_UNIT); 609 int s; 610 611 bp->b_resid = bp->b_bcount; 612 613 /* at file marks and end of tape, we just return '0 bytes available' */ 614 if (sc->flags & TPVOL) 615 goto xit; 616 617 if (bp->b_flags & B_READ) { 618 /* Check read access and no previous write to this tape. */ 619 if ((sc->flags & TPREAD) == 0 || (sc->flags & TPWANY)) 620 goto errxit; 621 622 /* For now, we assume that all data will be copied out */ 623 /* If read command outstanding, just skip down */ 624 if ((sc->flags & TPRO) == 0) { 625 if (!wtsense(sc, 1, TP_WRP)) { 626 /* Clear status. */ 627 goto errxit; 628 } 629 if (!wtcmd(sc, QIC_RDDATA)) { 630 /* Set read mode. */ 631 wtsense(sc, 1, TP_WRP); 632 goto errxit; 633 } 634 sc->flags |= TPRO | TPRANY; 635 } 636 } else { 637 /* Check write access and write protection. */ 638 /* No previous read from this tape allowed. */ 639 if ((sc->flags & TPWRITE) == 0 || (sc->flags & (TPWP | TPRANY))) 640 goto errxit; 641 642 /* If write command outstanding, just skip down */ 643 if ((sc->flags & TPWO) == 0) { 644 if (!wtsense(sc, 1, 0)) { 645 /* Clear status. */ 646 goto errxit; 647 } 648 if (!wtcmd(sc, QIC_WRTDATA)) { 649 /* Set write mode. */ 650 wtsense(sc, 1, 0); 651 goto errxit; 652 } 653 sc->flags |= TPWO | TPWANY; 654 } 655 } 656 657 if (bp->b_bcount == 0) 658 goto xit; 659 660 sc->flags &= ~TPEXCEP; 661 s = splbio(); 662 if (wtstart(sc, bp->b_flags, bp->b_data, bp->b_bcount)) { 663 wtwait(sc, 0, (bp->b_flags & B_READ) ? "wtread" : "wtwrite"); 664 bp->b_resid -= sc->dmacount; 665 } 666 splx(s); 667 668 if (sc->flags & TPEXCEP) { 669 errxit: 670 bp->b_flags |= B_ERROR; 671 bp->b_error = EIO; 672 } 673 xit: 674 biodone(bp); 675 return; 676 } 677 678 int 679 wtread(dev, uio, flags) 680 dev_t dev; 681 struct uio *uio; 682 int flags; 683 { 684 685 return (physio(wtstrategy, NULL, dev, B_READ, minphys, uio)); 686 } 687 688 int 689 wtwrite(dev, uio, flags) 690 dev_t dev; 691 struct uio *uio; 692 int flags; 693 { 694 695 return (physio(wtstrategy, NULL, dev, B_WRITE, minphys, uio)); 696 } 697 698 /* 699 * Interrupt routine. 700 */ 701 int 702 wtintr(arg) 703 void *arg; 704 { 705 struct wt_softc *sc = arg; 706 u_char x; 707 708 /* get status */ 709 x = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->regs.STATPORT); 710 WTDBPRINT(("wtintr() status=0x%x -- ", x)); 711 if ((x & (sc->regs.BUSY | sc->regs.NOEXCEP)) 712 == (sc->regs.BUSY | sc->regs.NOEXCEP)) { 713 WTDBPRINT(("busy\n")); 714 return 0; /* device is busy */ 715 } 716 717 /* 718 * Check if rewind finished. 719 */ 720 if (sc->flags & TPREW) { 721 WTDBPRINT(((x & (sc->regs.BUSY | sc->regs.NOEXCEP)) 722 == (sc->regs.BUSY | sc->regs.NOEXCEP) ? 723 "rewind busy?\n" : "rewind finished\n")); 724 sc->flags &= ~TPREW; /* rewind finished */ 725 wtsense(sc, 1, TP_WRP); 726 wakeup((caddr_t)sc); 727 return 1; 728 } 729 730 /* 731 * Check if writing/reading of file mark finished. 732 */ 733 if (sc->flags & (TPRMARK | TPWMARK)) { 734 WTDBPRINT(((x & (sc->regs.BUSY | sc->regs.NOEXCEP)) 735 == (sc->regs.BUSY | sc->regs.NOEXCEP) ? 736 "marker r/w busy?\n" : "marker r/w finished\n")); 737 if ((x & sc->regs.NOEXCEP) == 0) /* operation failed */ 738 wtsense(sc, 1, (sc->flags & TPRMARK) ? TP_WRP : 0); 739 sc->flags &= ~(TPRMARK | TPWMARK); /* operation finished */ 740 wakeup((caddr_t)sc); 741 return 1; 742 } 743 744 /* 745 * Do we started any i/o? If no, just return. 746 */ 747 if ((sc->flags & TPACTIVE) == 0) { 748 WTDBPRINT(("unexpected interrupt\n")); 749 return 0; 750 } 751 sc->flags &= ~TPACTIVE; 752 sc->dmacount += sc->bsize; /* increment counter */ 753 754 /* 755 * Clean up DMA. 756 */ 757 if ((sc->dmaflags & DMAMODE_READ) && 758 (sc->dmatotal - sc->dmacount) < sc->bsize) { 759 /* If reading short block, copy the internal buffer 760 * to the user memory. */ 761 isa_dmadone(sc->sc_ic, sc->chan); 762 memcpy(sc->dmavaddr, sc->buf, sc->dmatotal - sc->dmacount); 763 } else 764 isa_dmadone(sc->sc_ic, sc->chan); 765 766 /* 767 * On exception, check for end of file and end of volume. 768 */ 769 if ((x & sc->regs.NOEXCEP) == 0) { 770 WTDBPRINT(("i/o exception\n")); 771 wtsense(sc, 1, (sc->dmaflags & DMAMODE_READ) ? TP_WRP : 0); 772 if (sc->error & (TP_EOM | TP_FIL)) 773 sc->flags |= TPVOL; /* end of file */ 774 else 775 sc->flags |= TPEXCEP; /* i/o error */ 776 wakeup((caddr_t)sc); 777 return 1; 778 } 779 780 if (sc->dmacount < sc->dmatotal) { 781 /* Continue I/O. */ 782 sc->dmavaddr = (char *)sc->dmavaddr + sc->bsize; 783 wtdma(sc); 784 WTDBPRINT(("continue i/o, %d\n", sc->dmacount)); 785 return 1; 786 } 787 if (sc->dmacount > sc->dmatotal) /* short last block */ 788 sc->dmacount = sc->dmatotal; 789 /* Wake up user level. */ 790 wakeup((caddr_t)sc); 791 WTDBPRINT(("i/o finished, %d\n", sc->dmacount)); 792 return 1; 793 } 794 795 /* start the rewind operation */ 796 void 797 wtrewind(sc) 798 struct wt_softc *sc; 799 { 800 int rwmode = sc->flags & (TPRO | TPWO); 801 802 sc->flags &= ~(TPRO | TPWO | TPVOL); 803 /* 804 * Wangtek strictly follows QIC-02 standard: 805 * clearing ONLINE in read/write modes causes rewind. 806 * REWIND command is not allowed in read/write mode 807 * and gives `illegal command' error. 808 */ 809 if (sc->type == WANGTEK && rwmode) { 810 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->regs.CTLPORT, 0); 811 } else if (!wtcmd(sc, QIC_REWIND)) 812 return; 813 sc->flags |= TPSTART | TPREW; 814 wtclock(sc); 815 } 816 817 /* 818 * Start the `read marker' operation. 819 */ 820 int 821 wtreadfm(sc) 822 struct wt_softc *sc; 823 { 824 825 sc->flags &= ~(TPRO | TPWO | TPVOL); 826 if (!wtcmd(sc, QIC_READFM)) { 827 wtsense(sc, 1, TP_WRP); 828 return EIO; 829 } 830 sc->flags |= TPRMARK | TPRANY; 831 wtclock(sc); 832 /* Don't wait for completion here. */ 833 return 0; 834 } 835 836 /* 837 * Write marker to the tape. 838 */ 839 int 840 wtwritefm(sc) 841 struct wt_softc *sc; 842 { 843 844 tsleep((caddr_t)wtwritefm, WTPRI, "wtwfm", hz); 845 sc->flags &= ~(TPRO | TPWO); 846 if (!wtcmd(sc, QIC_WRITEFM)) { 847 wtsense(sc, 1, 0); 848 return EIO; 849 } 850 sc->flags |= TPWMARK | TPWANY; 851 wtclock(sc); 852 return wtwait(sc, 0, "wtwfm"); 853 } 854 855 /* 856 * While controller status & mask == bits continue waiting. 857 */ 858 u_char 859 wtsoft(sc, mask, bits) 860 struct wt_softc *sc; 861 int mask, bits; 862 { 863 bus_space_tag_t iot = sc->sc_iot; 864 bus_space_handle_t ioh = sc->sc_ioh; 865 u_char x; 866 int i; 867 868 869 /* Poll status port, waiting for specified bits. */ 870 for (i = 0; i < 1000; ++i) { /* up to 1 msec */ 871 x = bus_space_read_1(iot, ioh, sc->regs.STATPORT); 872 if ((x & mask) != bits) 873 return x; 874 delay(1); 875 } 876 for (i = 0; i < 100; ++i) { /* up to 10 msec */ 877 x = bus_space_read_1(iot, ioh, sc->regs.STATPORT); 878 if ((x & mask) != bits) 879 return x; 880 delay(100); 881 } 882 for (;;) { /* forever */ 883 x = bus_space_read_1(iot, ioh, sc->regs.STATPORT); 884 if ((x & mask) != bits) 885 return x; 886 tsleep((caddr_t)wtsoft, WTPRI, "wtsoft", 1); 887 } 888 } 889 890 /* 891 * Execute QIC command. 892 */ 893 int 894 wtcmd(sc, cmd) 895 struct wt_softc *sc; 896 int cmd; 897 { 898 bus_space_tag_t iot = sc->sc_iot; 899 bus_space_handle_t ioh = sc->sc_ioh; 900 u_char x; 901 int s; 902 903 WTDBPRINT(("wtcmd() cmd=0x%x\n", cmd)); 904 s = splbio(); 905 x = wtsoft(sc, sc->regs.BUSY | sc->regs.NOEXCEP, 906 sc->regs.BUSY | sc->regs.NOEXCEP); /* ready? */ 907 if ((x & sc->regs.NOEXCEP) == 0) { /* error */ 908 splx(s); 909 return 0; 910 } 911 912 /* output the command */ 913 bus_space_write_1(iot, ioh, sc->regs.CMDPORT, cmd); 914 915 /* set request */ 916 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, 917 sc->regs.REQUEST | sc->regs.ONLINE); 918 919 /* wait for ready */ 920 wtsoft(sc, sc->regs.BUSY, sc->regs.BUSY); 921 922 /* reset request */ 923 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, 924 sc->regs.IEN | sc->regs.ONLINE); 925 926 /* wait for not ready */ 927 wtsoft(sc, sc->regs.BUSY, 0); 928 splx(s); 929 return 1; 930 } 931 932 /* wait for the end of i/o, seeking marker or rewind operation */ 933 int 934 wtwait(sc, catch, msg) 935 struct wt_softc *sc; 936 int catch; 937 char *msg; 938 { 939 int error; 940 941 WTDBPRINT(("wtwait() `%s'\n", msg)); 942 while (sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK)) 943 if ((error = tsleep((caddr_t)sc, WTPRI | catch, msg, 0)) != 0) 944 return error; 945 return 0; 946 } 947 948 /* initialize DMA for the i/o operation */ 949 void 950 wtdma(sc) 951 struct wt_softc *sc; 952 { 953 bus_space_tag_t iot = sc->sc_iot; 954 bus_space_handle_t ioh = sc->sc_ioh; 955 956 sc->flags |= TPACTIVE; 957 wtclock(sc); 958 959 if (sc->type == ARCHIVE) { 960 /* Set DMA. */ 961 bus_space_write_1(iot, ioh, sc->regs.SDMAPORT, 0); 962 } 963 964 if ((sc->dmaflags & DMAMODE_READ) && 965 (sc->dmatotal - sc->dmacount) < sc->bsize) { 966 /* Reading short block; do it through the internal buffer. */ 967 isa_dmastart(sc->sc_ic, sc->chan, sc->buf, 968 sc->bsize, NULL, sc->dmaflags, BUS_DMA_NOWAIT); 969 } else 970 isa_dmastart(sc->sc_ic, sc->chan, sc->dmavaddr, 971 sc->bsize, NULL, sc->dmaflags, BUS_DMA_NOWAIT); 972 } 973 974 /* start i/o operation */ 975 int 976 wtstart(sc, flag, vaddr, len) 977 struct wt_softc *sc; 978 int flag; 979 void *vaddr; 980 size_t len; 981 { 982 u_char x; 983 984 WTDBPRINT(("wtstart()\n")); 985 x = wtsoft(sc, sc->regs.BUSY | sc->regs.NOEXCEP, 986 sc->regs.BUSY | sc->regs.NOEXCEP); /* ready? */ 987 if ((x & sc->regs.NOEXCEP) == 0) { 988 sc->flags |= TPEXCEP; /* error */ 989 return 0; 990 } 991 sc->flags &= ~TPEXCEP; /* clear exception flag */ 992 sc->dmavaddr = vaddr; 993 sc->dmatotal = len; 994 sc->dmacount = 0; 995 sc->dmaflags = flag & B_READ ? DMAMODE_READ : DMAMODE_WRITE; 996 wtdma(sc); 997 return 1; 998 } 999 1000 /* 1001 * Start timer. 1002 */ 1003 void 1004 wtclock(sc) 1005 struct wt_softc *sc; 1006 { 1007 1008 if (sc->flags & TPTIMER) 1009 return; 1010 sc->flags |= TPTIMER; 1011 /* 1012 * Some controllers seem to lose DMA interrupts too often. To make the 1013 * tape stream we need 1 tick timeout. 1014 */ 1015 callout_reset(&sc->sc_timer_ch, (sc->flags & TPACTIVE) ? 1 : hz, 1016 wttimer, sc); 1017 } 1018 1019 /* 1020 * Simulate an interrupt periodically while i/o is going. 1021 * This is necessary in case interrupts get eaten due to 1022 * multiple devices on a single IRQ line. 1023 */ 1024 void 1025 wttimer(arg) 1026 void *arg; 1027 { 1028 register struct wt_softc *sc = (struct wt_softc *)arg; 1029 int s; 1030 u_char status; 1031 1032 sc->flags &= ~TPTIMER; 1033 if ((sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK)) == 0) 1034 return; 1035 1036 /* If i/o going, simulate interrupt. */ 1037 s = splbio(); 1038 status = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->regs.STATPORT); 1039 if ((status & (sc->regs.BUSY | sc->regs.NOEXCEP)) 1040 != (sc->regs.BUSY | sc->regs.NOEXCEP)) { 1041 WTDBPRINT(("wttimer() -- ")); 1042 wtintr(sc); 1043 } 1044 splx(s); 1045 1046 /* Restart timer if i/o pending. */ 1047 if (sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK)) 1048 wtclock(sc); 1049 } 1050 1051 /* 1052 * Perform QIC-02 and QIC-36 compatible reset sequence. 1053 */ 1054 int 1055 wtreset(iot, ioh, regs) 1056 bus_space_tag_t iot; 1057 bus_space_handle_t ioh; 1058 struct wtregs *regs; 1059 { 1060 u_char x; 1061 int i; 1062 1063 /* send reset */ 1064 bus_space_write_1(iot, ioh, regs->CTLPORT, regs->RESET | regs->ONLINE); 1065 delay(30); 1066 /* turn off reset */ 1067 bus_space_write_1(iot, ioh, regs->CTLPORT, regs->ONLINE); 1068 delay(30); 1069 1070 /* Read the controller status. */ 1071 x = bus_space_read_1(iot, ioh, regs->STATPORT); 1072 if (x == 0xff) /* no port at this address? */ 1073 return 0; 1074 1075 /* Wait 3 sec for reset to complete. Needed for QIC-36 boards? */ 1076 for (i = 0; i < 3000; ++i) { 1077 if ((x & regs->BUSY) == 0 || (x & regs->NOEXCEP) == 0) 1078 break; 1079 delay(1000); 1080 x = bus_space_read_1(iot, ioh, regs->STATPORT); 1081 } 1082 return (x & regs->RESETMASK) == regs->RESETVAL; 1083 } 1084 1085 /* 1086 * Get controller status information. Return 0 if user i/o request should 1087 * receive an i/o error code. 1088 */ 1089 int 1090 wtsense(sc, verbose, ignore) 1091 struct wt_softc *sc; 1092 int verbose, ignore; 1093 { 1094 char *msg = 0; 1095 int error; 1096 1097 WTDBPRINT(("wtsense() ignore=0x%x\n", ignore)); 1098 sc->flags &= ~(TPRO | TPWO); 1099 if (!wtstatus(sc)) 1100 return 0; 1101 if ((sc->error & TP_ST0) == 0) 1102 sc->error &= ~TP_ST0MASK; 1103 if ((sc->error & TP_ST1) == 0) 1104 sc->error &= ~TP_ST1MASK; 1105 sc->error &= ~ignore; /* ignore certain errors */ 1106 error = sc->error & (TP_FIL | TP_BNL | TP_UDA | TP_EOM | TP_WRP | 1107 TP_USL | TP_CNI | TP_MBD | TP_NDT | TP_ILL); 1108 if (!error) 1109 return 1; 1110 if (!verbose) 1111 return 0; 1112 1113 /* lifted from tdriver.c from Wangtek */ 1114 if (error & TP_USL) 1115 msg = "Drive not online"; 1116 else if (error & TP_CNI) 1117 msg = "No cartridge"; 1118 else if ((error & TP_WRP) && (sc->flags & TPWP) == 0) { 1119 msg = "Tape is write protected"; 1120 sc->flags |= TPWP; 1121 } else if (error & TP_FIL) 1122 msg = 0 /*"Filemark detected"*/; 1123 else if (error & TP_EOM) 1124 msg = 0 /*"End of tape"*/; 1125 else if (error & TP_BNL) 1126 msg = "Block not located"; 1127 else if (error & TP_UDA) 1128 msg = "Unrecoverable data error"; 1129 else if (error & TP_NDT) 1130 msg = "No data detected"; 1131 else if (error & TP_ILL) 1132 msg = "Illegal command"; 1133 if (msg) 1134 printf("%s: %s\n", sc->sc_dev.dv_xname, msg); 1135 return 0; 1136 } 1137 1138 /* 1139 * Get controller status information. 1140 */ 1141 int 1142 wtstatus(sc) 1143 struct wt_softc *sc; 1144 { 1145 bus_space_tag_t iot = sc->sc_iot; 1146 bus_space_handle_t ioh = sc->sc_ioh; 1147 char *p; 1148 int s; 1149 1150 s = splbio(); 1151 wtsoft(sc, sc->regs.BUSY | sc->regs.NOEXCEP, 1152 sc->regs.BUSY | sc->regs.NOEXCEP); /* ready? */ 1153 /* send `read status' command */ 1154 bus_space_write_1(iot, ioh, sc->regs.CMDPORT, QIC_RDSTAT); 1155 1156 /* set request */ 1157 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, 1158 sc->regs.REQUEST | sc->regs.ONLINE); 1159 1160 /* wait for ready */ 1161 wtsoft(sc, sc->regs.BUSY, sc->regs.BUSY); 1162 /* reset request */ 1163 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, sc->regs.ONLINE); 1164 1165 /* wait for not ready */ 1166 wtsoft(sc, sc->regs.BUSY, 0); 1167 1168 p = (char *)&sc->error; 1169 while (p < (char *)&sc->error + 6) { 1170 u_char x = wtsoft(sc, sc->regs.BUSY | sc->regs.NOEXCEP, 1171 sc->regs.BUSY | sc->regs.NOEXCEP); 1172 1173 if ((x & sc->regs.NOEXCEP) == 0) { /* error */ 1174 splx(s); 1175 return 0; 1176 } 1177 1178 /* read status byte */ 1179 *p++ = bus_space_read_1(iot, ioh, sc->regs.DATAPORT); 1180 1181 /* set request */ 1182 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, 1183 sc->regs.REQUEST | sc->regs.ONLINE); 1184 1185 /* wait for not ready */ 1186 wtsoft(sc, sc->regs.BUSY, 0); 1187 1188 /* unset request */ 1189 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, sc->regs.ONLINE); 1190 } 1191 splx(s); 1192 return 1; 1193 } 1194