2 * Implementation of SCSI Sequential Access Peripheral driver for CAM.
4 * Copyright (c) 1999, 2000 Matthew Jacob
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification, immediately at the beginning of the file.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/queue.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
38 #include <sys/types.h>
41 #include <sys/limits.h>
42 #include <sys/malloc.h>
47 #include <sys/fcntl.h>
48 #include <sys/devicestat.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/cam_periph.h>
58 #include <cam/cam_xpt_periph.h>
59 #include <cam/cam_debug.h>
61 #include <cam/scsi/scsi_all.h>
62 #include <cam/scsi/scsi_message.h>
63 #include <cam/scsi/scsi_sa.h>
70 #define SA_IO_TIMEOUT 4
72 #ifndef SA_SPACE_TIMEOUT
73 #define SA_SPACE_TIMEOUT 1 * 60
75 #ifndef SA_REWIND_TIMEOUT
76 #define SA_REWIND_TIMEOUT 2 * 60
78 #ifndef SA_ERASE_TIMEOUT
79 #define SA_ERASE_TIMEOUT 4 * 60
82 #define SCSIOP_TIMEOUT (60 * 1000) /* not an option */
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)
90 * Additional options that can be set for config: SA_1FM_AT_EOT
93 #ifndef UNUSED_PARAMETER
94 #define UNUSED_PARAMETER(x) x = x
98 if (((ccb)->ccb_h.status & CAM_DEV_QFRZN) != 0) \
99 cam_release_devq((ccb)->ccb_h.path, 0, 0, 0, FALSE)
105 MALLOC_DEFINE(M_SCSISA, "SCSI sa", "SCSI sequential access buffers");
108 SA_STATE_NORMAL, SA_STATE_ABNORMAL
111 #define ccb_pflags ppriv_field0
112 #define ccb_bp ppriv_ptr1
114 #define SA_CCB_BUFFER_IO 0x0
115 #define SA_CCB_WAITING 0x1
116 #define SA_CCB_TYPEMASK 0x1
117 #define SA_POSITION_UPDATED 0x2
119 #define Set_CCB_Type(x, type) \
120 x->ccb_h.ccb_pflags &= ~SA_CCB_TYPEMASK; \
121 x->ccb_h.ccb_pflags |= type
123 #define CCB_Type(x) (x->ccb_h.ccb_pflags & SA_CCB_TYPEMASK)
128 SA_FLAG_OPEN = 0x0001,
129 SA_FLAG_FIXED = 0x0002,
130 SA_FLAG_TAPE_LOCKED = 0x0004,
131 SA_FLAG_TAPE_MOUNTED = 0x0008,
132 SA_FLAG_TAPE_WP = 0x0010,
133 SA_FLAG_TAPE_WRITTEN = 0x0020,
134 SA_FLAG_EOM_PENDING = 0x0040,
135 SA_FLAG_EIO_PENDING = 0x0080,
136 SA_FLAG_EOF_PENDING = 0x0100,
137 SA_FLAG_ERR_PENDING = (SA_FLAG_EOM_PENDING|SA_FLAG_EIO_PENDING|
138 SA_FLAG_EOF_PENDING),
139 SA_FLAG_INVALID = 0x0200,
140 SA_FLAG_COMP_ENABLED = 0x0400,
141 SA_FLAG_COMP_SUPP = 0x0800,
142 SA_FLAG_COMP_UNSUPP = 0x1000,
143 SA_FLAG_TAPE_FROZEN = 0x2000
147 SA_MODE_REWIND = 0x00,
148 SA_MODE_NOREWIND = 0x01,
149 SA_MODE_OFFLINE = 0x02
153 SA_PARAM_NONE = 0x00,
154 SA_PARAM_BLOCKSIZE = 0x01,
155 SA_PARAM_DENSITY = 0x02,
156 SA_PARAM_COMPRESSION = 0x04,
157 SA_PARAM_BUFF_MODE = 0x08,
158 SA_PARAM_NUMBLOCKS = 0x10,
160 SA_PARAM_SPEED = 0x40,
165 SA_QUIRK_NONE = 0x00,
166 SA_QUIRK_NOCOMP = 0x01, /* Can't deal with compression at all */
167 SA_QUIRK_FIXED = 0x02, /* Force fixed mode */
168 SA_QUIRK_VARIABLE = 0x04, /* Force variable mode */
169 SA_QUIRK_2FM = 0x08, /* Needs Two File Marks at EOD */
170 SA_QUIRK_1FM = 0x10, /* No more than 1 File Mark at EOD */
171 SA_QUIRK_NODREAD = 0x20, /* Don't try and dummy read density */
172 SA_QUIRK_NO_MODESEL = 0x40, /* Don't do mode select at all */
173 SA_QUIRK_NO_CPAGE = 0x80 /* Don't use DEVICE COMPRESSION page */
176 #define SAMODE(z) (dev2unit(z) & 0x3)
177 #define SADENSITY(z) ((dev2unit(z) >> 2) & 0x3)
178 #define SA_IS_CTRL(z) (dev2unit(z) & (1 << 4))
180 #define SA_NOT_CTLDEV 0
184 #define SA_ATYPE_NR 1
185 #define SA_ATYPE_ER 2
187 #define SAMINOR(ctl, mode, access) \
188 ((ctl << 4) | (mode << 2) | (access & 0x3))
190 #define SA_NUM_MODES 4
192 struct cdev *ctl_dev;
193 struct sa_mode_devs {
197 } mode_devs[SA_NUM_MODES];
204 struct bio_queue_head bio_queue;
206 struct devstat *device_stats;
213 u_int32_t comp_algorithm;
214 u_int32_t saved_comp_algorithm;
215 u_int32_t media_blksize;
216 u_int32_t last_media_blksize;
217 u_int32_t media_numblks;
218 u_int8_t media_density;
221 u_int8_t dsreg; /* mtio mt_dsreg, redux */
225 int last_resid_was_io;
228 * Relative to BOT Location.
237 struct scsi_sense_data _last_io_sense;
238 u_int32_t _last_io_resid;
239 u_int8_t _last_io_cdb[CAM_MAX_CDBLEN];
240 struct scsi_sense_data _last_ctl_sense;
241 u_int32_t _last_ctl_resid;
242 u_int8_t _last_ctl_cdb[CAM_MAX_CDBLEN];
243 #define last_io_sense errinfo._last_io_sense
244 #define last_io_resid errinfo._last_io_resid
245 #define last_io_cdb errinfo._last_io_cdb
246 #define last_ctl_sense errinfo._last_ctl_sense
247 #define last_ctl_resid errinfo._last_ctl_resid
248 #define last_ctl_cdb errinfo._last_ctl_cdb
251 * Misc other flags/state
255 open_rdonly : 1, /* open read-only */
256 open_pending_mount : 1, /* open pending mount */
257 ctrl_mode : 1; /* control device open */
260 struct sa_quirk_entry {
261 struct scsi_inquiry_pattern inq_pat; /* matching pattern */
262 sa_quirks quirks; /* specific quirk type */
263 u_int32_t prefblk; /* preferred blocksize when in fixed mode */
266 static struct sa_quirk_entry sa_quirk_table[] =
269 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "OnStream",
270 "ADR*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_NODREAD |
271 SA_QUIRK_1FM|SA_QUIRK_NO_MODESEL, 32768
274 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
275 "Python 06408*", "*"}, SA_QUIRK_NODREAD, 0
278 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
279 "Python 25601*", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_NODREAD, 0
282 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
283 "Python*", "*"}, SA_QUIRK_NODREAD, 0
286 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
287 "VIPER 150*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
290 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
291 "VIPER 2525 25462", "-011"},
292 SA_QUIRK_NOCOMP|SA_QUIRK_1FM|SA_QUIRK_NODREAD, 0
295 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
296 "VIPER 2525*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024
300 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
301 "C15*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_NO_CPAGE, 0,
305 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
306 "C56*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
309 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
310 "T20*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
313 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
314 "T4000*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
317 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
318 "HP-88780*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
321 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "KENNEDY",
322 "*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
325 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "M4 DATA",
326 "123107 SCSI*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
328 { /* jreynold@primenet.com */
329 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "Seagate",
330 "STT8000N*", "*"}, SA_QUIRK_1FM, 0
332 { /* mike@sentex.net */
333 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "Seagate",
334 "STT20000*", "*"}, SA_QUIRK_1FM, 0
337 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
338 " TDC 3600", "U07:"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
341 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
342 " TDC 3800", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
345 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
346 " TDC 4100", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
349 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
350 " TDC 4200", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
353 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
354 " SLR*", "*"}, SA_QUIRK_1FM, 0
357 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK",
358 "5525ES*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
361 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK",
362 "51000*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024
366 static d_open_t saopen;
367 static d_close_t saclose;
368 static d_strategy_t sastrategy;
369 static d_ioctl_t saioctl;
370 static periph_init_t sainit;
371 static periph_ctor_t saregister;
372 static periph_oninv_t saoninvalidate;
373 static periph_dtor_t sacleanup;
374 static periph_start_t sastart;
375 static void saasync(void *callback_arg, u_int32_t code,
376 struct cam_path *path, void *arg);
377 static void sadone(struct cam_periph *periph,
378 union ccb *start_ccb);
379 static int saerror(union ccb *ccb, u_int32_t cam_flags,
380 u_int32_t sense_flags);
381 static int samarkswanted(struct cam_periph *);
382 static int sacheckeod(struct cam_periph *periph);
383 static int sagetparams(struct cam_periph *periph,
384 sa_params params_to_get,
385 u_int32_t *blocksize, u_int8_t *density,
386 u_int32_t *numblocks, int *buff_mode,
387 u_int8_t *write_protect, u_int8_t *speed,
388 int *comp_supported, int *comp_enabled,
389 u_int32_t *comp_algorithm,
390 sa_comp_t *comp_page);
391 static int sasetparams(struct cam_periph *periph,
392 sa_params params_to_set,
393 u_int32_t blocksize, u_int8_t density,
394 u_int32_t comp_algorithm,
395 u_int32_t sense_flags);
396 static void saprevent(struct cam_periph *periph, int action);
397 static int sarewind(struct cam_periph *periph);
398 static int saspace(struct cam_periph *periph, int count,
399 scsi_space_code code);
400 static int samount(struct cam_periph *, int, struct cdev *);
401 static int saretension(struct cam_periph *periph);
402 static int sareservereleaseunit(struct cam_periph *periph,
404 static int saloadunload(struct cam_periph *periph, int load);
405 static int saerase(struct cam_periph *periph, int longerase);
406 static int sawritefilemarks(struct cam_periph *periph,
407 int nmarks, int setmarks);
408 static int sardpos(struct cam_periph *periph, int, u_int32_t *);
409 static int sasetpos(struct cam_periph *periph, int, u_int32_t *);
412 static struct periph_driver sadriver =
415 TAILQ_HEAD_INITIALIZER(sadriver.units), /* generation */ 0
418 PERIPHDRIVER_DECLARE(sa, sadriver);
420 /* For 2.2-stable support */
426 static struct cdevsw sa_cdevsw = {
427 .d_version = D_VERSION,
431 .d_write = physwrite,
433 .d_strategy = sastrategy,
435 .d_flags = D_TAPE | D_NEEDGIANT,
439 saopen(struct cdev *dev, int flags, int fmt, struct thread *td)
441 struct cam_periph *periph;
442 struct sa_softc *softc;
445 periph = (struct cam_periph *)dev->si_drv1;
446 if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
450 cam_periph_lock(periph);
452 softc = (struct sa_softc *)periph->softc;
454 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO,
455 ("saopen(%s): softc=0x%x\n", devtoname(dev), softc->flags));
457 if (SA_IS_CTRL(dev)) {
458 softc->ctrl_mode = 1;
459 cam_periph_unlock(periph);
463 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
464 cam_periph_unlock(periph);
465 cam_periph_release(periph);
469 if (softc->flags & SA_FLAG_OPEN) {
471 } else if (softc->flags & SA_FLAG_INVALID) {
475 * Preserve whether this is a read_only open.
477 softc->open_rdonly = (flags & O_RDWR) == O_RDONLY;
480 * The function samount ensures media is loaded and ready.
481 * It also does a device RESERVE if the tape isn't yet mounted.
483 * If the mount fails and this was a non-blocking open,
484 * make this a 'open_pending_mount' action.
486 error = samount(periph, flags, dev);
487 if (error && (flags & O_NONBLOCK)) {
488 softc->flags |= SA_FLAG_OPEN;
489 softc->open_pending_mount = 1;
490 cam_periph_unhold(periph);
491 cam_periph_unlock(periph);
497 cam_periph_unhold(periph);
498 cam_periph_unlock(periph);
499 cam_periph_release(periph);
503 saprevent(periph, PR_PREVENT);
504 softc->flags |= SA_FLAG_OPEN;
506 cam_periph_unhold(periph);
507 cam_periph_unlock(periph);
512 saclose(struct cdev *dev, int flag, int fmt, struct thread *td)
514 struct cam_periph *periph;
515 struct sa_softc *softc;
516 int mode, error, writing, tmp;
517 int closedbits = SA_FLAG_OPEN;
520 periph = (struct cam_periph *)dev->si_drv1;
524 cam_periph_lock(periph);
526 softc = (struct sa_softc *)periph->softc;
528 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO,
529 ("saclose(%s): softc=0x%x\n", devtoname(dev), softc->flags));
532 softc->open_rdonly = 0;
533 if (SA_IS_CTRL(dev)) {
534 softc->ctrl_mode = 0;
535 cam_periph_unlock(periph);
536 cam_periph_release(periph);
540 if (softc->open_pending_mount) {
541 softc->flags &= ~SA_FLAG_OPEN;
542 softc->open_pending_mount = 0;
543 cam_periph_unlock(periph);
544 cam_periph_release(periph);
548 if ((error = cam_periph_hold(periph, PRIBIO)) != 0) {
549 cam_periph_unlock(periph);
554 * Were we writing the tape?
556 writing = (softc->flags & SA_FLAG_TAPE_WRITTEN) != 0;
559 * See whether or not we need to write filemarks. If this
560 * fails, we probably have to assume we've lost tape
563 error = sacheckeod(periph);
565 xpt_print(periph->path,
566 "failed to write terminating filemark(s)\n");
567 softc->flags |= SA_FLAG_TAPE_FROZEN;
571 * Whatever we end up doing, allow users to eject tapes from here on.
573 saprevent(periph, PR_ALLOW);
576 * Decide how to end...
578 if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) {
579 closedbits |= SA_FLAG_TAPE_FROZEN;
580 } else switch (mode) {
581 case SA_MODE_OFFLINE:
583 * An 'offline' close is an unconditional release of
584 * frozen && mount conditions, irrespective of whether
585 * these operations succeeded. The reason for this is
586 * to allow at least some kind of programmatic way
587 * around our state getting all fouled up. If somebody
588 * issues an 'offline' command, that will be allowed
591 (void) sarewind(periph);
592 (void) saloadunload(periph, FALSE);
593 closedbits |= SA_FLAG_TAPE_MOUNTED|SA_FLAG_TAPE_FROZEN;
597 * If the rewind fails, return an error- if anyone cares,
598 * but not overwriting any previous error.
600 * We don't clear the notion of mounted here, but we do
601 * clear the notion of frozen if we successfully rewound.
603 tmp = sarewind(periph);
608 closedbits |= SA_FLAG_TAPE_FROZEN;
611 case SA_MODE_NOREWIND:
613 * If we're not rewinding/unloading the tape, find out
614 * whether we need to back up over one of two filemarks
615 * we wrote (if we wrote two filemarks) so that appends
616 * from this point on will be sane.
618 if (error == 0 && writing && (softc->quirks & SA_QUIRK_2FM)) {
619 tmp = saspace(periph, -1, SS_FILEMARKS);
621 xpt_print(periph->path, "unable to backspace "
622 "over one of double filemarks at end of "
624 xpt_print(periph->path, "it is possible that "
625 "this device needs a SA_QUIRK_1FM quirk set"
627 softc->flags |= SA_FLAG_TAPE_FROZEN;
632 xpt_print(periph->path, "unknown mode 0x%x in saclose\n", mode);
638 * We wish to note here that there are no more filemarks to be written.
640 softc->filemarks = 0;
641 softc->flags &= ~SA_FLAG_TAPE_WRITTEN;
644 * And we are no longer open for business.
646 softc->flags &= ~closedbits;
649 * Inform users if tape state if frozen....
651 if (softc->flags & SA_FLAG_TAPE_FROZEN) {
652 xpt_print(periph->path, "tape is now frozen- use an OFFLINE, "
653 "REWIND or MTEOM command to clear this state.\n");
656 /* release the device if it is no longer mounted */
657 if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0)
658 sareservereleaseunit(periph, FALSE);
660 cam_periph_unhold(periph);
661 cam_periph_unlock(periph);
662 cam_periph_release(periph);
668 * Actually translate the requested transfer into one the physical driver
669 * can understand. The transfer is described by a buf and will include
670 * only one physical transfer.
673 sastrategy(struct bio *bp)
675 struct cam_periph *periph;
676 struct sa_softc *softc;
678 bp->bio_resid = bp->bio_bcount;
679 if (SA_IS_CTRL(bp->bio_dev)) {
680 biofinish(bp, NULL, EINVAL);
683 periph = (struct cam_periph *)bp->bio_dev->si_drv1;
684 if (periph == NULL) {
685 biofinish(bp, NULL, ENXIO);
688 cam_periph_lock(periph);
690 softc = (struct sa_softc *)periph->softc;
692 if (softc->flags & SA_FLAG_INVALID) {
693 cam_periph_unlock(periph);
694 biofinish(bp, NULL, ENXIO);
698 if (softc->flags & SA_FLAG_TAPE_FROZEN) {
699 cam_periph_unlock(periph);
700 biofinish(bp, NULL, EPERM);
705 * This should actually never occur as the write(2)
706 * system call traps attempts to write to a read-only
709 if (bp->bio_cmd == BIO_WRITE && softc->open_rdonly) {
710 cam_periph_unlock(periph);
711 biofinish(bp, NULL, EBADF);
715 if (softc->open_pending_mount) {
716 int error = samount(periph, 0, bp->bio_dev);
718 cam_periph_unlock(periph);
719 biofinish(bp, NULL, ENXIO);
722 saprevent(periph, PR_PREVENT);
723 softc->open_pending_mount = 0;
728 * If it's a null transfer, return immediately
730 if (bp->bio_bcount == 0) {
731 cam_periph_unlock(periph);
737 if (softc->flags & SA_FLAG_FIXED) {
739 * Fixed block device. The byte count must
740 * be a multiple of our block size.
742 if (((softc->blk_mask != ~0) &&
743 ((bp->bio_bcount & softc->blk_mask) != 0)) ||
744 ((softc->blk_mask == ~0) &&
745 ((bp->bio_bcount % softc->min_blk) != 0))) {
746 xpt_print(periph->path, "Invalid request. Fixed block "
747 "device requests must be a multiple of %d bytes\n",
749 cam_periph_unlock(periph);
750 biofinish(bp, NULL, EINVAL);
753 } else if ((bp->bio_bcount > softc->max_blk) ||
754 (bp->bio_bcount < softc->min_blk) ||
755 (bp->bio_bcount & softc->blk_mask) != 0) {
757 xpt_print_path(periph->path);
758 printf("Invalid request. Variable block "
759 "device requests must be ");
760 if (softc->blk_mask != 0) {
761 printf("a multiple of %d ", (0x1 << softc->blk_gran));
763 printf("between %d and %d bytes\n", softc->min_blk,
765 cam_periph_unlock(periph);
766 biofinish(bp, NULL, EINVAL);
771 * Place it at the end of the queue.
773 bioq_insert_tail(&softc->bio_queue, bp);
774 softc->queue_count++;
776 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
777 ("sastrategy: queuing a %ld %s byte %s\n", bp->bio_bcount,
778 (softc->flags & SA_FLAG_FIXED)? "fixed" : "variable",
779 (bp->bio_cmd == BIO_READ)? "read" : "write"));
781 if (softc->queue_count > 1) {
782 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
783 ("sastrategy: queue count now %d\n", softc->queue_count));
787 * Schedule ourselves for performing the work.
789 xpt_schedule(periph, CAM_PRIORITY_NORMAL);
790 cam_periph_unlock(periph);
796 #define PENDING_MOUNT_CHECK(softc, periph, dev) \
797 if (softc->open_pending_mount) { \
798 error = samount(periph, 0, dev); \
802 saprevent(periph, PR_PREVENT); \
803 softc->open_pending_mount = 0; \
807 saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
809 struct cam_periph *periph;
810 struct sa_softc *softc;
811 scsi_space_code spaceop;
812 int didlockperiph = 0;
817 error = 0; /* shut up gcc */
818 spaceop = 0; /* shut up gcc */
820 periph = (struct cam_periph *)dev->si_drv1;
824 cam_periph_lock(periph);
825 softc = (struct sa_softc *)periph->softc;
828 * Check for control mode accesses. We allow MTIOCGET and
829 * MTIOCERRSTAT (but need to be the only one open in order
830 * to clear latched status), and MTSETBSIZE, MTSETDNSTY
831 * and MTCOMP (but need to be the only one accessing this
832 * device to run those).
835 if (SA_IS_CTRL(dev)) {
837 case MTIOCGETEOTMODEL:
842 * If the periph isn't already locked, lock it
843 * so our MTIOCERRSTAT can reset latched error stats.
845 * If the periph is already locked, skip it because
846 * we're just getting status and it'll be up to the
847 * other thread that has this device open to do
848 * an MTIOCERRSTAT that would clear latched status.
850 if ((periph->flags & CAM_PERIPH_LOCKED) == 0) {
851 error = cam_periph_hold(periph, PRIBIO|PCATCH);
860 struct mtop *mt = (struct mtop *) arg;
863 * Check to make sure it's an OP we can perform
864 * with no media inserted.
880 case MTIOCSETEOTMODEL:
882 * We need to acquire the peripheral here rather
883 * than at open time because we are sharing writable
884 * access to data structures.
886 error = cam_periph_hold(periph, PRIBIO|PCATCH);
898 * Find the device that the user is talking about
903 struct mtget *g = (struct mtget *)arg;
906 * If this isn't the control mode device, actually go out
907 * and ask the drive again what it's set to.
909 if (!SA_IS_CTRL(dev) && !softc->open_pending_mount) {
910 u_int8_t write_protect;
911 int comp_enabled, comp_supported;
912 error = sagetparams(periph, SA_PARAM_ALL,
913 &softc->media_blksize, &softc->media_density,
914 &softc->media_numblks, &softc->buffer_mode,
915 &write_protect, &softc->speed, &comp_supported,
916 &comp_enabled, &softc->comp_algorithm, NULL);
920 softc->flags |= SA_FLAG_TAPE_WP;
922 softc->flags &= ~SA_FLAG_TAPE_WP;
923 softc->flags &= ~(SA_FLAG_COMP_SUPP|
924 SA_FLAG_COMP_ENABLED|SA_FLAG_COMP_UNSUPP);
925 if (comp_supported) {
926 if (softc->saved_comp_algorithm == 0)
927 softc->saved_comp_algorithm =
928 softc->comp_algorithm;
929 softc->flags |= SA_FLAG_COMP_SUPP;
931 softc->flags |= SA_FLAG_COMP_ENABLED;
933 softc->flags |= SA_FLAG_COMP_UNSUPP;
935 bzero(g, sizeof(struct mtget));
936 g->mt_type = MT_ISAR;
937 if (softc->flags & SA_FLAG_COMP_UNSUPP) {
938 g->mt_comp = MT_COMP_UNSUPP;
939 g->mt_comp0 = MT_COMP_UNSUPP;
940 g->mt_comp1 = MT_COMP_UNSUPP;
941 g->mt_comp2 = MT_COMP_UNSUPP;
942 g->mt_comp3 = MT_COMP_UNSUPP;
944 if ((softc->flags & SA_FLAG_COMP_ENABLED) == 0) {
945 g->mt_comp = MT_COMP_DISABLED;
947 g->mt_comp = softc->comp_algorithm;
949 g->mt_comp0 = softc->comp_algorithm;
950 g->mt_comp1 = softc->comp_algorithm;
951 g->mt_comp2 = softc->comp_algorithm;
952 g->mt_comp3 = softc->comp_algorithm;
954 g->mt_density = softc->media_density;
955 g->mt_density0 = softc->media_density;
956 g->mt_density1 = softc->media_density;
957 g->mt_density2 = softc->media_density;
958 g->mt_density3 = softc->media_density;
959 g->mt_blksiz = softc->media_blksize;
960 g->mt_blksiz0 = softc->media_blksize;
961 g->mt_blksiz1 = softc->media_blksize;
962 g->mt_blksiz2 = softc->media_blksize;
963 g->mt_blksiz3 = softc->media_blksize;
964 g->mt_fileno = softc->fileno;
965 g->mt_blkno = softc->blkno;
966 g->mt_dsreg = (short) softc->dsreg;
968 * Yes, we know that this is likely to overflow
970 if (softc->last_resid_was_io) {
971 if ((g->mt_resid = (short) softc->last_io_resid) != 0) {
972 if (SA_IS_CTRL(dev) == 0 || didlockperiph) {
973 softc->last_io_resid = 0;
977 if ((g->mt_resid = (short)softc->last_ctl_resid) != 0) {
978 if (SA_IS_CTRL(dev) == 0 || didlockperiph) {
979 softc->last_ctl_resid = 0;
988 struct scsi_tape_errors *sep =
989 &((union mterrstat *)arg)->scsi_errstat;
991 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
992 ("saioctl: MTIOCERRSTAT\n"));
994 bzero(sep, sizeof(*sep));
995 sep->io_resid = softc->last_io_resid;
996 bcopy((caddr_t) &softc->last_io_sense, sep->io_sense,
997 sizeof (sep->io_sense));
998 bcopy((caddr_t) &softc->last_io_cdb, sep->io_cdb,
999 sizeof (sep->io_cdb));
1000 sep->ctl_resid = softc->last_ctl_resid;
1001 bcopy((caddr_t) &softc->last_ctl_sense, sep->ctl_sense,
1002 sizeof (sep->ctl_sense));
1003 bcopy((caddr_t) &softc->last_ctl_cdb, sep->ctl_cdb,
1004 sizeof (sep->ctl_cdb));
1006 if ((SA_IS_CTRL(dev) == 0 && softc->open_pending_mount) ||
1008 bzero((caddr_t) &softc->errinfo,
1009 sizeof (softc->errinfo));
1018 PENDING_MOUNT_CHECK(softc, periph, dev);
1020 mt = (struct mtop *)arg;
1023 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
1024 ("saioctl: op=0x%x count=0x%x\n",
1025 mt->mt_op, mt->mt_count));
1027 count = mt->mt_count;
1028 switch (mt->mt_op) {
1029 case MTWEOF: /* write an end-of-file marker */
1031 * We don't need to clear the SA_FLAG_TAPE_WRITTEN
1032 * flag because by keeping track of filemarks
1033 * we have last written we know ehether or not
1034 * we need to write more when we close the device.
1036 error = sawritefilemarks(periph, count, FALSE);
1038 case MTWSS: /* write a setmark */
1039 error = sawritefilemarks(periph, count, TRUE);
1041 case MTBSR: /* backward space record */
1042 case MTFSR: /* forward space record */
1043 case MTBSF: /* backward space file */
1044 case MTFSF: /* forward space file */
1045 case MTBSS: /* backward space setmark */
1046 case MTFSS: /* forward space setmark */
1047 case MTEOD: /* space to end of recorded medium */
1051 spaceop = SS_FILEMARKS;
1052 nmarks = softc->filemarks;
1053 error = sacheckeod(periph);
1055 xpt_print(periph->path,
1056 "EOD check prior to spacing failed\n");
1057 softc->flags |= SA_FLAG_EIO_PENDING;
1060 nmarks -= softc->filemarks;
1066 spaceop = SS_BLOCKS;
1077 spaceop = SS_SETMARKS;
1091 nmarks = softc->filemarks;
1093 * XXX: Why are we checking again?
1095 error = sacheckeod(periph);
1098 nmarks -= softc->filemarks;
1099 error = saspace(periph, count - nmarks, spaceop);
1101 * At this point, clear that we've written the tape
1102 * and that we've written any filemarks. We really
1103 * don't know what the applications wishes to do next-
1104 * the sacheckeod's will make sure we terminated the
1105 * tape correctly if we'd been writing, but the next
1106 * action the user application takes will set again
1107 * whether we need to write filemarks.
1110 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
1111 softc->filemarks = 0;
1114 case MTREW: /* rewind */
1115 PENDING_MOUNT_CHECK(softc, periph, dev);
1116 (void) sacheckeod(periph);
1117 error = sarewind(periph);
1120 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
1121 softc->flags &= ~SA_FLAG_ERR_PENDING;
1122 softc->filemarks = 0;
1124 case MTERASE: /* erase */
1125 PENDING_MOUNT_CHECK(softc, periph, dev);
1126 error = saerase(periph, count);
1128 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
1129 softc->flags &= ~SA_FLAG_ERR_PENDING;
1131 case MTRETENS: /* re-tension tape */
1132 PENDING_MOUNT_CHECK(softc, periph, dev);
1133 error = saretension(periph);
1135 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
1136 softc->flags &= ~SA_FLAG_ERR_PENDING;
1138 case MTOFFL: /* rewind and put the drive offline */
1140 PENDING_MOUNT_CHECK(softc, periph, dev);
1142 (void) sacheckeod(periph);
1144 softc->flags &= ~SA_FLAG_TAPE_WRITTEN;
1145 softc->filemarks = 0;
1147 error = sarewind(periph);
1148 /* clear the frozen flag anyway */
1149 softc->flags &= ~SA_FLAG_TAPE_FROZEN;
1152 * Be sure to allow media removal before ejecting.
1155 saprevent(periph, PR_ALLOW);
1157 error = saloadunload(periph, FALSE);
1159 softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
1164 case MTNOP: /* no operation, sets status only */
1165 case MTCACHE: /* enable controller cache */
1166 case MTNOCACHE: /* disable controller cache */
1170 case MTSETBSIZ: /* Set block size for device */
1172 PENDING_MOUNT_CHECK(softc, periph, dev);
1174 error = sasetparams(periph, SA_PARAM_BLOCKSIZE, count,
1177 softc->last_media_blksize =
1178 softc->media_blksize;
1179 softc->media_blksize = count;
1181 softc->flags |= SA_FLAG_FIXED;
1182 if (powerof2(count)) {
1185 softc->blk_mask = count - 1;
1187 softc->blk_mask = ~0;
1188 softc->blk_shift = 0;
1191 * Make the user's desire 'persistent'.
1193 softc->quirks &= ~SA_QUIRK_VARIABLE;
1194 softc->quirks |= SA_QUIRK_FIXED;
1196 softc->flags &= ~SA_FLAG_FIXED;
1197 if (softc->max_blk == 0) {
1198 softc->max_blk = ~0;
1200 softc->blk_shift = 0;
1201 if (softc->blk_gran != 0) {
1203 softc->blk_gran - 1;
1205 softc->blk_mask = 0;
1208 * Make the user's desire 'persistent'.
1210 softc->quirks |= SA_QUIRK_VARIABLE;
1211 softc->quirks &= ~SA_QUIRK_FIXED;
1215 case MTSETDNSTY: /* Set density for device and mode */
1216 PENDING_MOUNT_CHECK(softc, periph, dev);
1218 if (count > UCHAR_MAX) {
1222 error = sasetparams(periph, SA_PARAM_DENSITY,
1226 case MTCOMP: /* enable compression */
1227 PENDING_MOUNT_CHECK(softc, periph, dev);
1229 * Some devices don't support compression, and
1230 * don't like it if you ask them for the
1233 if ((softc->quirks & SA_QUIRK_NOCOMP) ||
1234 (softc->flags & SA_FLAG_COMP_UNSUPP)) {
1238 error = sasetparams(periph, SA_PARAM_COMPRESSION,
1239 0, 0, count, SF_NO_PRINT);
1251 PENDING_MOUNT_CHECK(softc, periph, dev);
1252 error = sardpos(periph, 0, (u_int32_t *) arg);
1255 PENDING_MOUNT_CHECK(softc, periph, dev);
1256 error = sardpos(periph, 1, (u_int32_t *) arg);
1259 PENDING_MOUNT_CHECK(softc, periph, dev);
1260 error = sasetpos(periph, 0, (u_int32_t *) arg);
1263 PENDING_MOUNT_CHECK(softc, periph, dev);
1264 error = sasetpos(periph, 1, (u_int32_t *) arg);
1266 case MTIOCGETEOTMODEL:
1268 if (softc->quirks & SA_QUIRK_1FM)
1272 *((u_int32_t *) arg) = mode;
1274 case MTIOCSETEOTMODEL:
1276 switch (*((u_int32_t *) arg)) {
1278 softc->quirks &= ~SA_QUIRK_2FM;
1279 softc->quirks |= SA_QUIRK_1FM;
1282 softc->quirks &= ~SA_QUIRK_1FM;
1283 softc->quirks |= SA_QUIRK_2FM;
1291 error = cam_periph_ioctl(periph, cmd, arg, saerror);
1296 * Check to see if we cleared a frozen state
1298 if (error == 0 && (softc->flags & SA_FLAG_TAPE_FROZEN)) {
1304 softc->fileno = (daddr_t) -1;
1305 softc->blkno = (daddr_t) -1;
1306 softc->flags &= ~SA_FLAG_TAPE_FROZEN;
1307 xpt_print(periph->path,
1308 "tape state now unfrozen.\n");
1314 if (didlockperiph) {
1315 cam_periph_unhold(periph);
1317 cam_periph_unlock(periph);
1327 * Install a global async callback.
1329 status = xpt_register_async(AC_FOUND_DEVICE, saasync, NULL, NULL);
1331 if (status != CAM_REQ_CMP) {
1332 printf("sa: Failed to attach master async callback "
1333 "due to status 0x%x!\n", status);
1338 saoninvalidate(struct cam_periph *periph)
1340 struct sa_softc *softc;
1342 softc = (struct sa_softc *)periph->softc;
1345 * De-register any async callbacks.
1347 xpt_register_async(0, saasync, periph, periph->path);
1349 softc->flags |= SA_FLAG_INVALID;
1352 * Return all queued I/O with ENXIO.
1353 * XXX Handle any transactions queued to the card
1354 * with XPT_ABORT_CCB.
1356 bioq_flush(&softc->bio_queue, NULL, ENXIO);
1357 softc->queue_count = 0;
1359 xpt_print(periph->path, "lost device\n");
1364 sacleanup(struct cam_periph *periph)
1366 struct sa_softc *softc;
1369 softc = (struct sa_softc *)periph->softc;
1371 xpt_print(periph->path, "removing device entry\n");
1372 devstat_remove_entry(softc->device_stats);
1373 cam_periph_unlock(periph);
1374 destroy_dev(softc->devs.ctl_dev);
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);
1380 cam_periph_lock(periph);
1381 free(softc, M_SCSISA);
1385 saasync(void *callback_arg, u_int32_t code,
1386 struct cam_path *path, void *arg)
1388 struct cam_periph *periph;
1390 periph = (struct cam_periph *)callback_arg;
1392 case AC_FOUND_DEVICE:
1394 struct ccb_getdev *cgd;
1397 cgd = (struct ccb_getdev *)arg;
1401 if (cgd->protocol != PROTO_SCSI)
1404 if (SID_TYPE(&cgd->inq_data) != T_SEQUENTIAL)
1408 * Allocate a peripheral instance for
1409 * this device and start the probe
1412 status = cam_periph_alloc(saregister, saoninvalidate,
1414 "sa", CAM_PERIPH_BIO, cgd->ccb_h.path,
1415 saasync, AC_FOUND_DEVICE, cgd);
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);
1424 cam_periph_async(periph, code, path, arg);
1430 saregister(struct cam_periph *periph, void *arg)
1432 struct sa_softc *softc;
1433 struct ccb_getdev *cgd;
1437 cgd = (struct ccb_getdev *)arg;
1438 if (periph == NULL) {
1439 printf("saregister: periph was NULL!!\n");
1440 return (CAM_REQ_CMP_ERR);
1444 printf("saregister: no getdev CCB, can't register device\n");
1445 return (CAM_REQ_CMP_ERR);
1448 softc = (struct sa_softc *)
1449 malloc(sizeof (*softc), M_SCSISA, M_NOWAIT | M_ZERO);
1450 if (softc == NULL) {
1451 printf("saregister: Unable to probe new device. "
1452 "Unable to allocate softc\n");
1453 return (CAM_REQ_CMP_ERR);
1455 softc->scsi_rev = SID_ANSI_REV(&cgd->inq_data);
1456 softc->state = SA_STATE_NORMAL;
1457 softc->fileno = (daddr_t) -1;
1458 softc->blkno = (daddr_t) -1;
1460 bioq_init(&softc->bio_queue);
1461 periph->softc = softc;
1464 * See if this device has any quirks.
1466 match = cam_quirkmatch((caddr_t)&cgd->inq_data,
1467 (caddr_t)sa_quirk_table,
1468 sizeof(sa_quirk_table)/sizeof(*sa_quirk_table),
1469 sizeof(*sa_quirk_table), scsi_inquiry_match);
1471 if (match != NULL) {
1472 softc->quirks = ((struct sa_quirk_entry *)match)->quirks;
1473 softc->last_media_blksize =
1474 ((struct sa_quirk_entry *)match)->prefblk;
1476 xpt_print(periph->path, "found quirk entry %d\n",
1477 (int) (((struct sa_quirk_entry *) match) - sa_quirk_table));
1480 softc->quirks = SA_QUIRK_NONE;
1483 * The SA driver supports a blocksize, but we don't know the
1484 * blocksize until we media is inserted. So, set a flag to
1485 * indicate that the blocksize is unavailable right now.
1487 cam_periph_unlock(periph);
1488 softc->device_stats = devstat_new_entry("sa", periph->unit_number, 0,
1489 DEVSTAT_BS_UNAVAILABLE, SID_TYPE(&cgd->inq_data) |
1490 DEVSTAT_TYPE_IF_SCSI, DEVSTAT_PRIORITY_TAPE);
1492 softc->devs.ctl_dev = make_dev(&sa_cdevsw, SAMINOR(SA_CTLDEV,
1493 0, SA_ATYPE_R), UID_ROOT, GID_OPERATOR,
1494 0660, "%s%d.ctl", periph->periph_name, periph->unit_number);
1495 softc->devs.ctl_dev->si_drv1 = periph;
1497 for (i = 0; i < SA_NUM_MODES; i++) {
1499 softc->devs.mode_devs[i].r_dev = make_dev(&sa_cdevsw,
1500 SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_R),
1501 UID_ROOT, GID_OPERATOR, 0660, "%s%d.%d",
1502 periph->periph_name, periph->unit_number, i);
1503 softc->devs.mode_devs[i].r_dev->si_drv1 = periph;
1505 softc->devs.mode_devs[i].nr_dev = make_dev(&sa_cdevsw,
1506 SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_NR),
1507 UID_ROOT, GID_OPERATOR, 0660, "n%s%d.%d",
1508 periph->periph_name, periph->unit_number, i);
1509 softc->devs.mode_devs[i].nr_dev->si_drv1 = periph;
1511 softc->devs.mode_devs[i].er_dev = make_dev(&sa_cdevsw,
1512 SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_ER),
1513 UID_ROOT, GID_OPERATOR, 0660, "e%s%d.%d",
1514 periph->periph_name, periph->unit_number, i);
1515 softc->devs.mode_devs[i].er_dev->si_drv1 = periph;
1518 * Make the (well known) aliases for the first mode.
1523 alias = make_dev_alias(softc->devs.mode_devs[i].r_dev,
1524 "%s%d", periph->periph_name, periph->unit_number);
1525 alias->si_drv1 = periph;
1526 alias = make_dev_alias(softc->devs.mode_devs[i].nr_dev,
1527 "n%s%d", periph->periph_name, periph->unit_number);
1528 alias->si_drv1 = periph;
1529 alias = make_dev_alias(softc->devs.mode_devs[i].er_dev,
1530 "e%s%d", periph->periph_name, periph->unit_number);
1531 alias->si_drv1 = periph;
1534 cam_periph_lock(periph);
1537 * Add an async callback so that we get
1538 * notified if this device goes away.
1540 xpt_register_async(AC_LOST_DEVICE, saasync, periph, periph->path);
1542 xpt_announce_periph(periph, NULL);
1544 return (CAM_REQ_CMP);
1548 sastart(struct cam_periph *periph, union ccb *start_ccb)
1550 struct sa_softc *softc;
1552 softc = (struct sa_softc *)periph->softc;
1554 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sastart\n"));
1557 switch (softc->state) {
1558 case SA_STATE_NORMAL:
1560 /* Pull a buffer from the queue and get going on it */
1564 * See if there is a buf with work for us to do..
1566 bp = bioq_first(&softc->bio_queue);
1567 if (periph->immediate_priority <= periph->pinfo.priority) {
1568 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
1569 ("queuing for immediate ccb\n"));
1570 Set_CCB_Type(start_ccb, SA_CCB_WAITING);
1571 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
1573 periph->immediate_priority = CAM_PRIORITY_NONE;
1574 wakeup(&periph->ccb_list);
1575 } else if (bp == NULL) {
1576 xpt_release_ccb(start_ccb);
1577 } else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) {
1578 struct bio *done_bp;
1580 softc->queue_count--;
1581 bioq_remove(&softc->bio_queue, bp);
1582 bp->bio_resid = bp->bio_bcount;
1584 if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) {
1586 * We now just clear errors in this case
1587 * and let the residual be the notifier.
1590 } else if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) {
1592 * This can only happen if we're reading
1593 * in fixed length mode. In this case,
1594 * we dump the rest of the list the
1598 if (bioq_first(&softc->bio_queue) != NULL) {
1602 } else if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) {
1603 bp->bio_error = EIO;
1604 bp->bio_flags |= BIO_ERROR;
1606 bp = bioq_first(&softc->bio_queue);
1608 * Only if we have no other buffers queued up
1609 * do we clear the pending error flag.
1612 softc->flags &= ~SA_FLAG_ERR_PENDING;
1613 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1614 ("sastart- ERR_PENDING now 0x%x, bp is %sNULL, "
1615 "%d more buffers queued up\n",
1616 (softc->flags & SA_FLAG_ERR_PENDING),
1617 (bp != NULL)? "not " : " ", softc->queue_count));
1618 xpt_release_ccb(start_ccb);
1623 bioq_remove(&softc->bio_queue, bp);
1624 softc->queue_count--;
1626 if ((softc->flags & SA_FLAG_FIXED) != 0) {
1627 if (softc->blk_shift != 0) {
1629 bp->bio_bcount >> softc->blk_shift;
1630 } else if (softc->media_blksize != 0) {
1631 length = bp->bio_bcount /
1632 softc->media_blksize;
1634 bp->bio_error = EIO;
1635 xpt_print(periph->path, "zero blocksize"
1636 " for FIXED length writes?\n");
1641 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
1642 ("issuing a %d fixed record %s\n",
1643 length, (bp->bio_cmd == BIO_READ)? "read" :
1647 length = bp->bio_bcount;
1649 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
1650 ("issuing a %d variable byte %s\n",
1651 length, (bp->bio_cmd == BIO_READ)? "read" :
1655 devstat_start_transaction_bio(softc->device_stats, bp);
1657 * Some people have theorized that we should
1658 * suppress illegal length indication if we are
1659 * running in variable block mode so that we don't
1660 * have to request sense every time our requested
1661 * block size is larger than the written block.
1662 * The residual information from the ccb allows
1663 * us to identify this situation anyway. The only
1664 * problem with this is that we will not get
1665 * information about blocks that are larger than
1666 * our read buffer unless we set the block size
1667 * in the mode page to something other than 0.
1669 * I believe that this is a non-issue. If user apps
1670 * don't adjust their read size to match our record
1671 * size, that's just life. Anyway, the typical usage
1672 * would be to issue, e.g., 64KB reads and occasionally
1673 * have to do deal with 512 byte or 1KB intermediate
1676 softc->dsreg = (bp->bio_cmd == BIO_READ)?
1677 MTIO_DSREG_RD : MTIO_DSREG_WR;
1678 scsi_sa_read_write(&start_ccb->csio, 0, sadone,
1679 MSG_SIMPLE_Q_TAG, (bp->bio_cmd == BIO_READ),
1680 FALSE, (softc->flags & SA_FLAG_FIXED) != 0,
1681 length, bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE,
1683 start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED;
1684 Set_CCB_Type(start_ccb, SA_CCB_BUFFER_IO);
1685 start_ccb->ccb_h.ccb_bp = bp;
1686 bp = bioq_first(&softc->bio_queue);
1687 xpt_action(start_ccb);
1691 /* Have more work to do, so ensure we stay scheduled */
1692 xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1696 case SA_STATE_ABNORMAL:
1698 panic("state 0x%x in sastart", softc->state);
1705 sadone(struct cam_periph *periph, union ccb *done_ccb)
1707 struct sa_softc *softc;
1708 struct ccb_scsiio *csio;
1710 softc = (struct sa_softc *)periph->softc;
1711 csio = &done_ccb->csio;
1712 switch (CCB_Type(csio)) {
1713 case SA_CCB_BUFFER_IO:
1718 softc->dsreg = MTIO_DSREG_REST;
1719 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
1721 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1722 if ((error = saerror(done_ccb, 0, 0)) == ERESTART) {
1724 * A retry was scheduled, so just return.
1733 * Catastrophic error. Mark the tape as frozen
1734 * (we no longer know tape position).
1736 * Return all queued I/O with EIO, and unfreeze
1737 * our queue so that future transactions that
1738 * attempt to fix this problem can get to the
1743 softc->flags |= SA_FLAG_TAPE_FROZEN;
1744 bioq_flush(&softc->bio_queue, NULL, EIO);
1747 bp->bio_resid = bp->bio_bcount;
1748 bp->bio_error = error;
1749 bp->bio_flags |= BIO_ERROR;
1751 * In the error case, position is updated in saerror.
1754 bp->bio_resid = csio->resid;
1756 if (csio->resid != 0) {
1757 bp->bio_flags |= BIO_ERROR;
1759 if (bp->bio_cmd == BIO_WRITE) {
1760 softc->flags |= SA_FLAG_TAPE_WRITTEN;
1761 softc->filemarks = 0;
1763 if (!(csio->ccb_h.ccb_pflags & SA_POSITION_UPDATED) &&
1764 (softc->blkno != (daddr_t) -1)) {
1765 if ((softc->flags & SA_FLAG_FIXED) != 0) {
1767 if (softc->blk_shift != 0) {
1768 l = bp->bio_bcount >>
1771 l = bp->bio_bcount /
1772 softc->media_blksize;
1774 softc->blkno += (daddr_t) l;
1781 * If we had an error (immediate or pending),
1782 * release the device queue now.
1784 if (error || (softc->flags & SA_FLAG_ERR_PENDING))
1785 cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0);
1787 if (error || bp->bio_resid) {
1788 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1789 ("error %d resid %ld count %ld\n", error,
1790 bp->bio_resid, bp->bio_bcount));
1793 biofinish(bp, softc->device_stats, 0);
1796 case SA_CCB_WAITING:
1798 /* Caller will release the CCB */
1799 wakeup(&done_ccb->ccb_h.cbfcnp);
1803 xpt_release_ccb(done_ccb);
1807 * Mount the tape (make sure it's ready for I/O).
1810 samount(struct cam_periph *periph, int oflags, struct cdev *dev)
1812 struct sa_softc *softc;
1817 * oflags can be checked for 'kind' of open (read-only check) - later
1818 * dev can be checked for a control-mode or compression open - later
1820 UNUSED_PARAMETER(oflags);
1821 UNUSED_PARAMETER(dev);
1824 softc = (struct sa_softc *)periph->softc;
1827 * This should determine if something has happend since the last
1828 * open/mount that would invalidate the mount. We do *not* want
1829 * to retry this command- we just want the status. But we only
1830 * do this if we're mounted already- if we're not mounted,
1831 * we don't care about the unit read state and can instead use
1832 * this opportunity to attempt to reserve the tape unit.
1835 if (softc->flags & SA_FLAG_TAPE_MOUNTED) {
1836 ccb = cam_periph_getccb(periph, 1);
1837 scsi_test_unit_ready(&ccb->csio, 0, sadone,
1838 MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, IO_TIMEOUT);
1839 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
1840 softc->device_stats);
1842 if (error == ENXIO) {
1843 softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
1844 scsi_test_unit_ready(&ccb->csio, 0, sadone,
1845 MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, IO_TIMEOUT);
1846 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
1847 softc->device_stats);
1851 * We don't need to freeze the tape because we
1852 * will now attempt to rewind/load it.
1854 softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
1855 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
1856 xpt_print(periph->path,
1857 "error %d on TUR in samount\n", error);
1861 error = sareservereleaseunit(periph, TRUE);
1865 ccb = cam_periph_getccb(periph, 1);
1866 scsi_test_unit_ready(&ccb->csio, 0, sadone,
1867 MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, IO_TIMEOUT);
1868 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
1869 softc->device_stats);
1873 if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) {
1874 struct scsi_read_block_limits_data *rblim = NULL;
1875 int comp_enabled, comp_supported;
1876 u_int8_t write_protect, guessing = 0;
1879 * Clear out old state.
1881 softc->flags &= ~(SA_FLAG_TAPE_WP|SA_FLAG_TAPE_WRITTEN|
1882 SA_FLAG_ERR_PENDING|SA_FLAG_COMP_ENABLED|
1883 SA_FLAG_COMP_SUPP|SA_FLAG_COMP_UNSUPP);
1884 softc->filemarks = 0;
1887 * *Very* first off, make sure we're loaded to BOT.
1889 scsi_load_unload(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE,
1890 FALSE, FALSE, 1, SSD_FULL_SIZE, REWIND_TIMEOUT);
1891 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
1892 softc->device_stats);
1896 * In case this doesn't work, do a REWIND instead
1899 scsi_rewind(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG,
1900 FALSE, SSD_FULL_SIZE, REWIND_TIMEOUT);
1901 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
1902 softc->device_stats);
1906 xpt_release_ccb(ccb);
1911 * Do a dummy test read to force access to the
1912 * media so that the drive will really know what's
1913 * there. We actually don't really care what the
1914 * blocksize on tape is and don't expect to really
1915 * read a full record.
1917 rblim = (struct scsi_read_block_limits_data *)
1918 malloc(8192, M_SCSISA, M_NOWAIT);
1919 if (rblim == NULL) {
1920 xpt_print(periph->path, "no memory for test read\n");
1921 xpt_release_ccb(ccb);
1926 if ((softc->quirks & SA_QUIRK_NODREAD) == 0) {
1927 scsi_sa_read_write(&ccb->csio, 0, sadone,
1928 MSG_SIMPLE_Q_TAG, 1, FALSE, 0, 8192,
1929 (void *) rblim, 8192, SSD_FULL_SIZE,
1931 (void) cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
1932 softc->device_stats);
1934 scsi_rewind(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG,
1935 FALSE, SSD_FULL_SIZE, REWIND_TIMEOUT);
1936 error = cam_periph_runccb(ccb, saerror, CAM_RETRY_SELTO,
1937 SF_NO_PRINT | SF_RETRY_UA,
1938 softc->device_stats);
1941 xpt_print(periph->path,
1942 "unable to rewind after test read\n");
1943 xpt_release_ccb(ccb);
1949 * Next off, determine block limits.
1951 scsi_read_block_limits(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG,
1952 rblim, SSD_FULL_SIZE, SCSIOP_TIMEOUT);
1954 error = cam_periph_runccb(ccb, saerror, CAM_RETRY_SELTO,
1955 SF_NO_PRINT | SF_RETRY_UA, softc->device_stats);
1958 xpt_release_ccb(ccb);
1962 * If it's less than SCSI-2, READ BLOCK LIMITS is not
1963 * a MANDATORY command. Anyway- it doesn't matter-
1964 * we can proceed anyway.
1966 softc->blk_gran = 0;
1967 softc->max_blk = ~0;
1970 if (softc->scsi_rev >= SCSI_REV_SPC) {
1971 softc->blk_gran = RBL_GRAN(rblim);
1973 softc->blk_gran = 0;
1976 * We take max_blk == min_blk to mean a default to
1977 * fixed mode- but note that whatever we get out of
1978 * sagetparams below will actually determine whether
1979 * we are actually *in* fixed mode.
1981 softc->max_blk = scsi_3btoul(rblim->maximum);
1982 softc->min_blk = scsi_2btoul(rblim->minimum);
1987 * Next, perform a mode sense to determine
1988 * current density, blocksize, compression etc.
1990 error = sagetparams(periph, SA_PARAM_ALL,
1991 &softc->media_blksize,
1992 &softc->media_density,
1993 &softc->media_numblks,
1994 &softc->buffer_mode, &write_protect,
1995 &softc->speed, &comp_supported,
1996 &comp_enabled, &softc->comp_algorithm,
2001 * We could work a little harder here. We could
2002 * adjust our attempts to get information. It
2003 * might be an ancient tape drive. If someone
2004 * nudges us, we'll do that.
2010 * If no quirk has determined that this is a device that is
2011 * preferred to be in fixed or variable mode, now is the time
2014 if ((softc->quirks & (SA_QUIRK_FIXED|SA_QUIRK_VARIABLE)) == 0) {
2017 * This could be expensive to find out. Luckily we
2018 * only need to do this once. If we start out in
2019 * 'default' mode, try and set ourselves to one
2020 * of the densities that would determine a wad
2021 * of other stuff. Go from highest to lowest.
2023 if (softc->media_density == SCSI_DEFAULT_DENSITY) {
2025 static u_int8_t ctry[] = {
2026 SCSI_DENSITY_HALFINCH_PE,
2027 SCSI_DENSITY_HALFINCH_6250C,
2028 SCSI_DENSITY_HALFINCH_6250,
2029 SCSI_DENSITY_HALFINCH_1600,
2030 SCSI_DENSITY_HALFINCH_800,
2031 SCSI_DENSITY_QIC_4GB,
2032 SCSI_DENSITY_QIC_2GB,
2033 SCSI_DENSITY_QIC_525_320,
2034 SCSI_DENSITY_QIC_150,
2035 SCSI_DENSITY_QIC_120,
2036 SCSI_DENSITY_QIC_24,
2037 SCSI_DENSITY_QIC_11_9TRK,
2038 SCSI_DENSITY_QIC_11_4TRK,
2039 SCSI_DENSITY_QIC_1320,
2040 SCSI_DENSITY_QIC_3080,
2043 for (i = 0; ctry[i]; i++) {
2044 error = sasetparams(periph,
2045 SA_PARAM_DENSITY, 0, ctry[i],
2048 softc->media_density = ctry[i];
2053 switch (softc->media_density) {
2054 case SCSI_DENSITY_QIC_11_4TRK:
2055 case SCSI_DENSITY_QIC_11_9TRK:
2056 case SCSI_DENSITY_QIC_24:
2057 case SCSI_DENSITY_QIC_120:
2058 case SCSI_DENSITY_QIC_150:
2059 case SCSI_DENSITY_QIC_525_320:
2060 case SCSI_DENSITY_QIC_1320:
2061 case SCSI_DENSITY_QIC_3080:
2062 softc->quirks &= ~SA_QUIRK_2FM;
2063 softc->quirks |= SA_QUIRK_FIXED|SA_QUIRK_1FM;
2064 softc->last_media_blksize = 512;
2066 case SCSI_DENSITY_QIC_4GB:
2067 case SCSI_DENSITY_QIC_2GB:
2068 softc->quirks &= ~SA_QUIRK_2FM;
2069 softc->quirks |= SA_QUIRK_FIXED|SA_QUIRK_1FM;
2070 softc->last_media_blksize = 1024;
2073 softc->last_media_blksize =
2074 softc->media_blksize;
2075 softc->quirks |= SA_QUIRK_VARIABLE;
2081 * If no quirk has determined that this is a device that needs
2082 * to have 2 Filemarks at EOD, now is the time to find out.
2085 if ((softc->quirks & SA_QUIRK_2FM) == 0) {
2086 switch (softc->media_density) {
2087 case SCSI_DENSITY_HALFINCH_800:
2088 case SCSI_DENSITY_HALFINCH_1600:
2089 case SCSI_DENSITY_HALFINCH_6250:
2090 case SCSI_DENSITY_HALFINCH_6250C:
2091 case SCSI_DENSITY_HALFINCH_PE:
2092 softc->quirks &= ~SA_QUIRK_1FM;
2093 softc->quirks |= SA_QUIRK_2FM;
2101 * Now validate that some info we got makes sense.
2103 if ((softc->max_blk < softc->media_blksize) ||
2104 (softc->min_blk > softc->media_blksize &&
2105 softc->media_blksize)) {
2106 xpt_print(periph->path,
2107 "BLOCK LIMITS (%d..%d) could not match current "
2108 "block settings (%d)- adjusting\n", softc->min_blk,
2109 softc->max_blk, softc->media_blksize);
2110 softc->max_blk = softc->min_blk =
2111 softc->media_blksize;
2115 * Now put ourselves into the right frame of mind based
2120 * If we want to be in FIXED mode and our current blocksize
2121 * is not equal to our last blocksize (if nonzero), try and
2122 * set ourselves to this last blocksize (as the 'preferred'
2123 * block size). The initial quirkmatch at registry sets the
2124 * initial 'last' blocksize. If, for whatever reason, this
2125 * 'last' blocksize is zero, set the blocksize to 512,
2126 * or min_blk if that's larger.
2128 if ((softc->quirks & SA_QUIRK_FIXED) &&
2129 (softc->quirks & SA_QUIRK_NO_MODESEL) == 0 &&
2130 (softc->media_blksize != softc->last_media_blksize)) {
2131 softc->media_blksize = softc->last_media_blksize;
2132 if (softc->media_blksize == 0) {
2133 softc->media_blksize = 512;
2134 if (softc->media_blksize < softc->min_blk) {
2135 softc->media_blksize = softc->min_blk;
2138 error = sasetparams(periph, SA_PARAM_BLOCKSIZE,
2139 softc->media_blksize, 0, 0, SF_NO_PRINT);
2141 xpt_print(periph->path,
2142 "unable to set fixed blocksize to %d\n",
2143 softc->media_blksize);
2148 if ((softc->quirks & SA_QUIRK_VARIABLE) &&
2149 (softc->media_blksize != 0)) {
2150 softc->last_media_blksize = softc->media_blksize;
2151 softc->media_blksize = 0;
2152 error = sasetparams(periph, SA_PARAM_BLOCKSIZE,
2153 0, 0, 0, SF_NO_PRINT);
2156 * If this fails and we were guessing, just
2157 * assume that we got it wrong and go try
2158 * fixed block mode. Don't even check against
2159 * density code at this point.
2162 softc->quirks &= ~SA_QUIRK_VARIABLE;
2163 softc->quirks |= SA_QUIRK_FIXED;
2164 if (softc->last_media_blksize == 0)
2165 softc->last_media_blksize = 512;
2168 xpt_print(periph->path,
2169 "unable to set variable blocksize\n");
2175 * Now that we have the current block size,
2176 * set up some parameters for sastart's usage.
2178 if (softc->media_blksize) {
2179 softc->flags |= SA_FLAG_FIXED;
2180 if (powerof2(softc->media_blksize)) {
2182 ffs(softc->media_blksize) - 1;
2183 softc->blk_mask = softc->media_blksize - 1;
2185 softc->blk_mask = ~0;
2186 softc->blk_shift = 0;
2190 * The SCSI-3 spec allows 0 to mean "unspecified".
2191 * The SCSI-1 spec allows 0 to mean 'infinite'.
2193 * Either works here.
2195 if (softc->max_blk == 0) {
2196 softc->max_blk = ~0;
2198 softc->blk_shift = 0;
2199 if (softc->blk_gran != 0) {
2200 softc->blk_mask = softc->blk_gran - 1;
2202 softc->blk_mask = 0;
2207 softc->flags |= SA_FLAG_TAPE_WP;
2209 if (comp_supported) {
2210 if (softc->saved_comp_algorithm == 0)
2211 softc->saved_comp_algorithm =
2212 softc->comp_algorithm;
2213 softc->flags |= SA_FLAG_COMP_SUPP;
2215 softc->flags |= SA_FLAG_COMP_ENABLED;
2217 softc->flags |= SA_FLAG_COMP_UNSUPP;
2219 if ((softc->buffer_mode == SMH_SA_BUF_MODE_NOBUF) &&
2220 (softc->quirks & SA_QUIRK_NO_MODESEL) == 0) {
2221 error = sasetparams(periph, SA_PARAM_BUFF_MODE, 0,
2224 softc->buffer_mode = SMH_SA_BUF_MODE_SIBUF;
2226 xpt_print(periph->path,
2227 "unable to set buffered mode\n");
2229 error = 0; /* not an error */
2234 softc->flags |= SA_FLAG_TAPE_MOUNTED;
2238 free(rblim, M_SCSISA);
2241 softc->dsreg = MTIO_DSREG_NIL;
2243 softc->fileno = softc->blkno = 0;
2244 softc->dsreg = MTIO_DSREG_REST;
2246 #ifdef SA_1FM_AT_EOD
2247 if ((softc->quirks & SA_QUIRK_2FM) == 0)
2248 softc->quirks |= SA_QUIRK_1FM;
2250 if ((softc->quirks & SA_QUIRK_1FM) == 0)
2251 softc->quirks |= SA_QUIRK_2FM;
2254 xpt_release_ccb(ccb);
2257 * If we return an error, we're not mounted any more,
2258 * so release any device reservation.
2261 (void) sareservereleaseunit(periph, FALSE);
2264 * Clear I/O residual.
2266 softc->last_io_resid = 0;
2267 softc->last_ctl_resid = 0;
2273 * How many filemarks do we need to write if we were to terminate the
2274 * tape session right now? Note that this can be a negative number
2278 samarkswanted(struct cam_periph *periph)
2281 struct sa_softc *softc;
2283 softc = (struct sa_softc *)periph->softc;
2285 if ((softc->flags & SA_FLAG_TAPE_WRITTEN) != 0) {
2287 if (softc->quirks & SA_QUIRK_2FM)
2290 markswanted -= softc->filemarks;
2291 return (markswanted);
2295 sacheckeod(struct cam_periph *periph)
2300 markswanted = samarkswanted(periph);
2302 if (markswanted > 0) {
2303 error = sawritefilemarks(periph, markswanted, FALSE);
2311 saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
2313 static const char *toobig =
2314 "%d-byte tape record bigger than supplied buffer\n";
2315 struct cam_periph *periph;
2316 struct sa_softc *softc;
2317 struct ccb_scsiio *csio;
2318 struct scsi_sense_data *sense;
2319 u_int32_t resid = 0;
2322 int error_code, sense_key, asc, ascq, error, aqvalid;
2324 periph = xpt_path_periph(ccb->ccb_h.path);
2325 softc = (struct sa_softc *)periph->softc;
2327 sense = &csio->sense_data;
2328 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
2329 aqvalid = sense->extra_len >= 6;
2332 status = csio->ccb_h.status & CAM_STATUS_MASK;
2335 * Calculate/latch up, any residuals... We do this in a funny 2-step
2336 * so we can print stuff here if we have CAM_DEBUG enabled for this
2339 if (status == CAM_SCSI_STATUS_ERROR) {
2340 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
2341 info = (int32_t) scsi_4btoul(sense->info);
2343 if ((softc->flags & SA_FLAG_FIXED) != 0)
2344 resid *= softc->media_blksize;
2346 resid = csio->dxfer_len;
2348 if ((softc->flags & SA_FLAG_FIXED) != 0) {
2349 if (softc->media_blksize)
2350 info /= softc->media_blksize;
2353 if (CCB_Type(csio) == SA_CCB_BUFFER_IO) {
2354 bcopy((caddr_t) sense, (caddr_t) &softc->last_io_sense,
2355 sizeof (struct scsi_sense_data));
2356 bcopy(csio->cdb_io.cdb_bytes, softc->last_io_cdb,
2357 (int) csio->cdb_len);
2358 softc->last_io_resid = resid;
2359 softc->last_resid_was_io = 1;
2361 bcopy((caddr_t) sense, (caddr_t) &softc->last_ctl_sense,
2362 sizeof (struct scsi_sense_data));
2363 bcopy(csio->cdb_io.cdb_bytes, softc->last_ctl_cdb,
2364 (int) csio->cdb_len);
2365 softc->last_ctl_resid = resid;
2366 softc->last_resid_was_io = 0;
2368 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("CDB[0]=0x%x Key 0x%x "
2369 "ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %d "
2370 "dxfer_len %d\n", csio->cdb_io.cdb_bytes[0] & 0xff,
2371 sense_key, asc, ascq, status,
2372 sense->flags & ~SSD_KEY_RESERVED, resid, csio->dxfer_len));
2374 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
2375 ("Cam Status 0x%x\n", status));
2381 case CAM_SCSI_STATUS_ERROR:
2383 * If a read/write command, we handle it here.
2385 if (CCB_Type(csio) != SA_CCB_WAITING) {
2389 * If this was just EOM/EOP, Filemark, Setmark or ILI detected
2390 * on a non read/write command, we assume it's not an error
2391 * and propagate the residule and return.
2393 if ((aqvalid && asc == 0 && ascq > 0 && ascq <= 5) ||
2394 (aqvalid == 0 && sense_key == SSD_KEY_NO_SENSE)) {
2395 csio->resid = resid;
2400 * Otherwise, we let the common code handle this.
2402 return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb));
2406 * We cannot depend upon CAM honoring retry counts for these.
2408 case CAM_SCSI_BUS_RESET:
2410 if (ccb->ccb_h.retry_count <= 0) {
2415 return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb));
2419 * Handle filemark, end of tape, mismatched record sizes....
2420 * From this point out, we're only handling read/write cases.
2421 * Handle writes && reads differently.
2424 if (csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
2425 if (sense_key == SSD_KEY_VOLUME_OVERFLOW) {
2426 csio->resid = resid;
2428 } else if (sense->flags & SSD_EOM) {
2429 softc->flags |= SA_FLAG_EOM_PENDING;
2431 * Grotesque as it seems, the few times
2432 * I've actually seen a non-zero resid,
2433 * the tape drive actually lied and had
2434 * written all the data!.
2439 csio->resid = resid;
2440 if (sense_key == SSD_KEY_BLANK_CHECK) {
2441 if (softc->quirks & SA_QUIRK_1FM) {
2443 softc->flags |= SA_FLAG_EOM_PENDING;
2447 } else if (sense->flags & SSD_FILEMARK) {
2448 if (softc->flags & SA_FLAG_FIXED) {
2450 softc->flags |= SA_FLAG_EOF_PENDING;
2453 * Unconditionally, if we detected a filemark on a read,
2454 * mark that we've run moved a file ahead.
2456 if (softc->fileno != (daddr_t) -1) {
2459 csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED;
2465 * Incorrect Length usually applies to read, but can apply to writes.
2467 if (error == 0 && (sense->flags & SSD_ILI)) {
2469 xpt_print(csio->ccb_h.path, toobig,
2470 csio->dxfer_len - info);
2471 csio->resid = csio->dxfer_len;
2474 csio->resid = resid;
2475 if (softc->flags & SA_FLAG_FIXED) {
2476 softc->flags |= SA_FLAG_EIO_PENDING;
2479 * Bump the block number if we hadn't seen a filemark.
2480 * Do this independent of errors (we've moved anyway).
2482 if ((sense->flags & SSD_FILEMARK) == 0) {
2483 if (softc->blkno != (daddr_t) -1) {
2485 csio->ccb_h.ccb_pflags |=
2486 SA_POSITION_UPDATED;
2494 * Unfreeze the queue if frozen as we're not returning anything
2495 * to our waiters that would indicate an I/O error has occurred
2505 sagetparams(struct cam_periph *periph, sa_params params_to_get,
2506 u_int32_t *blocksize, u_int8_t *density, u_int32_t *numblocks,
2507 int *buff_mode, u_int8_t *write_protect, u_int8_t *speed,
2508 int *comp_supported, int *comp_enabled, u_int32_t *comp_algorithm,
2513 struct scsi_mode_header_6 *mode_hdr;
2514 struct scsi_mode_blk_desc *mode_blk;
2515 int mode_buffer_len;
2516 struct sa_softc *softc;
2521 softc = (struct sa_softc *)periph->softc;
2522 ccb = cam_periph_getccb(periph, 1);
2523 if (softc->quirks & SA_QUIRK_NO_CPAGE)
2524 cpage = SA_DEVICE_CONFIGURATION_PAGE;
2526 cpage = SA_DATA_COMPRESSION_PAGE;
2529 mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk);
2531 if (params_to_get & SA_PARAM_COMPRESSION) {
2532 if (softc->quirks & SA_QUIRK_NOCOMP) {
2533 *comp_supported = FALSE;
2534 params_to_get &= ~SA_PARAM_COMPRESSION;
2536 mode_buffer_len += sizeof (sa_comp_t);
2539 /* XXX Fix M_NOWAIT */
2540 mode_buffer = malloc(mode_buffer_len, M_SCSISA, M_NOWAIT | M_ZERO);
2541 if (mode_buffer == NULL) {
2542 xpt_release_ccb(ccb);
2545 mode_hdr = (struct scsi_mode_header_6 *)mode_buffer;
2546 mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
2548 /* it is safe to retry this */
2549 scsi_mode_sense(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE,
2550 SMS_PAGE_CTRL_CURRENT, (params_to_get & SA_PARAM_COMPRESSION) ?
2551 cpage : SMS_VENDOR_SPECIFIC_PAGE, mode_buffer, mode_buffer_len,
2552 SSD_FULL_SIZE, SCSIOP_TIMEOUT);
2554 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
2555 softc->device_stats);
2558 status = ccb->ccb_h.status & CAM_STATUS_MASK;
2560 if (error == EINVAL && (params_to_get & SA_PARAM_COMPRESSION) != 0) {
2562 * Hmm. Let's see if we can try another page...
2563 * If we've already done that, give up on compression
2564 * for this device and remember this for the future
2565 * and attempt the request without asking for compression
2568 if (cpage == SA_DATA_COMPRESSION_PAGE) {
2569 cpage = SA_DEVICE_CONFIGURATION_PAGE;
2572 softc->quirks |= SA_QUIRK_NOCOMP;
2573 free(mode_buffer, M_SCSISA);
2575 } else if (status == CAM_SCSI_STATUS_ERROR) {
2576 /* Tell the user about the fatal error. */
2577 scsi_sense_print(&ccb->csio);
2578 goto sagetparamsexit;
2582 * If the user only wants the compression information, and
2583 * the device doesn't send back the block descriptor, it's
2584 * no big deal. If the user wants more than just
2585 * compression, though, and the device doesn't pass back the
2586 * block descriptor, we need to send another mode sense to
2587 * get the block descriptor.
2589 if ((mode_hdr->blk_desc_len == 0) &&
2590 (params_to_get & SA_PARAM_COMPRESSION) &&
2591 (params_to_get & ~(SA_PARAM_COMPRESSION))) {
2594 * Decrease the mode buffer length by the size of
2595 * the compression page, to make sure the data
2596 * there doesn't get overwritten.
2598 mode_buffer_len -= sizeof (sa_comp_t);
2601 * Now move the compression page that we presumably
2602 * got back down the memory chunk a little bit so
2603 * it doesn't get spammed.
2605 bcopy(&mode_hdr[0], &mode_hdr[1], sizeof (sa_comp_t));
2606 bzero(&mode_hdr[0], sizeof (mode_hdr[0]));
2609 * Now, we issue another mode sense and just ask
2610 * for the block descriptor, etc.
2613 scsi_mode_sense(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE,
2614 SMS_PAGE_CTRL_CURRENT, SMS_VENDOR_SPECIFIC_PAGE,
2615 mode_buffer, mode_buffer_len, SSD_FULL_SIZE,
2618 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
2619 softc->device_stats);
2623 goto sagetparamsexit;
2626 if (params_to_get & SA_PARAM_BLOCKSIZE)
2627 *blocksize = scsi_3btoul(mode_blk->blklen);
2629 if (params_to_get & SA_PARAM_NUMBLOCKS)
2630 *numblocks = scsi_3btoul(mode_blk->nblocks);
2632 if (params_to_get & SA_PARAM_BUFF_MODE)
2633 *buff_mode = mode_hdr->dev_spec & SMH_SA_BUF_MODE_MASK;
2635 if (params_to_get & SA_PARAM_DENSITY)
2636 *density = mode_blk->density;
2638 if (params_to_get & SA_PARAM_WP)
2639 *write_protect = (mode_hdr->dev_spec & SMH_SA_WP)? TRUE : FALSE;
2641 if (params_to_get & SA_PARAM_SPEED)
2642 *speed = mode_hdr->dev_spec & SMH_SA_SPEED_MASK;
2644 if (params_to_get & SA_PARAM_COMPRESSION) {
2645 sa_comp_t *ntcs = (sa_comp_t *) &mode_blk[1];
2646 if (cpage == SA_DATA_COMPRESSION_PAGE) {
2647 struct scsi_data_compression_page *cp = &ntcs->dcomp;
2649 (cp->dce_and_dcc & SA_DCP_DCC)? TRUE : FALSE;
2651 (cp->dce_and_dcc & SA_DCP_DCE)? TRUE : FALSE;
2652 *comp_algorithm = scsi_4btoul(cp->comp_algorithm);
2654 struct scsi_dev_conf_page *cp = &ntcs->dconf;
2656 * We don't really know whether this device supports
2657 * Data Compression if the the algorithm field is
2658 * zero. Just say we do.
2660 *comp_supported = TRUE;
2662 (cp->sel_comp_alg != SA_COMP_NONE)? TRUE : FALSE;
2663 *comp_algorithm = cp->sel_comp_alg;
2666 bcopy(ntcs, tcs, sizeof (sa_comp_t));
2669 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
2671 char *xyz = mode_buffer;
2672 xpt_print_path(periph->path);
2673 printf("Mode Sense Data=");
2674 for (idx = 0; idx < mode_buffer_len; idx++)
2675 printf(" 0x%02x", xyz[idx] & 0xff);
2681 xpt_release_ccb(ccb);
2682 free(mode_buffer, M_SCSISA);
2687 * The purpose of this function is to set one of four different parameters
2691 * - compression / compression algorithm
2694 * The assumption is that this will be called from saioctl(), and therefore
2695 * from a process context. Thus the waiting malloc calls below. If that
2696 * assumption ever changes, the malloc calls should be changed to be
2699 * Any or all of the four parameters may be set when this function is
2700 * called. It should handle setting more than one parameter at once.
2703 sasetparams(struct cam_periph *periph, sa_params params_to_set,
2704 u_int32_t blocksize, u_int8_t density, u_int32_t calg,
2705 u_int32_t sense_flags)
2707 struct sa_softc *softc;
2708 u_int32_t current_blocksize;
2709 u_int32_t current_calg;
2710 u_int8_t current_density;
2711 u_int8_t current_speed;
2712 int comp_enabled, comp_supported;
2714 int mode_buffer_len;
2715 struct scsi_mode_header_6 *mode_hdr;
2716 struct scsi_mode_blk_desc *mode_blk;
2717 sa_comp_t *ccomp, *cpage;
2719 union ccb *ccb = NULL;
2722 softc = (struct sa_softc *)periph->softc;
2724 ccomp = malloc(sizeof (sa_comp_t), M_SCSISA, M_NOWAIT);
2729 * Since it doesn't make sense to set the number of blocks, or
2730 * write protection, we won't try to get the current value. We
2731 * always want to get the blocksize, so we can set it back to the
2734 error = sagetparams(periph,
2735 params_to_set | SA_PARAM_BLOCKSIZE | SA_PARAM_SPEED,
2736 ¤t_blocksize, ¤t_density, NULL, &buff_mode, NULL,
2737 ¤t_speed, &comp_supported, &comp_enabled,
2738 ¤t_calg, ccomp);
2741 free(ccomp, M_SCSISA);
2745 mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk);
2746 if (params_to_set & SA_PARAM_COMPRESSION)
2747 mode_buffer_len += sizeof (sa_comp_t);
2749 mode_buffer = malloc(mode_buffer_len, M_SCSISA, M_NOWAIT | M_ZERO);
2750 if (mode_buffer == NULL) {
2751 free(ccomp, M_SCSISA);
2755 mode_hdr = (struct scsi_mode_header_6 *)mode_buffer;
2756 mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
2758 ccb = cam_periph_getccb(periph, 1);
2762 if (params_to_set & SA_PARAM_COMPRESSION) {
2764 cpage = (sa_comp_t *)&mode_blk[1];
2766 cpage = (sa_comp_t *)&mode_hdr[1];
2768 bcopy(ccomp, cpage, sizeof (sa_comp_t));
2769 cpage->hdr.pagecode &= ~0x80;
2774 * If the caller wants us to set the blocksize, use the one they
2775 * pass in. Otherwise, use the blocksize we got back from the
2776 * mode select above.
2779 if (params_to_set & SA_PARAM_BLOCKSIZE)
2780 scsi_ulto3b(blocksize, mode_blk->blklen);
2782 scsi_ulto3b(current_blocksize, mode_blk->blklen);
2785 * Set density if requested, else preserve old density.
2786 * SCSI_SAME_DENSITY only applies to SCSI-2 or better
2787 * devices, else density we've latched up in our softc.
2789 if (params_to_set & SA_PARAM_DENSITY) {
2790 mode_blk->density = density;
2791 } else if (softc->scsi_rev > SCSI_REV_CCS) {
2792 mode_blk->density = SCSI_SAME_DENSITY;
2794 mode_blk->density = softc->media_density;
2799 * For mode selects, these two fields must be zero.
2801 mode_hdr->data_length = 0;
2802 mode_hdr->medium_type = 0;
2804 /* set the speed to the current value */
2805 mode_hdr->dev_spec = current_speed;
2807 /* if set, set single-initiator buffering mode */
2808 if (softc->buffer_mode == SMH_SA_BUF_MODE_SIBUF) {
2809 mode_hdr->dev_spec |= SMH_SA_BUF_MODE_SIBUF;
2813 mode_hdr->blk_desc_len = sizeof(struct scsi_mode_blk_desc);
2815 mode_hdr->blk_desc_len = 0;
2818 * First, if the user wants us to set the compression algorithm or
2819 * just turn compression on, check to make sure that this drive
2820 * supports compression.
2822 if (params_to_set & SA_PARAM_COMPRESSION) {
2824 * If the compression algorithm is 0, disable compression.
2825 * If the compression algorithm is non-zero, enable
2826 * compression and set the compression type to the
2827 * specified compression algorithm, unless the algorithm is
2828 * MT_COMP_ENABLE. In that case, we look at the
2829 * compression algorithm that is currently set and if it is
2830 * non-zero, we leave it as-is. If it is zero, and we have
2831 * saved a compression algorithm from a time when
2832 * compression was enabled before, set the compression to
2835 switch (ccomp->hdr.pagecode & ~0x80) {
2836 case SA_DEVICE_CONFIGURATION_PAGE:
2838 struct scsi_dev_conf_page *dcp = &cpage->dconf;
2840 dcp->sel_comp_alg = SA_COMP_NONE;
2843 if (calg != MT_COMP_ENABLE) {
2844 dcp->sel_comp_alg = calg;
2845 } else if (dcp->sel_comp_alg == SA_COMP_NONE &&
2846 softc->saved_comp_algorithm != 0) {
2847 dcp->sel_comp_alg = softc->saved_comp_algorithm;
2851 case SA_DATA_COMPRESSION_PAGE:
2852 if (ccomp->dcomp.dce_and_dcc & SA_DCP_DCC) {
2853 struct scsi_data_compression_page *dcp = &cpage->dcomp;
2856 * Disable compression, but leave the
2857 * decompression and the capability bit
2860 dcp->dce_and_dcc = SA_DCP_DCC;
2861 dcp->dde_and_red |= SA_DCP_DDE;
2864 /* enable compression && decompression */
2865 dcp->dce_and_dcc = SA_DCP_DCE | SA_DCP_DCC;
2866 dcp->dde_and_red |= SA_DCP_DDE;
2868 * If there, use compression algorithm from caller.
2869 * Otherwise, if there's a saved compression algorithm
2870 * and there is no current algorithm, use the saved
2871 * algorithm. Else parrot back what we got and hope
2874 if (calg != MT_COMP_ENABLE) {
2875 scsi_ulto4b(calg, dcp->comp_algorithm);
2876 scsi_ulto4b(calg, dcp->decomp_algorithm);
2877 } else if (scsi_4btoul(dcp->comp_algorithm) == 0 &&
2878 softc->saved_comp_algorithm != 0) {
2879 scsi_ulto4b(softc->saved_comp_algorithm,
2880 dcp->comp_algorithm);
2881 scsi_ulto4b(softc->saved_comp_algorithm,
2882 dcp->decomp_algorithm);
2887 * Compression does not appear to be supported-
2888 * at least via the DATA COMPRESSION page. It
2889 * would be too much to ask us to believe that
2890 * the page itself is supported, but incorrectly
2891 * reports an ability to manipulate data compression,
2892 * so we'll assume that this device doesn't support
2893 * compression. We can just fall through for that.
2898 * The drive doesn't seem to support compression,
2899 * so turn off the set compression bit.
2901 params_to_set &= ~SA_PARAM_COMPRESSION;
2902 xpt_print(periph->path,
2903 "device does not seem to support compression\n");
2906 * If that was the only thing the user wanted us to set,
2907 * clean up allocated resources and return with
2908 * 'operation not supported'.
2910 if (params_to_set == SA_PARAM_NONE) {
2911 free(mode_buffer, M_SCSISA);
2912 xpt_release_ccb(ccb);
2917 * That wasn't the only thing the user wanted us to set.
2918 * So, decrease the stated mode buffer length by the
2919 * size of the compression mode page.
2921 mode_buffer_len -= sizeof(sa_comp_t);
2925 /* It is safe to retry this operation */
2926 scsi_mode_select(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG,
2927 (params_to_set & SA_PARAM_COMPRESSION)? TRUE : FALSE,
2928 FALSE, mode_buffer, mode_buffer_len, SSD_FULL_SIZE, SCSIOP_TIMEOUT);
2930 error = cam_periph_runccb(ccb, saerror, 0,
2931 sense_flags, softc->device_stats);
2934 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
2936 char *xyz = mode_buffer;
2937 xpt_print_path(periph->path);
2938 printf("Err%d, Mode Select Data=", error);
2939 for (idx = 0; idx < mode_buffer_len; idx++)
2940 printf(" 0x%02x", xyz[idx] & 0xff);
2947 * If we can, try without setting density/blocksize.
2950 if ((params_to_set &
2951 (SA_PARAM_DENSITY|SA_PARAM_BLOCKSIZE)) == 0) {
2956 mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
2957 cpage = (sa_comp_t *)&mode_blk[1];
2961 * If we were setting the blocksize, and that failed, we
2962 * want to set it to its original value. If we weren't
2963 * setting the blocksize, we don't want to change it.
2965 scsi_ulto3b(current_blocksize, mode_blk->blklen);
2968 * Set density if requested, else preserve old density.
2969 * SCSI_SAME_DENSITY only applies to SCSI-2 or better
2970 * devices, else density we've latched up in our softc.
2972 if (params_to_set & SA_PARAM_DENSITY) {
2973 mode_blk->density = current_density;
2974 } else if (softc->scsi_rev > SCSI_REV_CCS) {
2975 mode_blk->density = SCSI_SAME_DENSITY;
2977 mode_blk->density = softc->media_density;
2980 if (params_to_set & SA_PARAM_COMPRESSION)
2981 bcopy(ccomp, cpage, sizeof (sa_comp_t));
2984 * The retry count is the only CCB field that might have been
2985 * changed that we care about, so reset it back to 1.
2987 ccb->ccb_h.retry_count = 1;
2988 cam_periph_runccb(ccb, saerror, 0, sense_flags,
2989 softc->device_stats);
2993 xpt_release_ccb(ccb);
2996 free(ccomp, M_SCSISA);
2998 if (params_to_set & SA_PARAM_COMPRESSION) {
3000 softc->flags &= ~SA_FLAG_COMP_ENABLED;
3002 * Even if we get an error setting compression,
3003 * do not say that we don't support it. We could
3004 * have been wrong, or it may be media specific.
3005 * softc->flags &= ~SA_FLAG_COMP_SUPP;
3007 softc->saved_comp_algorithm = softc->comp_algorithm;
3008 softc->comp_algorithm = 0;
3010 softc->flags |= SA_FLAG_COMP_ENABLED;
3011 softc->comp_algorithm = calg;
3015 free(mode_buffer, M_SCSISA);
3020 saprevent(struct cam_periph *periph, int action)
3022 struct sa_softc *softc;
3026 softc = (struct sa_softc *)periph->softc;
3028 if ((action == PR_ALLOW) && (softc->flags & SA_FLAG_TAPE_LOCKED) == 0)
3030 if ((action == PR_PREVENT) && (softc->flags & SA_FLAG_TAPE_LOCKED) != 0)
3034 * We can be quiet about illegal requests.
3036 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
3041 ccb = cam_periph_getccb(periph, 1);
3043 /* It is safe to retry this operation */
3044 scsi_prevent(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, action,
3045 SSD_FULL_SIZE, SCSIOP_TIMEOUT);
3047 error = cam_periph_runccb(ccb, saerror, 0, sf, softc->device_stats);
3050 if (action == PR_ALLOW)
3051 softc->flags &= ~SA_FLAG_TAPE_LOCKED;
3053 softc->flags |= SA_FLAG_TAPE_LOCKED;
3056 xpt_release_ccb(ccb);
3060 sarewind(struct cam_periph *periph)
3063 struct sa_softc *softc;
3066 softc = (struct sa_softc *)periph->softc;
3068 ccb = cam_periph_getccb(periph, 1);
3070 /* It is safe to retry this operation */
3071 scsi_rewind(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE,
3072 SSD_FULL_SIZE, REWIND_TIMEOUT);
3074 softc->dsreg = MTIO_DSREG_REW;
3075 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
3076 softc->dsreg = MTIO_DSREG_REST;
3078 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
3079 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE);
3081 xpt_release_ccb(ccb);
3083 softc->fileno = softc->blkno = (daddr_t) 0;
3085 softc->fileno = softc->blkno = (daddr_t) -1;
3090 saspace(struct cam_periph *periph, int count, scsi_space_code code)
3093 struct sa_softc *softc;
3096 softc = (struct sa_softc *)periph->softc;
3098 ccb = cam_periph_getccb(periph, 1);
3100 /* This cannot be retried */
3102 scsi_space(&ccb->csio, 0, sadone, MSG_SIMPLE_Q_TAG, code, count,
3103 SSD_FULL_SIZE, SPACE_TIMEOUT);
3106 * Clear residual because we will be using it.
3108 softc->last_ctl_resid = 0;
3110 softc->dsreg = (count < 0)? MTIO_DSREG_REV : MTIO_DSREG_FWD;
3111 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
3112 softc->dsreg = MTIO_DSREG_REST;
3114 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
3115 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE);
3117 xpt_release_ccb(ccb);
3120 * If a spacing operation has failed, we need to invalidate
3123 * If the spacing operation was setmarks or to end of recorded data,
3124 * we no longer know our relative position.
3126 * If the spacing operations was spacing files in reverse, we
3127 * take account of the residual, but still check against less
3128 * than zero- if we've gone negative, we must have hit BOT.
3130 * If the spacing operations was spacing records in reverse and
3131 * we have a residual, we've either hit BOT or hit a filemark.
3132 * In the former case, we know our new record number (0). In
3133 * the latter case, we have absolutely no idea what the real
3134 * record number is- we've stopped between the end of the last
3135 * record in the previous file and the filemark that stopped
3136 * our spacing backwards.
3139 softc->fileno = softc->blkno = (daddr_t) -1;
3140 } else if (code == SS_SETMARKS || code == SS_EOD) {
3141 softc->fileno = softc->blkno = (daddr_t) -1;
3142 } else if (code == SS_FILEMARKS && softc->fileno != (daddr_t) -1) {
3143 softc->fileno += (count - softc->last_ctl_resid);
3144 if (softc->fileno < 0) /* we must of hit BOT */
3147 } else if (code == SS_BLOCKS && softc->blkno != (daddr_t) -1) {
3148 softc->blkno += (count - softc->last_ctl_resid);
3150 if (softc->last_ctl_resid || softc->blkno < 0) {
3151 if (softc->fileno == 0) {
3154 softc->blkno = (daddr_t) -1;
3163 sawritefilemarks(struct cam_periph *periph, int nmarks, int setmarks)
3166 struct sa_softc *softc;
3169 softc = (struct sa_softc *)periph->softc;
3170 if (softc->open_rdonly)
3173 ccb = cam_periph_getccb(periph, 1);
3175 * Clear residual because we will be using it.
3177 softc->last_ctl_resid = 0;
3179 softc->dsreg = MTIO_DSREG_FMK;
3180 /* this *must* not be retried */
3181 scsi_write_filemarks(&ccb->csio, 0, sadone, MSG_SIMPLE_Q_TAG,
3182 FALSE, setmarks, nmarks, SSD_FULL_SIZE, IO_TIMEOUT);
3183 softc->dsreg = MTIO_DSREG_REST;
3186 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
3188 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
3189 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE);
3191 if (error == 0 && nmarks) {
3192 struct sa_softc *softc = (struct sa_softc *)periph->softc;
3193 nwm = nmarks - softc->last_ctl_resid;
3194 softc->filemarks += nwm;
3197 xpt_release_ccb(ccb);
3200 * Update relative positions (if we're doing that).
3203 softc->fileno = softc->blkno = (daddr_t) -1;
3204 } else if (softc->fileno != (daddr_t) -1) {
3205 softc->fileno += nwm;
3212 sardpos(struct cam_periph *periph, int hard, u_int32_t *blkptr)
3214 struct scsi_tape_position_data loc;
3216 struct sa_softc *softc = (struct sa_softc *)periph->softc;
3220 * We try and flush any buffered writes here if we were writing
3221 * and we're trying to get hardware block position. It eats
3222 * up performance substantially, but I'm wary of drive firmware.
3224 * I think that *logical* block position is probably okay-
3225 * but hardware block position might have to wait for data
3226 * to hit media to be valid. Caveat Emptor.
3229 if (hard && (softc->flags & SA_FLAG_TAPE_WRITTEN)) {
3230 error = sawritefilemarks(periph, 0, 0);
3231 if (error && error != EACCES)
3235 ccb = cam_periph_getccb(periph, 1);
3236 scsi_read_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG,
3237 hard, &loc, SSD_FULL_SIZE, SCSIOP_TIMEOUT);
3238 softc->dsreg = MTIO_DSREG_RBSY;
3239 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
3240 softc->dsreg = MTIO_DSREG_REST;
3241 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
3242 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0);
3245 if (loc.flags & SA_RPOS_UNCERTAIN) {
3246 error = EINVAL; /* nothing is certain */
3248 *blkptr = scsi_4btoul(loc.firstblk);
3252 xpt_release_ccb(ccb);
3257 sasetpos(struct cam_periph *periph, int hard, u_int32_t *blkptr)
3260 struct sa_softc *softc;
3264 * We used to try and flush any buffered writes here.
3265 * Now we push this onto user applications to either
3266 * flush the pending writes themselves (via a zero count
3267 * WRITE FILEMARKS command) or they can trust their tape
3268 * drive to do this correctly for them.
3271 softc = (struct sa_softc *)periph->softc;
3272 ccb = cam_periph_getccb(periph, 1);
3275 scsi_set_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG,
3276 hard, *blkptr, SSD_FULL_SIZE, SPACE_TIMEOUT);
3279 softc->dsreg = MTIO_DSREG_POS;
3280 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
3281 softc->dsreg = MTIO_DSREG_REST;
3282 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
3283 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0);
3284 xpt_release_ccb(ccb);
3286 * Note relative file && block number position as now unknown.
3288 softc->fileno = softc->blkno = (daddr_t) -1;
3293 saretension(struct cam_periph *periph)
3296 struct sa_softc *softc;
3299 softc = (struct sa_softc *)periph->softc;
3301 ccb = cam_periph_getccb(periph, 1);
3303 /* It is safe to retry this operation */
3304 scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE,
3305 FALSE, TRUE, TRUE, SSD_FULL_SIZE, ERASE_TIMEOUT);
3307 softc->dsreg = MTIO_DSREG_TEN;
3308 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
3309 softc->dsreg = MTIO_DSREG_REST;
3311 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
3312 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE);
3313 xpt_release_ccb(ccb);
3315 softc->fileno = softc->blkno = (daddr_t) 0;
3317 softc->fileno = softc->blkno = (daddr_t) -1;
3322 sareservereleaseunit(struct cam_periph *periph, int reserve)
3325 struct sa_softc *softc;
3328 softc = (struct sa_softc *)periph->softc;
3329 ccb = cam_periph_getccb(periph, 1);
3331 /* It is safe to retry this operation */
3332 scsi_reserve_release_unit(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG,
3333 FALSE, 0, SSD_FULL_SIZE, SCSIOP_TIMEOUT, reserve);
3334 softc->dsreg = MTIO_DSREG_RBSY;
3335 error = cam_periph_runccb(ccb, saerror, 0,
3336 SF_RETRY_UA | SF_NO_PRINT, softc->device_stats);
3337 softc->dsreg = MTIO_DSREG_REST;
3339 xpt_release_ccb(ccb);
3342 * If the error was Illegal Request, then the device doesn't support
3343 * RESERVE/RELEASE. This is not an error.
3345 if (error == EINVAL) {
3353 saloadunload(struct cam_periph *periph, int load)
3356 struct sa_softc *softc;
3359 softc = (struct sa_softc *)periph->softc;
3361 ccb = cam_periph_getccb(periph, 1);
3363 /* It is safe to retry this operation */
3364 scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE,
3365 FALSE, FALSE, load, SSD_FULL_SIZE, REWIND_TIMEOUT);
3367 softc->dsreg = (load)? MTIO_DSREG_LD : MTIO_DSREG_UNL;
3368 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
3369 softc->dsreg = MTIO_DSREG_REST;
3371 xpt_release_ccb(ccb);
3373 if (error || load == 0)
3374 softc->fileno = softc->blkno = (daddr_t) -1;
3375 else if (error == 0)
3376 softc->fileno = softc->blkno = (daddr_t) 0;
3381 saerase(struct cam_periph *periph, int longerase)
3385 struct sa_softc *softc;
3388 softc = (struct sa_softc *)periph->softc;
3389 if (softc->open_rdonly)
3392 ccb = cam_periph_getccb(periph, 1);
3394 scsi_erase(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, FALSE, longerase,
3395 SSD_FULL_SIZE, ERASE_TIMEOUT);
3397 softc->dsreg = MTIO_DSREG_ZER;
3398 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
3399 softc->dsreg = MTIO_DSREG_REST;
3401 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
3402 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, FALSE);
3403 xpt_release_ccb(ccb);
3407 #endif /* _KERNEL */
3410 * Read tape block limits command.
3413 scsi_read_block_limits(struct ccb_scsiio *csio, u_int32_t retries,
3414 void (*cbfcnp)(struct cam_periph *, union ccb *),
3415 u_int8_t tag_action,
3416 struct scsi_read_block_limits_data *rlimit_buf,
3417 u_int8_t sense_len, u_int32_t timeout)
3419 struct scsi_read_block_limits *scsi_cmd;
3421 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_IN, tag_action,
3422 (u_int8_t *)rlimit_buf, sizeof(*rlimit_buf), sense_len,
3423 sizeof(*scsi_cmd), timeout);
3425 scsi_cmd = (struct scsi_read_block_limits *)&csio->cdb_io.cdb_bytes;
3426 bzero(scsi_cmd, sizeof(*scsi_cmd));
3427 scsi_cmd->opcode = READ_BLOCK_LIMITS;
3431 scsi_sa_read_write(struct ccb_scsiio *csio, u_int32_t retries,
3432 void (*cbfcnp)(struct cam_periph *, union ccb *),
3433 u_int8_t tag_action, int readop, int sli,
3434 int fixed, u_int32_t length, u_int8_t *data_ptr,
3435 u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout)
3437 struct scsi_sa_rw *scsi_cmd;
3439 scsi_cmd = (struct scsi_sa_rw *)&csio->cdb_io.cdb_bytes;
3440 scsi_cmd->opcode = readop ? SA_READ : SA_WRITE;
3441 scsi_cmd->sli_fixed = 0;
3443 scsi_cmd->sli_fixed |= SAR_SLI;
3445 scsi_cmd->sli_fixed |= SARW_FIXED;
3446 scsi_ulto3b(length, scsi_cmd->length);
3447 scsi_cmd->control = 0;
3449 cam_fill_csio(csio, retries, cbfcnp, readop ? CAM_DIR_IN : CAM_DIR_OUT,
3450 tag_action, data_ptr, dxfer_len, sense_len,
3451 sizeof(*scsi_cmd), timeout);
3455 scsi_load_unload(struct ccb_scsiio *csio, u_int32_t retries,
3456 void (*cbfcnp)(struct cam_periph *, union ccb *),
3457 u_int8_t tag_action, int immediate, int eot,
3458 int reten, int load, u_int8_t sense_len,
3461 struct scsi_load_unload *scsi_cmd;
3463 scsi_cmd = (struct scsi_load_unload *)&csio->cdb_io.cdb_bytes;
3464 bzero(scsi_cmd, sizeof(*scsi_cmd));
3465 scsi_cmd->opcode = LOAD_UNLOAD;
3467 scsi_cmd->immediate = SLU_IMMED;
3469 scsi_cmd->eot_reten_load |= SLU_EOT;
3471 scsi_cmd->eot_reten_load |= SLU_RETEN;
3473 scsi_cmd->eot_reten_load |= SLU_LOAD;
3475 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action,
3476 NULL, 0, sense_len, sizeof(*scsi_cmd), timeout);
3480 scsi_rewind(struct ccb_scsiio *csio, u_int32_t retries,
3481 void (*cbfcnp)(struct cam_periph *, union ccb *),
3482 u_int8_t tag_action, int immediate, u_int8_t sense_len,
3485 struct scsi_rewind *scsi_cmd;
3487 scsi_cmd = (struct scsi_rewind *)&csio->cdb_io.cdb_bytes;
3488 bzero(scsi_cmd, sizeof(*scsi_cmd));
3489 scsi_cmd->opcode = REWIND;
3491 scsi_cmd->immediate = SREW_IMMED;
3493 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
3494 0, sense_len, sizeof(*scsi_cmd), timeout);
3498 scsi_space(struct ccb_scsiio *csio, u_int32_t retries,
3499 void (*cbfcnp)(struct cam_periph *, union ccb *),
3500 u_int8_t tag_action, scsi_space_code code,
3501 u_int32_t count, u_int8_t sense_len, u_int32_t timeout)
3503 struct scsi_space *scsi_cmd;
3505 scsi_cmd = (struct scsi_space *)&csio->cdb_io.cdb_bytes;
3506 scsi_cmd->opcode = SPACE;
3507 scsi_cmd->code = code;
3508 scsi_ulto3b(count, scsi_cmd->count);
3509 scsi_cmd->control = 0;
3511 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
3512 0, sense_len, sizeof(*scsi_cmd), timeout);
3516 scsi_write_filemarks(struct ccb_scsiio *csio, u_int32_t retries,
3517 void (*cbfcnp)(struct cam_periph *, union ccb *),
3518 u_int8_t tag_action, int immediate, int setmark,
3519 u_int32_t num_marks, u_int8_t sense_len,
3522 struct scsi_write_filemarks *scsi_cmd;
3524 scsi_cmd = (struct scsi_write_filemarks *)&csio->cdb_io.cdb_bytes;
3525 bzero(scsi_cmd, sizeof(*scsi_cmd));
3526 scsi_cmd->opcode = WRITE_FILEMARKS;
3528 scsi_cmd->byte2 |= SWFMRK_IMMED;
3530 scsi_cmd->byte2 |= SWFMRK_WSMK;
3532 scsi_ulto3b(num_marks, scsi_cmd->num_marks);
3534 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
3535 0, sense_len, sizeof(*scsi_cmd), timeout);
3539 * The reserve and release unit commands differ only by their opcodes.
3542 scsi_reserve_release_unit(struct ccb_scsiio *csio, u_int32_t retries,
3543 void (*cbfcnp)(struct cam_periph *, union ccb *),
3544 u_int8_t tag_action, int third_party,
3545 int third_party_id, u_int8_t sense_len,
3546 u_int32_t timeout, int reserve)
3548 struct scsi_reserve_release_unit *scsi_cmd;
3550 scsi_cmd = (struct scsi_reserve_release_unit *)&csio->cdb_io.cdb_bytes;
3551 bzero(scsi_cmd, sizeof(*scsi_cmd));
3554 scsi_cmd->opcode = RESERVE_UNIT;
3556 scsi_cmd->opcode = RELEASE_UNIT;
3559 scsi_cmd->lun_thirdparty |= SRRU_3RD_PARTY;
3560 scsi_cmd->lun_thirdparty |=
3561 ((third_party_id << SRRU_3RD_SHAMT) & SRRU_3RD_MASK);
3564 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
3565 0, sense_len, sizeof(*scsi_cmd), timeout);
3569 scsi_erase(struct ccb_scsiio *csio, u_int32_t retries,
3570 void (*cbfcnp)(struct cam_periph *, union ccb *),
3571 u_int8_t tag_action, int immediate, int long_erase,
3572 u_int8_t sense_len, u_int32_t timeout)
3574 struct scsi_erase *scsi_cmd;
3576 scsi_cmd = (struct scsi_erase *)&csio->cdb_io.cdb_bytes;
3577 bzero(scsi_cmd, sizeof(*scsi_cmd));
3579 scsi_cmd->opcode = ERASE;
3582 scsi_cmd->lun_imm_long |= SE_IMMED;
3585 scsi_cmd->lun_imm_long |= SE_LONG;
3587 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
3588 0, sense_len, sizeof(*scsi_cmd), timeout);
3592 * Read Tape Position command.
3595 scsi_read_position(struct ccb_scsiio *csio, u_int32_t retries,
3596 void (*cbfcnp)(struct cam_periph *, union ccb *),
3597 u_int8_t tag_action, int hardsoft,
3598 struct scsi_tape_position_data *sbp,
3599 u_int8_t sense_len, u_int32_t timeout)
3601 struct scsi_tape_read_position *scmd;
3603 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_IN, tag_action,
3604 (u_int8_t *)sbp, sizeof (*sbp), sense_len, sizeof(*scmd), timeout);
3605 scmd = (struct scsi_tape_read_position *)&csio->cdb_io.cdb_bytes;
3606 bzero(scmd, sizeof(*scmd));
3607 scmd->opcode = READ_POSITION;
3608 scmd->byte1 = hardsoft;
3612 * Set Tape Position command.
3615 scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries,
3616 void (*cbfcnp)(struct cam_periph *, union ccb *),
3617 u_int8_t tag_action, int hardsoft, u_int32_t blkno,
3618 u_int8_t sense_len, u_int32_t timeout)
3620 struct scsi_tape_locate *scmd;
3622 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action,
3623 (u_int8_t *)NULL, 0, sense_len, sizeof(*scmd), timeout);
3624 scmd = (struct scsi_tape_locate *)&csio->cdb_io.cdb_bytes;
3625 bzero(scmd, sizeof(*scmd));
3626 scmd->opcode = LOCATE;
3628 scmd->byte1 |= SA_SPOS_BT;
3629 scsi_ulto4b(blkno, scmd->blkaddr);