1 /* 2 * $FreeBSD: src/sys/cam/scsi/scsi_sa.c,v 1.45.2.13 2002/12/17 17:08:50 trhodes Exp $ 3 * 4 * Implementation of SCSI Sequential Access Peripheral driver for CAM. 5 * 6 * Copyright (c) 1999, 2000 Matthew Jacob 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions, and the following disclaimer, 14 * without modification, immediately at the beginning of the file. 15 * 2. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32 #include <sys/param.h> 33 #include <sys/queue.h> 34 #ifdef _KERNEL 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #endif 38 #include <sys/types.h> 39 #ifdef _KERNEL 40 #include <sys/buf.h> 41 #include <sys/malloc.h> 42 #endif 43 #include <sys/mtio.h> 44 #include <sys/conf.h> 45 #ifdef _KERNEL 46 #include <sys/proc.h> 47 #include <sys/buf2.h> 48 #endif 49 #include <sys/caps.h> 50 #include <sys/fcntl.h> 51 #include <sys/devicestat.h> 52 #include <machine/limits.h> 53 54 #ifndef _KERNEL 55 #include <stdio.h> 56 #include <string.h> 57 #endif 58 59 #include "../cam.h" 60 #include "../cam_ccb.h" 61 #include "../cam_extend.h" 62 #include "../cam_periph.h" 63 #include "../cam_xpt_periph.h" 64 #include "../cam_debug.h" 65 66 #include "scsi_all.h" 67 #include "scsi_message.h" 68 #include "scsi_sa.h" 69 70 #ifdef _KERNEL 71 72 #include <opt_sa.h> 73 74 #ifndef SA_IO_TIMEOUT 75 #define SA_IO_TIMEOUT 4 76 #endif 77 #ifndef SA_SPACE_TIMEOUT 78 #define SA_SPACE_TIMEOUT 1 * 60 79 #endif 80 #ifndef SA_REWIND_TIMEOUT 81 #define SA_REWIND_TIMEOUT 2 * 60 82 #endif 83 #ifndef SA_ERASE_TIMEOUT 84 #define SA_ERASE_TIMEOUT 4 * 60 85 #endif 86 87 #define SCSIOP_TIMEOUT (60 * 1000) /* not an option */ 88 89 #define IO_TIMEOUT (SA_IO_TIMEOUT * 60 * 1000) 90 #define REWIND_TIMEOUT (SA_REWIND_TIMEOUT * 60 * 1000) 91 #define ERASE_TIMEOUT (SA_ERASE_TIMEOUT * 60 * 1000) 92 #define SPACE_TIMEOUT (SA_SPACE_TIMEOUT * 60 * 1000) 93 94 /* 95 * Additional options that can be set for config: SA_1FM_AT_EOT 96 */ 97 98 #define QFRLS(ccb) \ 99 if (((ccb)->ccb_h.status & CAM_DEV_QFRZN) != 0) \ 100 cam_release_devq((ccb)->ccb_h.path, 0, 0, 0, FALSE) 101 102 /* 103 * Driver states 104 */ 105 106 MALLOC_DEFINE(M_SCSISA, "SCSI sa", "SCSI sequential access buffers"); 107 108 typedef enum { 109 SA_STATE_NORMAL, SA_STATE_ABNORMAL 110 } sa_state; 111 112 #define ccb_pflags ppriv_field0 113 #define ccb_bio ppriv_ptr1 114 115 #define SA_CCB_POLLED 0x00 116 #define SA_CCB_BUFFER_IO 0x01 117 #define SA_CCB_WAITING 0x02 118 #define SA_CCB_TYPEMASK 0x0F 119 #define SA_POSITION_UPDATED 0x10 120 121 #define Set_CCB_Type(x, type) do { \ 122 x->ccb_h.ccb_pflags &= ~SA_CCB_TYPEMASK; \ 123 x->ccb_h.ccb_pflags |= type; \ 124 } while (0) 125 126 #define CCB_Type(x) (x->ccb_h.ccb_pflags & SA_CCB_TYPEMASK) 127 128 129 130 typedef enum { 131 SA_FLAG_OPEN = 0x0001, 132 SA_FLAG_FIXED = 0x0002, 133 SA_FLAG_TAPE_LOCKED = 0x0004, 134 SA_FLAG_TAPE_MOUNTED = 0x0008, 135 SA_FLAG_TAPE_WP = 0x0010, 136 SA_FLAG_TAPE_WRITTEN = 0x0020, 137 SA_FLAG_EOM_PENDING = 0x0040, 138 SA_FLAG_EIO_PENDING = 0x0080, 139 SA_FLAG_EOF_PENDING = 0x0100, 140 SA_FLAG_ERR_PENDING = (SA_FLAG_EOM_PENDING|SA_FLAG_EIO_PENDING| 141 SA_FLAG_EOF_PENDING), 142 SA_FLAG_INVALID = 0x0200, 143 SA_FLAG_COMP_ENABLED = 0x0400, 144 SA_FLAG_COMP_SUPP = 0x0800, 145 SA_FLAG_COMP_UNSUPP = 0x1000, 146 SA_FLAG_TAPE_FROZEN = 0x2000 147 } sa_flags; 148 149 typedef enum { 150 SA_MODE_REWIND = 0x00, 151 SA_MODE_NOREWIND = 0x01, 152 SA_MODE_OFFLINE = 0x02 153 } sa_mode; 154 155 typedef enum { 156 SA_PARAM_NONE = 0x00, 157 SA_PARAM_BLOCKSIZE = 0x01, 158 SA_PARAM_DENSITY = 0x02, 159 SA_PARAM_COMPRESSION = 0x04, 160 SA_PARAM_BUFF_MODE = 0x08, 161 SA_PARAM_NUMBLOCKS = 0x10, 162 SA_PARAM_WP = 0x20, 163 SA_PARAM_SPEED = 0x40, 164 SA_PARAM_ALL = 0x7f 165 } sa_params; 166 167 typedef enum { 168 SA_QUIRK_NONE = 0x00, 169 SA_QUIRK_NOCOMP = 0x01, /* Can't deal with compression at all */ 170 SA_QUIRK_FIXED = 0x02, /* Force fixed mode */ 171 SA_QUIRK_VARIABLE = 0x04, /* Force variable mode */ 172 SA_QUIRK_2FM = 0x08, /* Needs Two File Marks at EOD */ 173 SA_QUIRK_1FM = 0x10, /* No more than 1 File Mark at EOD */ 174 SA_QUIRK_NODREAD = 0x20, /* Don't try and dummy read density */ 175 SA_QUIRK_NO_MODESEL = 0x40, /* Don't do mode select at all */ 176 SA_QUIRK_NO_CPAGE = 0x80 /* Don't use DEVICE COMPRESSION page */ 177 } sa_quirks; 178 179 /* units are bits 4-7, 16-21 (1024 units) */ 180 #define SAUNIT(DEV) \ 181 (((minor(DEV) & 0xF0) >> 4) | ((minor(DEV) & 0x3f0000) >> 16)) 182 183 #define SAMODE(z) ((minor(z) & 0x3)) 184 #define SADENSITY(z) (((minor(z) >> 2) & 0x3)) 185 #define SA_IS_CTRL(z) (minor(z) & (1 << 29)) 186 187 #define SA_NOT_CTLDEV 0 188 #define SA_CTLDEV 1 189 190 #define SA_ATYPE_R 0 191 #define SA_ATYPE_NR 1 192 #define SA_ATYPE_ER 2 193 194 #define SAMINOR(ctl, unit, mode, access) \ 195 ((ctl << 29) | ((unit & 0x3f0) << 16) | ((unit & 0xf) << 4) | \ 196 (mode << 0x2) | (access & 0x3)) 197 198 #define SA_UNITMASK SAMINOR(0, -1, 0, 0) 199 #define SA_UNIT(unit) SAMINOR(0, unit, 0, 0) 200 201 #define SA_NUM_MODES 4 202 203 struct sa_softc { 204 sa_state state; 205 sa_flags flags; 206 sa_quirks quirks; 207 struct bio_queue_head bio_queue; 208 int queue_count; 209 struct devstat device_stats; 210 int blk_gran; 211 int blk_mask; 212 int blk_shift; 213 u_int32_t max_blk; 214 u_int32_t min_blk; 215 u_int32_t comp_algorithm; 216 u_int32_t saved_comp_algorithm; 217 u_int32_t media_blksize; 218 u_int32_t last_media_blksize; 219 u_int32_t media_numblks; 220 u_int8_t media_density; 221 u_int8_t speed; 222 u_int8_t scsi_rev; 223 u_int8_t dsreg; /* mtio mt_dsreg, redux */ 224 int buffer_mode; 225 int filemarks; 226 union ccb saved_ccb; 227 int last_resid_was_io; 228 229 /* 230 * Relative to BOT Location. 231 */ 232 daddr_t fileno; 233 daddr_t blkno; 234 235 /* 236 * Latched Error Info 237 */ 238 struct { 239 struct scsi_sense_data _last_io_sense; 240 u_int32_t _last_io_resid; 241 u_int8_t _last_io_cdb[CAM_MAX_CDBLEN]; 242 struct scsi_sense_data _last_ctl_sense; 243 u_int32_t _last_ctl_resid; 244 u_int8_t _last_ctl_cdb[CAM_MAX_CDBLEN]; 245 #define last_io_sense errinfo._last_io_sense 246 #define last_io_resid errinfo._last_io_resid 247 #define last_io_cdb errinfo._last_io_cdb 248 #define last_ctl_sense errinfo._last_ctl_sense 249 #define last_ctl_resid errinfo._last_ctl_resid 250 #define last_ctl_cdb errinfo._last_ctl_cdb 251 } errinfo; 252 /* 253 * Misc other flags/state 254 */ 255 u_int32_t 256 : 29, 257 open_rdonly : 1, /* open read-only */ 258 open_pending_mount : 1, /* open pending mount */ 259 ctrl_mode : 1; /* control device open */ 260 }; 261 262 struct sa_quirk_entry { 263 struct scsi_inquiry_pattern inq_pat; /* matching pattern */ 264 sa_quirks quirks; /* specific quirk type */ 265 u_int32_t prefblk; /* preferred blocksize when in fixed mode */ 266 }; 267 268 static struct sa_quirk_entry sa_quirk_table[] = 269 { 270 { 271 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "OnStream", 272 "ADR*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_NODREAD | 273 SA_QUIRK_1FM|SA_QUIRK_NO_MODESEL, 32768 274 }, 275 { 276 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE", 277 "Python 06408*", "*"}, SA_QUIRK_NODREAD, 0 278 }, 279 { 280 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE", 281 "Python 25601*", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_NODREAD, 0 282 }, 283 { 284 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE", 285 "Python*", "*"}, SA_QUIRK_NODREAD, 0 286 }, 287 { 288 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE", 289 "VIPER 150*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512 290 }, 291 { 292 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE", 293 "VIPER 2525 25462", "-011"}, 294 SA_QUIRK_NOCOMP|SA_QUIRK_1FM|SA_QUIRK_NODREAD, 0 295 }, 296 { 297 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE", 298 "VIPER 2525*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024 299 }, 300 #if 0 301 { 302 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP", 303 "C15*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_NO_CPAGE, 0, 304 }, 305 #endif 306 { 307 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP", 308 "C56*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0 309 }, 310 { 311 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP", 312 "T20*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512 313 }, 314 { 315 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP", 316 "T4000*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512 317 }, 318 { 319 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP", 320 "HP-88780*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0 321 }, 322 { 323 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "KENNEDY", 324 "*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0 325 }, 326 { 327 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "M4 DATA", 328 "123107 SCSI*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0 329 }, 330 { /* jreynold@primenet.com */ 331 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "Seagate", 332 "STT8000N*", "*"}, SA_QUIRK_1FM, 0 333 }, 334 { /* mike@sentex.net */ 335 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "Seagate", 336 "STT20000*", "*"}, SA_QUIRK_1FM, 0 337 }, 338 { 339 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG", 340 " TDC 3600", "U07:"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512 341 }, 342 { 343 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG", 344 " TDC 3800", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512 345 }, 346 { 347 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG", 348 " TDC 4100", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512 349 }, 350 { 351 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG", 352 " TDC 4200", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512 353 }, 354 { 355 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG", 356 " SLR*", "*"}, SA_QUIRK_1FM, 0 357 }, 358 { 359 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK", 360 "5525ES*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512 361 }, 362 { 363 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK", 364 "51000*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024 365 } 366 }; 367 368 static d_open_t saopen; 369 static d_close_t saclose; 370 static d_strategy_t sastrategy; 371 static d_ioctl_t saioctl; 372 static periph_init_t sainit; 373 static periph_ctor_t saregister; 374 static periph_oninv_t saoninvalidate; 375 static periph_dtor_t sacleanup; 376 static periph_start_t sastart; 377 static void saasync(void *callback_arg, u_int32_t code, 378 struct cam_path *path, void *arg); 379 static void sadone(struct cam_periph *periph, 380 union ccb *start_ccb); 381 static int saerror(union ccb *ccb, u_int32_t cam_flags, 382 u_int32_t sense_flags); 383 static int samarkswanted(struct cam_periph *); 384 static int sacheckeod(struct cam_periph *periph); 385 static int sagetparams(struct cam_periph *periph, 386 sa_params params_to_get, 387 u_int32_t *blocksize, u_int8_t *density, 388 u_int32_t *numblocks, int *buff_mode, 389 u_int8_t *write_protect, u_int8_t *speed, 390 int *comp_supported, int *comp_enabled, 391 u_int32_t *comp_algorithm, 392 sa_comp_t *comp_page); 393 static int sasetparams(struct cam_periph *periph, 394 sa_params params_to_set, 395 u_int32_t blocksize, u_int8_t density, 396 u_int32_t comp_algorithm, 397 u_int32_t sense_flags); 398 static void saprevent(struct cam_periph *periph, int action); 399 static int sarewind(struct cam_periph *periph); 400 static int saspace(struct cam_periph *periph, int count, 401 scsi_space_code code); 402 static int samount(struct cam_periph *, int, cdev_t); 403 static int saretension(struct cam_periph *periph); 404 static int sareservereleaseunit(struct cam_periph *periph, 405 int reserve); 406 static int saloadunload(struct cam_periph *periph, int load); 407 static int saerase(struct cam_periph *periph, int longerase); 408 static int sawritefilemarks(struct cam_periph *periph, 409 int nmarks, int setmarks); 410 static int sardpos(struct cam_periph *periph, int, u_int32_t *); 411 static int sasetpos(struct cam_periph *periph, int, u_int32_t *); 412 413 414 static struct periph_driver sadriver = 415 { 416 sainit, "sa", 417 TAILQ_HEAD_INITIALIZER(sadriver.units), /* generation */ 0 418 }; 419 420 PERIPHDRIVER_DECLARE(sa, sadriver); 421 422 /* For 2.2-stable support */ 423 #ifndef D_TAPE 424 #define D_TAPE 0 425 #endif 426 427 static struct dev_ops sa_ops = { 428 { "sa", 0, D_TAPE }, 429 .d_open = saopen, 430 .d_close = saclose, 431 .d_read = physread, 432 .d_write = physwrite, 433 .d_ioctl = saioctl, 434 .d_strategy = sastrategy, 435 }; 436 437 static struct extend_array *saperiphs; 438 439 static int 440 saopen(struct dev_open_args *ap) 441 { 442 cdev_t dev = ap->a_head.a_dev; 443 struct cam_periph *periph; 444 struct sa_softc *softc; 445 int unit; 446 int error; 447 448 /* 449 * Disallow CAM access if RESTRICTEDROOT 450 */ 451 if (caps_priv_check_self(SYSCAP_RESTRICTEDROOT)) 452 return (EPERM); 453 454 unit = SAUNIT(dev); 455 456 periph = cam_extend_get(saperiphs, unit); 457 if (cam_periph_acquire(periph) != CAM_REQ_CMP) { 458 return (ENXIO); 459 } 460 461 cam_periph_lock(periph); 462 463 softc = (struct sa_softc *)periph->softc; 464 465 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO, 466 ("saopen(%d): dev=0x%x softc=0x%x\n", unit, unit, softc->flags)); 467 468 if (SA_IS_CTRL(dev)) { 469 softc->ctrl_mode = 1; 470 cam_periph_unlock(periph); 471 return (0); 472 } 473 474 if ((error = cam_periph_hold(periph, PCATCH)) != 0) { 475 cam_periph_unlock(periph); 476 cam_periph_release(periph); 477 return (error); 478 } 479 480 if (softc->flags & SA_FLAG_OPEN) { 481 error = EBUSY; 482 } else if (softc->flags & SA_FLAG_INVALID) { 483 error = ENXIO; 484 } else { 485 /* 486 * Preserve whether this is a read_only open. 487 */ 488 softc->open_rdonly = (ap->a_oflags & O_RDWR) == O_RDONLY; 489 490 /* 491 * The function samount ensures media is loaded and ready. 492 * It also does a device RESERVE if the tape isn't yet mounted. 493 * 494 * If the mount fails and this was a non-blocking open, 495 * make this a 'open_pending_mount' action. 496 */ 497 error = samount(periph, ap->a_oflags, dev); 498 if (error && (ap->a_oflags & O_NONBLOCK)) { 499 softc->flags |= SA_FLAG_OPEN; 500 softc->open_pending_mount = 1; 501 cam_periph_unhold(periph, 1); 502 return (0); 503 } 504 } 505 506 if (error) { 507 cam_periph_unhold(periph, 1); 508 cam_periph_release(periph); 509 return (error); 510 } 511 512 saprevent(periph, PR_PREVENT); 513 softc->flags |= SA_FLAG_OPEN; 514 515 cam_periph_unhold(periph, 1); 516 return (error); 517 } 518 519 static int 520 saclose(struct dev_close_args *ap) 521 { 522 cdev_t dev = ap->a_head.a_dev; 523 struct cam_periph *periph; 524 struct sa_softc *softc; 525 int unit, mode, error, writing, tmp; 526 int closedbits = SA_FLAG_OPEN; 527 528 unit = SAUNIT(dev); 529 mode = SAMODE(dev); 530 periph = cam_extend_get(saperiphs, unit); 531 if (periph == NULL) 532 return (ENXIO); 533 534 cam_periph_lock(periph); 535 536 softc = (struct sa_softc *)periph->softc; 537 538 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO, 539 ("saclose(%d): dev=0x%x softc=0x%x\n", unit, unit, softc->flags)); 540 541 542 softc->open_rdonly = 0; 543 if (SA_IS_CTRL(dev)) { 544 softc->ctrl_mode = 0; 545 cam_periph_unlock(periph); 546 cam_periph_release(periph); 547 return (0); 548 } 549 550 if (softc->open_pending_mount) { 551 softc->flags &= ~SA_FLAG_OPEN; 552 softc->open_pending_mount = 0; 553 cam_periph_unlock(periph); 554 cam_periph_release(periph); 555 return (0); 556 } 557 558 if ((error = cam_periph_hold(periph, 0)) != 0) { 559 cam_periph_unlock(periph); 560 return (error); 561 } 562 563 /* 564 * Were we writing the tape? 565 */ 566 writing = (softc->flags & SA_FLAG_TAPE_WRITTEN) != 0; 567 568 /* 569 * See whether or not we need to write filemarks. If this 570 * fails, we probably have to assume we've lost tape 571 * position. 572 */ 573 error = sacheckeod(periph); 574 if (error) { 575 xpt_print(periph->path, 576 "failed to write terminating filemark(s)\n"); 577 softc->flags |= SA_FLAG_TAPE_FROZEN; 578 } 579 580 /* 581 * Whatever we end up doing, allow users to eject tapes from here on. 582 */ 583 saprevent(periph, PR_ALLOW); 584 585 /* 586 * Decide how to end... 587 */ 588 if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) { 589 closedbits |= SA_FLAG_TAPE_FROZEN; 590 } else switch (mode) { 591 case SA_MODE_OFFLINE: 592 /* 593 * An 'offline' close is an unconditional release of 594 * frozen && mount conditions, irrespective of whether 595 * these operations succeeded. The reason for this is 596 * to allow at least some kind of programmatic way 597 * around our state getting all fouled up. If somebody 598 * issues an 'offline' command, that will be allowed 599 * to clear state. 600 */ 601 sarewind(periph); 602 saloadunload(periph, FALSE); 603 closedbits |= SA_FLAG_TAPE_MOUNTED|SA_FLAG_TAPE_FROZEN; 604 break; 605 case SA_MODE_REWIND: 606 /* 607 * If the rewind fails, return an error- if anyone cares, 608 * but not overwriting any previous error. 609 * 610 * We don't clear the notion of mounted here, but we do 611 * clear the notion of frozen if we successfully rewound. 612 */ 613 tmp = sarewind(periph); 614 if (tmp) { 615 if (error != 0) 616 error = tmp; 617 } else { 618 closedbits |= SA_FLAG_TAPE_FROZEN; 619 } 620 break; 621 case SA_MODE_NOREWIND: 622 /* 623 * If we're not rewinding/unloading the tape, find out 624 * whether we need to back up over one of two filemarks 625 * we wrote (if we wrote two filemarks) so that appends 626 * from this point on will be sane. 627 */ 628 if (error == 0 && writing && (softc->quirks & SA_QUIRK_2FM)) { 629 tmp = saspace(periph, -1, SS_FILEMARKS); 630 if (tmp) { 631 xpt_print(periph->path, "unable to backspace " 632 "over one of double filemarks at end of " 633 "tape\n"); 634 xpt_print(periph->path, "it is possible that " 635 "this device needs a SA_QUIRK_1FM quirk set" 636 "for it\n"); 637 softc->flags |= SA_FLAG_TAPE_FROZEN; 638 } 639 } 640 break; 641 default: 642 xpt_print(periph->path, "unknown mode 0x%x in saclose\n", mode); 643 /* NOTREACHED */ 644 break; 645 } 646 647 /* 648 * We wish to note here that there are no more filemarks to be written. 649 */ 650 softc->filemarks = 0; 651 softc->flags &= ~SA_FLAG_TAPE_WRITTEN; 652 653 /* 654 * And we are no longer open for business. 655 */ 656 softc->flags &= ~closedbits; 657 658 /* 659 * Inform users if tape state if frozen.... 660 */ 661 if (softc->flags & SA_FLAG_TAPE_FROZEN) { 662 xpt_print(periph->path, "tape is now frozen- use an OFFLINE, " 663 "REWIND or MTEOM command to clear this state.\n"); 664 } 665 666 /* release the device if it is no longer mounted */ 667 if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) 668 sareservereleaseunit(periph, FALSE); 669 670 cam_periph_unhold(periph, 1); 671 cam_periph_release(periph); 672 673 return (error); 674 } 675 676 /* 677 * Actually translate the requested transfer into one the physical driver 678 * can understand. The transfer is described by a buf and will include 679 * only one physical transfer. 680 */ 681 static int 682 sastrategy(struct dev_strategy_args *ap) 683 { 684 cdev_t dev = ap->a_head.a_dev; 685 struct bio *bio = ap->a_bio; 686 struct buf *bp = bio->bio_buf; 687 struct cam_periph *periph; 688 struct sa_softc *softc; 689 u_int unit; 690 691 if (SA_IS_CTRL(dev)) { 692 bp->b_error = EINVAL; 693 goto bad; 694 } 695 unit = SAUNIT(dev); 696 periph = cam_extend_get(saperiphs, unit); 697 if (periph == NULL) { 698 bp->b_error = ENXIO; 699 goto bad; 700 } 701 cam_periph_lock(periph); 702 703 softc = (struct sa_softc *)periph->softc; 704 705 if (softc->flags & SA_FLAG_INVALID) { 706 cam_periph_unlock(periph); 707 bp->b_error = ENXIO; 708 goto bad; 709 } 710 711 if (softc->flags & SA_FLAG_TAPE_FROZEN) { 712 cam_periph_unlock(periph); 713 bp->b_error = EPERM; 714 goto bad; 715 } 716 717 /* 718 * This should actually never occur as the write(2) 719 * system call traps attempts to write to a read-only 720 * file descriptor. 721 */ 722 if (bp->b_cmd == BUF_CMD_WRITE && softc->open_rdonly) { 723 cam_periph_unlock(periph); 724 bp->b_error = EBADF; 725 goto bad; 726 } 727 728 if (softc->open_pending_mount) { 729 int error = samount(periph, 0, dev); 730 if (error) { 731 cam_periph_unlock(periph); 732 bp->b_error = ENXIO; 733 goto bad; 734 } 735 saprevent(periph, PR_PREVENT); 736 softc->open_pending_mount = 0; 737 } 738 739 /* 740 * If it's a null transfer, return immediately 741 */ 742 if (bp->b_bcount == 0) { 743 cam_periph_unlock(periph); 744 goto done; 745 } 746 747 /* valid request? */ 748 if (softc->flags & SA_FLAG_FIXED) { 749 /* 750 * Fixed block device. The byte count must 751 * be a multiple of our block size. 752 */ 753 if (((softc->blk_mask != ~0) && 754 ((bp->b_bcount & softc->blk_mask) != 0)) || 755 ((softc->blk_mask == ~0) && 756 ((bp->b_bcount % softc->min_blk) != 0))) { 757 xpt_print(periph->path, "Invalid request. Fixed block " 758 "device requests must be a multiple of %d bytes\n", 759 softc->min_blk); 760 cam_periph_unlock(periph); 761 bp->b_error = EINVAL; 762 goto bad; 763 } 764 } else if ((bp->b_bcount > softc->max_blk) || 765 (bp->b_bcount < softc->min_blk) || 766 (bp->b_bcount & softc->blk_mask) != 0) { 767 768 xpt_print_path(periph->path); 769 kprintf("Invalid request. Variable block " 770 "device requests must be "); 771 if (softc->blk_mask != 0) { 772 kprintf("a multiple of %d ", (0x1 << softc->blk_gran)); 773 } 774 kprintf("between %d and %d bytes\n", softc->min_blk, 775 softc->max_blk); 776 cam_periph_unlock(periph); 777 bp->b_error = EINVAL; 778 goto bad; 779 } 780 781 /* 782 * Place it at the end of the queue. 783 */ 784 bioq_insert_tail(&softc->bio_queue, bio); 785 softc->queue_count++; 786 #if 0 787 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, 788 ("sastrategy: queuing a %ld %s byte %s\n", bp->bio_bcount, 789 (softc->flags & SA_FLAG_FIXED)? "fixed" : "variable", 790 (bp->bio_cmd == BIO_READ)? "read" : "write")); 791 #endif 792 if (softc->queue_count > 1) { 793 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, 794 ("sastrategy: queue count now %d\n", softc->queue_count)); 795 } 796 797 /* 798 * Schedule ourselves for performing the work. 799 */ 800 xpt_schedule(periph, 1); 801 cam_periph_unlock(periph); 802 803 return(0); 804 bad: 805 bp->b_flags |= B_ERROR; 806 done: 807 808 /* 809 * Correctly set the buf to indicate a completed xfer 810 */ 811 bp->b_resid = bp->b_bcount; 812 biodone(bio); 813 return(0); 814 } 815 816 817 #define PENDING_MOUNT_CHECK(softc, periph, dev) \ 818 if (softc->open_pending_mount) { \ 819 error = samount(periph, 0, dev); \ 820 if (error) { \ 821 break; \ 822 } \ 823 saprevent(periph, PR_PREVENT); \ 824 softc->open_pending_mount = 0; \ 825 } 826 827 static int 828 saioctl(struct dev_ioctl_args *ap) 829 { 830 cdev_t dev = ap->a_head.a_dev; 831 caddr_t addr = ap->a_data; 832 struct cam_periph *periph; 833 struct sa_softc *softc; 834 scsi_space_code spaceop; 835 int didholdperiph = 0; 836 int unit; 837 int mode; 838 int error = 0; 839 840 unit = SAUNIT(dev); 841 mode = SAMODE(dev); 842 error = 0; /* shut up gcc */ 843 spaceop = 0; /* shut up gcc */ 844 845 periph = cam_extend_get(saperiphs, unit); 846 if (periph == NULL) 847 return (ENXIO); 848 849 cam_periph_lock(periph); 850 softc = (struct sa_softc *)periph->softc; 851 852 /* 853 * Check for control mode accesses. We allow MTIOCGET and 854 * MTIOCERRSTAT (but need to be the only one open in order 855 * to clear latched status), and MTSETBSIZE, MTSETDNSTY 856 * and MTCOMP (but need to be the only one accessing this 857 * device to run those). 858 */ 859 860 if (SA_IS_CTRL(dev)) { 861 switch (ap->a_cmd) { 862 case MTIOCGETEOTMODEL: 863 case MTIOCGET: 864 break; 865 case MTIOCERRSTAT: 866 /* 867 * If the periph isn't already locked, lock it 868 * so our MTIOCERRSTAT can reset latched error stats. 869 * 870 * If the periph is already locked, skip it because 871 * we're just getting status and it'll be up to the 872 * other thread that has this device open to do 873 * an MTIOCERRSTAT that would clear latched status. 874 */ 875 if ((periph->flags & CAM_PERIPH_LOCKED) == 0) { 876 error = cam_periph_hold(periph, PCATCH); 877 if (error != 0) { 878 return (error); 879 } 880 didholdperiph = 1; 881 } 882 break; 883 884 case MTIOCTOP: 885 { 886 struct mtop *mt = (struct mtop *) addr; 887 888 /* 889 * Check to make sure it's an OP we can perform 890 * with no media inserted. 891 */ 892 switch (mt->mt_op) { 893 case MTSETBSIZ: 894 case MTSETDNSTY: 895 case MTCOMP: 896 mt = NULL; 897 /* FALLTHROUGH */ 898 default: 899 break; 900 } 901 if (mt != NULL) { 902 break; 903 } 904 /* FALLTHROUGH */ 905 } 906 case MTIOCSETEOTMODEL: 907 /* 908 * We need to acquire the peripheral here rather 909 * than at open time because we are sharing writable 910 * access to data structures. 911 */ 912 error = cam_periph_hold(periph, PCATCH); 913 if (error != 0) { 914 return (error); 915 } 916 didholdperiph = 1; 917 break; 918 919 default: 920 return (EINVAL); 921 } 922 } 923 924 /* 925 * Find the device that the user is talking about 926 */ 927 switch (ap->a_cmd) { 928 case MTIOCGET: 929 { 930 struct mtget *g = (struct mtget *)addr; 931 932 /* 933 * If this isn't the control mode device, actually go out 934 * and ask the drive again what it's set to. 935 */ 936 if (!SA_IS_CTRL(dev) && !softc->open_pending_mount) { 937 u_int8_t write_protect = 0; /* silence gcc */ 938 int comp_enabled = 0; /* silence gcc */ 939 int comp_supported = 0; /* silence gcc */ 940 941 error = sagetparams(periph, SA_PARAM_ALL, 942 &softc->media_blksize, &softc->media_density, 943 &softc->media_numblks, &softc->buffer_mode, 944 &write_protect, &softc->speed, &comp_supported, 945 &comp_enabled, &softc->comp_algorithm, NULL); 946 if (error) 947 break; 948 if (write_protect) 949 softc->flags |= SA_FLAG_TAPE_WP; 950 else 951 softc->flags &= ~SA_FLAG_TAPE_WP; 952 softc->flags &= ~(SA_FLAG_COMP_SUPP| 953 SA_FLAG_COMP_ENABLED|SA_FLAG_COMP_UNSUPP); 954 if (comp_supported) { 955 if (softc->saved_comp_algorithm == 0) 956 softc->saved_comp_algorithm = 957 softc->comp_algorithm; 958 softc->flags |= SA_FLAG_COMP_SUPP; 959 if (comp_enabled) 960 softc->flags |= SA_FLAG_COMP_ENABLED; 961 } else 962 softc->flags |= SA_FLAG_COMP_UNSUPP; 963 } 964 bzero(g, sizeof(struct mtget)); 965 g->mt_type = MT_ISAR; 966 if (softc->flags & SA_FLAG_COMP_UNSUPP) { 967 g->mt_comp = MT_COMP_UNSUPP; 968 g->mt_comp0 = MT_COMP_UNSUPP; 969 g->mt_comp1 = MT_COMP_UNSUPP; 970 g->mt_comp2 = MT_COMP_UNSUPP; 971 g->mt_comp3 = MT_COMP_UNSUPP; 972 } else { 973 if ((softc->flags & SA_FLAG_COMP_ENABLED) == 0) { 974 g->mt_comp = MT_COMP_DISABLED; 975 } else { 976 g->mt_comp = softc->comp_algorithm; 977 } 978 g->mt_comp0 = softc->comp_algorithm; 979 g->mt_comp1 = softc->comp_algorithm; 980 g->mt_comp2 = softc->comp_algorithm; 981 g->mt_comp3 = softc->comp_algorithm; 982 } 983 g->mt_density = softc->media_density; 984 g->mt_density0 = softc->media_density; 985 g->mt_density1 = softc->media_density; 986 g->mt_density2 = softc->media_density; 987 g->mt_density3 = softc->media_density; 988 g->mt_blksiz = softc->media_blksize; 989 g->mt_blksiz0 = softc->media_blksize; 990 g->mt_blksiz1 = softc->media_blksize; 991 g->mt_blksiz2 = softc->media_blksize; 992 g->mt_blksiz3 = softc->media_blksize; 993 g->mt_fileno = softc->fileno; 994 g->mt_blkno = softc->blkno; 995 g->mt_dsreg = (short) softc->dsreg; 996 /* 997 * Yes, we know that this is likely to overflow 998 */ 999 if (softc->last_resid_was_io) { 1000 if ((g->mt_resid = (short) softc->last_io_resid) != 0) { 1001 if (SA_IS_CTRL(dev) == 0 || didholdperiph) { 1002 softc->last_io_resid = 0; 1003 } 1004 } 1005 } else { 1006 if ((g->mt_resid = (short)softc->last_ctl_resid) != 0) { 1007 if (SA_IS_CTRL(dev) == 0 || didholdperiph) { 1008 softc->last_ctl_resid = 0; 1009 } 1010 } 1011 } 1012 error = 0; 1013 break; 1014 } 1015 case MTIOCERRSTAT: 1016 { 1017 struct scsi_tape_errors *sep = 1018 &((union mterrstat *)addr)->scsi_errstat; 1019 1020 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 1021 ("saioctl: MTIOCERRSTAT\n")); 1022 1023 bzero(sep, sizeof(*sep)); 1024 sep->io_resid = softc->last_io_resid; 1025 bcopy((caddr_t) &softc->last_io_sense, sep->io_sense, 1026 sizeof (sep->io_sense)); 1027 bcopy((caddr_t) &softc->last_io_cdb, sep->io_cdb, 1028 sizeof (sep->io_cdb)); 1029 sep->ctl_resid = softc->last_ctl_resid; 1030 bcopy((caddr_t) &softc->last_ctl_sense, sep->ctl_sense, 1031 sizeof (sep->ctl_sense)); 1032 bcopy((caddr_t) &softc->last_ctl_cdb, sep->ctl_cdb, 1033 sizeof (sep->ctl_cdb)); 1034 1035 if ((SA_IS_CTRL(dev) == 0 && softc->open_pending_mount) || 1036 didholdperiph) 1037 bzero((caddr_t) &softc->errinfo, 1038 sizeof (softc->errinfo)); 1039 error = 0; 1040 break; 1041 } 1042 case MTIOCTOP: 1043 { 1044 struct mtop *mt; 1045 int count; 1046 1047 PENDING_MOUNT_CHECK(softc, periph, dev); 1048 1049 mt = (struct mtop *)addr; 1050 1051 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 1052 ("saioctl: op=0x%x count=0x%x\n", 1053 mt->mt_op, mt->mt_count)); 1054 1055 count = mt->mt_count; 1056 switch (mt->mt_op) { 1057 case MTWEOF: /* write an end-of-file marker */ 1058 /* 1059 * We don't need to clear the SA_FLAG_TAPE_WRITTEN 1060 * flag because by keeping track of filemarks 1061 * we have last written we know ehether or not 1062 * we need to write more when we close the device. 1063 */ 1064 error = sawritefilemarks(periph, count, FALSE); 1065 break; 1066 case MTWSS: /* write a setmark */ 1067 error = sawritefilemarks(periph, count, TRUE); 1068 break; 1069 case MTBSR: /* backward space record */ 1070 case MTFSR: /* forward space record */ 1071 case MTBSF: /* backward space file */ 1072 case MTFSF: /* forward space file */ 1073 case MTBSS: /* backward space setmark */ 1074 case MTFSS: /* forward space setmark */ 1075 case MTEOD: /* space to end of recorded medium */ 1076 { 1077 int nmarks; 1078 1079 spaceop = SS_FILEMARKS; 1080 nmarks = softc->filemarks; 1081 error = sacheckeod(periph); 1082 if (error) { 1083 xpt_print(periph->path, 1084 "EOD check prior to spacing failed\n"); 1085 softc->flags |= SA_FLAG_EIO_PENDING; 1086 break; 1087 } 1088 nmarks -= softc->filemarks; 1089 switch(mt->mt_op) { 1090 case MTBSR: 1091 count = -count; 1092 /* FALLTHROUGH */ 1093 case MTFSR: 1094 spaceop = SS_BLOCKS; 1095 break; 1096 case MTBSF: 1097 count = -count; 1098 /* FALLTHROUGH */ 1099 case MTFSF: 1100 break; 1101 case MTBSS: 1102 count = -count; 1103 /* FALLTHROUGH */ 1104 case MTFSS: 1105 spaceop = SS_SETMARKS; 1106 break; 1107 case MTEOD: 1108 spaceop = SS_EOD; 1109 count = 0; 1110 nmarks = 0; 1111 break; 1112 default: 1113 error = EINVAL; 1114 break; 1115 } 1116 if (error) 1117 break; 1118 1119 nmarks = softc->filemarks; 1120 /* 1121 * XXX: Why are we checking again? 1122 */ 1123 error = sacheckeod(periph); 1124 if (error) 1125 break; 1126 nmarks -= softc->filemarks; 1127 error = saspace(periph, count - nmarks, spaceop); 1128 /* 1129 * At this point, clear that we've written the tape 1130 * and that we've written any filemarks. We really 1131 * don't know what the applications wishes to do next- 1132 * the sacheckeod's will make sure we terminated the 1133 * tape correctly if we'd been writing, but the next 1134 * action the user application takes will set again 1135 * whether we need to write filemarks. 1136 */ 1137 softc->flags &= 1138 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN); 1139 softc->filemarks = 0; 1140 break; 1141 } 1142 case MTREW: /* rewind */ 1143 PENDING_MOUNT_CHECK(softc, periph, dev); 1144 sacheckeod(periph); 1145 error = sarewind(periph); 1146 /* see above */ 1147 softc->flags &= 1148 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN); 1149 softc->flags &= ~SA_FLAG_ERR_PENDING; 1150 softc->filemarks = 0; 1151 break; 1152 case MTERASE: /* erase */ 1153 PENDING_MOUNT_CHECK(softc, periph, dev); 1154 error = saerase(periph, count); 1155 softc->flags &= 1156 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN); 1157 softc->flags &= ~SA_FLAG_ERR_PENDING; 1158 break; 1159 case MTRETENS: /* re-tension tape */ 1160 PENDING_MOUNT_CHECK(softc, periph, dev); 1161 error = saretension(periph); 1162 softc->flags &= 1163 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN); 1164 softc->flags &= ~SA_FLAG_ERR_PENDING; 1165 break; 1166 case MTOFFL: /* rewind and put the drive offline */ 1167 1168 PENDING_MOUNT_CHECK(softc, periph, dev); 1169 1170 sacheckeod(periph); 1171 /* see above */ 1172 softc->flags &= ~SA_FLAG_TAPE_WRITTEN; 1173 softc->filemarks = 0; 1174 1175 error = sarewind(periph); 1176 /* clear the frozen flag anyway */ 1177 softc->flags &= ~SA_FLAG_TAPE_FROZEN; 1178 1179 /* 1180 * Be sure to allow media removal before ejecting. 1181 */ 1182 1183 saprevent(periph, PR_ALLOW); 1184 if (error == 0) { 1185 error = saloadunload(periph, FALSE); 1186 if (error == 0) { 1187 softc->flags &= ~SA_FLAG_TAPE_MOUNTED; 1188 } 1189 } 1190 break; 1191 1192 case MTNOP: /* no operation, sets status only */ 1193 case MTCACHE: /* enable controller cache */ 1194 case MTNOCACHE: /* disable controller cache */ 1195 error = 0; 1196 break; 1197 1198 case MTSETBSIZ: /* Set block size for device */ 1199 1200 PENDING_MOUNT_CHECK(softc, periph, dev); 1201 1202 error = sasetparams(periph, SA_PARAM_BLOCKSIZE, count, 1203 0, 0, 0); 1204 if (error == 0) { 1205 softc->last_media_blksize = 1206 softc->media_blksize; 1207 softc->media_blksize = count; 1208 if (count) { 1209 softc->flags |= SA_FLAG_FIXED; 1210 if (powerof2(count)) { 1211 softc->blk_shift = 1212 ffs(count) - 1; 1213 softc->blk_mask = count - 1; 1214 } else { 1215 softc->blk_mask = ~0; 1216 softc->blk_shift = 0; 1217 } 1218 /* 1219 * Make the user's desire 'persistent'. 1220 */ 1221 softc->quirks &= ~SA_QUIRK_VARIABLE; 1222 softc->quirks |= SA_QUIRK_FIXED; 1223 } else { 1224 softc->flags &= ~SA_FLAG_FIXED; 1225 if (softc->max_blk == 0) { 1226 softc->max_blk = ~0; 1227 } 1228 softc->blk_shift = 0; 1229 if (softc->blk_gran != 0) { 1230 softc->blk_mask = 1231 softc->blk_gran - 1; 1232 } else { 1233 softc->blk_mask = 0; 1234 } 1235 /* 1236 * Make the user's desire 'persistent'. 1237 */ 1238 softc->quirks |= SA_QUIRK_VARIABLE; 1239 softc->quirks &= ~SA_QUIRK_FIXED; 1240 } 1241 } 1242 break; 1243 case MTSETDNSTY: /* Set density for device and mode */ 1244 PENDING_MOUNT_CHECK(softc, periph, dev); 1245 1246 if (count > UCHAR_MAX) { 1247 error = EINVAL; 1248 break; 1249 } else { 1250 error = sasetparams(periph, SA_PARAM_DENSITY, 1251 0, count, 0, 0); 1252 } 1253 break; 1254 case MTCOMP: /* enable compression */ 1255 PENDING_MOUNT_CHECK(softc, periph, dev); 1256 /* 1257 * Some devices don't support compression, and 1258 * don't like it if you ask them for the 1259 * compression page. 1260 */ 1261 if ((softc->quirks & SA_QUIRK_NOCOMP) || 1262 (softc->flags & SA_FLAG_COMP_UNSUPP)) { 1263 error = ENODEV; 1264 break; 1265 } 1266 error = sasetparams(periph, SA_PARAM_COMPRESSION, 1267 0, 0, count, SF_NO_PRINT); 1268 break; 1269 default: 1270 error = EINVAL; 1271 } 1272 break; 1273 } 1274 case MTIOCIEOT: 1275 case MTIOCEEOT: 1276 error = 0; 1277 break; 1278 case MTIOCRDSPOS: 1279 PENDING_MOUNT_CHECK(softc, periph, dev); 1280 error = sardpos(periph, 0, (u_int32_t *) addr); 1281 break; 1282 case MTIOCRDHPOS: 1283 PENDING_MOUNT_CHECK(softc, periph, dev); 1284 error = sardpos(periph, 1, (u_int32_t *) addr); 1285 break; 1286 case MTIOCSLOCATE: 1287 PENDING_MOUNT_CHECK(softc, periph, dev); 1288 error = sasetpos(periph, 0, (u_int32_t *) addr); 1289 break; 1290 case MTIOCHLOCATE: 1291 PENDING_MOUNT_CHECK(softc, periph, dev); 1292 error = sasetpos(periph, 1, (u_int32_t *) addr); 1293 break; 1294 case MTIOCGETEOTMODEL: 1295 error = 0; 1296 if (softc->quirks & SA_QUIRK_1FM) 1297 mode = 1; 1298 else 1299 mode = 2; 1300 *((u_int32_t *) addr) = mode; 1301 break; 1302 case MTIOCSETEOTMODEL: 1303 error = 0; 1304 switch (*((u_int32_t *) addr)) { 1305 case 1: 1306 softc->quirks &= ~SA_QUIRK_2FM; 1307 softc->quirks |= SA_QUIRK_1FM; 1308 break; 1309 case 2: 1310 softc->quirks &= ~SA_QUIRK_1FM; 1311 softc->quirks |= SA_QUIRK_2FM; 1312 break; 1313 default: 1314 error = EINVAL; 1315 break; 1316 } 1317 break; 1318 default: 1319 error = cam_periph_ioctl(periph, ap->a_cmd, addr, saerror); 1320 break; 1321 } 1322 1323 /* 1324 * Check to see if we cleared a frozen state 1325 */ 1326 if (error == 0 && (softc->flags & SA_FLAG_TAPE_FROZEN)) { 1327 switch(ap->a_cmd) { 1328 case MTIOCRDSPOS: 1329 case MTIOCRDHPOS: 1330 case MTIOCSLOCATE: 1331 case MTIOCHLOCATE: 1332 softc->fileno = (daddr_t) -1; 1333 softc->blkno = (daddr_t) -1; 1334 softc->flags &= ~SA_FLAG_TAPE_FROZEN; 1335 xpt_print(periph->path, 1336 "tape state now unfrozen.\n"); 1337 break; 1338 default: 1339 break; 1340 } 1341 } 1342 if (didholdperiph) 1343 cam_periph_unhold(periph, 1); 1344 else 1345 cam_periph_unlock(periph); 1346 return (error); 1347 } 1348 1349 static void 1350 sainit(void) 1351 { 1352 cam_status status; 1353 1354 /* 1355 * Create our extend array for storing the devices we attach to. 1356 */ 1357 saperiphs = cam_extend_new(); 1358 if (saperiphs == NULL) { 1359 kprintf("sa: Failed to alloc extend array!\n"); 1360 return; 1361 } 1362 1363 /* 1364 * Install a global async callback. 1365 */ 1366 status = xpt_register_async(AC_FOUND_DEVICE, saasync, NULL, NULL); 1367 1368 if (status != CAM_REQ_CMP) { 1369 kprintf("sa: Failed to attach master async callback " 1370 "due to status 0x%x!\n", status); 1371 } 1372 } 1373 1374 static void 1375 saoninvalidate(struct cam_periph *periph) 1376 { 1377 struct sa_softc *softc; 1378 struct buf *q_bp; 1379 struct bio *q_bio; 1380 1381 softc = (struct sa_softc *)periph->softc; 1382 1383 /* 1384 * De-register any async callbacks. 1385 */ 1386 xpt_register_async(0, saasync, periph, periph->path); 1387 1388 softc->flags |= SA_FLAG_INVALID; 1389 1390 /* 1391 * Return all queued I/O with ENXIO. 1392 * XXX Handle any transactions queued to the card 1393 * with XPT_ABORT_CCB. 1394 */ 1395 while ((q_bio = bioq_takefirst(&softc->bio_queue)) != NULL) { 1396 q_bp = q_bio->bio_buf; 1397 q_bp->b_resid = q_bp->b_bcount; 1398 q_bp->b_error = ENXIO; 1399 q_bp->b_flags |= B_ERROR; 1400 biodone(q_bio); 1401 } 1402 softc->queue_count = 0; 1403 1404 xpt_print(periph->path, "lost device\n"); 1405 1406 } 1407 1408 static void 1409 sacleanup(struct cam_periph *periph) 1410 { 1411 struct sa_softc *softc; 1412 1413 softc = (struct sa_softc *)periph->softc; 1414 1415 devstat_remove_entry(&softc->device_stats); 1416 1417 cam_extend_release(saperiphs, periph->unit_number); 1418 xpt_print(periph->path, "removing device entry\n"); 1419 dev_ops_remove_minor(&sa_ops, /*SA_UNITMASK,*/ SA_UNIT(periph->unit_number)); 1420 kfree(softc, M_SCSISA); 1421 } 1422 1423 static void 1424 saasync(void *callback_arg, u_int32_t code, 1425 struct cam_path *path, void *arg) 1426 { 1427 struct cam_periph *periph; 1428 1429 periph = (struct cam_periph *)callback_arg; 1430 switch (code) { 1431 case AC_FOUND_DEVICE: 1432 { 1433 struct ccb_getdev *cgd; 1434 cam_status status; 1435 1436 cgd = (struct ccb_getdev *)arg; 1437 if (cgd == NULL) 1438 break; 1439 1440 if (SID_TYPE(&cgd->inq_data) != T_SEQUENTIAL) 1441 break; 1442 1443 /* 1444 * Allocate a peripheral instance for 1445 * this device and start the probe 1446 * process. 1447 */ 1448 status = cam_periph_alloc(saregister, saoninvalidate, 1449 sacleanup, sastart, 1450 "sa", CAM_PERIPH_BIO, cgd->ccb_h.path, 1451 saasync, AC_FOUND_DEVICE, cgd); 1452 1453 if (status != CAM_REQ_CMP 1454 && status != CAM_REQ_INPROG) 1455 kprintf("saasync: Unable to probe new device " 1456 "due to status 0x%x\n", status); 1457 break; 1458 } 1459 default: 1460 cam_periph_async(periph, code, path, arg); 1461 break; 1462 } 1463 } 1464 1465 static cam_status 1466 saregister(struct cam_periph *periph, void *arg) 1467 { 1468 struct sa_softc *softc; 1469 struct ccb_getdev *cgd; 1470 caddr_t match; 1471 int i; 1472 1473 cgd = (struct ccb_getdev *)arg; 1474 if (periph == NULL) { 1475 kprintf("saregister: periph was NULL!!\n"); 1476 return (CAM_REQ_CMP_ERR); 1477 } 1478 1479 if (cgd == NULL) { 1480 kprintf("saregister: no getdev CCB, can't register device\n"); 1481 return (CAM_REQ_CMP_ERR); 1482 } 1483 1484 softc = kmalloc(sizeof (*softc), M_SCSISA, M_INTWAIT | M_ZERO); 1485 softc->scsi_rev = SID_ANSI_REV(&cgd->inq_data); 1486 softc->state = SA_STATE_NORMAL; 1487 softc->fileno = (daddr_t) -1; 1488 softc->blkno = (daddr_t) -1; 1489 1490 bioq_init(&softc->bio_queue); 1491 periph->softc = softc; 1492 cam_extend_set(saperiphs, periph->unit_number, periph); 1493 1494 /* 1495 * See if this device has any quirks. 1496 */ 1497 match = cam_quirkmatch((caddr_t)&cgd->inq_data, 1498 (caddr_t)sa_quirk_table, 1499 NELEM(sa_quirk_table), 1500 sizeof(*sa_quirk_table), scsi_inquiry_match); 1501 1502 if (match != NULL) { 1503 softc->quirks = ((struct sa_quirk_entry *)match)->quirks; 1504 softc->last_media_blksize = 1505 ((struct sa_quirk_entry *)match)->prefblk; 1506 #ifdef CAMDEBUG 1507 xpt_print(periph->path, "found quirk entry %d\n", 1508 (int) (((struct sa_quirk_entry *) match) - sa_quirk_table)); 1509 #endif 1510 } else 1511 softc->quirks = SA_QUIRK_NONE; 1512 1513 /* 1514 * The SA driver supports a blocksize, but we don't know the 1515 * blocksize until we media is inserted. So, set a flag to 1516 * indicate that the blocksize is unavailable right now. 1517 */ 1518 cam_periph_unlock(periph); 1519 devstat_add_entry(&softc->device_stats, "sa", periph->unit_number, 0, 1520 DEVSTAT_BS_UNAVAILABLE, SID_TYPE(&cgd->inq_data) | 1521 DEVSTAT_TYPE_IF_SCSI, DEVSTAT_PRIORITY_TAPE); 1522 1523 make_dev(&sa_ops, SAMINOR(SA_CTLDEV, 1524 periph->unit_number, 0, SA_ATYPE_R), UID_ROOT, GID_OPERATOR, 1525 0660, "%s%d.ctl", periph->periph_name, periph->unit_number); 1526 1527 make_dev(&sa_ops, SAMINOR(SA_NOT_CTLDEV, 1528 periph->unit_number, 0, SA_ATYPE_R), UID_ROOT, GID_OPERATOR, 1529 0660, "%s%d", periph->periph_name, periph->unit_number); 1530 1531 make_dev(&sa_ops, SAMINOR(SA_NOT_CTLDEV, 1532 periph->unit_number, 0, SA_ATYPE_NR), UID_ROOT, GID_OPERATOR, 1533 0660, "n%s%d", periph->periph_name, periph->unit_number); 1534 1535 make_dev(&sa_ops, SAMINOR(SA_NOT_CTLDEV, 1536 periph->unit_number, 0, SA_ATYPE_ER), UID_ROOT, GID_OPERATOR, 1537 0660, "e%s%d", periph->periph_name, periph->unit_number); 1538 1539 for (i = 0; i < SA_NUM_MODES; i++) { 1540 1541 make_dev(&sa_ops, 1542 SAMINOR(SA_NOT_CTLDEV, periph->unit_number, i, SA_ATYPE_R), 1543 UID_ROOT, GID_OPERATOR, 0660, "%s%d.%d", 1544 periph->periph_name, periph->unit_number, i); 1545 1546 make_dev(&sa_ops, 1547 SAMINOR(SA_NOT_CTLDEV, periph->unit_number, i, SA_ATYPE_NR), 1548 UID_ROOT, GID_OPERATOR, 0660, "n%s%d.%d", 1549 periph->periph_name, periph->unit_number, i); 1550 1551 1552 make_dev(&sa_ops, 1553 SAMINOR(SA_NOT_CTLDEV, periph->unit_number, i, SA_ATYPE_ER), 1554 UID_ROOT, GID_OPERATOR, 0660, "e%s%d.%d", 1555 periph->periph_name, periph->unit_number, i); 1556 } 1557 cam_periph_lock(periph); 1558 1559 /* 1560 * Add an async callback so that we get 1561 * notified if this device goes away. 1562 */ 1563 xpt_register_async(AC_LOST_DEVICE, saasync, periph, periph->path); 1564 1565 xpt_announce_periph(periph, NULL); 1566 1567 return (CAM_REQ_CMP); 1568 } 1569 1570 static void 1571 sastart(struct cam_periph *periph, union ccb *start_ccb) 1572 { 1573 struct sa_softc *softc; 1574 1575 softc = (struct sa_softc *)periph->softc; 1576 1577 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sastart\n")); 1578 1579 1580 switch (softc->state) { 1581 case SA_STATE_NORMAL: 1582 { 1583 /* Pull a buffer from the queue and get going on it */ 1584 struct buf *bp; 1585 struct bio *bio; 1586 1587 /* 1588 * See if there is a buf with work for us to do.. 1589 */ 1590 bio = bioq_first(&softc->bio_queue); 1591 if (periph->immediate_priority <= periph->pinfo.priority) { 1592 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 1593 ("queuing for immediate ccb\n")); 1594 Set_CCB_Type(start_ccb, SA_CCB_WAITING); 1595 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 1596 periph_links.sle); 1597 periph->immediate_priority = CAM_PRIORITY_NONE; 1598 wakeup(&periph->ccb_list); 1599 } else if (bio == NULL) { 1600 xpt_release_ccb(start_ccb); 1601 } else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) { 1602 struct bio *done_bio; 1603 again: 1604 softc->queue_count--; 1605 bioq_remove(&softc->bio_queue, bio); 1606 bp = bio->bio_buf; 1607 bp->b_resid = bp->b_bcount; 1608 done_bio = bio; 1609 if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) { 1610 /* 1611 * We now just clear errors in this case 1612 * and let the residual be the notifier. 1613 */ 1614 bp->b_error = 0; 1615 } else if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) { 1616 /* 1617 * This can only happen if we're reading 1618 * in fixed length mode. In this case, 1619 * we dump the rest of the list the 1620 * same way. 1621 */ 1622 bp->b_error = 0; 1623 if (bioq_first(&softc->bio_queue) != NULL) { 1624 biodone(done_bio); 1625 goto again; 1626 } 1627 } else if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) { 1628 bp->b_error = EIO; 1629 bp->b_flags |= B_ERROR; 1630 } 1631 bio = bioq_first(&softc->bio_queue); 1632 /* 1633 * Only if we have no other buffers queued up 1634 * do we clear the pending error flag. 1635 */ 1636 if (bio == NULL) 1637 softc->flags &= ~SA_FLAG_ERR_PENDING; 1638 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, 1639 ("sastart- ERR_PENDING now 0x%x, bio is %sNULL, " 1640 "%d more buffers queued up\n", 1641 (softc->flags & SA_FLAG_ERR_PENDING), 1642 (bio != NULL)? "not " : " ", softc->queue_count)); 1643 xpt_release_ccb(start_ccb); 1644 biodone(done_bio); 1645 } else { 1646 u_int32_t length; 1647 1648 bioq_remove(&softc->bio_queue, bio); 1649 bp = bio->bio_buf; 1650 softc->queue_count--; 1651 1652 if ((softc->flags & SA_FLAG_FIXED) != 0) { 1653 if (softc->blk_shift != 0) { 1654 length = 1655 bp->b_bcount >> softc->blk_shift; 1656 } else if (softc->media_blksize != 0) { 1657 length = 1658 bp->b_bcount / softc->media_blksize; 1659 } else { 1660 bp->b_error = EIO; 1661 xpt_print(periph->path, "zero blocksize" 1662 " for FIXED length writes?\n"); 1663 biodone(bio); 1664 break; 1665 } 1666 #if 0 1667 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, 1668 ("issuing a %d fixed record %s\n", 1669 length, (bp->bio_cmd == BIO_READ)? "read" : 1670 "write")); 1671 #endif 1672 } else { 1673 length = bp->b_bcount; 1674 #if 0 1675 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, 1676 ("issuing a %d variable byte %s\n", 1677 length, (bp->bio_cmd == BIO_READ)? "read" : 1678 "write")); 1679 #endif 1680 } 1681 devstat_start_transaction(&softc->device_stats); 1682 /* 1683 * Some people have theorized that we should 1684 * suppress illegal length indication if we are 1685 * running in variable block mode so that we don't 1686 * have to request sense every time our requested 1687 * block size is larger than the written block. 1688 * The residual information from the ccb allows 1689 * us to identify this situation anyway. The only 1690 * problem with this is that we will not get 1691 * information about blocks that are larger than 1692 * our read buffer unless we set the block size 1693 * in the mode page to something other than 0. 1694 * 1695 * I believe that this is a non-issue. If user apps 1696 * don't adjust their read size to match our record 1697 * size, that's just life. Anyway, the typical usage 1698 * would be to issue, e.g., 64KB reads and occasionally 1699 * have to do deal with 512 byte or 1KB intermediate 1700 * records. 1701 */ 1702 softc->dsreg = (bp->b_cmd == BUF_CMD_READ) ? 1703 MTIO_DSREG_RD : MTIO_DSREG_WR; 1704 scsi_sa_read_write(&start_ccb->csio, 0, sadone, 1705 MSG_SIMPLE_Q_TAG, (bp->b_cmd == BUF_CMD_READ) != 0, 1706 FALSE, (softc->flags & SA_FLAG_FIXED) != 0, 1707 length, bp->b_data, bp->b_bcount, SSD_FULL_SIZE, 1708 IO_TIMEOUT); 1709 start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED; 1710 Set_CCB_Type(start_ccb, SA_CCB_BUFFER_IO); 1711 start_ccb->ccb_h.ccb_bio = bio; 1712 bio = bioq_first(&softc->bio_queue); 1713 xpt_action(start_ccb); 1714 } 1715 1716 if (bio != NULL) { 1717 /* Have more work to do, so ensure we stay scheduled */ 1718 xpt_schedule(periph, 1); 1719 } 1720 break; 1721 } 1722 case SA_STATE_ABNORMAL: 1723 default: 1724 panic("state 0x%x in sastart", softc->state); 1725 break; 1726 } 1727 } 1728 1729 1730 static void 1731 sadone(struct cam_periph *periph, union ccb *done_ccb) 1732 { 1733 struct sa_softc *softc; 1734 struct ccb_scsiio *csio; 1735 1736 softc = (struct sa_softc *)periph->softc; 1737 csio = &done_ccb->csio; 1738 1739 switch (CCB_Type(csio)) { 1740 case SA_CCB_BUFFER_IO: 1741 { 1742 struct buf *bp; 1743 struct bio *bio; 1744 int error; 1745 1746 softc->dsreg = MTIO_DSREG_REST; 1747 bio = (struct bio *)done_ccb->ccb_h.ccb_bio; 1748 bp = bio->bio_buf; 1749 error = 0; 1750 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1751 if ((error = saerror(done_ccb, 0, 0)) == ERESTART) { 1752 /* 1753 * A retry was scheduled, so just return. 1754 */ 1755 return; 1756 } 1757 } 1758 1759 if (error == EIO) { 1760 struct buf *q_bp; 1761 struct bio *q_bio; 1762 1763 /* 1764 * Catastrophic error. Mark the tape as frozen 1765 * (we no longer know tape position). 1766 * 1767 * Return all queued I/O with EIO, and unfreeze 1768 * our queue so that future transactions that 1769 * attempt to fix this problem can get to the 1770 * device. 1771 * 1772 */ 1773 1774 softc->flags |= SA_FLAG_TAPE_FROZEN; 1775 while ((q_bio = bioq_takefirst(&softc->bio_queue)) != NULL) { 1776 q_bp = q_bio->bio_buf; 1777 q_bp->b_resid = q_bp->b_bcount; 1778 q_bp->b_error = EIO; 1779 q_bp->b_flags |= B_ERROR; 1780 biodone(q_bio); 1781 } 1782 } 1783 if (error != 0) { 1784 bp->b_resid = bp->b_bcount; 1785 bp->b_error = error; 1786 bp->b_flags |= B_ERROR; 1787 /* 1788 * In the error case, position is updated in saerror. 1789 */ 1790 } else { 1791 bp->b_resid = csio->resid; 1792 bp->b_error = 0; 1793 if (csio->resid != 0) { 1794 bp->b_flags |= B_ERROR; 1795 } 1796 if (bp->b_cmd != BUF_CMD_READ) { 1797 softc->flags |= SA_FLAG_TAPE_WRITTEN; 1798 softc->filemarks = 0; 1799 } 1800 if (!(csio->ccb_h.ccb_pflags & SA_POSITION_UPDATED) && 1801 (softc->blkno != (daddr_t) -1)) { 1802 if ((softc->flags & SA_FLAG_FIXED) != 0) { 1803 u_int32_t l; 1804 if (softc->blk_shift != 0) { 1805 l = bp->b_bcount >> 1806 softc->blk_shift; 1807 } else { 1808 l = bp->b_bcount / 1809 softc->media_blksize; 1810 } 1811 softc->blkno += (daddr_t) l; 1812 } else { 1813 softc->blkno++; 1814 } 1815 } 1816 } 1817 /* 1818 * If we had an error (immediate or pending), 1819 * release the device queue now. 1820 */ 1821 if (error || (softc->flags & SA_FLAG_ERR_PENDING)) 1822 cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0); 1823 #ifdef CAMDEBUG 1824 if (error || bp->b_resid) { 1825 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, 1826 ("error %d resid %d count %d\n", error, 1827 bp->b_resid, bp->b_bcount)); 1828 } 1829 #endif 1830 devstat_end_transaction_buf(&softc->device_stats, bp); 1831 biodone(bio); 1832 break; 1833 } 1834 case SA_CCB_WAITING: 1835 { 1836 /* Caller will release the CCB */ 1837 wakeup(&done_ccb->ccb_h.cbfcnp); 1838 return; 1839 } 1840 case SA_CCB_POLLED: 1841 /* polled, caller releases ccb */ 1842 wakeup(&done_ccb->ccb_h.cbfcnp); 1843 return; 1844 } 1845 xpt_release_ccb(done_ccb); 1846 } 1847 1848 /* 1849 * Mount the tape (make sure it's ready for I/O). 1850 * 1851 * oflags can be checked for 'kind' of open (read-only check) - later 1852 * dev can be checked for a control-mode or compression open - later 1853 */ 1854 static int 1855 samount(struct cam_periph *periph, __unused int oflags, __unused cdev_t dev) 1856 { 1857 struct sa_softc *softc; 1858 union ccb *ccb; 1859 int error; 1860 1861 softc = (struct sa_softc *)periph->softc; 1862 1863 /* 1864 * This should determine if something has happend since the last 1865 * open/mount that would invalidate the mount. We do *not* want 1866 * to retry this command- we just want the status. But we only 1867 * do this if we're mounted already- if we're not mounted, 1868 * we don't care about the unit read state and can instead use 1869 * this opportunity to attempt to reserve the tape unit. 1870 */ 1871 1872 if (softc->flags & SA_FLAG_TAPE_MOUNTED) { 1873 ccb = cam_periph_getccb(periph, 1); 1874 Set_CCB_Type(ccb, SA_CCB_POLLED); 1875 1876 scsi_test_unit_ready(&ccb->csio, 0, sadone, 1877 MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, 1878 IO_TIMEOUT); 1879 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 1880 &softc->device_stats); 1881 QFRLS(ccb); 1882 if (error == ENXIO) { 1883 softc->flags &= ~SA_FLAG_TAPE_MOUNTED; 1884 scsi_test_unit_ready(&ccb->csio, 0, sadone, 1885 MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, IO_TIMEOUT); 1886 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 1887 &softc->device_stats); 1888 QFRLS(ccb); 1889 } else if (error) { 1890 /* 1891 * We don't need to freeze the tape because we 1892 * will now attempt to rewind/load it. 1893 */ 1894 softc->flags &= ~SA_FLAG_TAPE_MOUNTED; 1895 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) { 1896 xpt_print(periph->path, 1897 "error %d on TUR in samount\n", error); 1898 } 1899 } 1900 } else { 1901 error = sareservereleaseunit(periph, TRUE); 1902 if (error) { 1903 return (error); 1904 } 1905 ccb = cam_periph_getccb(periph, 1); 1906 Set_CCB_Type(ccb, SA_CCB_POLLED); 1907 scsi_test_unit_ready(&ccb->csio, 0, sadone, 1908 MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, 1909 IO_TIMEOUT); 1910 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 1911 &softc->device_stats); 1912 QFRLS(ccb); 1913 } 1914 1915 if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) { 1916 struct scsi_read_block_limits_data *rblim = NULL; 1917 int comp_enabled = 0; /* silence gcc */ 1918 int comp_supported = 0; /* silence gcc */ 1919 u_int8_t write_protect = 0; /* silence gcc */ 1920 u_int8_t guessing = 0; 1921 1922 /* 1923 * Clear out old state. 1924 */ 1925 softc->flags &= ~(SA_FLAG_TAPE_WP|SA_FLAG_TAPE_WRITTEN| 1926 SA_FLAG_ERR_PENDING|SA_FLAG_COMP_ENABLED| 1927 SA_FLAG_COMP_SUPP|SA_FLAG_COMP_UNSUPP); 1928 softc->filemarks = 0; 1929 1930 /* 1931 * *Very* first off, make sure we're loaded to BOT. 1932 */ 1933 scsi_load_unload(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE, 1934 FALSE, FALSE, 1, SSD_FULL_SIZE, REWIND_TIMEOUT); 1935 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 1936 &softc->device_stats); 1937 QFRLS(ccb); 1938 1939 /* 1940 * In case this doesn't work, do a REWIND instead 1941 */ 1942 if (error) { 1943 scsi_rewind(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, 1944 FALSE, SSD_FULL_SIZE, REWIND_TIMEOUT); 1945 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 1946 &softc->device_stats); 1947 QFRLS(ccb); 1948 } 1949 if (error) { 1950 xpt_release_ccb(ccb); 1951 goto exit; 1952 } 1953 1954 /* 1955 * Do a dummy test read to force access to the 1956 * media so that the drive will really know what's 1957 * there. We actually don't really care what the 1958 * blocksize on tape is and don't expect to really 1959 * read a full record. 1960 */ 1961 rblim = kmalloc(8192, M_SCSISA, M_INTWAIT); 1962 1963 if ((softc->quirks & SA_QUIRK_NODREAD) == 0) { 1964 scsi_sa_read_write(&ccb->csio, 0, sadone, 1965 MSG_SIMPLE_Q_TAG, 1, FALSE, 0, 8192, 1966 (void *) rblim, 8192, SSD_FULL_SIZE, 1967 IO_TIMEOUT); 1968 cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 1969 &softc->device_stats); 1970 QFRLS(ccb); 1971 scsi_rewind(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, 1972 FALSE, SSD_FULL_SIZE, REWIND_TIMEOUT); 1973 error = cam_periph_runccb(ccb, saerror, CAM_RETRY_SELTO, 1974 SF_NO_PRINT | SF_RETRY_UA, 1975 &softc->device_stats); 1976 QFRLS(ccb); 1977 if (error) { 1978 xpt_print(periph->path, 1979 "unable to rewind after test read\n"); 1980 xpt_release_ccb(ccb); 1981 goto exit; 1982 } 1983 } 1984 1985 /* 1986 * Next off, determine block limits. 1987 */ 1988 scsi_read_block_limits(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, 1989 rblim, SSD_FULL_SIZE, SCSIOP_TIMEOUT); 1990 1991 error = cam_periph_runccb(ccb, saerror, CAM_RETRY_SELTO, 1992 SF_NO_PRINT | SF_RETRY_UA, &softc->device_stats); 1993 1994 QFRLS(ccb); 1995 xpt_release_ccb(ccb); 1996 1997 if (error != 0) { 1998 /* 1999 * If it's less than SCSI-2, READ BLOCK LIMITS is not 2000 * a MANDATORY command. Anyway- it doesn't matter- 2001 * we can proceed anyway. 2002 */ 2003 softc->blk_gran = 0; 2004 softc->max_blk = ~0; 2005 softc->min_blk = 0; 2006 } else { 2007 if (softc->scsi_rev >= SCSI_REV_SPC) { 2008 softc->blk_gran = RBL_GRAN(rblim); 2009 } else { 2010 softc->blk_gran = 0; 2011 } 2012 /* 2013 * We take max_blk == min_blk to mean a default to 2014 * fixed mode- but note that whatever we get out of 2015 * sagetparams below will actually determine whether 2016 * we are actually *in* fixed mode. 2017 */ 2018 softc->max_blk = scsi_3btoul(rblim->maximum); 2019 softc->min_blk = scsi_2btoul(rblim->minimum); 2020 2021 2022 } 2023 /* 2024 * Next, perform a mode sense to determine 2025 * current density, blocksize, compression etc. 2026 */ 2027 error = sagetparams(periph, SA_PARAM_ALL, 2028 &softc->media_blksize, 2029 &softc->media_density, 2030 &softc->media_numblks, 2031 &softc->buffer_mode, &write_protect, 2032 &softc->speed, &comp_supported, 2033 &comp_enabled, &softc->comp_algorithm, 2034 NULL); 2035 2036 if (error != 0) { 2037 /* 2038 * We could work a little harder here. We could 2039 * adjust our attempts to get information. It 2040 * might be an ancient tape drive. If someone 2041 * nudges us, we'll do that. 2042 */ 2043 goto exit; 2044 } 2045 2046 /* 2047 * If no quirk has determined that this is a device that is 2048 * preferred to be in fixed or variable mode, now is the time 2049 * to find out. 2050 */ 2051 if ((softc->quirks & (SA_QUIRK_FIXED|SA_QUIRK_VARIABLE)) == 0) { 2052 guessing = 1; 2053 /* 2054 * This could be expensive to find out. Luckily we 2055 * only need to do this once. If we start out in 2056 * 'default' mode, try and set ourselves to one 2057 * of the densities that would determine a wad 2058 * of other stuff. Go from highest to lowest. 2059 */ 2060 if (softc->media_density == SCSI_DEFAULT_DENSITY) { 2061 int i; 2062 static u_int8_t ctry[] = { 2063 SCSI_DENSITY_HALFINCH_PE, 2064 SCSI_DENSITY_HALFINCH_6250C, 2065 SCSI_DENSITY_HALFINCH_6250, 2066 SCSI_DENSITY_HALFINCH_1600, 2067 SCSI_DENSITY_HALFINCH_800, 2068 SCSI_DENSITY_QIC_4GB, 2069 SCSI_DENSITY_QIC_2GB, 2070 SCSI_DENSITY_QIC_525_320, 2071 SCSI_DENSITY_QIC_150, 2072 SCSI_DENSITY_QIC_120, 2073 SCSI_DENSITY_QIC_24, 2074 SCSI_DENSITY_QIC_11_9TRK, 2075 SCSI_DENSITY_QIC_11_4TRK, 2076 SCSI_DENSITY_QIC_1320, 2077 SCSI_DENSITY_QIC_3080, 2078 0 2079 }; 2080 for (i = 0; ctry[i]; i++) { 2081 error = sasetparams(periph, 2082 SA_PARAM_DENSITY, 0, ctry[i], 2083 0, SF_NO_PRINT); 2084 if (error == 0) { 2085 softc->media_density = ctry[i]; 2086 break; 2087 } 2088 } 2089 } 2090 switch (softc->media_density) { 2091 case SCSI_DENSITY_QIC_11_4TRK: 2092 case SCSI_DENSITY_QIC_11_9TRK: 2093 case SCSI_DENSITY_QIC_24: 2094 case SCSI_DENSITY_QIC_120: 2095 case SCSI_DENSITY_QIC_150: 2096 case SCSI_DENSITY_QIC_525_320: 2097 case SCSI_DENSITY_QIC_1320: 2098 case SCSI_DENSITY_QIC_3080: 2099 softc->quirks &= ~SA_QUIRK_2FM; 2100 softc->quirks |= SA_QUIRK_FIXED|SA_QUIRK_1FM; 2101 softc->last_media_blksize = 512; 2102 break; 2103 case SCSI_DENSITY_QIC_4GB: 2104 case SCSI_DENSITY_QIC_2GB: 2105 softc->quirks &= ~SA_QUIRK_2FM; 2106 softc->quirks |= SA_QUIRK_FIXED|SA_QUIRK_1FM; 2107 softc->last_media_blksize = 1024; 2108 break; 2109 default: 2110 softc->last_media_blksize = 2111 softc->media_blksize; 2112 softc->quirks |= SA_QUIRK_VARIABLE; 2113 break; 2114 } 2115 } 2116 2117 /* 2118 * If no quirk has determined that this is a device that needs 2119 * to have 2 Filemarks at EOD, now is the time to find out. 2120 */ 2121 2122 if ((softc->quirks & SA_QUIRK_2FM) == 0) { 2123 switch (softc->media_density) { 2124 case SCSI_DENSITY_HALFINCH_800: 2125 case SCSI_DENSITY_HALFINCH_1600: 2126 case SCSI_DENSITY_HALFINCH_6250: 2127 case SCSI_DENSITY_HALFINCH_6250C: 2128 case SCSI_DENSITY_HALFINCH_PE: 2129 softc->quirks &= ~SA_QUIRK_1FM; 2130 softc->quirks |= SA_QUIRK_2FM; 2131 break; 2132 default: 2133 break; 2134 } 2135 } 2136 2137 /* 2138 * Now validate that some info we got makes sense. 2139 */ 2140 if ((softc->max_blk < softc->media_blksize) || 2141 (softc->min_blk > softc->media_blksize && 2142 softc->media_blksize)) { 2143 xpt_print(periph->path, 2144 "BLOCK LIMITS (%d..%d) could not match current " 2145 "block settings (%d)- adjusting\n", softc->min_blk, 2146 softc->max_blk, softc->media_blksize); 2147 softc->max_blk = softc->min_blk = 2148 softc->media_blksize; 2149 } 2150 2151 /* 2152 * Now put ourselves into the right frame of mind based 2153 * upon quirks... 2154 */ 2155 tryagain: 2156 /* 2157 * If we want to be in FIXED mode and our current blocksize 2158 * is not equal to our last blocksize (if nonzero), try and 2159 * set ourselves to this last blocksize (as the 'preferred' 2160 * block size). The initial quirkmatch at registry sets the 2161 * initial 'last' blocksize. If, for whatever reason, this 2162 * 'last' blocksize is zero, set the blocksize to 512, 2163 * or min_blk if that's larger. 2164 */ 2165 if ((softc->quirks & SA_QUIRK_FIXED) && 2166 (softc->quirks & SA_QUIRK_NO_MODESEL) == 0 && 2167 (softc->media_blksize != softc->last_media_blksize)) { 2168 softc->media_blksize = softc->last_media_blksize; 2169 if (softc->media_blksize == 0) { 2170 softc->media_blksize = 512; 2171 if (softc->media_blksize < softc->min_blk) { 2172 softc->media_blksize = softc->min_blk; 2173 } 2174 } 2175 error = sasetparams(periph, SA_PARAM_BLOCKSIZE, 2176 softc->media_blksize, 0, 0, SF_NO_PRINT); 2177 if (error) { 2178 xpt_print(periph->path, 2179 "unable to set fixed blocksize to %d\n", 2180 softc->media_blksize); 2181 goto exit; 2182 } 2183 } 2184 2185 if ((softc->quirks & SA_QUIRK_VARIABLE) && 2186 (softc->media_blksize != 0)) { 2187 softc->last_media_blksize = softc->media_blksize; 2188 softc->media_blksize = 0; 2189 error = sasetparams(periph, SA_PARAM_BLOCKSIZE, 2190 0, 0, 0, SF_NO_PRINT); 2191 if (error) { 2192 /* 2193 * If this fails and we were guessing, just 2194 * assume that we got it wrong and go try 2195 * fixed block mode. Don't even check against 2196 * density code at this point. 2197 */ 2198 if (guessing) { 2199 softc->quirks &= ~SA_QUIRK_VARIABLE; 2200 softc->quirks |= SA_QUIRK_FIXED; 2201 if (softc->last_media_blksize == 0) 2202 softc->last_media_blksize = 512; 2203 goto tryagain; 2204 } 2205 xpt_print(periph->path, 2206 "unable to set variable blocksize\n"); 2207 goto exit; 2208 } 2209 } 2210 2211 /* 2212 * Now that we have the current block size, 2213 * set up some parameters for sastart's usage. 2214 */ 2215 if (softc->media_blksize) { 2216 softc->flags |= SA_FLAG_FIXED; 2217 if (powerof2(softc->media_blksize)) { 2218 softc->blk_shift = 2219 ffs(softc->media_blksize) - 1; 2220 softc->blk_mask = softc->media_blksize - 1; 2221 } else { 2222 softc->blk_mask = ~0; 2223 softc->blk_shift = 0; 2224 } 2225 } else { 2226 /* 2227 * The SCSI-3 spec allows 0 to mean "unspecified". 2228 * The SCSI-1 spec allows 0 to mean 'infinite'. 2229 * 2230 * Either works here. 2231 */ 2232 if (softc->max_blk == 0) { 2233 softc->max_blk = ~0; 2234 } 2235 softc->blk_shift = 0; 2236 if (softc->blk_gran != 0) { 2237 softc->blk_mask = softc->blk_gran - 1; 2238 } else { 2239 softc->blk_mask = 0; 2240 } 2241 } 2242 2243 if (write_protect) 2244 softc->flags |= SA_FLAG_TAPE_WP; 2245 2246 if (comp_supported) { 2247 if (softc->saved_comp_algorithm == 0) 2248 softc->saved_comp_algorithm = 2249 softc->comp_algorithm; 2250 softc->flags |= SA_FLAG_COMP_SUPP; 2251 if (comp_enabled) 2252 softc->flags |= SA_FLAG_COMP_ENABLED; 2253 } else 2254 softc->flags |= SA_FLAG_COMP_UNSUPP; 2255 2256 if ((softc->buffer_mode == SMH_SA_BUF_MODE_NOBUF) && 2257 (softc->quirks & SA_QUIRK_NO_MODESEL) == 0) { 2258 error = sasetparams(periph, SA_PARAM_BUFF_MODE, 0, 2259 0, 0, SF_NO_PRINT); 2260 if (error == 0) { 2261 softc->buffer_mode = SMH_SA_BUF_MODE_SIBUF; 2262 } else { 2263 xpt_print(periph->path, 2264 "unable to set buffered mode\n"); 2265 } 2266 error = 0; /* not an error */ 2267 } 2268 2269 2270 if (error == 0) { 2271 softc->flags |= SA_FLAG_TAPE_MOUNTED; 2272 } 2273 exit: 2274 if (rblim != NULL) 2275 kfree(rblim, M_SCSISA); 2276 2277 if (error != 0) { 2278 softc->dsreg = MTIO_DSREG_NIL; 2279 } else { 2280 softc->fileno = softc->blkno = 0; 2281 softc->dsreg = MTIO_DSREG_REST; 2282 } 2283 #ifdef SA_1FM_AT_EOD 2284 if ((softc->quirks & SA_QUIRK_2FM) == 0) 2285 softc->quirks |= SA_QUIRK_1FM; 2286 #else 2287 if ((softc->quirks & SA_QUIRK_1FM) == 0) 2288 softc->quirks |= SA_QUIRK_2FM; 2289 #endif 2290 } else 2291 xpt_release_ccb(ccb); 2292 2293 /* 2294 * If we return an error, we're not mounted any more, 2295 * so release any device reservation. 2296 */ 2297 if (error != 0) { 2298 sareservereleaseunit(periph, FALSE); 2299 } else { 2300 /* 2301 * Clear I/O residual. 2302 */ 2303 softc->last_io_resid = 0; 2304 softc->last_ctl_resid = 0; 2305 } 2306 return (error); 2307 } 2308 2309 /* 2310 * How many filemarks do we need to write if we were to terminate the 2311 * tape session right now? Note that this can be a negative number 2312 */ 2313 2314 static int 2315 samarkswanted(struct cam_periph *periph) 2316 { 2317 int markswanted; 2318 struct sa_softc *softc; 2319 2320 softc = (struct sa_softc *)periph->softc; 2321 markswanted = 0; 2322 if ((softc->flags & SA_FLAG_TAPE_WRITTEN) != 0) { 2323 markswanted++; 2324 if (softc->quirks & SA_QUIRK_2FM) 2325 markswanted++; 2326 } 2327 markswanted -= softc->filemarks; 2328 return (markswanted); 2329 } 2330 2331 static int 2332 sacheckeod(struct cam_periph *periph) 2333 { 2334 int error; 2335 int markswanted; 2336 2337 markswanted = samarkswanted(periph); 2338 2339 if (markswanted > 0) { 2340 error = sawritefilemarks(periph, markswanted, FALSE); 2341 } else { 2342 error = 0; 2343 } 2344 return (error); 2345 } 2346 2347 static int 2348 saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) 2349 { 2350 static const char *toobig = 2351 "%d-byte tape record bigger than supplied buffer\n"; 2352 struct cam_periph *periph; 2353 struct sa_softc *softc; 2354 struct ccb_scsiio *csio; 2355 struct scsi_sense_data *sense; 2356 u_int32_t resid = 0; 2357 int32_t info = 0; 2358 cam_status status; 2359 int error_code, sense_key, asc, ascq, error, aqvalid; 2360 2361 periph = xpt_path_periph(ccb->ccb_h.path); 2362 softc = (struct sa_softc *)periph->softc; 2363 csio = &ccb->csio; 2364 sense = &csio->sense_data; 2365 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq); 2366 aqvalid = sense->extra_len >= 6; 2367 error = 0; 2368 2369 status = csio->ccb_h.status & CAM_STATUS_MASK; 2370 2371 /* 2372 * Calculate/latch up, any residuals... We do this in a funny 2-step 2373 * so we can print stuff here if we have CAM_DEBUG enabled for this 2374 * unit. 2375 */ 2376 if (status == CAM_SCSI_STATUS_ERROR) { 2377 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) { 2378 info = (int32_t) scsi_4btoul(sense->info); 2379 resid = info; 2380 if ((softc->flags & SA_FLAG_FIXED) != 0) 2381 resid *= softc->media_blksize; 2382 } else { 2383 resid = csio->dxfer_len; 2384 info = resid; 2385 if ((softc->flags & SA_FLAG_FIXED) != 0) { 2386 if (softc->media_blksize) 2387 info /= softc->media_blksize; 2388 } 2389 } 2390 if (CCB_Type(csio) == SA_CCB_BUFFER_IO) { 2391 bcopy((caddr_t) sense, (caddr_t) &softc->last_io_sense, 2392 sizeof (struct scsi_sense_data)); 2393 bcopy(csio->cdb_io.cdb_bytes, softc->last_io_cdb, 2394 (int) csio->cdb_len); 2395 softc->last_io_resid = resid; 2396 softc->last_resid_was_io = 1; 2397 } else { 2398 bcopy((caddr_t) sense, (caddr_t) &softc->last_ctl_sense, 2399 sizeof (struct scsi_sense_data)); 2400 bcopy(csio->cdb_io.cdb_bytes, softc->last_ctl_cdb, 2401 (int) csio->cdb_len); 2402 softc->last_ctl_resid = resid; 2403 softc->last_resid_was_io = 0; 2404 } 2405 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("CDB[0]=0x%x Key 0x%x " 2406 "ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %d " 2407 "dxfer_len %d\n", csio->cdb_io.cdb_bytes[0] & 0xff, 2408 sense_key, asc, ascq, status, 2409 sense->flags & ~SSD_KEY_RESERVED, resid, csio->dxfer_len)); 2410 } else { 2411 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, 2412 ("Cam Status 0x%x\n", status)); 2413 } 2414 2415 switch (status) { 2416 case CAM_REQ_CMP: 2417 return (0); 2418 case CAM_SCSI_STATUS_ERROR: 2419 /* 2420 * If a read/write command, we handle it here. 2421 */ 2422 if (CCB_Type(csio) != SA_CCB_WAITING) { 2423 break; 2424 } 2425 /* 2426 * If this was just EOM/EOP, Filemark, Setmark or ILI detected 2427 * on a non read/write command, we assume it's not an error 2428 * and propagate the residule and return. 2429 */ 2430 if ((aqvalid && asc == 0 && ascq > 0 && ascq <= 5) || 2431 (aqvalid == 0 && sense_key == SSD_KEY_NO_SENSE)) { 2432 csio->resid = resid; 2433 QFRLS(ccb); 2434 return (0); 2435 } 2436 /* 2437 * Otherwise, we let the common code handle this. 2438 */ 2439 return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb)); 2440 2441 /* 2442 * XXX: To Be Fixed 2443 * We cannot depend upon CAM honoring retry counts for these. 2444 */ 2445 case CAM_SCSI_BUS_RESET: 2446 case CAM_BDR_SENT: 2447 if (ccb->ccb_h.retry_count <= 0) { 2448 return (EIO); 2449 } 2450 /* FALLTHROUGH */ 2451 default: 2452 return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb)); 2453 } 2454 2455 /* 2456 * Handle filemark, end of tape, mismatched record sizes.... 2457 * From this point out, we're only handling read/write cases. 2458 * Handle writes && reads differently. 2459 */ 2460 2461 if (csio->cdb_io.cdb_bytes[0] == SA_WRITE) { 2462 if (sense_key == SSD_KEY_VOLUME_OVERFLOW) { 2463 csio->resid = resid; 2464 error = ENOSPC; 2465 } else if (sense->flags & SSD_EOM) { 2466 softc->flags |= SA_FLAG_EOM_PENDING; 2467 /* 2468 * Grotesque as it seems, the few times 2469 * I've actually seen a non-zero resid, 2470 * the tape drive actually lied and had 2471 * written all the data!. 2472 */ 2473 csio->resid = 0; 2474 } 2475 } else { 2476 csio->resid = resid; 2477 if (sense_key == SSD_KEY_BLANK_CHECK) { 2478 if (softc->quirks & SA_QUIRK_1FM) { 2479 error = 0; 2480 softc->flags |= SA_FLAG_EOM_PENDING; 2481 } else { 2482 error = EIO; 2483 } 2484 } else if (sense->flags & SSD_FILEMARK) { 2485 if (softc->flags & SA_FLAG_FIXED) { 2486 error = -1; 2487 softc->flags |= SA_FLAG_EOF_PENDING; 2488 } 2489 /* 2490 * Unconditionally, if we detected a filemark on a read, 2491 * mark that we've run moved a file ahead. 2492 */ 2493 if (softc->fileno != (daddr_t) -1) { 2494 softc->fileno++; 2495 softc->blkno = 0; 2496 csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED; 2497 } 2498 } 2499 } 2500 2501 /* 2502 * Incorrect Length usually applies to read, but can apply to writes. 2503 */ 2504 if (error == 0 && (sense->flags & SSD_ILI)) { 2505 if (info < 0) { 2506 xpt_print(csio->ccb_h.path, toobig, 2507 csio->dxfer_len - info); 2508 csio->resid = csio->dxfer_len; 2509 error = EIO; 2510 } else { 2511 csio->resid = resid; 2512 if (softc->flags & SA_FLAG_FIXED) { 2513 softc->flags |= SA_FLAG_EIO_PENDING; 2514 } 2515 /* 2516 * Bump the block number if we hadn't seen a filemark. 2517 * Do this independent of errors (we've moved anyway). 2518 */ 2519 if ((sense->flags & SSD_FILEMARK) == 0) { 2520 if (softc->blkno != (daddr_t) -1) { 2521 softc->blkno++; 2522 csio->ccb_h.ccb_pflags |= 2523 SA_POSITION_UPDATED; 2524 } 2525 } 2526 } 2527 } 2528 2529 if (error <= 0) { 2530 /* 2531 * Unfreeze the queue if frozen as we're not returning anything 2532 * to our waiters that would indicate an I/O error has occurred 2533 * (yet). 2534 */ 2535 QFRLS(ccb); 2536 error = 0; 2537 } 2538 return (error); 2539 } 2540 2541 static int 2542 sagetparams(struct cam_periph *periph, sa_params params_to_get, 2543 u_int32_t *blocksize, u_int8_t *density, u_int32_t *numblocks, 2544 int *buff_mode, u_int8_t *write_protect, u_int8_t *speed, 2545 int *comp_supported, int *comp_enabled, u_int32_t *comp_algorithm, 2546 sa_comp_t *tcs) 2547 { 2548 union ccb *ccb; 2549 void *mode_buffer; 2550 struct scsi_mode_header_6 *mode_hdr; 2551 struct scsi_mode_blk_desc *mode_blk; 2552 int mode_buffer_len; 2553 struct sa_softc *softc; 2554 u_int8_t cpage; 2555 int error; 2556 cam_status status; 2557 2558 softc = (struct sa_softc *)periph->softc; 2559 ccb = cam_periph_getccb(periph, 1); 2560 Set_CCB_Type(ccb, SA_CCB_POLLED); 2561 if (softc->quirks & SA_QUIRK_NO_CPAGE) 2562 cpage = SA_DEVICE_CONFIGURATION_PAGE; 2563 else 2564 cpage = SA_DATA_COMPRESSION_PAGE; 2565 2566 retry: 2567 mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk); 2568 2569 if (params_to_get & SA_PARAM_COMPRESSION) { 2570 if (softc->quirks & SA_QUIRK_NOCOMP) { 2571 *comp_supported = FALSE; 2572 params_to_get &= ~SA_PARAM_COMPRESSION; 2573 } else 2574 mode_buffer_len += sizeof (sa_comp_t); 2575 } 2576 2577 mode_buffer = kmalloc(mode_buffer_len, M_SCSISA, M_INTWAIT | M_ZERO); 2578 mode_hdr = (struct scsi_mode_header_6 *)mode_buffer; 2579 mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1]; 2580 2581 /* it is safe to retry this */ 2582 scsi_mode_sense(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE, 2583 SMS_PAGE_CTRL_CURRENT, (params_to_get & SA_PARAM_COMPRESSION) ? 2584 cpage : SMS_VENDOR_SPECIFIC_PAGE, mode_buffer, mode_buffer_len, 2585 SSD_FULL_SIZE, SCSIOP_TIMEOUT); 2586 2587 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 2588 &softc->device_stats); 2589 QFRLS(ccb); 2590 2591 status = ccb->ccb_h.status & CAM_STATUS_MASK; 2592 2593 if (error == EINVAL && (params_to_get & SA_PARAM_COMPRESSION) != 0) { 2594 /* 2595 * Hmm. Let's see if we can try another page... 2596 * If we've already done that, give up on compression 2597 * for this device and remember this for the future 2598 * and attempt the request without asking for compression 2599 * info. 2600 */ 2601 if (cpage == SA_DATA_COMPRESSION_PAGE) { 2602 cpage = SA_DEVICE_CONFIGURATION_PAGE; 2603 goto retry; 2604 } 2605 softc->quirks |= SA_QUIRK_NOCOMP; 2606 kfree(mode_buffer, M_SCSISA); 2607 goto retry; 2608 } else if (status == CAM_SCSI_STATUS_ERROR) { 2609 /* Tell the user about the fatal error. */ 2610 scsi_sense_print(&ccb->csio); 2611 goto sagetparamsexit; 2612 } 2613 2614 /* 2615 * If the user only wants the compression information, and 2616 * the device doesn't send back the block descriptor, it's 2617 * no big deal. If the user wants more than just 2618 * compression, though, and the device doesn't pass back the 2619 * block descriptor, we need to send another mode sense to 2620 * get the block descriptor. 2621 */ 2622 if ((mode_hdr->blk_desc_len == 0) && 2623 (params_to_get & SA_PARAM_COMPRESSION) && 2624 (params_to_get & ~(SA_PARAM_COMPRESSION))) { 2625 2626 /* 2627 * Decrease the mode buffer length by the size of 2628 * the compression page, to make sure the data 2629 * there doesn't get overwritten. 2630 */ 2631 mode_buffer_len -= sizeof (sa_comp_t); 2632 2633 /* 2634 * Now move the compression page that we presumably 2635 * got back down the memory chunk a little bit so 2636 * it doesn't get spammed. 2637 */ 2638 bcopy(&mode_hdr[0], &mode_hdr[1], sizeof (sa_comp_t)); 2639 bzero(&mode_hdr[0], sizeof (mode_hdr[0])); 2640 2641 /* 2642 * Now, we issue another mode sense and just ask 2643 * for the block descriptor, etc. 2644 */ 2645 2646 scsi_mode_sense(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE, 2647 SMS_PAGE_CTRL_CURRENT, SMS_VENDOR_SPECIFIC_PAGE, 2648 mode_buffer, mode_buffer_len, SSD_FULL_SIZE, 2649 SCSIOP_TIMEOUT); 2650 2651 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 2652 &softc->device_stats); 2653 QFRLS(ccb); 2654 2655 if (error != 0) 2656 goto sagetparamsexit; 2657 } 2658 2659 if (params_to_get & SA_PARAM_BLOCKSIZE) 2660 *blocksize = scsi_3btoul(mode_blk->blklen); 2661 2662 if (params_to_get & SA_PARAM_NUMBLOCKS) 2663 *numblocks = scsi_3btoul(mode_blk->nblocks); 2664 2665 if (params_to_get & SA_PARAM_BUFF_MODE) 2666 *buff_mode = mode_hdr->dev_spec & SMH_SA_BUF_MODE_MASK; 2667 2668 if (params_to_get & SA_PARAM_DENSITY) 2669 *density = mode_blk->density; 2670 2671 if (params_to_get & SA_PARAM_WP) 2672 *write_protect = (mode_hdr->dev_spec & SMH_SA_WP)? TRUE : FALSE; 2673 2674 if (params_to_get & SA_PARAM_SPEED) 2675 *speed = mode_hdr->dev_spec & SMH_SA_SPEED_MASK; 2676 2677 if (params_to_get & SA_PARAM_COMPRESSION) { 2678 sa_comp_t *ntcs = (sa_comp_t *) &mode_blk[1]; 2679 if (cpage == SA_DATA_COMPRESSION_PAGE) { 2680 struct scsi_data_compression_page *cp = &ntcs->dcomp; 2681 *comp_supported = 2682 (cp->dce_and_dcc & SA_DCP_DCC)? TRUE : FALSE; 2683 *comp_enabled = 2684 (cp->dce_and_dcc & SA_DCP_DCE)? TRUE : FALSE; 2685 *comp_algorithm = scsi_4btoul(cp->comp_algorithm); 2686 } else { 2687 struct scsi_dev_conf_page *cp = &ntcs->dconf; 2688 /* 2689 * We don't really know whether this device supports 2690 * Data Compression if the the algorithm field is 2691 * zero. Just say we do. 2692 */ 2693 *comp_supported = TRUE; 2694 *comp_enabled = 2695 (cp->sel_comp_alg != SA_COMP_NONE)? TRUE : FALSE; 2696 *comp_algorithm = cp->sel_comp_alg; 2697 } 2698 if (tcs != NULL) 2699 bcopy(ntcs, tcs, sizeof (sa_comp_t)); 2700 } 2701 2702 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) { 2703 int idx; 2704 char *xyz = mode_buffer; 2705 xpt_print_path(periph->path); 2706 kprintf("Mode Sense Data="); 2707 for (idx = 0; idx < mode_buffer_len; idx++) 2708 kprintf(" 0x%02x", xyz[idx] & 0xff); 2709 kprintf("\n"); 2710 } 2711 2712 sagetparamsexit: 2713 2714 xpt_release_ccb(ccb); 2715 kfree(mode_buffer, M_SCSISA); 2716 return (error); 2717 } 2718 2719 /* 2720 * The purpose of this function is to set one of four different parameters 2721 * for a tape drive: 2722 * - blocksize 2723 * - density 2724 * - compression / compression algorithm 2725 * - buffering mode 2726 * 2727 * The assumption is that this will be called from saioctl(), and therefore 2728 * from a process context. Thus the waiting malloc calls below. If that 2729 * assumption ever changes, the malloc calls should be changed to be 2730 * NOWAIT mallocs. 2731 * 2732 * Any or all of the four parameters may be set when this function is 2733 * called. It should handle setting more than one parameter at once. 2734 */ 2735 static int 2736 sasetparams(struct cam_periph *periph, sa_params params_to_set, 2737 u_int32_t blocksize, u_int8_t density, u_int32_t calg, 2738 u_int32_t sense_flags) 2739 { 2740 struct sa_softc *softc; 2741 u_int32_t current_blocksize = 0;/* silence gcc */ 2742 u_int32_t current_calg; 2743 u_int8_t current_density = 0; /* silence gcc */ 2744 u_int8_t current_speed = 0; /* silence gcc */ 2745 int comp_enabled, comp_supported; 2746 void *mode_buffer; 2747 int mode_buffer_len; 2748 struct scsi_mode_header_6 *mode_hdr; 2749 struct scsi_mode_blk_desc *mode_blk; 2750 sa_comp_t *ccomp, *cpage; 2751 int buff_mode; 2752 union ccb *ccb = NULL; 2753 int error; 2754 2755 softc = (struct sa_softc *)periph->softc; 2756 2757 ccomp = kmalloc(sizeof (sa_comp_t), M_SCSISA, M_INTWAIT); 2758 2759 /* 2760 * Since it doesn't make sense to set the number of blocks, or 2761 * write protection, we won't try to get the current value. We 2762 * always want to get the blocksize, so we can set it back to the 2763 * proper value. 2764 */ 2765 error = sagetparams(periph, 2766 params_to_set | SA_PARAM_BLOCKSIZE | SA_PARAM_SPEED, 2767 ¤t_blocksize, ¤t_density, NULL, &buff_mode, NULL, 2768 ¤t_speed, &comp_supported, &comp_enabled, 2769 ¤t_calg, ccomp); 2770 2771 if (error != 0) { 2772 kfree(ccomp, M_SCSISA); 2773 return (error); 2774 } 2775 2776 mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk); 2777 if (params_to_set & SA_PARAM_COMPRESSION) 2778 mode_buffer_len += sizeof (sa_comp_t); 2779 2780 mode_buffer = kmalloc(mode_buffer_len, M_SCSISA, M_INTWAIT | M_ZERO); 2781 2782 mode_hdr = (struct scsi_mode_header_6 *)mode_buffer; 2783 mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1]; 2784 2785 ccb = cam_periph_getccb(periph, 1); 2786 Set_CCB_Type(ccb, SA_CCB_POLLED); 2787 2788 retry: 2789 2790 if (params_to_set & SA_PARAM_COMPRESSION) { 2791 if (mode_blk) { 2792 cpage = (sa_comp_t *)&mode_blk[1]; 2793 } else { 2794 cpage = (sa_comp_t *)&mode_hdr[1]; 2795 } 2796 bcopy(ccomp, cpage, sizeof (sa_comp_t)); 2797 cpage->hdr.pagecode &= ~0x80; 2798 } else 2799 cpage = NULL; 2800 2801 /* 2802 * If the caller wants us to set the blocksize, use the one they 2803 * pass in. Otherwise, use the blocksize we got back from the 2804 * mode select above. 2805 */ 2806 if (mode_blk) { 2807 if (params_to_set & SA_PARAM_BLOCKSIZE) 2808 scsi_ulto3b(blocksize, mode_blk->blklen); 2809 else 2810 scsi_ulto3b(current_blocksize, mode_blk->blklen); 2811 2812 /* 2813 * Set density if requested, else preserve old density. 2814 * SCSI_SAME_DENSITY only applies to SCSI-2 or better 2815 * devices, else density we've latched up in our softc. 2816 */ 2817 if (params_to_set & SA_PARAM_DENSITY) { 2818 mode_blk->density = density; 2819 } else if (softc->scsi_rev > SCSI_REV_CCS) { 2820 mode_blk->density = SCSI_SAME_DENSITY; 2821 } else { 2822 mode_blk->density = softc->media_density; 2823 } 2824 } 2825 2826 /* 2827 * For mode selects, these two fields must be zero. 2828 */ 2829 mode_hdr->data_length = 0; 2830 mode_hdr->medium_type = 0; 2831 2832 /* set the speed to the current value */ 2833 mode_hdr->dev_spec = current_speed; 2834 2835 /* if set, set single-initiator buffering mode */ 2836 if (softc->buffer_mode == SMH_SA_BUF_MODE_SIBUF) { 2837 mode_hdr->dev_spec |= SMH_SA_BUF_MODE_SIBUF; 2838 } 2839 2840 if (mode_blk) 2841 mode_hdr->blk_desc_len = sizeof(struct scsi_mode_blk_desc); 2842 else 2843 mode_hdr->blk_desc_len = 0; 2844 2845 /* 2846 * First, if the user wants us to set the compression algorithm or 2847 * just turn compression on, check to make sure that this drive 2848 * supports compression. 2849 */ 2850 if (params_to_set & SA_PARAM_COMPRESSION) { 2851 /* 2852 * If the compression algorithm is 0, disable compression. 2853 * If the compression algorithm is non-zero, enable 2854 * compression and set the compression type to the 2855 * specified compression algorithm, unless the algorithm is 2856 * MT_COMP_ENABLE. In that case, we look at the 2857 * compression algorithm that is currently set and if it is 2858 * non-zero, we leave it as-is. If it is zero, and we have 2859 * saved a compression algorithm from a time when 2860 * compression was enabled before, set the compression to 2861 * the saved value. 2862 */ 2863 switch (ccomp->hdr.pagecode & ~0x80) { 2864 case SA_DEVICE_CONFIGURATION_PAGE: 2865 { 2866 struct scsi_dev_conf_page *dcp = &cpage->dconf; 2867 if (calg == 0) { 2868 dcp->sel_comp_alg = SA_COMP_NONE; 2869 break; 2870 } 2871 if (calg != MT_COMP_ENABLE) { 2872 dcp->sel_comp_alg = calg; 2873 } else if (dcp->sel_comp_alg == SA_COMP_NONE && 2874 softc->saved_comp_algorithm != 0) { 2875 dcp->sel_comp_alg = softc->saved_comp_algorithm; 2876 } 2877 break; 2878 } 2879 case SA_DATA_COMPRESSION_PAGE: 2880 if (ccomp->dcomp.dce_and_dcc & SA_DCP_DCC) { 2881 struct scsi_data_compression_page *dcp = &cpage->dcomp; 2882 if (calg == 0) { 2883 /* 2884 * Disable compression, but leave the 2885 * decompression and the capability bit 2886 * alone. 2887 */ 2888 dcp->dce_and_dcc = SA_DCP_DCC; 2889 dcp->dde_and_red |= SA_DCP_DDE; 2890 break; 2891 } 2892 /* enable compression && decompression */ 2893 dcp->dce_and_dcc = SA_DCP_DCE | SA_DCP_DCC; 2894 dcp->dde_and_red |= SA_DCP_DDE; 2895 /* 2896 * If there, use compression algorithm from caller. 2897 * Otherwise, if there's a saved compression algorithm 2898 * and there is no current algorithm, use the saved 2899 * algorithm. Else parrot back what we got and hope 2900 * for the best. 2901 */ 2902 if (calg != MT_COMP_ENABLE) { 2903 scsi_ulto4b(calg, dcp->comp_algorithm); 2904 scsi_ulto4b(calg, dcp->decomp_algorithm); 2905 } else if (scsi_4btoul(dcp->comp_algorithm) == 0 && 2906 softc->saved_comp_algorithm != 0) { 2907 scsi_ulto4b(softc->saved_comp_algorithm, 2908 dcp->comp_algorithm); 2909 scsi_ulto4b(softc->saved_comp_algorithm, 2910 dcp->decomp_algorithm); 2911 } 2912 break; 2913 } 2914 /* 2915 * Compression does not appear to be supported- 2916 * at least via the DATA COMPRESSION page. It 2917 * would be too much to ask us to believe that 2918 * the page itself is supported, but incorrectly 2919 * reports an ability to manipulate data compression, 2920 * so we'll assume that this device doesn't support 2921 * compression. We can just fall through for that. 2922 */ 2923 /* FALLTHROUGH */ 2924 default: 2925 /* 2926 * The drive doesn't seem to support compression, 2927 * so turn off the set compression bit. 2928 */ 2929 params_to_set &= ~SA_PARAM_COMPRESSION; 2930 xpt_print(periph->path, 2931 "device does not seem to support compression\n"); 2932 2933 /* 2934 * If that was the only thing the user wanted us to set, 2935 * clean up allocated resources and return with 2936 * 'operation not supported'. 2937 */ 2938 if (params_to_set == SA_PARAM_NONE) { 2939 kfree(mode_buffer, M_SCSISA); 2940 xpt_release_ccb(ccb); 2941 return (ENODEV); 2942 } 2943 2944 /* 2945 * That wasn't the only thing the user wanted us to set. 2946 * So, decrease the stated mode buffer length by the 2947 * size of the compression mode page. 2948 */ 2949 mode_buffer_len -= sizeof(sa_comp_t); 2950 } 2951 } 2952 2953 /* It is safe to retry this operation */ 2954 scsi_mode_select(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, 2955 (params_to_set & SA_PARAM_COMPRESSION)? TRUE : FALSE, 2956 FALSE, mode_buffer, mode_buffer_len, SSD_FULL_SIZE, SCSIOP_TIMEOUT); 2957 2958 error = cam_periph_runccb(ccb, saerror, 0, 2959 sense_flags, &softc->device_stats); 2960 QFRLS(ccb); 2961 2962 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) { 2963 int idx; 2964 char *xyz = mode_buffer; 2965 xpt_print_path(periph->path); 2966 kprintf("Err%d, Mode Select Data=", error); 2967 for (idx = 0; idx < mode_buffer_len; idx++) 2968 kprintf(" 0x%02x", xyz[idx] & 0xff); 2969 kprintf("\n"); 2970 } 2971 2972 2973 if (error) { 2974 /* 2975 * If we can, try without setting density/blocksize. 2976 */ 2977 if (mode_blk) { 2978 if ((params_to_set & 2979 (SA_PARAM_DENSITY|SA_PARAM_BLOCKSIZE)) == 0) { 2980 mode_blk = NULL; 2981 goto retry; 2982 } 2983 } else { 2984 mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1]; 2985 cpage = (sa_comp_t *)&mode_blk[1]; 2986 } 2987 2988 /* 2989 * If we were setting the blocksize, and that failed, we 2990 * want to set it to its original value. If we weren't 2991 * setting the blocksize, we don't want to change it. 2992 */ 2993 scsi_ulto3b(current_blocksize, mode_blk->blklen); 2994 2995 /* 2996 * Set density if requested, else preserve old density. 2997 * SCSI_SAME_DENSITY only applies to SCSI-2 or better 2998 * devices, else density we've latched up in our softc. 2999 */ 3000 if (params_to_set & SA_PARAM_DENSITY) { 3001 mode_blk->density = current_density; 3002 } else if (softc->scsi_rev > SCSI_REV_CCS) { 3003 mode_blk->density = SCSI_SAME_DENSITY; 3004 } else { 3005 mode_blk->density = softc->media_density; 3006 } 3007 3008 if (params_to_set & SA_PARAM_COMPRESSION) 3009 bcopy(ccomp, cpage, sizeof (sa_comp_t)); 3010 3011 /* 3012 * The retry count is the only CCB field that might have been 3013 * changed that we care about, so reset it back to 1. 3014 */ 3015 ccb->ccb_h.retry_count = 1; 3016 cam_periph_runccb(ccb, saerror, 0, sense_flags, 3017 &softc->device_stats); 3018 QFRLS(ccb); 3019 } 3020 3021 xpt_release_ccb(ccb); 3022 3023 if (ccomp != NULL) 3024 kfree(ccomp, M_SCSISA); 3025 3026 if (params_to_set & SA_PARAM_COMPRESSION) { 3027 if (error) { 3028 softc->flags &= ~SA_FLAG_COMP_ENABLED; 3029 /* 3030 * Even if we get an error setting compression, 3031 * do not say that we don't support it. We could 3032 * have been wrong, or it may be media specific. 3033 * softc->flags &= ~SA_FLAG_COMP_SUPP; 3034 */ 3035 softc->saved_comp_algorithm = softc->comp_algorithm; 3036 softc->comp_algorithm = 0; 3037 } else { 3038 softc->flags |= SA_FLAG_COMP_ENABLED; 3039 softc->comp_algorithm = calg; 3040 } 3041 } 3042 3043 kfree(mode_buffer, M_SCSISA); 3044 return (error); 3045 } 3046 3047 static void 3048 saprevent(struct cam_periph *periph, int action) 3049 { 3050 struct sa_softc *softc; 3051 union ccb *ccb; 3052 int error, sf; 3053 3054 softc = (struct sa_softc *)periph->softc; 3055 3056 if ((action == PR_ALLOW) && (softc->flags & SA_FLAG_TAPE_LOCKED) == 0) 3057 return; 3058 if ((action == PR_PREVENT) && (softc->flags & SA_FLAG_TAPE_LOCKED) != 0) 3059 return; 3060 3061 /* 3062 * We can be quiet about illegal requests. 3063 */ 3064 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) { 3065 sf = 0; 3066 } else 3067 sf = SF_QUIET_IR; 3068 3069 ccb = cam_periph_getccb(periph, 1); 3070 Set_CCB_Type(ccb, SA_CCB_POLLED); 3071 3072 /* It is safe to retry this operation */ 3073 scsi_prevent(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, action, 3074 SSD_FULL_SIZE, SCSIOP_TIMEOUT); 3075 3076 error = cam_periph_runccb(ccb, saerror, 0, sf, &softc->device_stats); 3077 QFRLS(ccb); 3078 if (error == 0) { 3079 if (action == PR_ALLOW) 3080 softc->flags &= ~SA_FLAG_TAPE_LOCKED; 3081 else 3082 softc->flags |= SA_FLAG_TAPE_LOCKED; 3083 } 3084 3085 xpt_release_ccb(ccb); 3086 } 3087 3088 static int 3089 sarewind(struct cam_periph *periph) 3090 { 3091 union ccb *ccb; 3092 struct sa_softc *softc; 3093 int error; 3094 3095 softc = (struct sa_softc *)periph->softc; 3096 3097 ccb = cam_periph_getccb(periph, 1); 3098 Set_CCB_Type(ccb, SA_CCB_POLLED); 3099 3100 /* It is safe to retry this operation */ 3101 scsi_rewind(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE, 3102 SSD_FULL_SIZE, REWIND_TIMEOUT); 3103 3104 softc->dsreg = MTIO_DSREG_REW; 3105 error = cam_periph_runccb(ccb, saerror, 0, 0, &softc->device_stats); 3106 softc->dsreg = MTIO_DSREG_REST; 3107 3108 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 3109 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE); 3110 3111 xpt_release_ccb(ccb); 3112 if (error == 0) 3113 softc->fileno = softc->blkno = (daddr_t) 0; 3114 else 3115 softc->fileno = softc->blkno = (daddr_t) -1; 3116 return (error); 3117 } 3118 3119 static int 3120 saspace(struct cam_periph *periph, int count, scsi_space_code code) 3121 { 3122 union ccb *ccb; 3123 struct sa_softc *softc; 3124 int error; 3125 3126 softc = (struct sa_softc *)periph->softc; 3127 3128 ccb = cam_periph_getccb(periph, 1); 3129 Set_CCB_Type(ccb, SA_CCB_POLLED); 3130 3131 /* This cannot be retried */ 3132 3133 scsi_space(&ccb->csio, 0, sadone, MSG_SIMPLE_Q_TAG, code, count, 3134 SSD_FULL_SIZE, SPACE_TIMEOUT); 3135 3136 /* 3137 * Clear residual because we will be using it. 3138 */ 3139 softc->last_ctl_resid = 0; 3140 3141 softc->dsreg = (count < 0)? MTIO_DSREG_REV : MTIO_DSREG_FWD; 3142 error = cam_periph_runccb(ccb, saerror, 0, 0, &softc->device_stats); 3143 softc->dsreg = MTIO_DSREG_REST; 3144 3145 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 3146 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE); 3147 3148 xpt_release_ccb(ccb); 3149 3150 /* 3151 * If a spacing operation has failed, we need to invalidate 3152 * this mount. 3153 * 3154 * If the spacing operation was setmarks or to end of recorded data, 3155 * we no longer know our relative position. 3156 * 3157 * If the spacing operations was spacing files in reverse, we 3158 * take account of the residual, but still check against less 3159 * than zero- if we've gone negative, we must have hit BOT. 3160 * 3161 * If the spacing operations was spacing records in reverse and 3162 * we have a residual, we've either hit BOT or hit a filemark. 3163 * In the former case, we know our new record number (0). In 3164 * the latter case, we have absolutely no idea what the real 3165 * record number is- we've stopped between the end of the last 3166 * record in the previous file and the filemark that stopped 3167 * our spacing backwards. 3168 */ 3169 if (error) { 3170 softc->fileno = softc->blkno = (daddr_t) -1; 3171 } else if (code == SS_SETMARKS || code == SS_EOD) { 3172 softc->fileno = softc->blkno = (daddr_t) -1; 3173 } else if (code == SS_FILEMARKS && softc->fileno != (daddr_t) -1) { 3174 softc->fileno += (count - softc->last_ctl_resid); 3175 if (softc->fileno < 0) /* we must of hit BOT */ 3176 softc->fileno = 0; 3177 softc->blkno = 0; 3178 } else if (code == SS_BLOCKS && softc->blkno != (daddr_t) -1) { 3179 softc->blkno += (count - softc->last_ctl_resid); 3180 if (count < 0) { 3181 if (softc->last_ctl_resid || softc->blkno < 0) { 3182 if (softc->fileno == 0) { 3183 softc->blkno = 0; 3184 } else { 3185 softc->blkno = (daddr_t) -1; 3186 } 3187 } 3188 } 3189 } 3190 return (error); 3191 } 3192 3193 static int 3194 sawritefilemarks(struct cam_periph *periph, int nmarks, int setmarks) 3195 { 3196 union ccb *ccb; 3197 struct sa_softc *softc; 3198 int error, nwm = 0; 3199 3200 softc = (struct sa_softc *)periph->softc; 3201 if (softc->open_rdonly) 3202 return (EBADF); 3203 3204 ccb = cam_periph_getccb(periph, 1); 3205 Set_CCB_Type(ccb, SA_CCB_POLLED); 3206 3207 /* 3208 * Clear residual because we will be using it. 3209 */ 3210 softc->last_ctl_resid = 0; 3211 3212 softc->dsreg = MTIO_DSREG_FMK; 3213 /* this *must* not be retried */ 3214 scsi_write_filemarks(&ccb->csio, 0, sadone, MSG_SIMPLE_Q_TAG, 3215 FALSE, setmarks, nmarks, SSD_FULL_SIZE, IO_TIMEOUT); 3216 softc->dsreg = MTIO_DSREG_REST; 3217 3218 3219 error = cam_periph_runccb(ccb, saerror, 0, 0, &softc->device_stats); 3220 3221 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 3222 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE); 3223 3224 if (error == 0 && nmarks) { 3225 struct sa_softc *softc = (struct sa_softc *)periph->softc; 3226 nwm = nmarks - softc->last_ctl_resid; 3227 softc->filemarks += nwm; 3228 } 3229 3230 xpt_release_ccb(ccb); 3231 3232 /* 3233 * Update relative positions (if we're doing that). 3234 */ 3235 if (error) { 3236 softc->fileno = softc->blkno = (daddr_t) -1; 3237 } else if (softc->fileno != (daddr_t) -1) { 3238 softc->fileno += nwm; 3239 softc->blkno = 0; 3240 } 3241 return (error); 3242 } 3243 3244 static int 3245 sardpos(struct cam_periph *periph, int hard, u_int32_t *blkptr) 3246 { 3247 struct scsi_tape_position_data loc; 3248 union ccb *ccb; 3249 struct sa_softc *softc = (struct sa_softc *)periph->softc; 3250 int error; 3251 3252 /* 3253 * We try and flush any buffered writes here if we were writing 3254 * and we're trying to get hardware block position. It eats 3255 * up performance substantially, but I'm wary of drive firmware. 3256 * 3257 * I think that *logical* block position is probably okay- 3258 * but hardware block position might have to wait for data 3259 * to hit media to be valid. Caveat Emptor. 3260 */ 3261 3262 if (hard && (softc->flags & SA_FLAG_TAPE_WRITTEN)) { 3263 error = sawritefilemarks(periph, 0, 0); 3264 if (error && error != EACCES) 3265 return (error); 3266 } 3267 3268 ccb = cam_periph_getccb(periph, 1); 3269 Set_CCB_Type(ccb, SA_CCB_POLLED); 3270 scsi_read_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, 3271 hard, &loc, SSD_FULL_SIZE, SCSIOP_TIMEOUT); 3272 softc->dsreg = MTIO_DSREG_RBSY; 3273 error = cam_periph_runccb(ccb, saerror, 0, 0, &softc->device_stats); 3274 softc->dsreg = MTIO_DSREG_REST; 3275 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 3276 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0); 3277 3278 if (error == 0) { 3279 if (loc.flags & SA_RPOS_UNCERTAIN) { 3280 error = EINVAL; /* nothing is certain */ 3281 } else { 3282 *blkptr = scsi_4btoul(loc.firstblk); 3283 } 3284 } 3285 3286 xpt_release_ccb(ccb); 3287 return (error); 3288 } 3289 3290 static int 3291 sasetpos(struct cam_periph *periph, int hard, u_int32_t *blkptr) 3292 { 3293 union ccb *ccb; 3294 struct sa_softc *softc; 3295 int error; 3296 3297 /* 3298 * We used to try and flush any buffered writes here. 3299 * Now we push this onto user applications to either 3300 * flush the pending writes themselves (via a zero count 3301 * WRITE FILEMARKS command) or they can trust their tape 3302 * drive to do this correctly for them. 3303 */ 3304 3305 softc = (struct sa_softc *)periph->softc; 3306 ccb = cam_periph_getccb(periph, 1); 3307 Set_CCB_Type(ccb, SA_CCB_POLLED); 3308 3309 scsi_set_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, 3310 hard, *blkptr, SSD_FULL_SIZE, SPACE_TIMEOUT); 3311 3312 3313 softc->dsreg = MTIO_DSREG_POS; 3314 error = cam_periph_runccb(ccb, saerror, 0, 0, &softc->device_stats); 3315 softc->dsreg = MTIO_DSREG_REST; 3316 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 3317 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0); 3318 xpt_release_ccb(ccb); 3319 /* 3320 * Note relative file && block number position as now unknown. 3321 */ 3322 softc->fileno = softc->blkno = (daddr_t) -1; 3323 return (error); 3324 } 3325 3326 static int 3327 saretension(struct cam_periph *periph) 3328 { 3329 union ccb *ccb; 3330 struct sa_softc *softc; 3331 int error; 3332 3333 softc = (struct sa_softc *)periph->softc; 3334 3335 ccb = cam_periph_getccb(periph, 1); 3336 Set_CCB_Type(ccb, SA_CCB_POLLED); 3337 3338 /* It is safe to retry this operation */ 3339 scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE, 3340 FALSE, TRUE, TRUE, SSD_FULL_SIZE, ERASE_TIMEOUT); 3341 3342 softc->dsreg = MTIO_DSREG_TEN; 3343 error = cam_periph_runccb(ccb, saerror, 0, 0, &softc->device_stats); 3344 softc->dsreg = MTIO_DSREG_REST; 3345 3346 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 3347 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE); 3348 xpt_release_ccb(ccb); 3349 if (error == 0) 3350 softc->fileno = softc->blkno = (daddr_t) 0; 3351 else 3352 softc->fileno = softc->blkno = (daddr_t) -1; 3353 return (error); 3354 } 3355 3356 static int 3357 sareservereleaseunit(struct cam_periph *periph, int reserve) 3358 { 3359 union ccb *ccb; 3360 struct sa_softc *softc; 3361 int error; 3362 3363 softc = (struct sa_softc *)periph->softc; 3364 ccb = cam_periph_getccb(periph, 1); 3365 Set_CCB_Type(ccb, SA_CCB_POLLED); 3366 3367 /* It is safe to retry this operation */ 3368 scsi_reserve_release_unit(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, 3369 FALSE, 0, SSD_FULL_SIZE, SCSIOP_TIMEOUT, reserve); 3370 softc->dsreg = MTIO_DSREG_RBSY; 3371 error = cam_periph_runccb(ccb, saerror, 0, 3372 SF_RETRY_UA | SF_NO_PRINT, &softc->device_stats); 3373 softc->dsreg = MTIO_DSREG_REST; 3374 QFRLS(ccb); 3375 xpt_release_ccb(ccb); 3376 3377 /* 3378 * If the error was Illegal Request, then the device doesn't support 3379 * RESERVE/RELEASE. This is not an error. 3380 */ 3381 if (error == EINVAL) { 3382 error = 0; 3383 } 3384 3385 return (error); 3386 } 3387 3388 static int 3389 saloadunload(struct cam_periph *periph, int load) 3390 { 3391 union ccb *ccb; 3392 struct sa_softc *softc; 3393 int error; 3394 3395 softc = (struct sa_softc *)periph->softc; 3396 3397 ccb = cam_periph_getccb(periph, 1); 3398 Set_CCB_Type(ccb, SA_CCB_POLLED); 3399 3400 /* It is safe to retry this operation */ 3401 scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE, 3402 FALSE, FALSE, load, SSD_FULL_SIZE, REWIND_TIMEOUT); 3403 3404 softc->dsreg = (load)? MTIO_DSREG_LD : MTIO_DSREG_UNL; 3405 error = cam_periph_runccb(ccb, saerror, 0, 0, &softc->device_stats); 3406 softc->dsreg = MTIO_DSREG_REST; 3407 QFRLS(ccb); 3408 xpt_release_ccb(ccb); 3409 3410 if (error || load == 0) 3411 softc->fileno = softc->blkno = (daddr_t) -1; 3412 else if (error == 0) 3413 softc->fileno = softc->blkno = (daddr_t) 0; 3414 return (error); 3415 } 3416 3417 static int 3418 saerase(struct cam_periph *periph, int longerase) 3419 { 3420 3421 union ccb *ccb; 3422 struct sa_softc *softc; 3423 int error; 3424 3425 softc = (struct sa_softc *)periph->softc; 3426 if (softc->open_rdonly) 3427 return (EBADF); 3428 3429 ccb = cam_periph_getccb(periph, 1); 3430 Set_CCB_Type(ccb, SA_CCB_POLLED); 3431 3432 scsi_erase(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, FALSE, longerase, 3433 SSD_FULL_SIZE, ERASE_TIMEOUT); 3434 3435 softc->dsreg = MTIO_DSREG_ZER; 3436 error = cam_periph_runccb(ccb, saerror, 0, 0, &softc->device_stats); 3437 softc->dsreg = MTIO_DSREG_REST; 3438 3439 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 3440 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE); 3441 xpt_release_ccb(ccb); 3442 return (error); 3443 } 3444 3445 #endif /* _KERNEL */ 3446 3447 /* 3448 * Read tape block limits command. 3449 */ 3450 void 3451 scsi_read_block_limits(struct ccb_scsiio *csio, u_int32_t retries, 3452 void (*cbfcnp)(struct cam_periph *, union ccb *), 3453 u_int8_t tag_action, 3454 struct scsi_read_block_limits_data *rlimit_buf, 3455 u_int8_t sense_len, u_int32_t timeout) 3456 { 3457 struct scsi_read_block_limits *scsi_cmd; 3458 3459 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_IN, tag_action, 3460 (u_int8_t *)rlimit_buf, sizeof(*rlimit_buf), sense_len, 3461 sizeof(*scsi_cmd), timeout); 3462 3463 scsi_cmd = (struct scsi_read_block_limits *)&csio->cdb_io.cdb_bytes; 3464 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3465 scsi_cmd->opcode = READ_BLOCK_LIMITS; 3466 } 3467 3468 void 3469 scsi_sa_read_write(struct ccb_scsiio *csio, u_int32_t retries, 3470 void (*cbfcnp)(struct cam_periph *, union ccb *), 3471 u_int8_t tag_action, int readop, int sli, 3472 int fixed, u_int32_t length, u_int8_t *data_ptr, 3473 u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout) 3474 { 3475 struct scsi_sa_rw *scsi_cmd; 3476 3477 scsi_cmd = (struct scsi_sa_rw *)&csio->cdb_io.cdb_bytes; 3478 scsi_cmd->opcode = readop ? SA_READ : SA_WRITE; 3479 scsi_cmd->sli_fixed = 0; 3480 if (sli && readop) 3481 scsi_cmd->sli_fixed |= SAR_SLI; 3482 if (fixed) 3483 scsi_cmd->sli_fixed |= SARW_FIXED; 3484 scsi_ulto3b(length, scsi_cmd->length); 3485 scsi_cmd->control = 0; 3486 3487 cam_fill_csio(csio, retries, cbfcnp, readop ? CAM_DIR_IN : CAM_DIR_OUT, 3488 tag_action, data_ptr, dxfer_len, sense_len, 3489 sizeof(*scsi_cmd), timeout); 3490 } 3491 3492 void 3493 scsi_load_unload(struct ccb_scsiio *csio, u_int32_t retries, 3494 void (*cbfcnp)(struct cam_periph *, union ccb *), 3495 u_int8_t tag_action, int immediate, int eot, 3496 int reten, int load, u_int8_t sense_len, 3497 u_int32_t timeout) 3498 { 3499 struct scsi_load_unload *scsi_cmd; 3500 3501 scsi_cmd = (struct scsi_load_unload *)&csio->cdb_io.cdb_bytes; 3502 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3503 scsi_cmd->opcode = LOAD_UNLOAD; 3504 if (immediate) 3505 scsi_cmd->immediate = SLU_IMMED; 3506 if (eot) 3507 scsi_cmd->eot_reten_load |= SLU_EOT; 3508 if (reten) 3509 scsi_cmd->eot_reten_load |= SLU_RETEN; 3510 if (load) 3511 scsi_cmd->eot_reten_load |= SLU_LOAD; 3512 3513 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, 3514 NULL, 0, sense_len, sizeof(*scsi_cmd), timeout); 3515 } 3516 3517 void 3518 scsi_rewind(struct ccb_scsiio *csio, u_int32_t retries, 3519 void (*cbfcnp)(struct cam_periph *, union ccb *), 3520 u_int8_t tag_action, int immediate, u_int8_t sense_len, 3521 u_int32_t timeout) 3522 { 3523 struct scsi_rewind *scsi_cmd; 3524 3525 scsi_cmd = (struct scsi_rewind *)&csio->cdb_io.cdb_bytes; 3526 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3527 scsi_cmd->opcode = REWIND; 3528 if (immediate) 3529 scsi_cmd->immediate = SREW_IMMED; 3530 3531 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL, 3532 0, sense_len, sizeof(*scsi_cmd), timeout); 3533 } 3534 3535 void 3536 scsi_space(struct ccb_scsiio *csio, u_int32_t retries, 3537 void (*cbfcnp)(struct cam_periph *, union ccb *), 3538 u_int8_t tag_action, scsi_space_code code, 3539 u_int32_t count, u_int8_t sense_len, u_int32_t timeout) 3540 { 3541 struct scsi_space *scsi_cmd; 3542 3543 scsi_cmd = (struct scsi_space *)&csio->cdb_io.cdb_bytes; 3544 scsi_cmd->opcode = SPACE; 3545 scsi_cmd->code = code; 3546 scsi_ulto3b(count, scsi_cmd->count); 3547 scsi_cmd->control = 0; 3548 3549 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL, 3550 0, sense_len, sizeof(*scsi_cmd), timeout); 3551 } 3552 3553 void 3554 scsi_write_filemarks(struct ccb_scsiio *csio, u_int32_t retries, 3555 void (*cbfcnp)(struct cam_periph *, union ccb *), 3556 u_int8_t tag_action, int immediate, int setmark, 3557 u_int32_t num_marks, u_int8_t sense_len, 3558 u_int32_t timeout) 3559 { 3560 struct scsi_write_filemarks *scsi_cmd; 3561 3562 scsi_cmd = (struct scsi_write_filemarks *)&csio->cdb_io.cdb_bytes; 3563 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3564 scsi_cmd->opcode = WRITE_FILEMARKS; 3565 if (immediate) 3566 scsi_cmd->byte2 |= SWFMRK_IMMED; 3567 if (setmark) 3568 scsi_cmd->byte2 |= SWFMRK_WSMK; 3569 3570 scsi_ulto3b(num_marks, scsi_cmd->num_marks); 3571 3572 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL, 3573 0, sense_len, sizeof(*scsi_cmd), timeout); 3574 } 3575 3576 /* 3577 * The reserve and release unit commands differ only by their opcodes. 3578 */ 3579 void 3580 scsi_reserve_release_unit(struct ccb_scsiio *csio, u_int32_t retries, 3581 void (*cbfcnp)(struct cam_periph *, union ccb *), 3582 u_int8_t tag_action, int third_party, 3583 int third_party_id, u_int8_t sense_len, 3584 u_int32_t timeout, int reserve) 3585 { 3586 struct scsi_reserve_release_unit *scsi_cmd; 3587 3588 scsi_cmd = (struct scsi_reserve_release_unit *)&csio->cdb_io.cdb_bytes; 3589 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3590 3591 if (reserve) 3592 scsi_cmd->opcode = RESERVE_UNIT; 3593 else 3594 scsi_cmd->opcode = RELEASE_UNIT; 3595 3596 if (third_party) { 3597 scsi_cmd->lun_thirdparty |= SRRU_3RD_PARTY; 3598 scsi_cmd->lun_thirdparty |= 3599 ((third_party_id << SRRU_3RD_SHAMT) & SRRU_3RD_MASK); 3600 } 3601 3602 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL, 3603 0, sense_len, sizeof(*scsi_cmd), timeout); 3604 } 3605 3606 void 3607 scsi_erase(struct ccb_scsiio *csio, u_int32_t retries, 3608 void (*cbfcnp)(struct cam_periph *, union ccb *), 3609 u_int8_t tag_action, int immediate, int long_erase, 3610 u_int8_t sense_len, u_int32_t timeout) 3611 { 3612 struct scsi_erase *scsi_cmd; 3613 3614 scsi_cmd = (struct scsi_erase *)&csio->cdb_io.cdb_bytes; 3615 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3616 3617 scsi_cmd->opcode = ERASE; 3618 3619 if (immediate) 3620 scsi_cmd->lun_imm_long |= SE_IMMED; 3621 3622 if (long_erase) 3623 scsi_cmd->lun_imm_long |= SE_LONG; 3624 3625 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL, 3626 0, sense_len, sizeof(*scsi_cmd), timeout); 3627 } 3628 3629 /* 3630 * Read Tape Position command. 3631 */ 3632 void 3633 scsi_read_position(struct ccb_scsiio *csio, u_int32_t retries, 3634 void (*cbfcnp)(struct cam_periph *, union ccb *), 3635 u_int8_t tag_action, int hardsoft, 3636 struct scsi_tape_position_data *sbp, 3637 u_int8_t sense_len, u_int32_t timeout) 3638 { 3639 struct scsi_tape_read_position *scmd; 3640 3641 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_IN, tag_action, 3642 (u_int8_t *)sbp, sizeof (*sbp), sense_len, sizeof(*scmd), timeout); 3643 scmd = (struct scsi_tape_read_position *)&csio->cdb_io.cdb_bytes; 3644 bzero(scmd, sizeof(*scmd)); 3645 scmd->opcode = READ_POSITION; 3646 scmd->byte1 = hardsoft; 3647 } 3648 3649 /* 3650 * Set Tape Position command. 3651 */ 3652 void 3653 scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries, 3654 void (*cbfcnp)(struct cam_periph *, union ccb *), 3655 u_int8_t tag_action, int hardsoft, u_int32_t blkno, 3656 u_int8_t sense_len, u_int32_t timeout) 3657 { 3658 struct scsi_tape_locate *scmd; 3659 3660 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, 3661 NULL, 0, sense_len, sizeof(*scmd), timeout); 3662 scmd = (struct scsi_tape_locate *)&csio->cdb_io.cdb_bytes; 3663 bzero(scmd, sizeof(*scmd)); 3664 scmd->opcode = LOCATE; 3665 if (hardsoft) 3666 scmd->byte1 |= SA_SPOS_BT; 3667 scsi_ulto4b(blkno, scmd->blkaddr); 3668 } 3669