1 /* $NetBSD: mt.c,v 1.11 2007/07/29 12:15:43 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 1996-2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Copyright (c) 1982, 1990, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * the Systems Programming Group of the University of Utah Computer 45 * Science Department. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. Neither the name of the University nor the names of its contributors 56 * may be used to endorse or promote products derived from this software 57 * without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * from: Utah $Hdr: rd.c 1.44 92/12/26$ 72 * 73 * @(#)rd.c 8.2 (Berkeley) 5/19/94 74 */ 75 76 /* 77 * Copyright (c) 1988 University of Utah. 78 * 79 * This code is derived from software contributed to Berkeley by 80 * the Systems Programming Group of the University of Utah Computer 81 * Science Department. 82 * 83 * Redistribution and use in source and binary forms, with or without 84 * modification, are permitted provided that the following conditions 85 * are met: 86 * 1. Redistributions of source code must retain the above copyright 87 * notice, this list of conditions and the following disclaimer. 88 * 2. Redistributions in binary form must reproduce the above copyright 89 * notice, this list of conditions and the following disclaimer in the 90 * documentation and/or other materials provided with the distribution. 91 * 3. All advertising materials mentioning features or use of this software 92 * must display the following acknowledgement: 93 * This product includes software developed by the University of 94 * California, Berkeley and its contributors. 95 * 4. Neither the name of the University nor the names of its contributors 96 * may be used to endorse or promote products derived from this software 97 * without specific prior written permission. 98 * 99 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 100 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 101 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 102 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 103 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 104 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 105 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 106 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 107 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 108 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 109 * SUCH DAMAGE. 110 * 111 * from: Utah $Hdr: rd.c 1.44 92/12/26$ 112 * 113 * @(#)rd.c 8.2 (Berkeley) 5/19/94 114 */ 115 116 /* 117 * Magnetic tape driver (HP7974a, HP7978a/b, HP7979a, HP7980a, HP7980xc) 118 * Original version contributed by Mt. Xinu. 119 * Modified for 4.4BSD by Mark Davies and Andrew Vignaux, Department of 120 * Computer Science, Victoria University of Wellington 121 */ 122 123 #include <sys/cdefs.h> 124 __KERNEL_RCSID(0, "$NetBSD: mt.c,v 1.11 2007/07/29 12:15:43 ad Exp $"); 125 126 #include <sys/param.h> 127 #include <sys/systm.h> 128 #include <sys/callout.h> 129 #include <sys/buf.h> 130 #include <sys/bufq.h> 131 #include <sys/ioctl.h> 132 #include <sys/mtio.h> 133 #include <sys/file.h> 134 #include <sys/proc.h> 135 #include <sys/tty.h> 136 #include <sys/kernel.h> 137 #include <sys/tprintf.h> 138 #include <sys/device.h> 139 #include <sys/conf.h> 140 141 #include <dev/gpib/gpibvar.h> 142 #include <dev/gpib/cs80busvar.h> 143 144 #include <dev/gpib/mtreg.h> 145 146 #ifdef DEBUG 147 int mtdebug = 0; 148 #define MDB_ANY 0xff 149 #define MDB_FOLLOW 0x01 150 #define DPRINTF(mask, str) if (mtdebug & (mask)) printf str 151 #else 152 #define DPRINTF(mask, str) /* nothing */ 153 #endif 154 155 struct mt_softc { 156 struct device sc_dev; 157 158 gpib_chipset_tag_t sc_ic; 159 gpib_handle_t sc_hdl; 160 161 int sc_slave; /* GPIB slave address (0-6) */ 162 short sc_flags; /* see below */ 163 u_char sc_lastdsj; /* place for DSJ in mtreaddsj() */ 164 u_char sc_lastecmd; /* place for End Command in mtreaddsj() */ 165 short sc_recvtimeo; /* count of gpibsend timeouts to prevent hang */ 166 short sc_statindex; /* index for next sc_stat when MTF_STATTIMEO */ 167 struct mt_stat sc_stat;/* status bytes last read from device */ 168 short sc_density; /* current density of tape (mtio.h format) */ 169 short sc_type; /* tape drive model (hardware IDs) */ 170 tpr_t sc_ttyp; 171 struct bufq_state *sc_tab;/* buf queue */ 172 int sc_active; 173 struct buf sc_bufstore; /* XXX buffer storage */ 174 175 struct callout sc_start_ch; 176 struct callout sc_intr_ch; 177 }; 178 179 #define MTUNIT(x) (minor(x) & 0x03) 180 181 #define B_CMD B_DEVPRIVATE /* command buf instead of data */ 182 #define b_cmd b_blkno /* blkno holds cmd when B_CMD */ 183 184 int mtmatch(struct device *, struct cfdata *, void *); 185 void mtattach(struct device *, struct device *, void *); 186 187 CFATTACH_DECL(mt, sizeof(struct mt_softc), 188 mtmatch, mtattach, NULL, NULL); 189 190 int mtlookup(int, int, int); 191 void mtustart(struct mt_softc *); 192 int mtreaddsj(struct mt_softc *, int); 193 int mtcommand(dev_t, int, int); 194 195 void mtintr_callout(void *); 196 void mtstart_callout(void *); 197 198 void mtcallback(void *, int); 199 void mtstart(struct mt_softc *); 200 void mtintr(struct mt_softc *); 201 202 dev_type_open(mtopen); 203 dev_type_close(mtclose); 204 dev_type_read(mtread); 205 dev_type_write(mtwrite); 206 dev_type_ioctl(mtioctl); 207 dev_type_strategy(mtstrategy); 208 209 const struct bdevsw mt_bdevsw = { 210 mtopen, mtclose, mtstrategy, mtioctl, nodump, nosize, D_TAPE 211 }; 212 213 const struct cdevsw mt_cdevsw = { 214 mtopen, mtclose, mtread, mtwrite, mtioctl, 215 nostop, notty, nopoll, nommap, nokqfilter, D_TAPE 216 }; 217 218 219 extern struct cfdriver mt_cd; 220 221 struct mtinfo { 222 u_short hwid; 223 const char *desc; 224 } mtinfo[] = { 225 { MT7978ID, "7978" }, 226 { MT7979AID, "7979A" }, 227 { MT7980ID, "7980" }, 228 { MT7974AID, "7974A" }, 229 }; 230 int nmtinfo = sizeof(mtinfo) / sizeof(mtinfo[0]); 231 232 233 int 234 mtlookup(id, slave, punit) 235 int id; 236 int slave; 237 int punit; 238 { 239 int i; 240 241 for (i = 0; i < nmtinfo; i++) 242 if (mtinfo[i].hwid == id) 243 break; 244 if (i == nmtinfo) 245 return (-1); 246 return (0); 247 } 248 249 int 250 mtmatch(parent, match, aux) 251 struct device *parent; 252 struct cfdata *match; 253 void *aux; 254 { 255 struct cs80bus_attach_args *ca = aux; 256 257 ca->ca_punit = 0; 258 return (mtlookup(ca->ca_id, ca->ca_slave, ca->ca_punit) == 0); 259 } 260 261 void 262 mtattach(parent, self, aux) 263 struct device *parent, *self; 264 void *aux; 265 { 266 struct mt_softc *sc = device_private(self); 267 struct cs80bus_attach_args *ca = aux; 268 int type; 269 270 sc->sc_ic = ca->ca_ic; 271 sc->sc_slave = ca->ca_slave; 272 273 if ((type = mtlookup(ca->ca_id, ca->ca_slave, ca->ca_punit)) < 0) 274 return; 275 276 printf(": %s tape\n", mtinfo[type].desc); 277 278 sc->sc_type = type; 279 sc->sc_flags = MTF_EXISTS; 280 281 bufq_alloc(&sc->sc_tab, "fcfs", 0); 282 callout_init(&sc->sc_start_ch, 0); 283 callout_init(&sc->sc_intr_ch, 0); 284 285 if (gpibregister(sc->sc_ic, sc->sc_slave, mtcallback, sc, 286 &sc->sc_hdl)) { 287 printf("%s: can't register callback\n", sc->sc_dev.dv_xname); 288 return; 289 } 290 } 291 292 /* 293 * Perform a read of "Device Status Jump" register and update the 294 * status if necessary. If status is read, the given "ecmd" is also 295 * performed, unless "ecmd" is zero. Returns DSJ value, -1 on failure 296 * and -2 on "temporary" failure. 297 */ 298 int 299 mtreaddsj(sc, ecmd) 300 struct mt_softc *sc; 301 int ecmd; 302 { 303 int retval; 304 305 if (sc->sc_flags & MTF_STATTIMEO) 306 goto getstats; 307 retval = gpibrecv(sc->sc_ic, 308 (sc->sc_flags & MTF_DSJTIMEO) ? -1 : sc->sc_slave, 309 MTT_DSJ, &(sc->sc_lastdsj), 1); 310 sc->sc_flags &= ~MTF_DSJTIMEO; 311 if (retval != 1) { 312 DPRINTF(MDB_ANY, ("%s can't gpibrecv DSJ", 313 sc->sc_dev.dv_xname)); 314 if (sc->sc_recvtimeo == 0) 315 sc->sc_recvtimeo = hz; 316 if (--sc->sc_recvtimeo == 0) 317 return (-1); 318 if (retval == 0) 319 sc->sc_flags |= MTF_DSJTIMEO; 320 return (-2); 321 } 322 sc->sc_recvtimeo = 0; 323 sc->sc_statindex = 0; 324 DPRINTF(MDB_ANY, ("%s readdsj: 0x%x", sc->sc_dev.dv_xname, 325 sc->sc_lastdsj)); 326 sc->sc_lastecmd = ecmd; 327 switch (sc->sc_lastdsj) { 328 case 0: 329 if (ecmd & MTE_DSJ_FORCE) 330 break; 331 return (0); 332 333 case 2: 334 sc->sc_lastecmd = MTE_COMPLETE; 335 case 1: 336 break; 337 338 default: 339 printf("%s readdsj: DSJ 0x%x\n", sc->sc_dev.dv_xname, 340 sc->sc_lastdsj); 341 return (-1); 342 } 343 344 getstats: 345 retval = gpibrecv(sc->sc_ic, 346 (sc->sc_flags & MTF_STATCONT) ? -1 : sc->sc_slave, MTT_STAT, 347 ((char *)&(sc->sc_stat)) + sc->sc_statindex, 348 sizeof(sc->sc_stat) - sc->sc_statindex); 349 sc->sc_flags &= ~(MTF_STATTIMEO | MTF_STATCONT); 350 if (retval != sizeof(sc->sc_stat) - sc->sc_statindex) { 351 if (sc->sc_recvtimeo == 0) 352 sc->sc_recvtimeo = hz; 353 if (--sc->sc_recvtimeo != 0) { 354 if (retval >= 0) { 355 sc->sc_statindex += retval; 356 sc->sc_flags |= MTF_STATCONT; 357 } 358 sc->sc_flags |= MTF_STATTIMEO; 359 return (-2); 360 } 361 printf("%s readdsj: can't read status", sc->sc_dev.dv_xname); 362 return (-1); 363 } 364 sc->sc_recvtimeo = 0; 365 sc->sc_statindex = 0; 366 DPRINTF(MDB_ANY, ("%s readdsj: status is %x %x %x %x %x %x", 367 sc->sc_dev.dv_xname, 368 sc->sc_stat1, sc->sc_stat2, sc->sc_stat3, 369 sc->sc_stat4, sc->sc_stat5, sc->sc_stat6)); 370 if (sc->sc_lastecmd) 371 (void) gpibsend(sc->sc_ic, sc->sc_slave, 372 MTL_ECMD, &(sc->sc_lastecmd), 1); 373 return ((int) sc->sc_lastdsj); 374 } 375 376 int 377 mtopen(dev, flag, mode, l) 378 dev_t dev; 379 int flag, mode; 380 struct lwp *l; 381 { 382 struct mt_softc *sc; 383 int req_den; 384 int error; 385 386 sc = device_lookup(&mt_cd, MTUNIT(dev)); 387 if (sc == NULL || (sc->sc_flags & MTF_EXISTS) == 0) 388 return (ENXIO); 389 390 if (sc->sc_flags & MTF_OPEN) 391 return (EBUSY); 392 393 DPRINTF(MDB_ANY, ("%s open: flags 0x%x", sc->sc_dev.dv_xname, 394 sc->sc_flags)); 395 396 sc->sc_flags |= MTF_OPEN; 397 sc->sc_ttyp = tprintf_open(l->l_proc); 398 if ((sc->sc_flags & MTF_ALIVE) == 0) { 399 error = mtcommand(dev, MTRESET, 0); 400 if (error != 0 || (sc->sc_flags & MTF_ALIVE) == 0) 401 goto errout; 402 if ((sc->sc_stat1 & (SR1_BOT | SR1_ONLINE)) == SR1_ONLINE) 403 (void) mtcommand(dev, MTREW, 0); 404 } 405 for (;;) { 406 if ((error = mtcommand(dev, MTNOP, 0)) != 0) 407 goto errout; 408 if (!(sc->sc_flags & MTF_REW)) 409 break; 410 if (tsleep((void *) &lbolt, PCATCH | (PZERO + 1), 411 "mt", 0) != 0) { 412 error = EINTR; 413 goto errout; 414 } 415 } 416 if ((flag & FWRITE) && (sc->sc_stat1 & SR1_RO)) { 417 error = EROFS; 418 goto errout; 419 } 420 if (!(sc->sc_stat1 & SR1_ONLINE)) { 421 uprintf("%s: not online\n", sc->sc_dev.dv_xname); 422 error = EIO; 423 goto errout; 424 } 425 /* 426 * Select density: 427 * - find out what density the drive is set to 428 * (i.e. the density of the current tape) 429 * - if we are going to write 430 * - if we're not at the beginning of the tape 431 * - complain if we want to change densities 432 * - otherwise, select the mtcommand to set the density 433 * 434 * If the drive doesn't support it then don't change the recorded 435 * density. 436 * 437 * The original MOREbsd code had these additional conditions 438 * for the mid-tape change 439 * 440 * req_den != T_BADBPI && 441 * sc->sc_density != T_6250BPI 442 * 443 * which suggests that it would be possible to write multiple 444 * densities if req_den == T_BAD_BPI or the current tape 445 * density was 6250. Testing of our 7980 suggests that the 446 * device cannot change densities mid-tape. 447 * 448 * ajv@comp.vuw.ac.nz 449 */ 450 sc->sc_density = (sc->sc_stat2 & SR2_6250) ? T_6250BPI : ( 451 (sc->sc_stat3 & SR3_1600) ? T_1600BPI : ( 452 (sc->sc_stat3 & SR3_800) ? T_800BPI : -1)); 453 req_den = (dev & T_DENSEL); 454 455 if (flag & FWRITE) { 456 if (!(sc->sc_stat1 & SR1_BOT)) { 457 if (sc->sc_density != req_den) { 458 uprintf("%s: can't change density mid-tape\n", 459 sc->sc_dev.dv_xname); 460 error = EIO; 461 goto errout; 462 } 463 } 464 else { 465 int mtset_density = 466 (req_den == T_800BPI ? MTSET800BPI : ( 467 req_den == T_1600BPI ? MTSET1600BPI : ( 468 req_den == T_6250BPI ? MTSET6250BPI : ( 469 sc->sc_type == MT7980ID 470 ? MTSET6250DC 471 : MTSET6250BPI)))); 472 if (mtcommand(dev, mtset_density, 0) == 0) 473 sc->sc_density = req_den; 474 } 475 } 476 return (0); 477 errout: 478 sc->sc_flags &= ~MTF_OPEN; 479 return (error); 480 } 481 482 int 483 mtclose(dev, flag, fmt, l) 484 dev_t dev; 485 int flag, fmt; 486 struct lwp *l; 487 { 488 struct mt_softc *sc; 489 490 sc = device_lookup(&mt_cd, MTUNIT(dev)); 491 if (sc == NULL) 492 return (ENXIO); 493 494 if (sc->sc_flags & MTF_WRT) { 495 (void) mtcommand(dev, MTWEOF, 2); 496 (void) mtcommand(dev, MTBSF, 0); 497 } 498 if ((minor(dev) & T_NOREWIND) == 0) 499 (void) mtcommand(dev, MTREW, 0); 500 sc->sc_flags &= ~MTF_OPEN; 501 tprintf_close(sc->sc_ttyp); 502 return (0); 503 } 504 505 int 506 mtcommand(dev, cmd, cnt) 507 dev_t dev; 508 int cmd; 509 int cnt; 510 { 511 struct mt_softc *sc; 512 struct buf *bp; 513 int error = 0; 514 515 sc = device_lookup(&mt_cd, MTUNIT(dev)); 516 bp = &sc->sc_bufstore; 517 518 if (bp->b_flags & B_BUSY) 519 return (EBUSY); 520 521 bp->b_cmd = cmd; 522 bp->b_dev = dev; 523 do { 524 bp->b_flags = B_BUSY | B_CMD; 525 mtstrategy(bp); 526 biowait(bp); 527 if (bp->b_error != 0) { 528 error = (int) (unsigned) bp->b_error; 529 break; 530 } 531 } while (--cnt > 0); 532 #if 0 533 bp->b_flags = 0 /*&= ~B_BUSY*/; 534 #else 535 bp->b_flags &= ~B_BUSY; 536 #endif 537 return (error); 538 } 539 540 /* 541 * Only thing to check here is for legal record lengths (writes only). 542 */ 543 void 544 mtstrategy(bp) 545 struct buf *bp; 546 { 547 struct mt_softc *sc; 548 int s; 549 550 sc = device_lookup(&mt_cd, MTUNIT(bp->b_dev)); 551 552 DPRINTF(MDB_ANY, ("%s strategy", sc->sc_dev.dv_xname)); 553 554 if ((bp->b_flags & (B_CMD | B_READ)) == 0) { 555 #define WRITE_BITS_IGNORED 8 556 #if 0 557 if (bp->b_bcount & ((1 << WRITE_BITS_IGNORED) - 1)) { 558 tprintf(sc->sc_ttyp, 559 "%s: write record must be multiple of %d\n", 560 sc->sc_dev.dv_xname, 1 << WRITE_BITS_IGNORED); 561 goto error; 562 } 563 #endif 564 s = 16 * 1024; 565 if (sc->sc_stat2 & SR2_LONGREC) { 566 switch (sc->sc_density) { 567 case T_1600BPI: 568 s = 32 * 1024; 569 break; 570 571 case T_6250BPI: 572 case T_BADBPI: 573 s = 60 * 1024; 574 break; 575 } 576 } 577 if (bp->b_bcount > s) { 578 tprintf(sc->sc_ttyp, 579 "%s: write record (%d) too big: limit (%d)\n", 580 sc->sc_dev.dv_xname, bp->b_bcount, s); 581 #if 0 /* XXX see above */ 582 error: 583 #endif 584 bp->b_error = EIO; 585 biodone(bp); 586 return; 587 } 588 } 589 s = splbio(); 590 BUFQ_PUT(sc->sc_tab, bp); 591 if (sc->sc_active == 0) { 592 sc->sc_active = 1; 593 mtustart(sc); 594 } 595 splx(s); 596 } 597 598 void 599 mtustart(sc) 600 struct mt_softc *sc; 601 { 602 603 DPRINTF(MDB_ANY, ("%s ustart", sc->sc_dev.dv_xname)); 604 if (gpibrequest(sc->sc_ic, sc->sc_hdl)) 605 mtstart(sc); 606 } 607 608 void 609 mtcallback(v, action) 610 void *v; 611 int action; 612 { 613 struct mt_softc *sc = v; 614 615 DPRINTF(MDB_FOLLOW, ("mtcallback: v=%p, action=%d\n", v, action)); 616 617 switch (action) { 618 case GPIBCBF_START: 619 mtstart(sc); 620 break; 621 case GPIBCBF_INTR: 622 mtintr(sc); 623 break; 624 #ifdef DEBUG 625 default: 626 printf("mtcallback: unknown action %d\n", action); 627 break; 628 #endif 629 } 630 } 631 632 void 633 mtintr_callout(arg) 634 void *arg; 635 { 636 struct mt_softc *sc = arg; 637 int s = splbio(); 638 639 gpibppclear(sc->sc_ic); 640 mtintr(sc); 641 splx(s); 642 } 643 644 void 645 mtstart_callout(arg) 646 void *arg; 647 { 648 int s = splbio(); 649 650 mtstart((struct mt_softc *)arg); 651 splx(s); 652 } 653 654 void 655 mtstart(sc) 656 struct mt_softc *sc; 657 { 658 struct buf *bp; 659 short cmdcount = 1; 660 u_char cmdbuf[2]; 661 662 DPRINTF(MDB_ANY, ("%s start", sc->sc_dev.dv_xname)); 663 sc->sc_flags &= ~MTF_WRT; 664 bp = BUFQ_PEEK(sc->sc_tab); 665 if ((sc->sc_flags & MTF_ALIVE) == 0 && 666 ((bp->b_flags & B_CMD) == 0 || bp->b_cmd != MTRESET)) 667 goto fatalerror; 668 669 if (sc->sc_flags & MTF_REW) { 670 if (!gpibpptest(sc->sc_ic, sc->sc_slave)) 671 goto stillrew; 672 switch (mtreaddsj(sc, MTE_DSJ_FORCE|MTE_COMPLETE|MTE_IDLE)) { 673 case 0: 674 case 1: 675 stillrew: 676 if ((sc->sc_stat1 & SR1_BOT) || 677 !(sc->sc_stat1 & SR1_ONLINE)) { 678 sc->sc_flags &= ~MTF_REW; 679 break; 680 } 681 case -2: 682 /* 683 * -2 means "timeout" reading DSJ, which is probably 684 * temporary. This is considered OK when doing a NOP, 685 * but not otherwise. 686 */ 687 if (sc->sc_flags & (MTF_DSJTIMEO | MTF_STATTIMEO)) { 688 callout_reset(&sc->sc_start_ch, hz >> 5, 689 mtstart_callout, sc); 690 return; 691 } 692 case 2: 693 if (bp->b_cmd != MTNOP || !(bp->b_flags & B_CMD)) { 694 bp->b_error = EBUSY; 695 goto done; 696 } 697 goto done; 698 699 default: 700 goto fatalerror; 701 } 702 } 703 if (bp->b_flags & B_CMD) { 704 if (sc->sc_flags & MTF_PASTEOT) { 705 switch(bp->b_cmd) { 706 case MTFSF: 707 case MTWEOF: 708 case MTFSR: 709 bp->b_error = ENOSPC; 710 goto done; 711 712 case MTBSF: 713 case MTOFFL: 714 case MTBSR: 715 case MTREW: 716 sc->sc_flags &= ~(MTF_PASTEOT | MTF_ATEOT); 717 break; 718 } 719 } 720 switch(bp->b_cmd) { 721 case MTFSF: 722 if (sc->sc_flags & MTF_HITEOF) 723 goto done; 724 cmdbuf[0] = MTTC_FSF; 725 break; 726 727 case MTBSF: 728 if (sc->sc_flags & MTF_HITBOF) 729 goto done; 730 cmdbuf[0] = MTTC_BSF; 731 break; 732 733 case MTOFFL: 734 sc->sc_flags |= MTF_REW; 735 cmdbuf[0] = MTTC_REWOFF; 736 break; 737 738 case MTWEOF: 739 cmdbuf[0] = MTTC_WFM; 740 break; 741 742 case MTBSR: 743 cmdbuf[0] = MTTC_BSR; 744 break; 745 746 case MTFSR: 747 cmdbuf[0] = MTTC_FSR; 748 break; 749 750 case MTREW: 751 sc->sc_flags |= MTF_REW; 752 cmdbuf[0] = MTTC_REW; 753 break; 754 755 case MTNOP: 756 /* 757 * NOP is supposed to set status bits. 758 * Force readdsj to do it. 759 */ 760 switch (mtreaddsj(sc, 761 MTE_DSJ_FORCE | MTE_COMPLETE | MTE_IDLE)) { 762 default: 763 goto done; 764 765 case -1: 766 /* 767 * If this fails, perform a device clear 768 * to fix any protocol problems and (most 769 * likely) get the status. 770 */ 771 bp->b_cmd = MTRESET; 772 break; 773 774 case -2: 775 callout_reset(&sc->sc_start_ch, hz >> 5, 776 mtstart_callout, sc); 777 return; 778 } 779 780 case MTRESET: 781 /* 782 * 1) selected device clear (send with "-2" secondary) 783 * 2) set timeout, then wait for "service request" 784 * 3) interrupt will read DSJ (and END COMPLETE-IDLE) 785 */ 786 if (gpibsend(sc->sc_ic, sc->sc_slave, -2, NULL, 0)){ 787 printf("%s can't reset", sc->sc_dev.dv_xname); 788 goto fatalerror; 789 } 790 callout_reset(&sc->sc_intr_ch, 4*hz, mtintr_callout, 791 sc); 792 gpibawait(sc->sc_ic); 793 return; 794 795 case MTSET800BPI: 796 cmdbuf[0] = MTTC_800; 797 break; 798 799 case MTSET1600BPI: 800 cmdbuf[0] = MTTC_1600; 801 break; 802 803 case MTSET6250BPI: 804 cmdbuf[0] = MTTC_6250; 805 break; 806 807 case MTSET6250DC: 808 cmdbuf[0] = MTTC_DC6250; 809 break; 810 } 811 } else { 812 if (sc->sc_flags & MTF_PASTEOT) { 813 bp->b_error = ENOSPC; 814 goto done; 815 } 816 if (bp->b_flags & B_READ) { 817 sc->sc_flags |= MTF_IO; 818 cmdbuf[0] = MTTC_READ; 819 } else { 820 sc->sc_flags |= MTF_WRT | MTF_IO; 821 cmdbuf[0] = MTTC_WRITE; 822 cmdbuf[1] = (bp->b_bcount +((1 << WRITE_BITS_IGNORED) - 1)) >> WRITE_BITS_IGNORED; 823 cmdcount = 2; 824 } 825 } 826 if (gpibsend(sc->sc_ic, sc->sc_slave, MTL_TCMD, cmdbuf, cmdcount) 827 == cmdcount) { 828 if (sc->sc_flags & MTF_REW) 829 goto done; 830 gpibawait(sc->sc_ic); 831 return; 832 } 833 fatalerror: 834 /* 835 * If anything fails, the drive is probably hosed, so mark it not 836 * "ALIVE" (but it EXISTS and is OPEN or we wouldn't be here, and 837 * if, last we heard, it was REWinding, remember that). 838 */ 839 sc->sc_flags &= MTF_EXISTS | MTF_OPEN | MTF_REW; 840 bp->b_error = EIO; 841 done: 842 sc->sc_flags &= ~(MTF_HITEOF | MTF_HITBOF); 843 (void)BUFQ_GET(sc->sc_tab); 844 biodone(bp); 845 gpibrelease(sc->sc_ic, sc->sc_hdl); 846 if ((bp = BUFQ_PEEK(sc->sc_tab)) == NULL) 847 sc->sc_active = 0; 848 else 849 mtustart(sc); 850 } 851 852 void 853 mtintr(sc) 854 struct mt_softc *sc; 855 { 856 struct buf *bp; 857 int slave, dir, i; 858 u_char cmdbuf[4]; 859 860 slave = sc->sc_slave; 861 862 bp = BUFQ_PEEK(sc->sc_tab); 863 if (bp == NULL) { 864 printf("%s intr: bp == NULL", sc->sc_dev.dv_xname); 865 return; 866 } 867 868 DPRINTF(MDB_ANY, ("%s intr", sc->sc_dev.dv_xname)); 869 870 /* 871 * Some operation completed. Read status bytes and report errors. 872 * Clear EOF flags here `cause they're set once on specific conditions 873 * below when a command succeeds. 874 * A DSJ of 2 always means keep waiting. If the command was READ 875 * (and we're in data DMA phase) stop data transfer first. 876 */ 877 sc->sc_flags &= ~(MTF_HITEOF | MTF_HITBOF); 878 if ((bp->b_flags & (B_CMD|B_READ)) == B_READ && 879 !(sc->sc_flags & (MTF_IO | MTF_STATTIMEO | MTF_DSJTIMEO))){ 880 cmdbuf[0] = MTE_STOP; 881 (void) gpibsend(sc->sc_ic, slave, MTL_ECMD,cmdbuf,1); 882 } 883 switch (mtreaddsj(sc, 0)) { 884 case 0: 885 break; 886 887 case 1: 888 /* 889 * If we're in the middle of a READ/WRITE and have yet to 890 * start the data transfer, a DSJ of one should terminate it. 891 */ 892 sc->sc_flags &= ~MTF_IO; 893 break; 894 895 case 2: 896 (void) gpibawait(sc->sc_ic); 897 return; 898 899 case -2: 900 /* 901 * -2 means that the drive failed to respond quickly enough 902 * to the request for DSJ. It's probably just "busy" figuring 903 * it out and will know in a little bit... 904 */ 905 callout_reset(&sc->sc_intr_ch, hz >> 5, mtintr_callout, sc); 906 return; 907 908 default: 909 printf("%s intr: can't get drive stat", sc->sc_dev.dv_xname); 910 goto error; 911 } 912 if (sc->sc_stat1 & (SR1_ERR | SR1_REJECT)) { 913 i = sc->sc_stat4 & SR4_ERCLMASK; 914 printf("%s: %s error, retry %d, SR2/3 %x/%x, code %d", 915 sc->sc_dev.dv_xname, i == SR4_DEVICE ? "device" : 916 (i == SR4_PROTOCOL ? "protocol" : 917 (i == SR4_SELFTEST ? "selftest" : "unknown")), 918 sc->sc_stat4 & SR4_RETRYMASK, sc->sc_stat2, 919 sc->sc_stat3, sc->sc_stat5); 920 921 if ((bp->b_flags & B_CMD) && bp->b_cmd == MTRESET) 922 callout_stop(&sc->sc_intr_ch); 923 if (sc->sc_stat3 & SR3_POWERUP) 924 sc->sc_flags &= MTF_OPEN | MTF_EXISTS; 925 goto error; 926 } 927 /* 928 * Report and clear any soft errors. 929 */ 930 if (sc->sc_stat1 & SR1_SOFTERR) { 931 printf("%s: soft error, retry %d\n", sc->sc_dev.dv_xname, 932 sc->sc_stat4 & SR4_RETRYMASK); 933 sc->sc_stat1 &= ~SR1_SOFTERR; 934 } 935 /* 936 * We've initiated a read or write, but haven't actually started to 937 * DMA the data yet. At this point, the drive's ready. 938 */ 939 if (sc->sc_flags & MTF_IO) { 940 sc->sc_flags &= ~MTF_IO; 941 dir = (bp->b_flags & B_READ ? GPIB_READ : GPIB_WRITE); 942 gpibxfer(sc->sc_ic, slave, 943 dir == GPIB_READ ? MTT_READ : MTL_WRITE, 944 bp->b_data, bp->b_bcount, dir, dir == GPIB_READ); 945 return; 946 } 947 /* 948 * Check for End Of Tape - we're allowed to hit EOT and then write (or 949 * read) one more record. If we get here and have not already hit EOT, 950 * return ENOSPC to inform the process that it's hit it. If we get 951 * here and HAVE already hit EOT, don't allow any more operations that 952 * move the tape forward. 953 */ 954 if (sc->sc_stat1 & SR1_EOT) { 955 if (sc->sc_flags & MTF_ATEOT) 956 sc->sc_flags |= MTF_PASTEOT; 957 else { 958 bp->b_error = ENOSPC; 959 sc->sc_flags |= MTF_ATEOT; 960 } 961 } 962 /* 963 * If a motion command was being executed, check for Tape Marks. 964 * If we were doing data, make sure we got the right amount, and 965 * check for hitting tape marks on reads. 966 */ 967 if (bp->b_flags & B_CMD) { 968 if (sc->sc_stat1 & SR1_EOF) { 969 if (bp->b_cmd == MTFSR) 970 sc->sc_flags |= MTF_HITEOF; 971 if (bp->b_cmd == MTBSR) 972 sc->sc_flags |= MTF_HITBOF; 973 } 974 if (bp->b_cmd == MTRESET) { 975 callout_stop(&sc->sc_intr_ch); 976 sc->sc_flags |= MTF_ALIVE; 977 } 978 } else { 979 i = gpibrecv(sc->sc_ic, slave, MTT_BCNT, cmdbuf, 2); 980 if (i != 2) { 981 printf("%s intr: can't get xfer length\n", 982 sc->sc_dev.dv_xname); 983 goto error; 984 } 985 i = (int) *((u_short *) cmdbuf); 986 if (i <= bp->b_bcount) { 987 if (i == 0) 988 sc->sc_flags |= MTF_HITEOF; 989 bp->b_resid = bp->b_bcount - i; 990 DPRINTF(MDB_ANY, ("%s intr: bcount %ld, resid %ld", 991 sc->sc_dev.dv_xname, bp->b_bcount, bp->b_resid)); 992 } else { 993 tprintf(sc->sc_ttyp, 994 "%s: record (%d) larger than wanted (%d)\n", 995 sc->sc_dev.dv_xname, i, bp->b_bcount); 996 error: 997 sc->sc_flags &= ~MTF_IO; 998 bp->b_error = EIO; 999 } 1000 } 1001 /* 1002 * The operation is completely done. 1003 * Let the drive know with an END command. 1004 */ 1005 cmdbuf[0] = MTE_COMPLETE | MTE_IDLE; 1006 (void) gpibsend(sc->sc_ic, slave, MTL_ECMD, cmdbuf, 1); 1007 bp->b_flags &= ~B_CMD; 1008 (void)BUFQ_GET(sc->sc_tab); 1009 biodone(bp); 1010 gpibrelease(sc->sc_ic, sc->sc_hdl); 1011 if (BUFQ_PEEK(sc->sc_tab) == NULL) 1012 sc->sc_active = 0; 1013 else 1014 mtustart(sc); 1015 } 1016 1017 int 1018 mtread(dev, uio, flags) 1019 dev_t dev; 1020 struct uio *uio; 1021 int flags; 1022 { 1023 struct mt_softc *sc; 1024 1025 sc = device_lookup(&mt_cd, MTUNIT(dev)); 1026 1027 return (physio(mtstrategy, &sc->sc_bufstore, 1028 dev, B_READ, minphys, uio)); 1029 } 1030 1031 int 1032 mtwrite(dev, uio, flags) 1033 dev_t dev; 1034 struct uio *uio; 1035 int flags; 1036 { 1037 struct mt_softc *sc; 1038 1039 sc = device_lookup(&mt_cd, MTUNIT(dev)); 1040 1041 return (physio(mtstrategy, &sc->sc_bufstore, 1042 dev, B_WRITE, minphys, uio)); 1043 } 1044 1045 int 1046 mtioctl(dev, cmd, data, flag, l) 1047 dev_t dev; 1048 u_long cmd; 1049 void *data; 1050 int flag; 1051 struct lwp *l; 1052 { 1053 struct mtop *op; 1054 int cnt; 1055 1056 switch (cmd) { 1057 case MTIOCTOP: 1058 op = (struct mtop *)data; 1059 switch(op->mt_op) { 1060 case MTWEOF: 1061 case MTFSF: 1062 case MTBSR: 1063 case MTBSF: 1064 case MTFSR: 1065 cnt = op->mt_count; 1066 break; 1067 1068 case MTOFFL: 1069 case MTREW: 1070 case MTNOP: 1071 cnt = 0; 1072 break; 1073 1074 default: 1075 return (EINVAL); 1076 } 1077 return (mtcommand(dev, op->mt_op, cnt)); 1078 1079 case MTIOCGET: 1080 break; 1081 1082 default: 1083 return (EINVAL); 1084 } 1085 return (0); 1086 } 1087