1 /* $NetBSD: mt.c,v 1.2 2003/08/07 16:30:56 agc 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.2 2003/08/07 16:30:56 agc 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/ioctl.h> 131 #include <sys/mtio.h> 132 #include <sys/file.h> 133 #include <sys/proc.h> 134 #include <sys/tty.h> 135 #include <sys/kernel.h> 136 #include <sys/tprintf.h> 137 #include <sys/device.h> 138 #include <sys/conf.h> 139 140 #include <dev/gpib/gpibvar.h> 141 #include <dev/gpib/cs80busvar.h> 142 143 #include <dev/gpib/mtreg.h> 144 145 #ifdef DEBUG 146 int mtdebug = 0; 147 #define MDB_ANY 0xff 148 #define MDB_FOLLOW 0x01 149 #define DPRINTF(mask, str) if (mtdebug & (mask)) printf str 150 #else 151 #define DPRINTF(mask, str) /* nothing */ 152 #endif 153 154 struct mt_softc { 155 struct device sc_dev; 156 157 gpib_chipset_tag_t sc_ic; 158 gpib_handle_t sc_hdl; 159 160 int sc_slave; /* GPIB slave address (0-6) */ 161 short sc_flags; /* see below */ 162 u_char sc_lastdsj; /* place for DSJ in mtreaddsj() */ 163 u_char sc_lastecmd; /* place for End Command in mtreaddsj() */ 164 short sc_recvtimeo; /* count of gpibsend timeouts to prevent hang */ 165 short sc_statindex; /* index for next sc_stat when MTF_STATTIMEO */ 166 struct mt_stat sc_stat;/* status bytes last read from device */ 167 short sc_density; /* current density of tape (mtio.h format) */ 168 short sc_type; /* tape drive model (hardware IDs) */ 169 tpr_t sc_ttyp; 170 struct bufq_state sc_tab;/* buf queue */ 171 int sc_active; 172 struct buf sc_bufstore; /* XXX buffer storage */ 173 174 struct callout sc_start_ch; 175 struct callout sc_intr_ch; 176 }; 177 178 #define MTUNIT(x) (minor(x) & 0x03) 179 180 #define B_CMD B_XXX /* command buf instead of data */ 181 #define b_cmd b_blkno /* blkno holds cmd when B_CMD */ 182 183 int mtmatch(struct device *, struct cfdata *, void *); 184 void mtattach(struct device *, struct device *, void *); 185 186 CFATTACH_DECL(mt, sizeof(struct mt_softc), 187 mtmatch, mtattach, NULL, NULL); 188 189 int mtlookup(int, int, int); 190 void mtustart(struct mt_softc *); 191 int mtreaddsj(struct mt_softc *, int); 192 int mtcommand(dev_t, int, int); 193 194 void mtintr_callout(void *); 195 void mtstart_callout(void *); 196 197 void mtcallback(void *, int); 198 void mtstart(struct mt_softc *); 199 void mtintr(struct mt_softc *); 200 201 dev_type_open(mtopen); 202 dev_type_close(mtclose); 203 dev_type_read(mtread); 204 dev_type_write(mtwrite); 205 dev_type_ioctl(mtioctl); 206 dev_type_strategy(mtstrategy); 207 208 const struct bdevsw mt_bdevsw = { 209 mtopen, mtclose, mtstrategy, mtioctl, nodump, nosize, D_TAPE 210 }; 211 212 const struct cdevsw mt_cdevsw = { 213 mtopen, mtclose, mtread, mtwrite, mtioctl, 214 nostop, notty, nopoll, nommap, nokqfilter, D_TAPE 215 }; 216 217 218 extern struct cfdriver mt_cd; 219 220 struct mtinfo { 221 u_short hwid; 222 char *desc; 223 } mtinfo[] = { 224 { MT7978ID, "7978" }, 225 { MT7979AID, "7979A" }, 226 { MT7980ID, "7980" }, 227 { MT7974AID, "7974A" }, 228 }; 229 int nmtinfo = sizeof(mtinfo) / sizeof(mtinfo[0]); 230 231 232 int 233 mtlookup(id, slave, punit) 234 int id; 235 int slave; 236 int punit; 237 { 238 int i; 239 240 for (i = 0; i < nmtinfo; i++) 241 if (mtinfo[i].hwid == id) 242 break; 243 if (i == nmtinfo) 244 return (-1); 245 return (0); 246 } 247 248 int 249 mtmatch(parent, match, aux) 250 struct device *parent; 251 struct cfdata *match; 252 void *aux; 253 { 254 struct cs80bus_attach_args *ca = aux; 255 256 ca->ca_punit = 0; 257 return (mtlookup(ca->ca_id, ca->ca_slave, ca->ca_punit) == 0); 258 } 259 260 void 261 mtattach(parent, self, aux) 262 struct device *parent, *self; 263 void *aux; 264 { 265 struct mt_softc *sc = (struct mt_softc *)self; 266 struct cs80bus_attach_args *ca = aux; 267 int type; 268 269 sc->sc_ic = ca->ca_ic; 270 sc->sc_slave = ca->ca_slave; 271 272 if ((type = mtlookup(ca->ca_id, ca->ca_slave, ca->ca_punit)) < 0) 273 return; 274 275 printf(": %s tape\n", mtinfo[type].desc); 276 277 sc->sc_type = type; 278 sc->sc_flags = MTF_EXISTS; 279 280 bufq_alloc(&sc->sc_tab, BUFQ_FCFS); 281 callout_init(&sc->sc_start_ch); 282 callout_init(&sc->sc_intr_ch); 283 284 if (gpibregister(sc->sc_ic, sc->sc_slave, mtcallback, sc, 285 &sc->sc_hdl)) { 286 printf("%s: can't register callback\n", sc->sc_dev.dv_xname); 287 return; 288 } 289 } 290 291 /* 292 * Perform a read of "Device Status Jump" register and update the 293 * status if necessary. If status is read, the given "ecmd" is also 294 * performed, unless "ecmd" is zero. Returns DSJ value, -1 on failure 295 * and -2 on "temporary" failure. 296 */ 297 int 298 mtreaddsj(sc, ecmd) 299 struct mt_softc *sc; 300 int ecmd; 301 { 302 int retval; 303 304 if (sc->sc_flags & MTF_STATTIMEO) 305 goto getstats; 306 retval = gpibrecv(sc->sc_ic, 307 (sc->sc_flags & MTF_DSJTIMEO) ? -1 : sc->sc_slave, 308 MTT_DSJ, &(sc->sc_lastdsj), 1); 309 sc->sc_flags &= ~MTF_DSJTIMEO; 310 if (retval != 1) { 311 DPRINTF(MDB_ANY, ("%s can't gpibrecv DSJ", 312 sc->sc_dev.dv_xname)); 313 if (sc->sc_recvtimeo == 0) 314 sc->sc_recvtimeo = hz; 315 if (--sc->sc_recvtimeo == 0) 316 return (-1); 317 if (retval == 0) 318 sc->sc_flags |= MTF_DSJTIMEO; 319 return (-2); 320 } 321 sc->sc_recvtimeo = 0; 322 sc->sc_statindex = 0; 323 DPRINTF(MDB_ANY, ("%s readdsj: 0x%x", sc->sc_dev.dv_xname, 324 sc->sc_lastdsj)); 325 sc->sc_lastecmd = ecmd; 326 switch (sc->sc_lastdsj) { 327 case 0: 328 if (ecmd & MTE_DSJ_FORCE) 329 break; 330 return (0); 331 332 case 2: 333 sc->sc_lastecmd = MTE_COMPLETE; 334 case 1: 335 break; 336 337 default: 338 printf("%s readdsj: DSJ 0x%x\n", sc->sc_dev.dv_xname, 339 sc->sc_lastdsj); 340 return (-1); 341 } 342 343 getstats: 344 retval = gpibrecv(sc->sc_ic, 345 (sc->sc_flags & MTF_STATCONT) ? -1 : sc->sc_slave, MTT_STAT, 346 ((char *)&(sc->sc_stat)) + sc->sc_statindex, 347 sizeof(sc->sc_stat) - sc->sc_statindex); 348 sc->sc_flags &= ~(MTF_STATTIMEO | MTF_STATCONT); 349 if (retval != sizeof(sc->sc_stat) - sc->sc_statindex) { 350 if (sc->sc_recvtimeo == 0) 351 sc->sc_recvtimeo = hz; 352 if (--sc->sc_recvtimeo != 0) { 353 if (retval >= 0) { 354 sc->sc_statindex += retval; 355 sc->sc_flags |= MTF_STATCONT; 356 } 357 sc->sc_flags |= MTF_STATTIMEO; 358 return (-2); 359 } 360 printf("%s readdsj: can't read status", sc->sc_dev.dv_xname); 361 return (-1); 362 } 363 sc->sc_recvtimeo = 0; 364 sc->sc_statindex = 0; 365 DPRINTF(MDB_ANY, ("%s readdsj: status is %x %x %x %x %x %x", 366 sc->sc_dev.dv_xname, 367 sc->sc_stat1, sc->sc_stat2, sc->sc_stat3, 368 sc->sc_stat4, sc->sc_stat5, sc->sc_stat6)); 369 if (sc->sc_lastecmd) 370 (void) gpibsend(sc->sc_ic, sc->sc_slave, 371 MTL_ECMD, &(sc->sc_lastecmd), 1); 372 return ((int) sc->sc_lastdsj); 373 } 374 375 int 376 mtopen(dev, flag, mode, p) 377 dev_t dev; 378 int flag, mode; 379 struct proc *p; 380 { 381 struct mt_softc *sc; 382 int req_den; 383 int error; 384 385 sc = device_lookup(&mt_cd, MTUNIT(dev)); 386 if (sc == NULL || (sc->sc_flags & MTF_EXISTS) == 0) 387 return (ENXIO); 388 389 if (sc->sc_flags & MTF_OPEN) 390 return (EBUSY); 391 392 DPRINTF(MDB_ANY, ("%s open: flags 0x%x", sc->sc_dev.dv_xname, 393 sc->sc_flags)); 394 395 sc->sc_flags |= MTF_OPEN; 396 sc->sc_ttyp = tprintf_open(p); 397 if ((sc->sc_flags & MTF_ALIVE) == 0) { 398 error = mtcommand(dev, MTRESET, 0); 399 if (error != 0 || (sc->sc_flags & MTF_ALIVE) == 0) 400 goto errout; 401 if ((sc->sc_stat1 & (SR1_BOT | SR1_ONLINE)) == SR1_ONLINE) 402 (void) mtcommand(dev, MTREW, 0); 403 } 404 for (;;) { 405 if ((error = mtcommand(dev, MTNOP, 0)) != 0) 406 goto errout; 407 if (!(sc->sc_flags & MTF_REW)) 408 break; 409 if (tsleep((caddr_t) &lbolt, PCATCH | (PZERO + 1), 410 "mt", 0) != 0) { 411 error = EINTR; 412 goto errout; 413 } 414 } 415 if ((flag & FWRITE) && (sc->sc_stat1 & SR1_RO)) { 416 error = EROFS; 417 goto errout; 418 } 419 if (!(sc->sc_stat1 & SR1_ONLINE)) { 420 uprintf("%s: not online\n", sc->sc_dev.dv_xname); 421 error = EIO; 422 goto errout; 423 } 424 /* 425 * Select density: 426 * - find out what density the drive is set to 427 * (i.e. the density of the current tape) 428 * - if we are going to write 429 * - if we're not at the beginning of the tape 430 * - complain if we want to change densities 431 * - otherwise, select the mtcommand to set the density 432 * 433 * If the drive doesn't support it then don't change the recorded 434 * density. 435 * 436 * The original MOREbsd code had these additional conditions 437 * for the mid-tape change 438 * 439 * req_den != T_BADBPI && 440 * sc->sc_density != T_6250BPI 441 * 442 * which suggests that it would be possible to write multiple 443 * densities if req_den == T_BAD_BPI or the current tape 444 * density was 6250. Testing of our 7980 suggests that the 445 * device cannot change densities mid-tape. 446 * 447 * ajv@comp.vuw.ac.nz 448 */ 449 sc->sc_density = (sc->sc_stat2 & SR2_6250) ? T_6250BPI : ( 450 (sc->sc_stat3 & SR3_1600) ? T_1600BPI : ( 451 (sc->sc_stat3 & SR3_800) ? T_800BPI : -1)); 452 req_den = (dev & T_DENSEL); 453 454 if (flag & FWRITE) { 455 if (!(sc->sc_stat1 & SR1_BOT)) { 456 if (sc->sc_density != req_den) { 457 uprintf("%s: can't change density mid-tape\n", 458 sc->sc_dev.dv_xname); 459 error = EIO; 460 goto errout; 461 } 462 } 463 else { 464 int mtset_density = 465 (req_den == T_800BPI ? MTSET800BPI : ( 466 req_den == T_1600BPI ? MTSET1600BPI : ( 467 req_den == T_6250BPI ? MTSET6250BPI : ( 468 sc->sc_type == MT7980ID 469 ? MTSET6250DC 470 : MTSET6250BPI)))); 471 if (mtcommand(dev, mtset_density, 0) == 0) 472 sc->sc_density = req_den; 473 } 474 } 475 return (0); 476 errout: 477 sc->sc_flags &= ~MTF_OPEN; 478 return (error); 479 } 480 481 int 482 mtclose(dev, flag, fmt, p) 483 dev_t dev; 484 int flag, fmt; 485 struct proc *p; 486 { 487 struct mt_softc *sc; 488 489 sc = device_lookup(&mt_cd, MTUNIT(dev)); 490 if (sc == NULL) 491 return (ENXIO); 492 493 if (sc->sc_flags & MTF_WRT) { 494 (void) mtcommand(dev, MTWEOF, 2); 495 (void) mtcommand(dev, MTBSF, 0); 496 } 497 if ((minor(dev) & T_NOREWIND) == 0) 498 (void) mtcommand(dev, MTREW, 0); 499 sc->sc_flags &= ~MTF_OPEN; 500 tprintf_close(sc->sc_ttyp); 501 return (0); 502 } 503 504 int 505 mtcommand(dev, cmd, cnt) 506 dev_t dev; 507 int cmd; 508 int cnt; 509 { 510 struct mt_softc *sc; 511 struct buf *bp; 512 int error = 0; 513 514 sc = device_lookup(&mt_cd, MTUNIT(dev)); 515 bp = &sc->sc_bufstore; 516 517 if (bp->b_flags & B_BUSY) 518 return (EBUSY); 519 520 bp->b_cmd = cmd; 521 bp->b_dev = dev; 522 do { 523 bp->b_flags = B_BUSY | B_CMD; 524 mtstrategy(bp); 525 biowait(bp); 526 if (bp->b_flags & B_ERROR) { 527 error = (int) (unsigned) bp->b_error; 528 break; 529 } 530 } while (--cnt > 0); 531 #if 0 532 bp->b_flags = 0 /*&= ~B_BUSY*/; 533 #else 534 bp->b_flags &= ~B_BUSY; 535 #endif 536 return (error); 537 } 538 539 /* 540 * Only thing to check here is for legal record lengths (writes only). 541 */ 542 void 543 mtstrategy(bp) 544 struct buf *bp; 545 { 546 struct mt_softc *sc; 547 int s; 548 549 sc = device_lookup(&mt_cd, MTUNIT(bp->b_dev)); 550 551 DPRINTF(MDB_ANY, ("%s strategy", sc->sc_dev.dv_xname)); 552 553 if ((bp->b_flags & (B_CMD | B_READ)) == 0) { 554 #define WRITE_BITS_IGNORED 8 555 #if 0 556 if (bp->b_bcount & ((1 << WRITE_BITS_IGNORED) - 1)) { 557 tprintf(sc->sc_ttyp, 558 "%s: write record must be multiple of %d\n", 559 sc->sc_dev.dv_xname, 1 << WRITE_BITS_IGNORED); 560 goto error; 561 } 562 #endif 563 s = 16 * 1024; 564 if (sc->sc_stat2 & SR2_LONGREC) { 565 switch (sc->sc_density) { 566 case T_1600BPI: 567 s = 32 * 1024; 568 break; 569 570 case T_6250BPI: 571 case T_BADBPI: 572 s = 60 * 1024; 573 break; 574 } 575 } 576 if (bp->b_bcount > s) { 577 tprintf(sc->sc_ttyp, 578 "%s: write record (%ld) too big: limit (%d)\n", 579 sc->sc_dev.dv_xname, bp->b_bcount, s); 580 #if 0 /* XXX see above */ 581 error: 582 #endif 583 bp->b_flags |= B_ERROR; 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 errdone; 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 errdone; 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 errdone; 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 errdone: 842 bp->b_flags |= B_ERROR; 843 done: 844 sc->sc_flags &= ~(MTF_HITEOF | MTF_HITBOF); 845 (void)BUFQ_GET(&sc->sc_tab); 846 biodone(bp); 847 gpibrelease(sc->sc_ic, sc->sc_hdl); 848 if ((bp = BUFQ_PEEK(&sc->sc_tab)) == NULL) 849 sc->sc_active = 0; 850 else 851 mtustart(sc); 852 } 853 854 void 855 mtintr(sc) 856 struct mt_softc *sc; 857 { 858 struct buf *bp; 859 int slave, dir, i; 860 u_char cmdbuf[4]; 861 862 slave = sc->sc_slave; 863 864 bp = BUFQ_PEEK(&sc->sc_tab); 865 if (bp == NULL) { 866 printf("%s intr: bp == NULL", sc->sc_dev.dv_xname); 867 return; 868 } 869 870 DPRINTF(MDB_ANY, ("%s intr", sc->sc_dev.dv_xname)); 871 872 /* 873 * Some operation completed. Read status bytes and report errors. 874 * Clear EOF flags here `cause they're set once on specific conditions 875 * below when a command succeeds. 876 * A DSJ of 2 always means keep waiting. If the command was READ 877 * (and we're in data DMA phase) stop data transfer first. 878 */ 879 sc->sc_flags &= ~(MTF_HITEOF | MTF_HITBOF); 880 if ((bp->b_flags & (B_CMD|B_READ)) == B_READ && 881 !(sc->sc_flags & (MTF_IO | MTF_STATTIMEO | MTF_DSJTIMEO))){ 882 cmdbuf[0] = MTE_STOP; 883 (void) gpibsend(sc->sc_ic, slave, MTL_ECMD,cmdbuf,1); 884 } 885 switch (mtreaddsj(sc, 0)) { 886 case 0: 887 break; 888 889 case 1: 890 /* 891 * If we're in the middle of a READ/WRITE and have yet to 892 * start the data transfer, a DSJ of one should terminate it. 893 */ 894 sc->sc_flags &= ~MTF_IO; 895 break; 896 897 case 2: 898 (void) gpibawait(sc->sc_ic); 899 return; 900 901 case -2: 902 /* 903 * -2 means that the drive failed to respond quickly enough 904 * to the request for DSJ. It's probably just "busy" figuring 905 * it out and will know in a little bit... 906 */ 907 callout_reset(&sc->sc_intr_ch, hz >> 5, mtintr_callout, sc); 908 return; 909 910 default: 911 printf("%s intr: can't get drive stat", sc->sc_dev.dv_xname); 912 goto error; 913 } 914 if (sc->sc_stat1 & (SR1_ERR | SR1_REJECT)) { 915 i = sc->sc_stat4 & SR4_ERCLMASK; 916 printf("%s: %s error, retry %d, SR2/3 %x/%x, code %d", 917 sc->sc_dev.dv_xname, i == SR4_DEVICE ? "device" : 918 (i == SR4_PROTOCOL ? "protocol" : 919 (i == SR4_SELFTEST ? "selftest" : "unknown")), 920 sc->sc_stat4 & SR4_RETRYMASK, sc->sc_stat2, 921 sc->sc_stat3, sc->sc_stat5); 922 923 if ((bp->b_flags & B_CMD) && bp->b_cmd == MTRESET) 924 callout_stop(&sc->sc_intr_ch); 925 if (sc->sc_stat3 & SR3_POWERUP) 926 sc->sc_flags &= MTF_OPEN | MTF_EXISTS; 927 goto error; 928 } 929 /* 930 * Report and clear any soft errors. 931 */ 932 if (sc->sc_stat1 & SR1_SOFTERR) { 933 printf("%s: soft error, retry %d\n", sc->sc_dev.dv_xname, 934 sc->sc_stat4 & SR4_RETRYMASK); 935 sc->sc_stat1 &= ~SR1_SOFTERR; 936 } 937 /* 938 * We've initiated a read or write, but haven't actually started to 939 * DMA the data yet. At this point, the drive's ready. 940 */ 941 if (sc->sc_flags & MTF_IO) { 942 sc->sc_flags &= ~MTF_IO; 943 dir = (bp->b_flags & B_READ ? GPIB_READ : GPIB_WRITE); 944 gpibxfer(sc->sc_ic, slave, 945 dir == GPIB_READ ? MTT_READ : MTL_WRITE, 946 bp->b_data, bp->b_bcount, dir, dir == GPIB_READ); 947 return; 948 } 949 /* 950 * Check for End Of Tape - we're allowed to hit EOT and then write (or 951 * read) one more record. If we get here and have not already hit EOT, 952 * return ENOSPC to inform the process that it's hit it. If we get 953 * here and HAVE already hit EOT, don't allow any more operations that 954 * move the tape forward. 955 */ 956 if (sc->sc_stat1 & SR1_EOT) { 957 if (sc->sc_flags & MTF_ATEOT) 958 sc->sc_flags |= MTF_PASTEOT; 959 else { 960 bp->b_flags |= B_ERROR; 961 bp->b_error = ENOSPC; 962 sc->sc_flags |= MTF_ATEOT; 963 } 964 } 965 /* 966 * If a motion command was being executed, check for Tape Marks. 967 * If we were doing data, make sure we got the right amount, and 968 * check for hitting tape marks on reads. 969 */ 970 if (bp->b_flags & B_CMD) { 971 if (sc->sc_stat1 & SR1_EOF) { 972 if (bp->b_cmd == MTFSR) 973 sc->sc_flags |= MTF_HITEOF; 974 if (bp->b_cmd == MTBSR) 975 sc->sc_flags |= MTF_HITBOF; 976 } 977 if (bp->b_cmd == MTRESET) { 978 callout_stop(&sc->sc_intr_ch); 979 sc->sc_flags |= MTF_ALIVE; 980 } 981 } else { 982 i = gpibrecv(sc->sc_ic, slave, MTT_BCNT, cmdbuf, 2); 983 if (i != 2) { 984 printf("%s intr: can't get xfer length\n", 985 sc->sc_dev.dv_xname); 986 goto error; 987 } 988 i = (int) *((u_short *) cmdbuf); 989 if (i <= bp->b_bcount) { 990 if (i == 0) 991 sc->sc_flags |= MTF_HITEOF; 992 bp->b_resid = bp->b_bcount - i; 993 DPRINTF(MDB_ANY, ("%s intr: bcount %ld, resid %ld", 994 sc->sc_dev.dv_xname, bp->b_bcount, bp->b_resid)); 995 } else { 996 tprintf(sc->sc_ttyp, 997 "%s: record (%d) larger than wanted (%ld)\n", 998 sc->sc_dev.dv_xname, i, bp->b_bcount); 999 error: 1000 sc->sc_flags &= ~MTF_IO; 1001 bp->b_error = EIO; 1002 bp->b_flags |= B_ERROR; 1003 } 1004 } 1005 /* 1006 * The operation is completely done. 1007 * Let the drive know with an END command. 1008 */ 1009 cmdbuf[0] = MTE_COMPLETE | MTE_IDLE; 1010 (void) gpibsend(sc->sc_ic, slave, MTL_ECMD, cmdbuf, 1); 1011 bp->b_flags &= ~B_CMD; 1012 (void)BUFQ_GET(&sc->sc_tab); 1013 biodone(bp); 1014 gpibrelease(sc->sc_ic, sc->sc_hdl); 1015 if (BUFQ_PEEK(&sc->sc_tab) == NULL) 1016 sc->sc_active = 0; 1017 else 1018 mtustart(sc); 1019 } 1020 1021 int 1022 mtread(dev, uio, flags) 1023 dev_t dev; 1024 struct uio *uio; 1025 int flags; 1026 { 1027 struct mt_softc *sc; 1028 1029 sc = device_lookup(&mt_cd, MTUNIT(dev)); 1030 1031 return (physio(mtstrategy, &sc->sc_bufstore, 1032 dev, B_READ, minphys, uio)); 1033 } 1034 1035 int 1036 mtwrite(dev, uio, flags) 1037 dev_t dev; 1038 struct uio *uio; 1039 int flags; 1040 { 1041 struct mt_softc *sc; 1042 1043 sc = device_lookup(&mt_cd, MTUNIT(dev)); 1044 1045 return (physio(mtstrategy, &sc->sc_bufstore, 1046 dev, B_WRITE, minphys, uio)); 1047 } 1048 1049 int 1050 mtioctl(dev, cmd, data, flag, p) 1051 dev_t dev; 1052 u_long cmd; 1053 caddr_t data; 1054 int flag; 1055 struct proc *p; 1056 { 1057 struct mtop *op; 1058 int cnt; 1059 1060 switch (cmd) { 1061 case MTIOCTOP: 1062 op = (struct mtop *)data; 1063 switch(op->mt_op) { 1064 case MTWEOF: 1065 case MTFSF: 1066 case MTBSR: 1067 case MTBSF: 1068 case MTFSR: 1069 cnt = op->mt_count; 1070 break; 1071 1072 case MTOFFL: 1073 case MTREW: 1074 case MTNOP: 1075 cnt = 0; 1076 break; 1077 1078 default: 1079 return (EINVAL); 1080 } 1081 return (mtcommand(dev, op->mt_op, cnt)); 1082 1083 case MTIOCGET: 1084 break; 1085 1086 default: 1087 return (EINVAL); 1088 } 1089 return (0); 1090 } 1091