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