2 * $FreeBSD: src/sys/cam/scsi/scsi_sa.c,v 1.45.2.13 2002/12/17 17:08:50 trhodes Exp $
4 * Implementation of SCSI Sequential Access Peripheral driver for CAM.
6 * Copyright (c) 1999, 2000 Matthew Jacob
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification, immediately at the beginning of the file.
15 * 2. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
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/malloc.h>
50 #include <sys/fcntl.h>
51 #include <sys/devicestat.h>
52 #include <machine/limits.h>
60 #include "../cam_ccb.h"
61 #include "../cam_extend.h"
62 #include "../cam_periph.h"
63 #include "../cam_xpt_periph.h"
64 #include "../cam_debug.h"
67 #include "scsi_message.h"
75 #define SA_IO_TIMEOUT 4
77 #ifndef SA_SPACE_TIMEOUT
78 #define SA_SPACE_TIMEOUT 1 * 60
80 #ifndef SA_REWIND_TIMEOUT
81 #define SA_REWIND_TIMEOUT 2 * 60
83 #ifndef SA_ERASE_TIMEOUT
84 #define SA_ERASE_TIMEOUT 4 * 60
87 #define SCSIOP_TIMEOUT (60 * 1000) /* not an option */
89 #define IO_TIMEOUT (SA_IO_TIMEOUT * 60 * 1000)
90 #define REWIND_TIMEOUT (SA_REWIND_TIMEOUT * 60 * 1000)
91 #define ERASE_TIMEOUT (SA_ERASE_TIMEOUT * 60 * 1000)
92 #define SPACE_TIMEOUT (SA_SPACE_TIMEOUT * 60 * 1000)
95 * Additional options that can be set for config: SA_1FM_AT_EOT
99 if (((ccb)->ccb_h.status & CAM_DEV_QFRZN) != 0) \
100 cam_release_devq((ccb)->ccb_h.path, 0, 0, 0, FALSE)
106 MALLOC_DEFINE(M_SCSISA
, "SCSI sa", "SCSI sequential access buffers");
109 SA_STATE_NORMAL
, SA_STATE_ABNORMAL
112 #define ccb_pflags ppriv_field0
113 #define ccb_bio ppriv_ptr1
115 #define SA_CCB_POLLED 0x00
116 #define SA_CCB_BUFFER_IO 0x01
117 #define SA_CCB_WAITING 0x02
118 #define SA_CCB_TYPEMASK 0x0F
119 #define SA_POSITION_UPDATED 0x10
121 #define Set_CCB_Type(x, type) do { \
122 x->ccb_h.ccb_pflags &= ~SA_CCB_TYPEMASK; \
123 x->ccb_h.ccb_pflags |= type; \
126 #define CCB_Type(x) (x->ccb_h.ccb_pflags & SA_CCB_TYPEMASK)
131 SA_FLAG_OPEN
= 0x0001,
132 SA_FLAG_FIXED
= 0x0002,
133 SA_FLAG_TAPE_LOCKED
= 0x0004,
134 SA_FLAG_TAPE_MOUNTED
= 0x0008,
135 SA_FLAG_TAPE_WP
= 0x0010,
136 SA_FLAG_TAPE_WRITTEN
= 0x0020,
137 SA_FLAG_EOM_PENDING
= 0x0040,
138 SA_FLAG_EIO_PENDING
= 0x0080,
139 SA_FLAG_EOF_PENDING
= 0x0100,
140 SA_FLAG_ERR_PENDING
= (SA_FLAG_EOM_PENDING
|SA_FLAG_EIO_PENDING
|
141 SA_FLAG_EOF_PENDING
),
142 SA_FLAG_INVALID
= 0x0200,
143 SA_FLAG_COMP_ENABLED
= 0x0400,
144 SA_FLAG_COMP_SUPP
= 0x0800,
145 SA_FLAG_COMP_UNSUPP
= 0x1000,
146 SA_FLAG_TAPE_FROZEN
= 0x2000
150 SA_MODE_REWIND
= 0x00,
151 SA_MODE_NOREWIND
= 0x01,
152 SA_MODE_OFFLINE
= 0x02
156 SA_PARAM_NONE
= 0x00,
157 SA_PARAM_BLOCKSIZE
= 0x01,
158 SA_PARAM_DENSITY
= 0x02,
159 SA_PARAM_COMPRESSION
= 0x04,
160 SA_PARAM_BUFF_MODE
= 0x08,
161 SA_PARAM_NUMBLOCKS
= 0x10,
163 SA_PARAM_SPEED
= 0x40,
168 SA_QUIRK_NONE
= 0x00,
169 SA_QUIRK_NOCOMP
= 0x01, /* Can't deal with compression at all */
170 SA_QUIRK_FIXED
= 0x02, /* Force fixed mode */
171 SA_QUIRK_VARIABLE
= 0x04, /* Force variable mode */
172 SA_QUIRK_2FM
= 0x08, /* Needs Two File Marks at EOD */
173 SA_QUIRK_1FM
= 0x10, /* No more than 1 File Mark at EOD */
174 SA_QUIRK_NODREAD
= 0x20, /* Don't try and dummy read density */
175 SA_QUIRK_NO_MODESEL
= 0x40, /* Don't do mode select at all */
176 SA_QUIRK_NO_CPAGE
= 0x80 /* Don't use DEVICE COMPRESSION page */
179 /* units are bits 4-7, 16-21 (1024 units) */
180 #define SAUNIT(DEV) \
181 (((minor(DEV) & 0xF0) >> 4) | ((minor(DEV) & 0x3f0000) >> 16))
183 #define SAMODE(z) ((minor(z) & 0x3))
184 #define SADENSITY(z) (((minor(z) >> 2) & 0x3))
185 #define SA_IS_CTRL(z) (minor(z) & (1 << 29))
187 #define SA_NOT_CTLDEV 0
191 #define SA_ATYPE_NR 1
192 #define SA_ATYPE_ER 2
194 #define SAMINOR(ctl, unit, mode, access) \
195 ((ctl << 29) | ((unit & 0x3f0) << 16) | ((unit & 0xf) << 4) | \
196 (mode << 0x2) | (access & 0x3))
198 #define SA_UNITMASK SAMINOR(0, -1, 0, 0)
199 #define SA_UNIT(unit) SAMINOR(0, unit, 0, 0)
201 #define SA_NUM_MODES 4
207 struct bio_queue_head bio_queue
;
209 struct devstat device_stats
;
215 u_int32_t comp_algorithm
;
216 u_int32_t saved_comp_algorithm
;
217 u_int32_t media_blksize
;
218 u_int32_t last_media_blksize
;
219 u_int32_t media_numblks
;
220 u_int8_t media_density
;
223 u_int8_t dsreg
; /* mtio mt_dsreg, redux */
227 int last_resid_was_io
;
230 * Relative to BOT Location.
239 struct scsi_sense_data _last_io_sense
;
240 u_int32_t _last_io_resid
;
241 u_int8_t _last_io_cdb
[CAM_MAX_CDBLEN
];
242 struct scsi_sense_data _last_ctl_sense
;
243 u_int32_t _last_ctl_resid
;
244 u_int8_t _last_ctl_cdb
[CAM_MAX_CDBLEN
];
245 #define last_io_sense errinfo._last_io_sense
246 #define last_io_resid errinfo._last_io_resid
247 #define last_io_cdb errinfo._last_io_cdb
248 #define last_ctl_sense errinfo._last_ctl_sense
249 #define last_ctl_resid errinfo._last_ctl_resid
250 #define last_ctl_cdb errinfo._last_ctl_cdb
253 * Misc other flags/state
257 open_rdonly
: 1, /* open read-only */
258 open_pending_mount
: 1, /* open pending mount */
259 ctrl_mode
: 1; /* control device open */
262 struct sa_quirk_entry
{
263 struct scsi_inquiry_pattern inq_pat
; /* matching pattern */
264 sa_quirks quirks
; /* specific quirk type */
265 u_int32_t prefblk
; /* preferred blocksize when in fixed mode */
268 static struct sa_quirk_entry sa_quirk_table
[] =
271 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "OnStream",
272 "ADR*", "*"}, SA_QUIRK_FIXED
|SA_QUIRK_NODREAD
|
273 SA_QUIRK_1FM
|SA_QUIRK_NO_MODESEL
, 32768
276 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "ARCHIVE",
277 "Python 06408*", "*"}, SA_QUIRK_NODREAD
, 0
280 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "ARCHIVE",
281 "Python 25601*", "*"}, SA_QUIRK_NOCOMP
|SA_QUIRK_NODREAD
, 0
284 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "ARCHIVE",
285 "Python*", "*"}, SA_QUIRK_NODREAD
, 0
288 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "ARCHIVE",
289 "VIPER 150*", "*"}, SA_QUIRK_FIXED
|SA_QUIRK_1FM
, 512
292 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "ARCHIVE",
293 "VIPER 2525 25462", "-011"},
294 SA_QUIRK_NOCOMP
|SA_QUIRK_1FM
|SA_QUIRK_NODREAD
, 0
297 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "ARCHIVE",
298 "VIPER 2525*", "*"}, SA_QUIRK_FIXED
|SA_QUIRK_1FM
, 1024
302 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "HP",
303 "C15*", "*"}, SA_QUIRK_VARIABLE
|SA_QUIRK_NO_CPAGE
, 0,
307 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "HP",
308 "C56*", "*"}, SA_QUIRK_VARIABLE
|SA_QUIRK_2FM
, 0
311 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "HP",
312 "T20*", "*"}, SA_QUIRK_FIXED
|SA_QUIRK_1FM
, 512
315 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "HP",
316 "T4000*", "*"}, SA_QUIRK_FIXED
|SA_QUIRK_1FM
, 512
319 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "HP",
320 "HP-88780*", "*"}, SA_QUIRK_VARIABLE
|SA_QUIRK_2FM
, 0
323 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "KENNEDY",
324 "*", "*"}, SA_QUIRK_VARIABLE
|SA_QUIRK_2FM
, 0
327 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "M4 DATA",
328 "123107 SCSI*", "*"}, SA_QUIRK_VARIABLE
|SA_QUIRK_2FM
, 0
330 { /* jreynold@primenet.com */
331 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "Seagate",
332 "STT8000N*", "*"}, SA_QUIRK_1FM
, 0
334 { /* mike@sentex.net */
335 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "Seagate",
336 "STT20000*", "*"}, SA_QUIRK_1FM
, 0
339 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "TANDBERG",
340 " TDC 3600", "U07:"}, SA_QUIRK_NOCOMP
|SA_QUIRK_1FM
, 512
343 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "TANDBERG",
344 " TDC 3800", "*"}, SA_QUIRK_NOCOMP
|SA_QUIRK_1FM
, 512
347 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "TANDBERG",
348 " TDC 4100", "*"}, SA_QUIRK_NOCOMP
|SA_QUIRK_1FM
, 512
351 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "TANDBERG",
352 " TDC 4200", "*"}, SA_QUIRK_NOCOMP
|SA_QUIRK_1FM
, 512
355 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "TANDBERG",
356 " SLR*", "*"}, SA_QUIRK_1FM
, 0
359 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "WANGTEK",
360 "5525ES*", "*"}, SA_QUIRK_FIXED
|SA_QUIRK_1FM
, 512
363 { T_SEQUENTIAL
, SIP_MEDIA_REMOVABLE
, "WANGTEK",
364 "51000*", "*"}, SA_QUIRK_FIXED
|SA_QUIRK_1FM
, 1024
368 static d_open_t saopen
;
369 static d_close_t saclose
;
370 static d_strategy_t sastrategy
;
371 static d_ioctl_t saioctl
;
372 static periph_init_t sainit
;
373 static periph_ctor_t saregister
;
374 static periph_oninv_t saoninvalidate
;
375 static periph_dtor_t sacleanup
;
376 static periph_start_t sastart
;
377 static void saasync(void *callback_arg
, u_int32_t code
,
378 struct cam_path
*path
, void *arg
);
379 static void sadone(struct cam_periph
*periph
,
380 union ccb
*start_ccb
);
381 static int saerror(union ccb
*ccb
, u_int32_t cam_flags
,
382 u_int32_t sense_flags
);
383 static int samarkswanted(struct cam_periph
*);
384 static int sacheckeod(struct cam_periph
*periph
);
385 static int sagetparams(struct cam_periph
*periph
,
386 sa_params params_to_get
,
387 u_int32_t
*blocksize
, u_int8_t
*density
,
388 u_int32_t
*numblocks
, int *buff_mode
,
389 u_int8_t
*write_protect
, u_int8_t
*speed
,
390 int *comp_supported
, int *comp_enabled
,
391 u_int32_t
*comp_algorithm
,
392 sa_comp_t
*comp_page
);
393 static int sasetparams(struct cam_periph
*periph
,
394 sa_params params_to_set
,
395 u_int32_t blocksize
, u_int8_t density
,
396 u_int32_t comp_algorithm
,
397 u_int32_t sense_flags
);
398 static void saprevent(struct cam_periph
*periph
, int action
);
399 static int sarewind(struct cam_periph
*periph
);
400 static int saspace(struct cam_periph
*periph
, int count
,
401 scsi_space_code code
);
402 static int samount(struct cam_periph
*, int, cdev_t
);
403 static int saretension(struct cam_periph
*periph
);
404 static int sareservereleaseunit(struct cam_periph
*periph
,
406 static int saloadunload(struct cam_periph
*periph
, int load
);
407 static int saerase(struct cam_periph
*periph
, int longerase
);
408 static int sawritefilemarks(struct cam_periph
*periph
,
409 int nmarks
, int setmarks
);
410 static int sardpos(struct cam_periph
*periph
, int, u_int32_t
*);
411 static int sasetpos(struct cam_periph
*periph
, int, u_int32_t
*);
414 static struct periph_driver sadriver
=
417 TAILQ_HEAD_INITIALIZER(sadriver
.units
), /* generation */ 0
420 PERIPHDRIVER_DECLARE(sa
, sadriver
);
422 /* For 2.2-stable support */
427 static struct dev_ops sa_ops
= {
432 .d_write
= physwrite
,
434 .d_strategy
= sastrategy
,
437 static struct extend_array
*saperiphs
;
440 saopen(struct dev_open_args
*ap
)
442 cdev_t dev
= ap
->a_head
.a_dev
;
443 struct cam_periph
*periph
;
444 struct sa_softc
*softc
;
449 * Disallow CAM access if RESTRICTEDROOT
451 if (caps_priv_check_self(SYSCAP_RESTRICTEDROOT
))
456 periph
= cam_extend_get(saperiphs
, unit
);
457 if (cam_periph_acquire(periph
) != CAM_REQ_CMP
) {
461 cam_periph_lock(periph
);
463 softc
= (struct sa_softc
*)periph
->softc
;
465 CAM_DEBUG(periph
->path
, CAM_DEBUG_TRACE
|CAM_DEBUG_INFO
,
466 ("saopen(%d): dev=0x%x softc=0x%x\n", unit
, unit
, softc
->flags
));
468 if (SA_IS_CTRL(dev
)) {
469 softc
->ctrl_mode
= 1;
470 cam_periph_unlock(periph
);
474 if ((error
= cam_periph_hold(periph
, PCATCH
)) != 0) {
475 cam_periph_unlock(periph
);
476 cam_periph_release(periph
);
480 if (softc
->flags
& SA_FLAG_OPEN
) {
482 } else if (softc
->flags
& SA_FLAG_INVALID
) {
486 * Preserve whether this is a read_only open.
488 softc
->open_rdonly
= (ap
->a_oflags
& O_RDWR
) == O_RDONLY
;
491 * The function samount ensures media is loaded and ready.
492 * It also does a device RESERVE if the tape isn't yet mounted.
494 * If the mount fails and this was a non-blocking open,
495 * make this a 'open_pending_mount' action.
497 error
= samount(periph
, ap
->a_oflags
, dev
);
498 if (error
&& (ap
->a_oflags
& O_NONBLOCK
)) {
499 softc
->flags
|= SA_FLAG_OPEN
;
500 softc
->open_pending_mount
= 1;
501 cam_periph_unhold(periph
, 1);
507 cam_periph_unhold(periph
, 1);
508 cam_periph_release(periph
);
512 saprevent(periph
, PR_PREVENT
);
513 softc
->flags
|= SA_FLAG_OPEN
;
515 cam_periph_unhold(periph
, 1);
520 saclose(struct dev_close_args
*ap
)
522 cdev_t dev
= ap
->a_head
.a_dev
;
523 struct cam_periph
*periph
;
524 struct sa_softc
*softc
;
525 int unit
, mode
, error
, writing
, tmp
;
526 int closedbits
= SA_FLAG_OPEN
;
530 periph
= cam_extend_get(saperiphs
, unit
);
534 cam_periph_lock(periph
);
536 softc
= (struct sa_softc
*)periph
->softc
;
538 CAM_DEBUG(periph
->path
, CAM_DEBUG_TRACE
|CAM_DEBUG_INFO
,
539 ("saclose(%d): dev=0x%x softc=0x%x\n", unit
, unit
, softc
->flags
));
542 softc
->open_rdonly
= 0;
543 if (SA_IS_CTRL(dev
)) {
544 softc
->ctrl_mode
= 0;
545 cam_periph_unlock(periph
);
546 cam_periph_release(periph
);
550 if (softc
->open_pending_mount
) {
551 softc
->flags
&= ~SA_FLAG_OPEN
;
552 softc
->open_pending_mount
= 0;
553 cam_periph_unlock(periph
);
554 cam_periph_release(periph
);
558 if ((error
= cam_periph_hold(periph
, 0)) != 0) {
559 cam_periph_unlock(periph
);
564 * Were we writing the tape?
566 writing
= (softc
->flags
& SA_FLAG_TAPE_WRITTEN
) != 0;
569 * See whether or not we need to write filemarks. If this
570 * fails, we probably have to assume we've lost tape
573 error
= sacheckeod(periph
);
575 xpt_print(periph
->path
,
576 "failed to write terminating filemark(s)\n");
577 softc
->flags
|= SA_FLAG_TAPE_FROZEN
;
581 * Whatever we end up doing, allow users to eject tapes from here on.
583 saprevent(periph
, PR_ALLOW
);
586 * Decide how to end...
588 if ((softc
->flags
& SA_FLAG_TAPE_MOUNTED
) == 0) {
589 closedbits
|= SA_FLAG_TAPE_FROZEN
;
590 } else switch (mode
) {
591 case SA_MODE_OFFLINE
:
593 * An 'offline' close is an unconditional release of
594 * frozen && mount conditions, irrespective of whether
595 * these operations succeeded. The reason for this is
596 * to allow at least some kind of programmatic way
597 * around our state getting all fouled up. If somebody
598 * issues an 'offline' command, that will be allowed
602 saloadunload(periph
, FALSE
);
603 closedbits
|= SA_FLAG_TAPE_MOUNTED
|SA_FLAG_TAPE_FROZEN
;
607 * If the rewind fails, return an error- if anyone cares,
608 * but not overwriting any previous error.
610 * We don't clear the notion of mounted here, but we do
611 * clear the notion of frozen if we successfully rewound.
613 tmp
= sarewind(periph
);
618 closedbits
|= SA_FLAG_TAPE_FROZEN
;
621 case SA_MODE_NOREWIND
:
623 * If we're not rewinding/unloading the tape, find out
624 * whether we need to back up over one of two filemarks
625 * we wrote (if we wrote two filemarks) so that appends
626 * from this point on will be sane.
628 if (error
== 0 && writing
&& (softc
->quirks
& SA_QUIRK_2FM
)) {
629 tmp
= saspace(periph
, -1, SS_FILEMARKS
);
631 xpt_print(periph
->path
, "unable to backspace "
632 "over one of double filemarks at end of "
634 xpt_print(periph
->path
, "it is possible that "
635 "this device needs a SA_QUIRK_1FM quirk set"
637 softc
->flags
|= SA_FLAG_TAPE_FROZEN
;
642 xpt_print(periph
->path
, "unknown mode 0x%x in saclose\n", mode
);
648 * We wish to note here that there are no more filemarks to be written.
650 softc
->filemarks
= 0;
651 softc
->flags
&= ~SA_FLAG_TAPE_WRITTEN
;
654 * And we are no longer open for business.
656 softc
->flags
&= ~closedbits
;
659 * Inform users if tape state if frozen....
661 if (softc
->flags
& SA_FLAG_TAPE_FROZEN
) {
662 xpt_print(periph
->path
, "tape is now frozen- use an OFFLINE, "
663 "REWIND or MTEOM command to clear this state.\n");
666 /* release the device if it is no longer mounted */
667 if ((softc
->flags
& SA_FLAG_TAPE_MOUNTED
) == 0)
668 sareservereleaseunit(periph
, FALSE
);
670 cam_periph_unhold(periph
, 1);
671 cam_periph_release(periph
);
677 * Actually translate the requested transfer into one the physical driver
678 * can understand. The transfer is described by a buf and will include
679 * only one physical transfer.
682 sastrategy(struct dev_strategy_args
*ap
)
684 cdev_t dev
= ap
->a_head
.a_dev
;
685 struct bio
*bio
= ap
->a_bio
;
686 struct buf
*bp
= bio
->bio_buf
;
687 struct cam_periph
*periph
;
688 struct sa_softc
*softc
;
691 if (SA_IS_CTRL(dev
)) {
692 bp
->b_error
= EINVAL
;
696 periph
= cam_extend_get(saperiphs
, unit
);
697 if (periph
== NULL
) {
701 cam_periph_lock(periph
);
703 softc
= (struct sa_softc
*)periph
->softc
;
705 if (softc
->flags
& SA_FLAG_INVALID
) {
706 cam_periph_unlock(periph
);
711 if (softc
->flags
& SA_FLAG_TAPE_FROZEN
) {
712 cam_periph_unlock(periph
);
718 * This should actually never occur as the write(2)
719 * system call traps attempts to write to a read-only
722 if (bp
->b_cmd
== BUF_CMD_WRITE
&& softc
->open_rdonly
) {
723 cam_periph_unlock(periph
);
728 if (softc
->open_pending_mount
) {
729 int error
= samount(periph
, 0, dev
);
731 cam_periph_unlock(periph
);
735 saprevent(periph
, PR_PREVENT
);
736 softc
->open_pending_mount
= 0;
740 * If it's a null transfer, return immediately
742 if (bp
->b_bcount
== 0) {
743 cam_periph_unlock(periph
);
748 if (softc
->flags
& SA_FLAG_FIXED
) {
750 * Fixed block device. The byte count must
751 * be a multiple of our block size.
753 if (((softc
->blk_mask
!= ~0) &&
754 ((bp
->b_bcount
& softc
->blk_mask
) != 0)) ||
755 ((softc
->blk_mask
== ~0) &&
756 ((bp
->b_bcount
% softc
->min_blk
) != 0))) {
757 xpt_print(periph
->path
, "Invalid request. Fixed block "
758 "device requests must be a multiple of %d bytes\n",
760 cam_periph_unlock(periph
);
761 bp
->b_error
= EINVAL
;
764 } else if ((bp
->b_bcount
> softc
->max_blk
) ||
765 (bp
->b_bcount
< softc
->min_blk
) ||
766 (bp
->b_bcount
& softc
->blk_mask
) != 0) {
768 xpt_print_path(periph
->path
);
769 kprintf("Invalid request. Variable block "
770 "device requests must be ");
771 if (softc
->blk_mask
!= 0) {
772 kprintf("a multiple of %d ", (0x1 << softc
->blk_gran
));
774 kprintf("between %d and %d bytes\n", softc
->min_blk
,
776 cam_periph_unlock(periph
);
777 bp
->b_error
= EINVAL
;
782 * Place it at the end of the queue.
784 bioq_insert_tail(&softc
->bio_queue
, bio
);
785 softc
->queue_count
++;
787 CAM_DEBUG(periph
->path
, CAM_DEBUG_INFO
,
788 ("sastrategy: queuing a %ld %s byte %s\n", bp
->bio_bcount
,
789 (softc
->flags
& SA_FLAG_FIXED
)? "fixed" : "variable",
790 (bp
->bio_cmd
== BIO_READ
)? "read" : "write"));
792 if (softc
->queue_count
> 1) {
793 CAM_DEBUG(periph
->path
, CAM_DEBUG_INFO
,
794 ("sastrategy: queue count now %d\n", softc
->queue_count
));
798 * Schedule ourselves for performing the work.
800 xpt_schedule(periph
, 1);
801 cam_periph_unlock(periph
);
805 bp
->b_flags
|= B_ERROR
;
809 * Correctly set the buf to indicate a completed xfer
811 bp
->b_resid
= bp
->b_bcount
;
817 #define PENDING_MOUNT_CHECK(softc, periph, dev) \
818 if (softc->open_pending_mount) { \
819 error = samount(periph, 0, dev); \
823 saprevent(periph, PR_PREVENT); \
824 softc->open_pending_mount = 0; \
828 saioctl(struct dev_ioctl_args
*ap
)
830 cdev_t dev
= ap
->a_head
.a_dev
;
831 caddr_t addr
= ap
->a_data
;
832 struct cam_periph
*periph
;
833 struct sa_softc
*softc
;
834 scsi_space_code spaceop
;
835 int didholdperiph
= 0;
842 error
= 0; /* shut up gcc */
843 spaceop
= 0; /* shut up gcc */
845 periph
= cam_extend_get(saperiphs
, unit
);
849 cam_periph_lock(periph
);
850 softc
= (struct sa_softc
*)periph
->softc
;
853 * Check for control mode accesses. We allow MTIOCGET and
854 * MTIOCERRSTAT (but need to be the only one open in order
855 * to clear latched status), and MTSETBSIZE, MTSETDNSTY
856 * and MTCOMP (but need to be the only one accessing this
857 * device to run those).
860 if (SA_IS_CTRL(dev
)) {
862 case MTIOCGETEOTMODEL
:
867 * If the periph isn't already locked, lock it
868 * so our MTIOCERRSTAT can reset latched error stats.
870 * If the periph is already locked, skip it because
871 * we're just getting status and it'll be up to the
872 * other thread that has this device open to do
873 * an MTIOCERRSTAT that would clear latched status.
875 if ((periph
->flags
& CAM_PERIPH_LOCKED
) == 0) {
876 error
= cam_periph_hold(periph
, PCATCH
);
886 struct mtop
*mt
= (struct mtop
*) addr
;
889 * Check to make sure it's an OP we can perform
890 * with no media inserted.
906 case MTIOCSETEOTMODEL
:
908 * We need to acquire the peripheral here rather
909 * than at open time because we are sharing writable
910 * access to data structures.
912 error
= cam_periph_hold(periph
, PCATCH
);
925 * Find the device that the user is talking about
930 struct mtget
*g
= (struct mtget
*)addr
;
933 * If this isn't the control mode device, actually go out
934 * and ask the drive again what it's set to.
936 if (!SA_IS_CTRL(dev
) && !softc
->open_pending_mount
) {
937 u_int8_t write_protect
= 0; /* silence gcc */
938 int comp_enabled
= 0; /* silence gcc */
939 int comp_supported
= 0; /* silence gcc */
941 error
= sagetparams(periph
, SA_PARAM_ALL
,
942 &softc
->media_blksize
, &softc
->media_density
,
943 &softc
->media_numblks
, &softc
->buffer_mode
,
944 &write_protect
, &softc
->speed
, &comp_supported
,
945 &comp_enabled
, &softc
->comp_algorithm
, NULL
);
949 softc
->flags
|= SA_FLAG_TAPE_WP
;
951 softc
->flags
&= ~SA_FLAG_TAPE_WP
;
952 softc
->flags
&= ~(SA_FLAG_COMP_SUPP
|
953 SA_FLAG_COMP_ENABLED
|SA_FLAG_COMP_UNSUPP
);
954 if (comp_supported
) {
955 if (softc
->saved_comp_algorithm
== 0)
956 softc
->saved_comp_algorithm
=
957 softc
->comp_algorithm
;
958 softc
->flags
|= SA_FLAG_COMP_SUPP
;
960 softc
->flags
|= SA_FLAG_COMP_ENABLED
;
962 softc
->flags
|= SA_FLAG_COMP_UNSUPP
;
964 bzero(g
, sizeof(struct mtget
));
965 g
->mt_type
= MT_ISAR
;
966 if (softc
->flags
& SA_FLAG_COMP_UNSUPP
) {
967 g
->mt_comp
= MT_COMP_UNSUPP
;
968 g
->mt_comp0
= MT_COMP_UNSUPP
;
969 g
->mt_comp1
= MT_COMP_UNSUPP
;
970 g
->mt_comp2
= MT_COMP_UNSUPP
;
971 g
->mt_comp3
= MT_COMP_UNSUPP
;
973 if ((softc
->flags
& SA_FLAG_COMP_ENABLED
) == 0) {
974 g
->mt_comp
= MT_COMP_DISABLED
;
976 g
->mt_comp
= softc
->comp_algorithm
;
978 g
->mt_comp0
= softc
->comp_algorithm
;
979 g
->mt_comp1
= softc
->comp_algorithm
;
980 g
->mt_comp2
= softc
->comp_algorithm
;
981 g
->mt_comp3
= softc
->comp_algorithm
;
983 g
->mt_density
= softc
->media_density
;
984 g
->mt_density0
= softc
->media_density
;
985 g
->mt_density1
= softc
->media_density
;
986 g
->mt_density2
= softc
->media_density
;
987 g
->mt_density3
= softc
->media_density
;
988 g
->mt_blksiz
= softc
->media_blksize
;
989 g
->mt_blksiz0
= softc
->media_blksize
;
990 g
->mt_blksiz1
= softc
->media_blksize
;
991 g
->mt_blksiz2
= softc
->media_blksize
;
992 g
->mt_blksiz3
= softc
->media_blksize
;
993 g
->mt_fileno
= softc
->fileno
;
994 g
->mt_blkno
= softc
->blkno
;
995 g
->mt_dsreg
= (short) softc
->dsreg
;
997 * Yes, we know that this is likely to overflow
999 if (softc
->last_resid_was_io
) {
1000 if ((g
->mt_resid
= (short) softc
->last_io_resid
) != 0) {
1001 if (SA_IS_CTRL(dev
) == 0 || didholdperiph
) {
1002 softc
->last_io_resid
= 0;
1006 if ((g
->mt_resid
= (short)softc
->last_ctl_resid
) != 0) {
1007 if (SA_IS_CTRL(dev
) == 0 || didholdperiph
) {
1008 softc
->last_ctl_resid
= 0;
1017 struct scsi_tape_errors
*sep
=
1018 &((union mterrstat
*)addr
)->scsi_errstat
;
1020 CAM_DEBUG(periph
->path
, CAM_DEBUG_TRACE
,
1021 ("saioctl: MTIOCERRSTAT\n"));
1023 bzero(sep
, sizeof(*sep
));
1024 sep
->io_resid
= softc
->last_io_resid
;
1025 bcopy((caddr_t
) &softc
->last_io_sense
, sep
->io_sense
,
1026 sizeof (sep
->io_sense
));
1027 bcopy((caddr_t
) &softc
->last_io_cdb
, sep
->io_cdb
,
1028 sizeof (sep
->io_cdb
));
1029 sep
->ctl_resid
= softc
->last_ctl_resid
;
1030 bcopy((caddr_t
) &softc
->last_ctl_sense
, sep
->ctl_sense
,
1031 sizeof (sep
->ctl_sense
));
1032 bcopy((caddr_t
) &softc
->last_ctl_cdb
, sep
->ctl_cdb
,
1033 sizeof (sep
->ctl_cdb
));
1035 if ((SA_IS_CTRL(dev
) == 0 && softc
->open_pending_mount
) ||
1037 bzero((caddr_t
) &softc
->errinfo
,
1038 sizeof (softc
->errinfo
));
1047 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1049 mt
= (struct mtop
*)addr
;
1051 CAM_DEBUG(periph
->path
, CAM_DEBUG_TRACE
,
1052 ("saioctl: op=0x%x count=0x%x\n",
1053 mt
->mt_op
, mt
->mt_count
));
1055 count
= mt
->mt_count
;
1056 switch (mt
->mt_op
) {
1057 case MTWEOF
: /* write an end-of-file marker */
1059 * We don't need to clear the SA_FLAG_TAPE_WRITTEN
1060 * flag because by keeping track of filemarks
1061 * we have last written we know ehether or not
1062 * we need to write more when we close the device.
1064 error
= sawritefilemarks(periph
, count
, FALSE
);
1066 case MTWSS
: /* write a setmark */
1067 error
= sawritefilemarks(periph
, count
, TRUE
);
1069 case MTBSR
: /* backward space record */
1070 case MTFSR
: /* forward space record */
1071 case MTBSF
: /* backward space file */
1072 case MTFSF
: /* forward space file */
1073 case MTBSS
: /* backward space setmark */
1074 case MTFSS
: /* forward space setmark */
1075 case MTEOD
: /* space to end of recorded medium */
1079 spaceop
= SS_FILEMARKS
;
1080 nmarks
= softc
->filemarks
;
1081 error
= sacheckeod(periph
);
1083 xpt_print(periph
->path
,
1084 "EOD check prior to spacing failed\n");
1085 softc
->flags
|= SA_FLAG_EIO_PENDING
;
1088 nmarks
-= softc
->filemarks
;
1094 spaceop
= SS_BLOCKS
;
1105 spaceop
= SS_SETMARKS
;
1119 nmarks
= softc
->filemarks
;
1121 * XXX: Why are we checking again?
1123 error
= sacheckeod(periph
);
1126 nmarks
-= softc
->filemarks
;
1127 error
= saspace(periph
, count
- nmarks
, spaceop
);
1129 * At this point, clear that we've written the tape
1130 * and that we've written any filemarks. We really
1131 * don't know what the applications wishes to do next-
1132 * the sacheckeod's will make sure we terminated the
1133 * tape correctly if we'd been writing, but the next
1134 * action the user application takes will set again
1135 * whether we need to write filemarks.
1138 ~(SA_FLAG_TAPE_WRITTEN
|SA_FLAG_TAPE_FROZEN
);
1139 softc
->filemarks
= 0;
1142 case MTREW
: /* rewind */
1143 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1145 error
= sarewind(periph
);
1148 ~(SA_FLAG_TAPE_WRITTEN
|SA_FLAG_TAPE_FROZEN
);
1149 softc
->flags
&= ~SA_FLAG_ERR_PENDING
;
1150 softc
->filemarks
= 0;
1152 case MTERASE
: /* erase */
1153 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1154 error
= saerase(periph
, count
);
1156 ~(SA_FLAG_TAPE_WRITTEN
|SA_FLAG_TAPE_FROZEN
);
1157 softc
->flags
&= ~SA_FLAG_ERR_PENDING
;
1159 case MTRETENS
: /* re-tension tape */
1160 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1161 error
= saretension(periph
);
1163 ~(SA_FLAG_TAPE_WRITTEN
|SA_FLAG_TAPE_FROZEN
);
1164 softc
->flags
&= ~SA_FLAG_ERR_PENDING
;
1166 case MTOFFL
: /* rewind and put the drive offline */
1168 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1172 softc
->flags
&= ~SA_FLAG_TAPE_WRITTEN
;
1173 softc
->filemarks
= 0;
1175 error
= sarewind(periph
);
1176 /* clear the frozen flag anyway */
1177 softc
->flags
&= ~SA_FLAG_TAPE_FROZEN
;
1180 * Be sure to allow media removal before ejecting.
1183 saprevent(periph
, PR_ALLOW
);
1185 error
= saloadunload(periph
, FALSE
);
1187 softc
->flags
&= ~SA_FLAG_TAPE_MOUNTED
;
1192 case MTNOP
: /* no operation, sets status only */
1193 case MTCACHE
: /* enable controller cache */
1194 case MTNOCACHE
: /* disable controller cache */
1198 case MTSETBSIZ
: /* Set block size for device */
1200 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1202 error
= sasetparams(periph
, SA_PARAM_BLOCKSIZE
, count
,
1205 softc
->last_media_blksize
=
1206 softc
->media_blksize
;
1207 softc
->media_blksize
= count
;
1209 softc
->flags
|= SA_FLAG_FIXED
;
1210 if (powerof2(count
)) {
1213 softc
->blk_mask
= count
- 1;
1215 softc
->blk_mask
= ~0;
1216 softc
->blk_shift
= 0;
1219 * Make the user's desire 'persistent'.
1221 softc
->quirks
&= ~SA_QUIRK_VARIABLE
;
1222 softc
->quirks
|= SA_QUIRK_FIXED
;
1224 softc
->flags
&= ~SA_FLAG_FIXED
;
1225 if (softc
->max_blk
== 0) {
1226 softc
->max_blk
= ~0;
1228 softc
->blk_shift
= 0;
1229 if (softc
->blk_gran
!= 0) {
1231 softc
->blk_gran
- 1;
1233 softc
->blk_mask
= 0;
1236 * Make the user's desire 'persistent'.
1238 softc
->quirks
|= SA_QUIRK_VARIABLE
;
1239 softc
->quirks
&= ~SA_QUIRK_FIXED
;
1243 case MTSETDNSTY
: /* Set density for device and mode */
1244 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1246 if (count
> UCHAR_MAX
) {
1250 error
= sasetparams(periph
, SA_PARAM_DENSITY
,
1254 case MTCOMP
: /* enable compression */
1255 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1257 * Some devices don't support compression, and
1258 * don't like it if you ask them for the
1261 if ((softc
->quirks
& SA_QUIRK_NOCOMP
) ||
1262 (softc
->flags
& SA_FLAG_COMP_UNSUPP
)) {
1266 error
= sasetparams(periph
, SA_PARAM_COMPRESSION
,
1267 0, 0, count
, SF_NO_PRINT
);
1279 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1280 error
= sardpos(periph
, 0, (u_int32_t
*) addr
);
1283 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1284 error
= sardpos(periph
, 1, (u_int32_t
*) addr
);
1287 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1288 error
= sasetpos(periph
, 0, (u_int32_t
*) addr
);
1291 PENDING_MOUNT_CHECK(softc
, periph
, dev
);
1292 error
= sasetpos(periph
, 1, (u_int32_t
*) addr
);
1294 case MTIOCGETEOTMODEL
:
1296 if (softc
->quirks
& SA_QUIRK_1FM
)
1300 *((u_int32_t
*) addr
) = mode
;
1302 case MTIOCSETEOTMODEL
:
1304 switch (*((u_int32_t
*) addr
)) {
1306 softc
->quirks
&= ~SA_QUIRK_2FM
;
1307 softc
->quirks
|= SA_QUIRK_1FM
;
1310 softc
->quirks
&= ~SA_QUIRK_1FM
;
1311 softc
->quirks
|= SA_QUIRK_2FM
;
1319 error
= cam_periph_ioctl(periph
, ap
->a_cmd
, addr
, saerror
);
1324 * Check to see if we cleared a frozen state
1326 if (error
== 0 && (softc
->flags
& SA_FLAG_TAPE_FROZEN
)) {
1332 softc
->fileno
= (daddr_t
) -1;
1333 softc
->blkno
= (daddr_t
) -1;
1334 softc
->flags
&= ~SA_FLAG_TAPE_FROZEN
;
1335 xpt_print(periph
->path
,
1336 "tape state now unfrozen.\n");
1343 cam_periph_unhold(periph
, 1);
1345 cam_periph_unlock(periph
);
1355 * Create our extend array for storing the devices we attach to.
1357 saperiphs
= cam_extend_new();
1358 if (saperiphs
== NULL
) {
1359 kprintf("sa: Failed to alloc extend array!\n");
1364 * Install a global async callback.
1366 status
= xpt_register_async(AC_FOUND_DEVICE
, saasync
, NULL
, NULL
);
1368 if (status
!= CAM_REQ_CMP
) {
1369 kprintf("sa: Failed to attach master async callback "
1370 "due to status 0x%x!\n", status
);
1375 saoninvalidate(struct cam_periph
*periph
)
1377 struct sa_softc
*softc
;
1381 softc
= (struct sa_softc
*)periph
->softc
;
1384 * De-register any async callbacks.
1386 xpt_register_async(0, saasync
, periph
, periph
->path
);
1388 softc
->flags
|= SA_FLAG_INVALID
;
1391 * Return all queued I/O with ENXIO.
1392 * XXX Handle any transactions queued to the card
1393 * with XPT_ABORT_CCB.
1395 while ((q_bio
= bioq_takefirst(&softc
->bio_queue
)) != NULL
) {
1396 q_bp
= q_bio
->bio_buf
;
1397 q_bp
->b_resid
= q_bp
->b_bcount
;
1398 q_bp
->b_error
= ENXIO
;
1399 q_bp
->b_flags
|= B_ERROR
;
1402 softc
->queue_count
= 0;
1404 xpt_print(periph
->path
, "lost device\n");
1409 sacleanup(struct cam_periph
*periph
)
1411 struct sa_softc
*softc
;
1413 softc
= (struct sa_softc
*)periph
->softc
;
1415 devstat_remove_entry(&softc
->device_stats
);
1417 cam_extend_release(saperiphs
, periph
->unit_number
);
1418 xpt_print(periph
->path
, "removing device entry\n");
1419 dev_ops_remove_minor(&sa_ops
, /*SA_UNITMASK,*/ SA_UNIT(periph
->unit_number
));
1420 kfree(softc
, M_SCSISA
);
1424 saasync(void *callback_arg
, u_int32_t code
,
1425 struct cam_path
*path
, void *arg
)
1427 struct cam_periph
*periph
;
1429 periph
= (struct cam_periph
*)callback_arg
;
1431 case AC_FOUND_DEVICE
:
1433 struct ccb_getdev
*cgd
;
1436 cgd
= (struct ccb_getdev
*)arg
;
1440 if (SID_TYPE(&cgd
->inq_data
) != T_SEQUENTIAL
)
1444 * Allocate a peripheral instance for
1445 * this device and start the probe
1448 status
= cam_periph_alloc(saregister
, saoninvalidate
,
1450 "sa", CAM_PERIPH_BIO
, cgd
->ccb_h
.path
,
1451 saasync
, AC_FOUND_DEVICE
, cgd
);
1453 if (status
!= CAM_REQ_CMP
1454 && status
!= CAM_REQ_INPROG
)
1455 kprintf("saasync: Unable to probe new device "
1456 "due to status 0x%x\n", status
);
1460 cam_periph_async(periph
, code
, path
, arg
);
1466 saregister(struct cam_periph
*periph
, void *arg
)
1468 struct sa_softc
*softc
;
1469 struct ccb_getdev
*cgd
;
1473 cgd
= (struct ccb_getdev
*)arg
;
1474 if (periph
== NULL
) {
1475 kprintf("saregister: periph was NULL!!\n");
1476 return (CAM_REQ_CMP_ERR
);
1480 kprintf("saregister: no getdev CCB, can't register device\n");
1481 return (CAM_REQ_CMP_ERR
);
1484 softc
= kmalloc(sizeof (*softc
), M_SCSISA
, M_INTWAIT
| M_ZERO
);
1485 softc
->scsi_rev
= SID_ANSI_REV(&cgd
->inq_data
);
1486 softc
->state
= SA_STATE_NORMAL
;
1487 softc
->fileno
= (daddr_t
) -1;
1488 softc
->blkno
= (daddr_t
) -1;
1490 bioq_init(&softc
->bio_queue
);
1491 periph
->softc
= softc
;
1492 cam_extend_set(saperiphs
, periph
->unit_number
, periph
);
1495 * See if this device has any quirks.
1497 match
= cam_quirkmatch((caddr_t
)&cgd
->inq_data
,
1498 (caddr_t
)sa_quirk_table
,
1499 NELEM(sa_quirk_table
),
1500 sizeof(*sa_quirk_table
), scsi_inquiry_match
);
1502 if (match
!= NULL
) {
1503 softc
->quirks
= ((struct sa_quirk_entry
*)match
)->quirks
;
1504 softc
->last_media_blksize
=
1505 ((struct sa_quirk_entry
*)match
)->prefblk
;
1507 xpt_print(periph
->path
, "found quirk entry %d\n",
1508 (int) (((struct sa_quirk_entry
*) match
) - sa_quirk_table
));
1511 softc
->quirks
= SA_QUIRK_NONE
;
1514 * The SA driver supports a blocksize, but we don't know the
1515 * blocksize until we media is inserted. So, set a flag to
1516 * indicate that the blocksize is unavailable right now.
1518 cam_periph_unlock(periph
);
1519 devstat_add_entry(&softc
->device_stats
, "sa", periph
->unit_number
, 0,
1520 DEVSTAT_BS_UNAVAILABLE
, SID_TYPE(&cgd
->inq_data
) |
1521 DEVSTAT_TYPE_IF_SCSI
, DEVSTAT_PRIORITY_TAPE
);
1523 make_dev(&sa_ops
, SAMINOR(SA_CTLDEV
,
1524 periph
->unit_number
, 0, SA_ATYPE_R
), UID_ROOT
, GID_OPERATOR
,
1525 0660, "%s%d.ctl", periph
->periph_name
, periph
->unit_number
);
1527 make_dev(&sa_ops
, SAMINOR(SA_NOT_CTLDEV
,
1528 periph
->unit_number
, 0, SA_ATYPE_R
), UID_ROOT
, GID_OPERATOR
,
1529 0660, "%s%d", periph
->periph_name
, periph
->unit_number
);
1531 make_dev(&sa_ops
, SAMINOR(SA_NOT_CTLDEV
,
1532 periph
->unit_number
, 0, SA_ATYPE_NR
), UID_ROOT
, GID_OPERATOR
,
1533 0660, "n%s%d", periph
->periph_name
, periph
->unit_number
);
1535 make_dev(&sa_ops
, SAMINOR(SA_NOT_CTLDEV
,
1536 periph
->unit_number
, 0, SA_ATYPE_ER
), UID_ROOT
, GID_OPERATOR
,
1537 0660, "e%s%d", periph
->periph_name
, periph
->unit_number
);
1539 for (i
= 0; i
< SA_NUM_MODES
; i
++) {
1542 SAMINOR(SA_NOT_CTLDEV
, periph
->unit_number
, i
, SA_ATYPE_R
),
1543 UID_ROOT
, GID_OPERATOR
, 0660, "%s%d.%d",
1544 periph
->periph_name
, periph
->unit_number
, i
);
1547 SAMINOR(SA_NOT_CTLDEV
, periph
->unit_number
, i
, SA_ATYPE_NR
),
1548 UID_ROOT
, GID_OPERATOR
, 0660, "n%s%d.%d",
1549 periph
->periph_name
, periph
->unit_number
, i
);
1553 SAMINOR(SA_NOT_CTLDEV
, periph
->unit_number
, i
, SA_ATYPE_ER
),
1554 UID_ROOT
, GID_OPERATOR
, 0660, "e%s%d.%d",
1555 periph
->periph_name
, periph
->unit_number
, i
);
1557 cam_periph_lock(periph
);
1560 * Add an async callback so that we get
1561 * notified if this device goes away.
1563 xpt_register_async(AC_LOST_DEVICE
, saasync
, periph
, periph
->path
);
1565 xpt_announce_periph(periph
, NULL
);
1567 return (CAM_REQ_CMP
);
1571 sastart(struct cam_periph
*periph
, union ccb
*start_ccb
)
1573 struct sa_softc
*softc
;
1575 softc
= (struct sa_softc
*)periph
->softc
;
1577 CAM_DEBUG(periph
->path
, CAM_DEBUG_TRACE
, ("sastart\n"));
1580 switch (softc
->state
) {
1581 case SA_STATE_NORMAL
:
1583 /* Pull a buffer from the queue and get going on it */
1588 * See if there is a buf with work for us to do..
1590 bio
= bioq_first(&softc
->bio_queue
);
1591 if (periph
->immediate_priority
<= periph
->pinfo
.priority
) {
1592 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE
,
1593 ("queuing for immediate ccb\n"));
1594 Set_CCB_Type(start_ccb
, SA_CCB_WAITING
);
1595 SLIST_INSERT_HEAD(&periph
->ccb_list
, &start_ccb
->ccb_h
,
1597 periph
->immediate_priority
= CAM_PRIORITY_NONE
;
1598 wakeup(&periph
->ccb_list
);
1599 } else if (bio
== NULL
) {
1600 xpt_release_ccb(start_ccb
);
1601 } else if ((softc
->flags
& SA_FLAG_ERR_PENDING
) != 0) {
1602 struct bio
*done_bio
;
1604 softc
->queue_count
--;
1605 bioq_remove(&softc
->bio_queue
, bio
);
1607 bp
->b_resid
= bp
->b_bcount
;
1609 if ((softc
->flags
& SA_FLAG_EOM_PENDING
) != 0) {
1611 * We now just clear errors in this case
1612 * and let the residual be the notifier.
1615 } else if ((softc
->flags
& SA_FLAG_EOF_PENDING
) != 0) {
1617 * This can only happen if we're reading
1618 * in fixed length mode. In this case,
1619 * we dump the rest of the list the
1623 if (bioq_first(&softc
->bio_queue
) != NULL
) {
1627 } else if ((softc
->flags
& SA_FLAG_EIO_PENDING
) != 0) {
1629 bp
->b_flags
|= B_ERROR
;
1631 bio
= bioq_first(&softc
->bio_queue
);
1633 * Only if we have no other buffers queued up
1634 * do we clear the pending error flag.
1637 softc
->flags
&= ~SA_FLAG_ERR_PENDING
;
1638 CAM_DEBUG(periph
->path
, CAM_DEBUG_INFO
,
1639 ("sastart- ERR_PENDING now 0x%x, bio is %sNULL, "
1640 "%d more buffers queued up\n",
1641 (softc
->flags
& SA_FLAG_ERR_PENDING
),
1642 (bio
!= NULL
)? "not " : " ", softc
->queue_count
));
1643 xpt_release_ccb(start_ccb
);
1648 bioq_remove(&softc
->bio_queue
, bio
);
1650 softc
->queue_count
--;
1652 if ((softc
->flags
& SA_FLAG_FIXED
) != 0) {
1653 if (softc
->blk_shift
!= 0) {
1655 bp
->b_bcount
>> softc
->blk_shift
;
1656 } else if (softc
->media_blksize
!= 0) {
1658 bp
->b_bcount
/ softc
->media_blksize
;
1661 xpt_print(periph
->path
, "zero blocksize"
1662 " for FIXED length writes?\n");
1667 CAM_DEBUG(start_ccb
->ccb_h
.path
, CAM_DEBUG_INFO
,
1668 ("issuing a %d fixed record %s\n",
1669 length
, (bp
->bio_cmd
== BIO_READ
)? "read" :
1673 length
= bp
->b_bcount
;
1675 CAM_DEBUG(start_ccb
->ccb_h
.path
, CAM_DEBUG_INFO
,
1676 ("issuing a %d variable byte %s\n",
1677 length
, (bp
->bio_cmd
== BIO_READ
)? "read" :
1681 devstat_start_transaction(&softc
->device_stats
);
1683 * Some people have theorized that we should
1684 * suppress illegal length indication if we are
1685 * running in variable block mode so that we don't
1686 * have to request sense every time our requested
1687 * block size is larger than the written block.
1688 * The residual information from the ccb allows
1689 * us to identify this situation anyway. The only
1690 * problem with this is that we will not get
1691 * information about blocks that are larger than
1692 * our read buffer unless we set the block size
1693 * in the mode page to something other than 0.
1695 * I believe that this is a non-issue. If user apps
1696 * don't adjust their read size to match our record
1697 * size, that's just life. Anyway, the typical usage
1698 * would be to issue, e.g., 64KB reads and occasionally
1699 * have to do deal with 512 byte or 1KB intermediate
1702 softc
->dsreg
= (bp
->b_cmd
== BUF_CMD_READ
) ?
1703 MTIO_DSREG_RD
: MTIO_DSREG_WR
;
1704 scsi_sa_read_write(&start_ccb
->csio
, 0, sadone
,
1705 MSG_SIMPLE_Q_TAG
, (bp
->b_cmd
== BUF_CMD_READ
) != 0,
1706 FALSE
, (softc
->flags
& SA_FLAG_FIXED
) != 0,
1707 length
, bp
->b_data
, bp
->b_bcount
, SSD_FULL_SIZE
,
1709 start_ccb
->ccb_h
.ccb_pflags
&= ~SA_POSITION_UPDATED
;
1710 Set_CCB_Type(start_ccb
, SA_CCB_BUFFER_IO
);
1711 start_ccb
->ccb_h
.ccb_bio
= bio
;
1712 bio
= bioq_first(&softc
->bio_queue
);
1713 xpt_action(start_ccb
);
1717 /* Have more work to do, so ensure we stay scheduled */
1718 xpt_schedule(periph
, 1);
1722 case SA_STATE_ABNORMAL
:
1724 panic("state 0x%x in sastart", softc
->state
);
1731 sadone(struct cam_periph
*periph
, union ccb
*done_ccb
)
1733 struct sa_softc
*softc
;
1734 struct ccb_scsiio
*csio
;
1736 softc
= (struct sa_softc
*)periph
->softc
;
1737 csio
= &done_ccb
->csio
;
1739 switch (CCB_Type(csio
)) {
1740 case SA_CCB_BUFFER_IO
:
1746 softc
->dsreg
= MTIO_DSREG_REST
;
1747 bio
= (struct bio
*)done_ccb
->ccb_h
.ccb_bio
;
1750 if ((done_ccb
->ccb_h
.status
& CAM_STATUS_MASK
) != CAM_REQ_CMP
) {
1751 if ((error
= saerror(done_ccb
, 0, 0)) == ERESTART
) {
1753 * A retry was scheduled, so just return.
1764 * Catastrophic error. Mark the tape as frozen
1765 * (we no longer know tape position).
1767 * Return all queued I/O with EIO, and unfreeze
1768 * our queue so that future transactions that
1769 * attempt to fix this problem can get to the
1774 softc
->flags
|= SA_FLAG_TAPE_FROZEN
;
1775 while ((q_bio
= bioq_takefirst(&softc
->bio_queue
)) != NULL
) {
1776 q_bp
= q_bio
->bio_buf
;
1777 q_bp
->b_resid
= q_bp
->b_bcount
;
1778 q_bp
->b_error
= EIO
;
1779 q_bp
->b_flags
|= B_ERROR
;
1784 bp
->b_resid
= bp
->b_bcount
;
1785 bp
->b_error
= error
;
1786 bp
->b_flags
|= B_ERROR
;
1788 * In the error case, position is updated in saerror.
1791 bp
->b_resid
= csio
->resid
;
1793 if (csio
->resid
!= 0) {
1794 bp
->b_flags
|= B_ERROR
;
1796 if (bp
->b_cmd
!= BUF_CMD_READ
) {
1797 softc
->flags
|= SA_FLAG_TAPE_WRITTEN
;
1798 softc
->filemarks
= 0;
1800 if (!(csio
->ccb_h
.ccb_pflags
& SA_POSITION_UPDATED
) &&
1801 (softc
->blkno
!= (daddr_t
) -1)) {
1802 if ((softc
->flags
& SA_FLAG_FIXED
) != 0) {
1804 if (softc
->blk_shift
!= 0) {
1809 softc
->media_blksize
;
1811 softc
->blkno
+= (daddr_t
) l
;
1818 * If we had an error (immediate or pending),
1819 * release the device queue now.
1821 if (error
|| (softc
->flags
& SA_FLAG_ERR_PENDING
))
1822 cam_release_devq(done_ccb
->ccb_h
.path
, 0, 0, 0, 0);
1824 if (error
|| bp
->b_resid
) {
1825 CAM_DEBUG(periph
->path
, CAM_DEBUG_INFO
,
1826 ("error %d resid %d count %d\n", error
,
1827 bp
->b_resid
, bp
->b_bcount
));
1830 devstat_end_transaction_buf(&softc
->device_stats
, bp
);
1834 case SA_CCB_WAITING
:
1836 /* Caller will release the CCB */
1837 wakeup(&done_ccb
->ccb_h
.cbfcnp
);
1841 /* polled, caller releases ccb */
1842 wakeup(&done_ccb
->ccb_h
.cbfcnp
);
1845 xpt_release_ccb(done_ccb
);
1849 * Mount the tape (make sure it's ready for I/O).
1851 * oflags can be checked for 'kind' of open (read-only check) - later
1852 * dev can be checked for a control-mode or compression open - later
1855 samount(struct cam_periph
*periph
, __unused
int oflags
, __unused cdev_t dev
)
1857 struct sa_softc
*softc
;
1861 softc
= (struct sa_softc
*)periph
->softc
;
1864 * This should determine if something has happend since the last
1865 * open/mount that would invalidate the mount. We do *not* want
1866 * to retry this command- we just want the status. But we only
1867 * do this if we're mounted already- if we're not mounted,
1868 * we don't care about the unit read state and can instead use
1869 * this opportunity to attempt to reserve the tape unit.
1872 if (softc
->flags
& SA_FLAG_TAPE_MOUNTED
) {
1873 ccb
= cam_periph_getccb(periph
, 1);
1874 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
1876 scsi_test_unit_ready(&ccb
->csio
, 0, sadone
,
1877 MSG_SIMPLE_Q_TAG
, SSD_FULL_SIZE
,
1879 error
= cam_periph_runccb(ccb
, saerror
, 0, SF_NO_PRINT
,
1880 &softc
->device_stats
);
1882 if (error
== ENXIO
) {
1883 softc
->flags
&= ~SA_FLAG_TAPE_MOUNTED
;
1884 scsi_test_unit_ready(&ccb
->csio
, 0, sadone
,
1885 MSG_SIMPLE_Q_TAG
, SSD_FULL_SIZE
, IO_TIMEOUT
);
1886 error
= cam_periph_runccb(ccb
, saerror
, 0, SF_NO_PRINT
,
1887 &softc
->device_stats
);
1891 * We don't need to freeze the tape because we
1892 * will now attempt to rewind/load it.
1894 softc
->flags
&= ~SA_FLAG_TAPE_MOUNTED
;
1895 if (CAM_DEBUGGED(periph
->path
, CAM_DEBUG_INFO
)) {
1896 xpt_print(periph
->path
,
1897 "error %d on TUR in samount\n", error
);
1901 error
= sareservereleaseunit(periph
, TRUE
);
1905 ccb
= cam_periph_getccb(periph
, 1);
1906 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
1907 scsi_test_unit_ready(&ccb
->csio
, 0, sadone
,
1908 MSG_SIMPLE_Q_TAG
, SSD_FULL_SIZE
,
1910 error
= cam_periph_runccb(ccb
, saerror
, 0, SF_NO_PRINT
,
1911 &softc
->device_stats
);
1915 if ((softc
->flags
& SA_FLAG_TAPE_MOUNTED
) == 0) {
1916 struct scsi_read_block_limits_data
*rblim
= NULL
;
1917 int comp_enabled
= 0; /* silence gcc */
1918 int comp_supported
= 0; /* silence gcc */
1919 u_int8_t write_protect
= 0; /* silence gcc */
1920 u_int8_t guessing
= 0;
1923 * Clear out old state.
1925 softc
->flags
&= ~(SA_FLAG_TAPE_WP
|SA_FLAG_TAPE_WRITTEN
|
1926 SA_FLAG_ERR_PENDING
|SA_FLAG_COMP_ENABLED
|
1927 SA_FLAG_COMP_SUPP
|SA_FLAG_COMP_UNSUPP
);
1928 softc
->filemarks
= 0;
1931 * *Very* first off, make sure we're loaded to BOT.
1933 scsi_load_unload(&ccb
->csio
, 2, sadone
, MSG_SIMPLE_Q_TAG
, FALSE
,
1934 FALSE
, FALSE
, 1, SSD_FULL_SIZE
, REWIND_TIMEOUT
);
1935 error
= cam_periph_runccb(ccb
, saerror
, 0, SF_NO_PRINT
,
1936 &softc
->device_stats
);
1940 * In case this doesn't work, do a REWIND instead
1943 scsi_rewind(&ccb
->csio
, 2, sadone
, MSG_SIMPLE_Q_TAG
,
1944 FALSE
, SSD_FULL_SIZE
, REWIND_TIMEOUT
);
1945 error
= cam_periph_runccb(ccb
, saerror
, 0, SF_NO_PRINT
,
1946 &softc
->device_stats
);
1950 xpt_release_ccb(ccb
);
1955 * Do a dummy test read to force access to the
1956 * media so that the drive will really know what's
1957 * there. We actually don't really care what the
1958 * blocksize on tape is and don't expect to really
1959 * read a full record.
1961 rblim
= kmalloc(8192, M_SCSISA
, M_INTWAIT
);
1963 if ((softc
->quirks
& SA_QUIRK_NODREAD
) == 0) {
1964 scsi_sa_read_write(&ccb
->csio
, 0, sadone
,
1965 MSG_SIMPLE_Q_TAG
, 1, FALSE
, 0, 8192,
1966 (void *) rblim
, 8192, SSD_FULL_SIZE
,
1968 cam_periph_runccb(ccb
, saerror
, 0, SF_NO_PRINT
,
1969 &softc
->device_stats
);
1971 scsi_rewind(&ccb
->csio
, 1, sadone
, MSG_SIMPLE_Q_TAG
,
1972 FALSE
, SSD_FULL_SIZE
, REWIND_TIMEOUT
);
1973 error
= cam_periph_runccb(ccb
, saerror
, CAM_RETRY_SELTO
,
1974 SF_NO_PRINT
| SF_RETRY_UA
,
1975 &softc
->device_stats
);
1978 xpt_print(periph
->path
,
1979 "unable to rewind after test read\n");
1980 xpt_release_ccb(ccb
);
1986 * Next off, determine block limits.
1988 scsi_read_block_limits(&ccb
->csio
, 5, sadone
, MSG_SIMPLE_Q_TAG
,
1989 rblim
, SSD_FULL_SIZE
, SCSIOP_TIMEOUT
);
1991 error
= cam_periph_runccb(ccb
, saerror
, CAM_RETRY_SELTO
,
1992 SF_NO_PRINT
| SF_RETRY_UA
, &softc
->device_stats
);
1995 xpt_release_ccb(ccb
);
1999 * If it's less than SCSI-2, READ BLOCK LIMITS is not
2000 * a MANDATORY command. Anyway- it doesn't matter-
2001 * we can proceed anyway.
2003 softc
->blk_gran
= 0;
2004 softc
->max_blk
= ~0;
2007 if (softc
->scsi_rev
>= SCSI_REV_SPC
) {
2008 softc
->blk_gran
= RBL_GRAN(rblim
);
2010 softc
->blk_gran
= 0;
2013 * We take max_blk == min_blk to mean a default to
2014 * fixed mode- but note that whatever we get out of
2015 * sagetparams below will actually determine whether
2016 * we are actually *in* fixed mode.
2018 softc
->max_blk
= scsi_3btoul(rblim
->maximum
);
2019 softc
->min_blk
= scsi_2btoul(rblim
->minimum
);
2024 * Next, perform a mode sense to determine
2025 * current density, blocksize, compression etc.
2027 error
= sagetparams(periph
, SA_PARAM_ALL
,
2028 &softc
->media_blksize
,
2029 &softc
->media_density
,
2030 &softc
->media_numblks
,
2031 &softc
->buffer_mode
, &write_protect
,
2032 &softc
->speed
, &comp_supported
,
2033 &comp_enabled
, &softc
->comp_algorithm
,
2038 * We could work a little harder here. We could
2039 * adjust our attempts to get information. It
2040 * might be an ancient tape drive. If someone
2041 * nudges us, we'll do that.
2047 * If no quirk has determined that this is a device that is
2048 * preferred to be in fixed or variable mode, now is the time
2051 if ((softc
->quirks
& (SA_QUIRK_FIXED
|SA_QUIRK_VARIABLE
)) == 0) {
2054 * This could be expensive to find out. Luckily we
2055 * only need to do this once. If we start out in
2056 * 'default' mode, try and set ourselves to one
2057 * of the densities that would determine a wad
2058 * of other stuff. Go from highest to lowest.
2060 if (softc
->media_density
== SCSI_DEFAULT_DENSITY
) {
2062 static u_int8_t ctry
[] = {
2063 SCSI_DENSITY_HALFINCH_PE
,
2064 SCSI_DENSITY_HALFINCH_6250C
,
2065 SCSI_DENSITY_HALFINCH_6250
,
2066 SCSI_DENSITY_HALFINCH_1600
,
2067 SCSI_DENSITY_HALFINCH_800
,
2068 SCSI_DENSITY_QIC_4GB
,
2069 SCSI_DENSITY_QIC_2GB
,
2070 SCSI_DENSITY_QIC_525_320
,
2071 SCSI_DENSITY_QIC_150
,
2072 SCSI_DENSITY_QIC_120
,
2073 SCSI_DENSITY_QIC_24
,
2074 SCSI_DENSITY_QIC_11_9TRK
,
2075 SCSI_DENSITY_QIC_11_4TRK
,
2076 SCSI_DENSITY_QIC_1320
,
2077 SCSI_DENSITY_QIC_3080
,
2080 for (i
= 0; ctry
[i
]; i
++) {
2081 error
= sasetparams(periph
,
2082 SA_PARAM_DENSITY
, 0, ctry
[i
],
2085 softc
->media_density
= ctry
[i
];
2090 switch (softc
->media_density
) {
2091 case SCSI_DENSITY_QIC_11_4TRK
:
2092 case SCSI_DENSITY_QIC_11_9TRK
:
2093 case SCSI_DENSITY_QIC_24
:
2094 case SCSI_DENSITY_QIC_120
:
2095 case SCSI_DENSITY_QIC_150
:
2096 case SCSI_DENSITY_QIC_525_320
:
2097 case SCSI_DENSITY_QIC_1320
:
2098 case SCSI_DENSITY_QIC_3080
:
2099 softc
->quirks
&= ~SA_QUIRK_2FM
;
2100 softc
->quirks
|= SA_QUIRK_FIXED
|SA_QUIRK_1FM
;
2101 softc
->last_media_blksize
= 512;
2103 case SCSI_DENSITY_QIC_4GB
:
2104 case SCSI_DENSITY_QIC_2GB
:
2105 softc
->quirks
&= ~SA_QUIRK_2FM
;
2106 softc
->quirks
|= SA_QUIRK_FIXED
|SA_QUIRK_1FM
;
2107 softc
->last_media_blksize
= 1024;
2110 softc
->last_media_blksize
=
2111 softc
->media_blksize
;
2112 softc
->quirks
|= SA_QUIRK_VARIABLE
;
2118 * If no quirk has determined that this is a device that needs
2119 * to have 2 Filemarks at EOD, now is the time to find out.
2122 if ((softc
->quirks
& SA_QUIRK_2FM
) == 0) {
2123 switch (softc
->media_density
) {
2124 case SCSI_DENSITY_HALFINCH_800
:
2125 case SCSI_DENSITY_HALFINCH_1600
:
2126 case SCSI_DENSITY_HALFINCH_6250
:
2127 case SCSI_DENSITY_HALFINCH_6250C
:
2128 case SCSI_DENSITY_HALFINCH_PE
:
2129 softc
->quirks
&= ~SA_QUIRK_1FM
;
2130 softc
->quirks
|= SA_QUIRK_2FM
;
2138 * Now validate that some info we got makes sense.
2140 if ((softc
->max_blk
< softc
->media_blksize
) ||
2141 (softc
->min_blk
> softc
->media_blksize
&&
2142 softc
->media_blksize
)) {
2143 xpt_print(periph
->path
,
2144 "BLOCK LIMITS (%d..%d) could not match current "
2145 "block settings (%d)- adjusting\n", softc
->min_blk
,
2146 softc
->max_blk
, softc
->media_blksize
);
2147 softc
->max_blk
= softc
->min_blk
=
2148 softc
->media_blksize
;
2152 * Now put ourselves into the right frame of mind based
2157 * If we want to be in FIXED mode and our current blocksize
2158 * is not equal to our last blocksize (if nonzero), try and
2159 * set ourselves to this last blocksize (as the 'preferred'
2160 * block size). The initial quirkmatch at registry sets the
2161 * initial 'last' blocksize. If, for whatever reason, this
2162 * 'last' blocksize is zero, set the blocksize to 512,
2163 * or min_blk if that's larger.
2165 if ((softc
->quirks
& SA_QUIRK_FIXED
) &&
2166 (softc
->quirks
& SA_QUIRK_NO_MODESEL
) == 0 &&
2167 (softc
->media_blksize
!= softc
->last_media_blksize
)) {
2168 softc
->media_blksize
= softc
->last_media_blksize
;
2169 if (softc
->media_blksize
== 0) {
2170 softc
->media_blksize
= 512;
2171 if (softc
->media_blksize
< softc
->min_blk
) {
2172 softc
->media_blksize
= softc
->min_blk
;
2175 error
= sasetparams(periph
, SA_PARAM_BLOCKSIZE
,
2176 softc
->media_blksize
, 0, 0, SF_NO_PRINT
);
2178 xpt_print(periph
->path
,
2179 "unable to set fixed blocksize to %d\n",
2180 softc
->media_blksize
);
2185 if ((softc
->quirks
& SA_QUIRK_VARIABLE
) &&
2186 (softc
->media_blksize
!= 0)) {
2187 softc
->last_media_blksize
= softc
->media_blksize
;
2188 softc
->media_blksize
= 0;
2189 error
= sasetparams(periph
, SA_PARAM_BLOCKSIZE
,
2190 0, 0, 0, SF_NO_PRINT
);
2193 * If this fails and we were guessing, just
2194 * assume that we got it wrong and go try
2195 * fixed block mode. Don't even check against
2196 * density code at this point.
2199 softc
->quirks
&= ~SA_QUIRK_VARIABLE
;
2200 softc
->quirks
|= SA_QUIRK_FIXED
;
2201 if (softc
->last_media_blksize
== 0)
2202 softc
->last_media_blksize
= 512;
2205 xpt_print(periph
->path
,
2206 "unable to set variable blocksize\n");
2212 * Now that we have the current block size,
2213 * set up some parameters for sastart's usage.
2215 if (softc
->media_blksize
) {
2216 softc
->flags
|= SA_FLAG_FIXED
;
2217 if (powerof2(softc
->media_blksize
)) {
2219 ffs(softc
->media_blksize
) - 1;
2220 softc
->blk_mask
= softc
->media_blksize
- 1;
2222 softc
->blk_mask
= ~0;
2223 softc
->blk_shift
= 0;
2227 * The SCSI-3 spec allows 0 to mean "unspecified".
2228 * The SCSI-1 spec allows 0 to mean 'infinite'.
2230 * Either works here.
2232 if (softc
->max_blk
== 0) {
2233 softc
->max_blk
= ~0;
2235 softc
->blk_shift
= 0;
2236 if (softc
->blk_gran
!= 0) {
2237 softc
->blk_mask
= softc
->blk_gran
- 1;
2239 softc
->blk_mask
= 0;
2244 softc
->flags
|= SA_FLAG_TAPE_WP
;
2246 if (comp_supported
) {
2247 if (softc
->saved_comp_algorithm
== 0)
2248 softc
->saved_comp_algorithm
=
2249 softc
->comp_algorithm
;
2250 softc
->flags
|= SA_FLAG_COMP_SUPP
;
2252 softc
->flags
|= SA_FLAG_COMP_ENABLED
;
2254 softc
->flags
|= SA_FLAG_COMP_UNSUPP
;
2256 if ((softc
->buffer_mode
== SMH_SA_BUF_MODE_NOBUF
) &&
2257 (softc
->quirks
& SA_QUIRK_NO_MODESEL
) == 0) {
2258 error
= sasetparams(periph
, SA_PARAM_BUFF_MODE
, 0,
2261 softc
->buffer_mode
= SMH_SA_BUF_MODE_SIBUF
;
2263 xpt_print(periph
->path
,
2264 "unable to set buffered mode\n");
2266 error
= 0; /* not an error */
2271 softc
->flags
|= SA_FLAG_TAPE_MOUNTED
;
2275 kfree(rblim
, M_SCSISA
);
2278 softc
->dsreg
= MTIO_DSREG_NIL
;
2280 softc
->fileno
= softc
->blkno
= 0;
2281 softc
->dsreg
= MTIO_DSREG_REST
;
2283 #ifdef SA_1FM_AT_EOD
2284 if ((softc
->quirks
& SA_QUIRK_2FM
) == 0)
2285 softc
->quirks
|= SA_QUIRK_1FM
;
2287 if ((softc
->quirks
& SA_QUIRK_1FM
) == 0)
2288 softc
->quirks
|= SA_QUIRK_2FM
;
2291 xpt_release_ccb(ccb
);
2294 * If we return an error, we're not mounted any more,
2295 * so release any device reservation.
2298 sareservereleaseunit(periph
, FALSE
);
2301 * Clear I/O residual.
2303 softc
->last_io_resid
= 0;
2304 softc
->last_ctl_resid
= 0;
2310 * How many filemarks do we need to write if we were to terminate the
2311 * tape session right now? Note that this can be a negative number
2315 samarkswanted(struct cam_periph
*periph
)
2318 struct sa_softc
*softc
;
2320 softc
= (struct sa_softc
*)periph
->softc
;
2322 if ((softc
->flags
& SA_FLAG_TAPE_WRITTEN
) != 0) {
2324 if (softc
->quirks
& SA_QUIRK_2FM
)
2327 markswanted
-= softc
->filemarks
;
2328 return (markswanted
);
2332 sacheckeod(struct cam_periph
*periph
)
2337 markswanted
= samarkswanted(periph
);
2339 if (markswanted
> 0) {
2340 error
= sawritefilemarks(periph
, markswanted
, FALSE
);
2348 saerror(union ccb
*ccb
, u_int32_t cflgs
, u_int32_t sflgs
)
2350 static const char *toobig
=
2351 "%d-byte tape record bigger than supplied buffer\n";
2352 struct cam_periph
*periph
;
2353 struct sa_softc
*softc
;
2354 struct ccb_scsiio
*csio
;
2355 struct scsi_sense_data
*sense
;
2356 u_int32_t resid
= 0;
2359 int error_code
, sense_key
, asc
, ascq
, error
, aqvalid
;
2361 periph
= xpt_path_periph(ccb
->ccb_h
.path
);
2362 softc
= (struct sa_softc
*)periph
->softc
;
2364 sense
= &csio
->sense_data
;
2365 scsi_extract_sense(sense
, &error_code
, &sense_key
, &asc
, &ascq
);
2366 aqvalid
= sense
->extra_len
>= 6;
2369 status
= csio
->ccb_h
.status
& CAM_STATUS_MASK
;
2372 * Calculate/latch up, any residuals... We do this in a funny 2-step
2373 * so we can print stuff here if we have CAM_DEBUG enabled for this
2376 if (status
== CAM_SCSI_STATUS_ERROR
) {
2377 if ((sense
->error_code
& SSD_ERRCODE_VALID
) != 0) {
2378 info
= (int32_t) scsi_4btoul(sense
->info
);
2380 if ((softc
->flags
& SA_FLAG_FIXED
) != 0)
2381 resid
*= softc
->media_blksize
;
2383 resid
= csio
->dxfer_len
;
2385 if ((softc
->flags
& SA_FLAG_FIXED
) != 0) {
2386 if (softc
->media_blksize
)
2387 info
/= softc
->media_blksize
;
2390 if (CCB_Type(csio
) == SA_CCB_BUFFER_IO
) {
2391 bcopy((caddr_t
) sense
, (caddr_t
) &softc
->last_io_sense
,
2392 sizeof (struct scsi_sense_data
));
2393 bcopy(csio
->cdb_io
.cdb_bytes
, softc
->last_io_cdb
,
2394 (int) csio
->cdb_len
);
2395 softc
->last_io_resid
= resid
;
2396 softc
->last_resid_was_io
= 1;
2398 bcopy((caddr_t
) sense
, (caddr_t
) &softc
->last_ctl_sense
,
2399 sizeof (struct scsi_sense_data
));
2400 bcopy(csio
->cdb_io
.cdb_bytes
, softc
->last_ctl_cdb
,
2401 (int) csio
->cdb_len
);
2402 softc
->last_ctl_resid
= resid
;
2403 softc
->last_resid_was_io
= 0;
2405 CAM_DEBUG(periph
->path
, CAM_DEBUG_INFO
, ("CDB[0]=0x%x Key 0x%x "
2406 "ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %d "
2407 "dxfer_len %d\n", csio
->cdb_io
.cdb_bytes
[0] & 0xff,
2408 sense_key
, asc
, ascq
, status
,
2409 sense
->flags
& ~SSD_KEY_RESERVED
, resid
, csio
->dxfer_len
));
2411 CAM_DEBUG(periph
->path
, CAM_DEBUG_INFO
,
2412 ("Cam Status 0x%x\n", status
));
2418 case CAM_SCSI_STATUS_ERROR
:
2420 * If a read/write command, we handle it here.
2422 if (CCB_Type(csio
) != SA_CCB_WAITING
) {
2426 * If this was just EOM/EOP, Filemark, Setmark or ILI detected
2427 * on a non read/write command, we assume it's not an error
2428 * and propagate the residule and return.
2430 if ((aqvalid
&& asc
== 0 && ascq
> 0 && ascq
<= 5) ||
2431 (aqvalid
== 0 && sense_key
== SSD_KEY_NO_SENSE
)) {
2432 csio
->resid
= resid
;
2437 * Otherwise, we let the common code handle this.
2439 return (cam_periph_error(ccb
, cflgs
, sflgs
, &softc
->saved_ccb
));
2443 * We cannot depend upon CAM honoring retry counts for these.
2445 case CAM_SCSI_BUS_RESET
:
2447 if (ccb
->ccb_h
.retry_count
<= 0) {
2452 return (cam_periph_error(ccb
, cflgs
, sflgs
, &softc
->saved_ccb
));
2456 * Handle filemark, end of tape, mismatched record sizes....
2457 * From this point out, we're only handling read/write cases.
2458 * Handle writes && reads differently.
2461 if (csio
->cdb_io
.cdb_bytes
[0] == SA_WRITE
) {
2462 if (sense_key
== SSD_KEY_VOLUME_OVERFLOW
) {
2463 csio
->resid
= resid
;
2465 } else if (sense
->flags
& SSD_EOM
) {
2466 softc
->flags
|= SA_FLAG_EOM_PENDING
;
2468 * Grotesque as it seems, the few times
2469 * I've actually seen a non-zero resid,
2470 * the tape drive actually lied and had
2471 * written all the data!.
2476 csio
->resid
= resid
;
2477 if (sense_key
== SSD_KEY_BLANK_CHECK
) {
2478 if (softc
->quirks
& SA_QUIRK_1FM
) {
2480 softc
->flags
|= SA_FLAG_EOM_PENDING
;
2484 } else if (sense
->flags
& SSD_FILEMARK
) {
2485 if (softc
->flags
& SA_FLAG_FIXED
) {
2487 softc
->flags
|= SA_FLAG_EOF_PENDING
;
2490 * Unconditionally, if we detected a filemark on a read,
2491 * mark that we've run moved a file ahead.
2493 if (softc
->fileno
!= (daddr_t
) -1) {
2496 csio
->ccb_h
.ccb_pflags
|= SA_POSITION_UPDATED
;
2502 * Incorrect Length usually applies to read, but can apply to writes.
2504 if (error
== 0 && (sense
->flags
& SSD_ILI
)) {
2506 xpt_print(csio
->ccb_h
.path
, toobig
,
2507 csio
->dxfer_len
- info
);
2508 csio
->resid
= csio
->dxfer_len
;
2511 csio
->resid
= resid
;
2512 if (softc
->flags
& SA_FLAG_FIXED
) {
2513 softc
->flags
|= SA_FLAG_EIO_PENDING
;
2516 * Bump the block number if we hadn't seen a filemark.
2517 * Do this independent of errors (we've moved anyway).
2519 if ((sense
->flags
& SSD_FILEMARK
) == 0) {
2520 if (softc
->blkno
!= (daddr_t
) -1) {
2522 csio
->ccb_h
.ccb_pflags
|=
2523 SA_POSITION_UPDATED
;
2531 * Unfreeze the queue if frozen as we're not returning anything
2532 * to our waiters that would indicate an I/O error has occurred
2542 sagetparams(struct cam_periph
*periph
, sa_params params_to_get
,
2543 u_int32_t
*blocksize
, u_int8_t
*density
, u_int32_t
*numblocks
,
2544 int *buff_mode
, u_int8_t
*write_protect
, u_int8_t
*speed
,
2545 int *comp_supported
, int *comp_enabled
, u_int32_t
*comp_algorithm
,
2550 struct scsi_mode_header_6
*mode_hdr
;
2551 struct scsi_mode_blk_desc
*mode_blk
;
2552 int mode_buffer_len
;
2553 struct sa_softc
*softc
;
2558 softc
= (struct sa_softc
*)periph
->softc
;
2559 ccb
= cam_periph_getccb(periph
, 1);
2560 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
2561 if (softc
->quirks
& SA_QUIRK_NO_CPAGE
)
2562 cpage
= SA_DEVICE_CONFIGURATION_PAGE
;
2564 cpage
= SA_DATA_COMPRESSION_PAGE
;
2567 mode_buffer_len
= sizeof(*mode_hdr
) + sizeof(*mode_blk
);
2569 if (params_to_get
& SA_PARAM_COMPRESSION
) {
2570 if (softc
->quirks
& SA_QUIRK_NOCOMP
) {
2571 *comp_supported
= FALSE
;
2572 params_to_get
&= ~SA_PARAM_COMPRESSION
;
2574 mode_buffer_len
+= sizeof (sa_comp_t
);
2577 mode_buffer
= kmalloc(mode_buffer_len
, M_SCSISA
, M_INTWAIT
| M_ZERO
);
2578 mode_hdr
= (struct scsi_mode_header_6
*)mode_buffer
;
2579 mode_blk
= (struct scsi_mode_blk_desc
*)&mode_hdr
[1];
2581 /* it is safe to retry this */
2582 scsi_mode_sense(&ccb
->csio
, 5, sadone
, MSG_SIMPLE_Q_TAG
, FALSE
,
2583 SMS_PAGE_CTRL_CURRENT
, (params_to_get
& SA_PARAM_COMPRESSION
) ?
2584 cpage
: SMS_VENDOR_SPECIFIC_PAGE
, mode_buffer
, mode_buffer_len
,
2585 SSD_FULL_SIZE
, SCSIOP_TIMEOUT
);
2587 error
= cam_periph_runccb(ccb
, saerror
, 0, SF_NO_PRINT
,
2588 &softc
->device_stats
);
2591 status
= ccb
->ccb_h
.status
& CAM_STATUS_MASK
;
2593 if (error
== EINVAL
&& (params_to_get
& SA_PARAM_COMPRESSION
) != 0) {
2595 * Hmm. Let's see if we can try another page...
2596 * If we've already done that, give up on compression
2597 * for this device and remember this for the future
2598 * and attempt the request without asking for compression
2601 if (cpage
== SA_DATA_COMPRESSION_PAGE
) {
2602 cpage
= SA_DEVICE_CONFIGURATION_PAGE
;
2605 softc
->quirks
|= SA_QUIRK_NOCOMP
;
2606 kfree(mode_buffer
, M_SCSISA
);
2608 } else if (status
== CAM_SCSI_STATUS_ERROR
) {
2609 /* Tell the user about the fatal error. */
2610 scsi_sense_print(&ccb
->csio
);
2611 goto sagetparamsexit
;
2615 * If the user only wants the compression information, and
2616 * the device doesn't send back the block descriptor, it's
2617 * no big deal. If the user wants more than just
2618 * compression, though, and the device doesn't pass back the
2619 * block descriptor, we need to send another mode sense to
2620 * get the block descriptor.
2622 if ((mode_hdr
->blk_desc_len
== 0) &&
2623 (params_to_get
& SA_PARAM_COMPRESSION
) &&
2624 (params_to_get
& ~(SA_PARAM_COMPRESSION
))) {
2627 * Decrease the mode buffer length by the size of
2628 * the compression page, to make sure the data
2629 * there doesn't get overwritten.
2631 mode_buffer_len
-= sizeof (sa_comp_t
);
2634 * Now move the compression page that we presumably
2635 * got back down the memory chunk a little bit so
2636 * it doesn't get spammed.
2638 bcopy(&mode_hdr
[0], &mode_hdr
[1], sizeof (sa_comp_t
));
2639 bzero(&mode_hdr
[0], sizeof (mode_hdr
[0]));
2642 * Now, we issue another mode sense and just ask
2643 * for the block descriptor, etc.
2646 scsi_mode_sense(&ccb
->csio
, 2, sadone
, MSG_SIMPLE_Q_TAG
, FALSE
,
2647 SMS_PAGE_CTRL_CURRENT
, SMS_VENDOR_SPECIFIC_PAGE
,
2648 mode_buffer
, mode_buffer_len
, SSD_FULL_SIZE
,
2651 error
= cam_periph_runccb(ccb
, saerror
, 0, SF_NO_PRINT
,
2652 &softc
->device_stats
);
2656 goto sagetparamsexit
;
2659 if (params_to_get
& SA_PARAM_BLOCKSIZE
)
2660 *blocksize
= scsi_3btoul(mode_blk
->blklen
);
2662 if (params_to_get
& SA_PARAM_NUMBLOCKS
)
2663 *numblocks
= scsi_3btoul(mode_blk
->nblocks
);
2665 if (params_to_get
& SA_PARAM_BUFF_MODE
)
2666 *buff_mode
= mode_hdr
->dev_spec
& SMH_SA_BUF_MODE_MASK
;
2668 if (params_to_get
& SA_PARAM_DENSITY
)
2669 *density
= mode_blk
->density
;
2671 if (params_to_get
& SA_PARAM_WP
)
2672 *write_protect
= (mode_hdr
->dev_spec
& SMH_SA_WP
)? TRUE
: FALSE
;
2674 if (params_to_get
& SA_PARAM_SPEED
)
2675 *speed
= mode_hdr
->dev_spec
& SMH_SA_SPEED_MASK
;
2677 if (params_to_get
& SA_PARAM_COMPRESSION
) {
2678 sa_comp_t
*ntcs
= (sa_comp_t
*) &mode_blk
[1];
2679 if (cpage
== SA_DATA_COMPRESSION_PAGE
) {
2680 struct scsi_data_compression_page
*cp
= &ntcs
->dcomp
;
2682 (cp
->dce_and_dcc
& SA_DCP_DCC
)? TRUE
: FALSE
;
2684 (cp
->dce_and_dcc
& SA_DCP_DCE
)? TRUE
: FALSE
;
2685 *comp_algorithm
= scsi_4btoul(cp
->comp_algorithm
);
2687 struct scsi_dev_conf_page
*cp
= &ntcs
->dconf
;
2689 * We don't really know whether this device supports
2690 * Data Compression if the the algorithm field is
2691 * zero. Just say we do.
2693 *comp_supported
= TRUE
;
2695 (cp
->sel_comp_alg
!= SA_COMP_NONE
)? TRUE
: FALSE
;
2696 *comp_algorithm
= cp
->sel_comp_alg
;
2699 bcopy(ntcs
, tcs
, sizeof (sa_comp_t
));
2702 if (CAM_DEBUGGED(periph
->path
, CAM_DEBUG_INFO
)) {
2704 char *xyz
= mode_buffer
;
2705 xpt_print_path(periph
->path
);
2706 kprintf("Mode Sense Data=");
2707 for (idx
= 0; idx
< mode_buffer_len
; idx
++)
2708 kprintf(" 0x%02x", xyz
[idx
] & 0xff);
2714 xpt_release_ccb(ccb
);
2715 kfree(mode_buffer
, M_SCSISA
);
2720 * The purpose of this function is to set one of four different parameters
2724 * - compression / compression algorithm
2727 * The assumption is that this will be called from saioctl(), and therefore
2728 * from a process context. Thus the waiting malloc calls below. If that
2729 * assumption ever changes, the malloc calls should be changed to be
2732 * Any or all of the four parameters may be set when this function is
2733 * called. It should handle setting more than one parameter at once.
2736 sasetparams(struct cam_periph
*periph
, sa_params params_to_set
,
2737 u_int32_t blocksize
, u_int8_t density
, u_int32_t calg
,
2738 u_int32_t sense_flags
)
2740 struct sa_softc
*softc
;
2741 u_int32_t current_blocksize
= 0;/* silence gcc */
2742 u_int32_t current_calg
;
2743 u_int8_t current_density
= 0; /* silence gcc */
2744 u_int8_t current_speed
= 0; /* silence gcc */
2745 int comp_enabled
, comp_supported
;
2747 int mode_buffer_len
;
2748 struct scsi_mode_header_6
*mode_hdr
;
2749 struct scsi_mode_blk_desc
*mode_blk
;
2750 sa_comp_t
*ccomp
, *cpage
;
2752 union ccb
*ccb
= NULL
;
2755 softc
= (struct sa_softc
*)periph
->softc
;
2757 ccomp
= kmalloc(sizeof (sa_comp_t
), M_SCSISA
, M_INTWAIT
);
2760 * Since it doesn't make sense to set the number of blocks, or
2761 * write protection, we won't try to get the current value. We
2762 * always want to get the blocksize, so we can set it back to the
2765 error
= sagetparams(periph
,
2766 params_to_set
| SA_PARAM_BLOCKSIZE
| SA_PARAM_SPEED
,
2767 ¤t_blocksize
, ¤t_density
, NULL
, &buff_mode
, NULL
,
2768 ¤t_speed
, &comp_supported
, &comp_enabled
,
2769 ¤t_calg
, ccomp
);
2772 kfree(ccomp
, M_SCSISA
);
2776 mode_buffer_len
= sizeof(*mode_hdr
) + sizeof(*mode_blk
);
2777 if (params_to_set
& SA_PARAM_COMPRESSION
)
2778 mode_buffer_len
+= sizeof (sa_comp_t
);
2780 mode_buffer
= kmalloc(mode_buffer_len
, M_SCSISA
, M_INTWAIT
| M_ZERO
);
2782 mode_hdr
= (struct scsi_mode_header_6
*)mode_buffer
;
2783 mode_blk
= (struct scsi_mode_blk_desc
*)&mode_hdr
[1];
2785 ccb
= cam_periph_getccb(periph
, 1);
2786 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
2790 if (params_to_set
& SA_PARAM_COMPRESSION
) {
2792 cpage
= (sa_comp_t
*)&mode_blk
[1];
2794 cpage
= (sa_comp_t
*)&mode_hdr
[1];
2796 bcopy(ccomp
, cpage
, sizeof (sa_comp_t
));
2797 cpage
->hdr
.pagecode
&= ~0x80;
2802 * If the caller wants us to set the blocksize, use the one they
2803 * pass in. Otherwise, use the blocksize we got back from the
2804 * mode select above.
2807 if (params_to_set
& SA_PARAM_BLOCKSIZE
)
2808 scsi_ulto3b(blocksize
, mode_blk
->blklen
);
2810 scsi_ulto3b(current_blocksize
, mode_blk
->blklen
);
2813 * Set density if requested, else preserve old density.
2814 * SCSI_SAME_DENSITY only applies to SCSI-2 or better
2815 * devices, else density we've latched up in our softc.
2817 if (params_to_set
& SA_PARAM_DENSITY
) {
2818 mode_blk
->density
= density
;
2819 } else if (softc
->scsi_rev
> SCSI_REV_CCS
) {
2820 mode_blk
->density
= SCSI_SAME_DENSITY
;
2822 mode_blk
->density
= softc
->media_density
;
2827 * For mode selects, these two fields must be zero.
2829 mode_hdr
->data_length
= 0;
2830 mode_hdr
->medium_type
= 0;
2832 /* set the speed to the current value */
2833 mode_hdr
->dev_spec
= current_speed
;
2835 /* if set, set single-initiator buffering mode */
2836 if (softc
->buffer_mode
== SMH_SA_BUF_MODE_SIBUF
) {
2837 mode_hdr
->dev_spec
|= SMH_SA_BUF_MODE_SIBUF
;
2841 mode_hdr
->blk_desc_len
= sizeof(struct scsi_mode_blk_desc
);
2843 mode_hdr
->blk_desc_len
= 0;
2846 * First, if the user wants us to set the compression algorithm or
2847 * just turn compression on, check to make sure that this drive
2848 * supports compression.
2850 if (params_to_set
& SA_PARAM_COMPRESSION
) {
2852 * If the compression algorithm is 0, disable compression.
2853 * If the compression algorithm is non-zero, enable
2854 * compression and set the compression type to the
2855 * specified compression algorithm, unless the algorithm is
2856 * MT_COMP_ENABLE. In that case, we look at the
2857 * compression algorithm that is currently set and if it is
2858 * non-zero, we leave it as-is. If it is zero, and we have
2859 * saved a compression algorithm from a time when
2860 * compression was enabled before, set the compression to
2863 switch (ccomp
->hdr
.pagecode
& ~0x80) {
2864 case SA_DEVICE_CONFIGURATION_PAGE
:
2866 struct scsi_dev_conf_page
*dcp
= &cpage
->dconf
;
2868 dcp
->sel_comp_alg
= SA_COMP_NONE
;
2871 if (calg
!= MT_COMP_ENABLE
) {
2872 dcp
->sel_comp_alg
= calg
;
2873 } else if (dcp
->sel_comp_alg
== SA_COMP_NONE
&&
2874 softc
->saved_comp_algorithm
!= 0) {
2875 dcp
->sel_comp_alg
= softc
->saved_comp_algorithm
;
2879 case SA_DATA_COMPRESSION_PAGE
:
2880 if (ccomp
->dcomp
.dce_and_dcc
& SA_DCP_DCC
) {
2881 struct scsi_data_compression_page
*dcp
= &cpage
->dcomp
;
2884 * Disable compression, but leave the
2885 * decompression and the capability bit
2888 dcp
->dce_and_dcc
= SA_DCP_DCC
;
2889 dcp
->dde_and_red
|= SA_DCP_DDE
;
2892 /* enable compression && decompression */
2893 dcp
->dce_and_dcc
= SA_DCP_DCE
| SA_DCP_DCC
;
2894 dcp
->dde_and_red
|= SA_DCP_DDE
;
2896 * If there, use compression algorithm from caller.
2897 * Otherwise, if there's a saved compression algorithm
2898 * and there is no current algorithm, use the saved
2899 * algorithm. Else parrot back what we got and hope
2902 if (calg
!= MT_COMP_ENABLE
) {
2903 scsi_ulto4b(calg
, dcp
->comp_algorithm
);
2904 scsi_ulto4b(calg
, dcp
->decomp_algorithm
);
2905 } else if (scsi_4btoul(dcp
->comp_algorithm
) == 0 &&
2906 softc
->saved_comp_algorithm
!= 0) {
2907 scsi_ulto4b(softc
->saved_comp_algorithm
,
2908 dcp
->comp_algorithm
);
2909 scsi_ulto4b(softc
->saved_comp_algorithm
,
2910 dcp
->decomp_algorithm
);
2915 * Compression does not appear to be supported-
2916 * at least via the DATA COMPRESSION page. It
2917 * would be too much to ask us to believe that
2918 * the page itself is supported, but incorrectly
2919 * reports an ability to manipulate data compression,
2920 * so we'll assume that this device doesn't support
2921 * compression. We can just fall through for that.
2926 * The drive doesn't seem to support compression,
2927 * so turn off the set compression bit.
2929 params_to_set
&= ~SA_PARAM_COMPRESSION
;
2930 xpt_print(periph
->path
,
2931 "device does not seem to support compression\n");
2934 * If that was the only thing the user wanted us to set,
2935 * clean up allocated resources and return with
2936 * 'operation not supported'.
2938 if (params_to_set
== SA_PARAM_NONE
) {
2939 kfree(mode_buffer
, M_SCSISA
);
2940 xpt_release_ccb(ccb
);
2945 * That wasn't the only thing the user wanted us to set.
2946 * So, decrease the stated mode buffer length by the
2947 * size of the compression mode page.
2949 mode_buffer_len
-= sizeof(sa_comp_t
);
2953 /* It is safe to retry this operation */
2954 scsi_mode_select(&ccb
->csio
, 5, sadone
, MSG_SIMPLE_Q_TAG
,
2955 (params_to_set
& SA_PARAM_COMPRESSION
)? TRUE
: FALSE
,
2956 FALSE
, mode_buffer
, mode_buffer_len
, SSD_FULL_SIZE
, SCSIOP_TIMEOUT
);
2958 error
= cam_periph_runccb(ccb
, saerror
, 0,
2959 sense_flags
, &softc
->device_stats
);
2962 if (CAM_DEBUGGED(periph
->path
, CAM_DEBUG_INFO
)) {
2964 char *xyz
= mode_buffer
;
2965 xpt_print_path(periph
->path
);
2966 kprintf("Err%d, Mode Select Data=", error
);
2967 for (idx
= 0; idx
< mode_buffer_len
; idx
++)
2968 kprintf(" 0x%02x", xyz
[idx
] & 0xff);
2975 * If we can, try without setting density/blocksize.
2978 if ((params_to_set
&
2979 (SA_PARAM_DENSITY
|SA_PARAM_BLOCKSIZE
)) == 0) {
2984 mode_blk
= (struct scsi_mode_blk_desc
*)&mode_hdr
[1];
2985 cpage
= (sa_comp_t
*)&mode_blk
[1];
2989 * If we were setting the blocksize, and that failed, we
2990 * want to set it to its original value. If we weren't
2991 * setting the blocksize, we don't want to change it.
2993 scsi_ulto3b(current_blocksize
, mode_blk
->blklen
);
2996 * Set density if requested, else preserve old density.
2997 * SCSI_SAME_DENSITY only applies to SCSI-2 or better
2998 * devices, else density we've latched up in our softc.
3000 if (params_to_set
& SA_PARAM_DENSITY
) {
3001 mode_blk
->density
= current_density
;
3002 } else if (softc
->scsi_rev
> SCSI_REV_CCS
) {
3003 mode_blk
->density
= SCSI_SAME_DENSITY
;
3005 mode_blk
->density
= softc
->media_density
;
3008 if (params_to_set
& SA_PARAM_COMPRESSION
)
3009 bcopy(ccomp
, cpage
, sizeof (sa_comp_t
));
3012 * The retry count is the only CCB field that might have been
3013 * changed that we care about, so reset it back to 1.
3015 ccb
->ccb_h
.retry_count
= 1;
3016 cam_periph_runccb(ccb
, saerror
, 0, sense_flags
,
3017 &softc
->device_stats
);
3021 xpt_release_ccb(ccb
);
3024 kfree(ccomp
, M_SCSISA
);
3026 if (params_to_set
& SA_PARAM_COMPRESSION
) {
3028 softc
->flags
&= ~SA_FLAG_COMP_ENABLED
;
3030 * Even if we get an error setting compression,
3031 * do not say that we don't support it. We could
3032 * have been wrong, or it may be media specific.
3033 * softc->flags &= ~SA_FLAG_COMP_SUPP;
3035 softc
->saved_comp_algorithm
= softc
->comp_algorithm
;
3036 softc
->comp_algorithm
= 0;
3038 softc
->flags
|= SA_FLAG_COMP_ENABLED
;
3039 softc
->comp_algorithm
= calg
;
3043 kfree(mode_buffer
, M_SCSISA
);
3048 saprevent(struct cam_periph
*periph
, int action
)
3050 struct sa_softc
*softc
;
3054 softc
= (struct sa_softc
*)periph
->softc
;
3056 if ((action
== PR_ALLOW
) && (softc
->flags
& SA_FLAG_TAPE_LOCKED
) == 0)
3058 if ((action
== PR_PREVENT
) && (softc
->flags
& SA_FLAG_TAPE_LOCKED
) != 0)
3062 * We can be quiet about illegal requests.
3064 if (CAM_DEBUGGED(periph
->path
, CAM_DEBUG_INFO
)) {
3069 ccb
= cam_periph_getccb(periph
, 1);
3070 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3072 /* It is safe to retry this operation */
3073 scsi_prevent(&ccb
->csio
, 5, sadone
, MSG_SIMPLE_Q_TAG
, action
,
3074 SSD_FULL_SIZE
, SCSIOP_TIMEOUT
);
3076 error
= cam_periph_runccb(ccb
, saerror
, 0, sf
, &softc
->device_stats
);
3079 if (action
== PR_ALLOW
)
3080 softc
->flags
&= ~SA_FLAG_TAPE_LOCKED
;
3082 softc
->flags
|= SA_FLAG_TAPE_LOCKED
;
3085 xpt_release_ccb(ccb
);
3089 sarewind(struct cam_periph
*periph
)
3092 struct sa_softc
*softc
;
3095 softc
= (struct sa_softc
*)periph
->softc
;
3097 ccb
= cam_periph_getccb(periph
, 1);
3098 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3100 /* It is safe to retry this operation */
3101 scsi_rewind(&ccb
->csio
, 2, sadone
, MSG_SIMPLE_Q_TAG
, FALSE
,
3102 SSD_FULL_SIZE
, REWIND_TIMEOUT
);
3104 softc
->dsreg
= MTIO_DSREG_REW
;
3105 error
= cam_periph_runccb(ccb
, saerror
, 0, 0, &softc
->device_stats
);
3106 softc
->dsreg
= MTIO_DSREG_REST
;
3108 if ((ccb
->ccb_h
.status
& CAM_DEV_QFRZN
) != 0)
3109 cam_release_devq(ccb
->ccb_h
.path
, 0, 0, 0, FALSE
);
3111 xpt_release_ccb(ccb
);
3113 softc
->fileno
= softc
->blkno
= (daddr_t
) 0;
3115 softc
->fileno
= softc
->blkno
= (daddr_t
) -1;
3120 saspace(struct cam_periph
*periph
, int count
, scsi_space_code code
)
3123 struct sa_softc
*softc
;
3126 softc
= (struct sa_softc
*)periph
->softc
;
3128 ccb
= cam_periph_getccb(periph
, 1);
3129 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3131 /* This cannot be retried */
3133 scsi_space(&ccb
->csio
, 0, sadone
, MSG_SIMPLE_Q_TAG
, code
, count
,
3134 SSD_FULL_SIZE
, SPACE_TIMEOUT
);
3137 * Clear residual because we will be using it.
3139 softc
->last_ctl_resid
= 0;
3141 softc
->dsreg
= (count
< 0)? MTIO_DSREG_REV
: MTIO_DSREG_FWD
;
3142 error
= cam_periph_runccb(ccb
, saerror
, 0, 0, &softc
->device_stats
);
3143 softc
->dsreg
= MTIO_DSREG_REST
;
3145 if ((ccb
->ccb_h
.status
& CAM_DEV_QFRZN
) != 0)
3146 cam_release_devq(ccb
->ccb_h
.path
, 0, 0, 0, FALSE
);
3148 xpt_release_ccb(ccb
);
3151 * If a spacing operation has failed, we need to invalidate
3154 * If the spacing operation was setmarks or to end of recorded data,
3155 * we no longer know our relative position.
3157 * If the spacing operations was spacing files in reverse, we
3158 * take account of the residual, but still check against less
3159 * than zero- if we've gone negative, we must have hit BOT.
3161 * If the spacing operations was spacing records in reverse and
3162 * we have a residual, we've either hit BOT or hit a filemark.
3163 * In the former case, we know our new record number (0). In
3164 * the latter case, we have absolutely no idea what the real
3165 * record number is- we've stopped between the end of the last
3166 * record in the previous file and the filemark that stopped
3167 * our spacing backwards.
3170 softc
->fileno
= softc
->blkno
= (daddr_t
) -1;
3171 } else if (code
== SS_SETMARKS
|| code
== SS_EOD
) {
3172 softc
->fileno
= softc
->blkno
= (daddr_t
) -1;
3173 } else if (code
== SS_FILEMARKS
&& softc
->fileno
!= (daddr_t
) -1) {
3174 softc
->fileno
+= (count
- softc
->last_ctl_resid
);
3175 if (softc
->fileno
< 0) /* we must of hit BOT */
3178 } else if (code
== SS_BLOCKS
&& softc
->blkno
!= (daddr_t
) -1) {
3179 softc
->blkno
+= (count
- softc
->last_ctl_resid
);
3181 if (softc
->last_ctl_resid
|| softc
->blkno
< 0) {
3182 if (softc
->fileno
== 0) {
3185 softc
->blkno
= (daddr_t
) -1;
3194 sawritefilemarks(struct cam_periph
*periph
, int nmarks
, int setmarks
)
3197 struct sa_softc
*softc
;
3200 softc
= (struct sa_softc
*)periph
->softc
;
3201 if (softc
->open_rdonly
)
3204 ccb
= cam_periph_getccb(periph
, 1);
3205 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3208 * Clear residual because we will be using it.
3210 softc
->last_ctl_resid
= 0;
3212 softc
->dsreg
= MTIO_DSREG_FMK
;
3213 /* this *must* not be retried */
3214 scsi_write_filemarks(&ccb
->csio
, 0, sadone
, MSG_SIMPLE_Q_TAG
,
3215 FALSE
, setmarks
, nmarks
, SSD_FULL_SIZE
, IO_TIMEOUT
);
3216 softc
->dsreg
= MTIO_DSREG_REST
;
3219 error
= cam_periph_runccb(ccb
, saerror
, 0, 0, &softc
->device_stats
);
3221 if ((ccb
->ccb_h
.status
& CAM_DEV_QFRZN
) != 0)
3222 cam_release_devq(ccb
->ccb_h
.path
, 0, 0, 0, FALSE
);
3224 if (error
== 0 && nmarks
) {
3225 struct sa_softc
*softc
= (struct sa_softc
*)periph
->softc
;
3226 nwm
= nmarks
- softc
->last_ctl_resid
;
3227 softc
->filemarks
+= nwm
;
3230 xpt_release_ccb(ccb
);
3233 * Update relative positions (if we're doing that).
3236 softc
->fileno
= softc
->blkno
= (daddr_t
) -1;
3237 } else if (softc
->fileno
!= (daddr_t
) -1) {
3238 softc
->fileno
+= nwm
;
3245 sardpos(struct cam_periph
*periph
, int hard
, u_int32_t
*blkptr
)
3247 struct scsi_tape_position_data loc
;
3249 struct sa_softc
*softc
= (struct sa_softc
*)periph
->softc
;
3253 * We try and flush any buffered writes here if we were writing
3254 * and we're trying to get hardware block position. It eats
3255 * up performance substantially, but I'm wary of drive firmware.
3257 * I think that *logical* block position is probably okay-
3258 * but hardware block position might have to wait for data
3259 * to hit media to be valid. Caveat Emptor.
3262 if (hard
&& (softc
->flags
& SA_FLAG_TAPE_WRITTEN
)) {
3263 error
= sawritefilemarks(periph
, 0, 0);
3264 if (error
&& error
!= EACCES
)
3268 ccb
= cam_periph_getccb(periph
, 1);
3269 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3270 scsi_read_position(&ccb
->csio
, 1, sadone
, MSG_SIMPLE_Q_TAG
,
3271 hard
, &loc
, SSD_FULL_SIZE
, SCSIOP_TIMEOUT
);
3272 softc
->dsreg
= MTIO_DSREG_RBSY
;
3273 error
= cam_periph_runccb(ccb
, saerror
, 0, 0, &softc
->device_stats
);
3274 softc
->dsreg
= MTIO_DSREG_REST
;
3275 if ((ccb
->ccb_h
.status
& CAM_DEV_QFRZN
) != 0)
3276 cam_release_devq(ccb
->ccb_h
.path
, 0, 0, 0, 0);
3279 if (loc
.flags
& SA_RPOS_UNCERTAIN
) {
3280 error
= EINVAL
; /* nothing is certain */
3282 *blkptr
= scsi_4btoul(loc
.firstblk
);
3286 xpt_release_ccb(ccb
);
3291 sasetpos(struct cam_periph
*periph
, int hard
, u_int32_t
*blkptr
)
3294 struct sa_softc
*softc
;
3298 * We used to try and flush any buffered writes here.
3299 * Now we push this onto user applications to either
3300 * flush the pending writes themselves (via a zero count
3301 * WRITE FILEMARKS command) or they can trust their tape
3302 * drive to do this correctly for them.
3305 softc
= (struct sa_softc
*)periph
->softc
;
3306 ccb
= cam_periph_getccb(periph
, 1);
3307 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3309 scsi_set_position(&ccb
->csio
, 1, sadone
, MSG_SIMPLE_Q_TAG
,
3310 hard
, *blkptr
, SSD_FULL_SIZE
, SPACE_TIMEOUT
);
3313 softc
->dsreg
= MTIO_DSREG_POS
;
3314 error
= cam_periph_runccb(ccb
, saerror
, 0, 0, &softc
->device_stats
);
3315 softc
->dsreg
= MTIO_DSREG_REST
;
3316 if ((ccb
->ccb_h
.status
& CAM_DEV_QFRZN
) != 0)
3317 cam_release_devq(ccb
->ccb_h
.path
, 0, 0, 0, 0);
3318 xpt_release_ccb(ccb
);
3320 * Note relative file && block number position as now unknown.
3322 softc
->fileno
= softc
->blkno
= (daddr_t
) -1;
3327 saretension(struct cam_periph
*periph
)
3330 struct sa_softc
*softc
;
3333 softc
= (struct sa_softc
*)periph
->softc
;
3335 ccb
= cam_periph_getccb(periph
, 1);
3336 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3338 /* It is safe to retry this operation */
3339 scsi_load_unload(&ccb
->csio
, 5, sadone
, MSG_SIMPLE_Q_TAG
, FALSE
,
3340 FALSE
, TRUE
, TRUE
, SSD_FULL_SIZE
, ERASE_TIMEOUT
);
3342 softc
->dsreg
= MTIO_DSREG_TEN
;
3343 error
= cam_periph_runccb(ccb
, saerror
, 0, 0, &softc
->device_stats
);
3344 softc
->dsreg
= MTIO_DSREG_REST
;
3346 if ((ccb
->ccb_h
.status
& CAM_DEV_QFRZN
) != 0)
3347 cam_release_devq(ccb
->ccb_h
.path
, 0, 0, 0, FALSE
);
3348 xpt_release_ccb(ccb
);
3350 softc
->fileno
= softc
->blkno
= (daddr_t
) 0;
3352 softc
->fileno
= softc
->blkno
= (daddr_t
) -1;
3357 sareservereleaseunit(struct cam_periph
*periph
, int reserve
)
3360 struct sa_softc
*softc
;
3363 softc
= (struct sa_softc
*)periph
->softc
;
3364 ccb
= cam_periph_getccb(periph
, 1);
3365 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3367 /* It is safe to retry this operation */
3368 scsi_reserve_release_unit(&ccb
->csio
, 2, sadone
, MSG_SIMPLE_Q_TAG
,
3369 FALSE
, 0, SSD_FULL_SIZE
, SCSIOP_TIMEOUT
, reserve
);
3370 softc
->dsreg
= MTIO_DSREG_RBSY
;
3371 error
= cam_periph_runccb(ccb
, saerror
, 0,
3372 SF_RETRY_UA
| SF_NO_PRINT
, &softc
->device_stats
);
3373 softc
->dsreg
= MTIO_DSREG_REST
;
3375 xpt_release_ccb(ccb
);
3378 * If the error was Illegal Request, then the device doesn't support
3379 * RESERVE/RELEASE. This is not an error.
3381 if (error
== EINVAL
) {
3389 saloadunload(struct cam_periph
*periph
, int load
)
3392 struct sa_softc
*softc
;
3395 softc
= (struct sa_softc
*)periph
->softc
;
3397 ccb
= cam_periph_getccb(periph
, 1);
3398 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3400 /* It is safe to retry this operation */
3401 scsi_load_unload(&ccb
->csio
, 5, sadone
, MSG_SIMPLE_Q_TAG
, FALSE
,
3402 FALSE
, FALSE
, load
, SSD_FULL_SIZE
, REWIND_TIMEOUT
);
3404 softc
->dsreg
= (load
)? MTIO_DSREG_LD
: MTIO_DSREG_UNL
;
3405 error
= cam_periph_runccb(ccb
, saerror
, 0, 0, &softc
->device_stats
);
3406 softc
->dsreg
= MTIO_DSREG_REST
;
3408 xpt_release_ccb(ccb
);
3410 if (error
|| load
== 0)
3411 softc
->fileno
= softc
->blkno
= (daddr_t
) -1;
3412 else if (error
== 0)
3413 softc
->fileno
= softc
->blkno
= (daddr_t
) 0;
3418 saerase(struct cam_periph
*periph
, int longerase
)
3422 struct sa_softc
*softc
;
3425 softc
= (struct sa_softc
*)periph
->softc
;
3426 if (softc
->open_rdonly
)
3429 ccb
= cam_periph_getccb(periph
, 1);
3430 Set_CCB_Type(ccb
, SA_CCB_POLLED
);
3432 scsi_erase(&ccb
->csio
, 1, sadone
, MSG_SIMPLE_Q_TAG
, FALSE
, longerase
,
3433 SSD_FULL_SIZE
, ERASE_TIMEOUT
);
3435 softc
->dsreg
= MTIO_DSREG_ZER
;
3436 error
= cam_periph_runccb(ccb
, saerror
, 0, 0, &softc
->device_stats
);
3437 softc
->dsreg
= MTIO_DSREG_REST
;
3439 if ((ccb
->ccb_h
.status
& CAM_DEV_QFRZN
) != 0)
3440 cam_release_devq(ccb
->ccb_h
.path
, 0, 0, 0, FALSE
);
3441 xpt_release_ccb(ccb
);
3445 #endif /* _KERNEL */
3448 * Read tape block limits command.
3451 scsi_read_block_limits(struct ccb_scsiio
*csio
, u_int32_t retries
,
3452 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3453 u_int8_t tag_action
,
3454 struct scsi_read_block_limits_data
*rlimit_buf
,
3455 u_int8_t sense_len
, u_int32_t timeout
)
3457 struct scsi_read_block_limits
*scsi_cmd
;
3459 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_IN
, tag_action
,
3460 (u_int8_t
*)rlimit_buf
, sizeof(*rlimit_buf
), sense_len
,
3461 sizeof(*scsi_cmd
), timeout
);
3463 scsi_cmd
= (struct scsi_read_block_limits
*)&csio
->cdb_io
.cdb_bytes
;
3464 bzero(scsi_cmd
, sizeof(*scsi_cmd
));
3465 scsi_cmd
->opcode
= READ_BLOCK_LIMITS
;
3469 scsi_sa_read_write(struct ccb_scsiio
*csio
, u_int32_t retries
,
3470 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3471 u_int8_t tag_action
, int readop
, int sli
,
3472 int fixed
, u_int32_t length
, u_int8_t
*data_ptr
,
3473 u_int32_t dxfer_len
, u_int8_t sense_len
, u_int32_t timeout
)
3475 struct scsi_sa_rw
*scsi_cmd
;
3477 scsi_cmd
= (struct scsi_sa_rw
*)&csio
->cdb_io
.cdb_bytes
;
3478 scsi_cmd
->opcode
= readop
? SA_READ
: SA_WRITE
;
3479 scsi_cmd
->sli_fixed
= 0;
3481 scsi_cmd
->sli_fixed
|= SAR_SLI
;
3483 scsi_cmd
->sli_fixed
|= SARW_FIXED
;
3484 scsi_ulto3b(length
, scsi_cmd
->length
);
3485 scsi_cmd
->control
= 0;
3487 cam_fill_csio(csio
, retries
, cbfcnp
, readop
? CAM_DIR_IN
: CAM_DIR_OUT
,
3488 tag_action
, data_ptr
, dxfer_len
, sense_len
,
3489 sizeof(*scsi_cmd
), timeout
);
3493 scsi_load_unload(struct ccb_scsiio
*csio
, u_int32_t retries
,
3494 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3495 u_int8_t tag_action
, int immediate
, int eot
,
3496 int reten
, int load
, u_int8_t sense_len
,
3499 struct scsi_load_unload
*scsi_cmd
;
3501 scsi_cmd
= (struct scsi_load_unload
*)&csio
->cdb_io
.cdb_bytes
;
3502 bzero(scsi_cmd
, sizeof(*scsi_cmd
));
3503 scsi_cmd
->opcode
= LOAD_UNLOAD
;
3505 scsi_cmd
->immediate
= SLU_IMMED
;
3507 scsi_cmd
->eot_reten_load
|= SLU_EOT
;
3509 scsi_cmd
->eot_reten_load
|= SLU_RETEN
;
3511 scsi_cmd
->eot_reten_load
|= SLU_LOAD
;
3513 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_NONE
, tag_action
,
3514 NULL
, 0, sense_len
, sizeof(*scsi_cmd
), timeout
);
3518 scsi_rewind(struct ccb_scsiio
*csio
, u_int32_t retries
,
3519 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3520 u_int8_t tag_action
, int immediate
, u_int8_t sense_len
,
3523 struct scsi_rewind
*scsi_cmd
;
3525 scsi_cmd
= (struct scsi_rewind
*)&csio
->cdb_io
.cdb_bytes
;
3526 bzero(scsi_cmd
, sizeof(*scsi_cmd
));
3527 scsi_cmd
->opcode
= REWIND
;
3529 scsi_cmd
->immediate
= SREW_IMMED
;
3531 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_NONE
, tag_action
, NULL
,
3532 0, sense_len
, sizeof(*scsi_cmd
), timeout
);
3536 scsi_space(struct ccb_scsiio
*csio
, u_int32_t retries
,
3537 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3538 u_int8_t tag_action
, scsi_space_code code
,
3539 u_int32_t count
, u_int8_t sense_len
, u_int32_t timeout
)
3541 struct scsi_space
*scsi_cmd
;
3543 scsi_cmd
= (struct scsi_space
*)&csio
->cdb_io
.cdb_bytes
;
3544 scsi_cmd
->opcode
= SPACE
;
3545 scsi_cmd
->code
= code
;
3546 scsi_ulto3b(count
, scsi_cmd
->count
);
3547 scsi_cmd
->control
= 0;
3549 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_NONE
, tag_action
, NULL
,
3550 0, sense_len
, sizeof(*scsi_cmd
), timeout
);
3554 scsi_write_filemarks(struct ccb_scsiio
*csio
, u_int32_t retries
,
3555 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3556 u_int8_t tag_action
, int immediate
, int setmark
,
3557 u_int32_t num_marks
, u_int8_t sense_len
,
3560 struct scsi_write_filemarks
*scsi_cmd
;
3562 scsi_cmd
= (struct scsi_write_filemarks
*)&csio
->cdb_io
.cdb_bytes
;
3563 bzero(scsi_cmd
, sizeof(*scsi_cmd
));
3564 scsi_cmd
->opcode
= WRITE_FILEMARKS
;
3566 scsi_cmd
->byte2
|= SWFMRK_IMMED
;
3568 scsi_cmd
->byte2
|= SWFMRK_WSMK
;
3570 scsi_ulto3b(num_marks
, scsi_cmd
->num_marks
);
3572 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_NONE
, tag_action
, NULL
,
3573 0, sense_len
, sizeof(*scsi_cmd
), timeout
);
3577 * The reserve and release unit commands differ only by their opcodes.
3580 scsi_reserve_release_unit(struct ccb_scsiio
*csio
, u_int32_t retries
,
3581 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3582 u_int8_t tag_action
, int third_party
,
3583 int third_party_id
, u_int8_t sense_len
,
3584 u_int32_t timeout
, int reserve
)
3586 struct scsi_reserve_release_unit
*scsi_cmd
;
3588 scsi_cmd
= (struct scsi_reserve_release_unit
*)&csio
->cdb_io
.cdb_bytes
;
3589 bzero(scsi_cmd
, sizeof(*scsi_cmd
));
3592 scsi_cmd
->opcode
= RESERVE_UNIT
;
3594 scsi_cmd
->opcode
= RELEASE_UNIT
;
3597 scsi_cmd
->lun_thirdparty
|= SRRU_3RD_PARTY
;
3598 scsi_cmd
->lun_thirdparty
|=
3599 ((third_party_id
<< SRRU_3RD_SHAMT
) & SRRU_3RD_MASK
);
3602 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_NONE
, tag_action
, NULL
,
3603 0, sense_len
, sizeof(*scsi_cmd
), timeout
);
3607 scsi_erase(struct ccb_scsiio
*csio
, u_int32_t retries
,
3608 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3609 u_int8_t tag_action
, int immediate
, int long_erase
,
3610 u_int8_t sense_len
, u_int32_t timeout
)
3612 struct scsi_erase
*scsi_cmd
;
3614 scsi_cmd
= (struct scsi_erase
*)&csio
->cdb_io
.cdb_bytes
;
3615 bzero(scsi_cmd
, sizeof(*scsi_cmd
));
3617 scsi_cmd
->opcode
= ERASE
;
3620 scsi_cmd
->lun_imm_long
|= SE_IMMED
;
3623 scsi_cmd
->lun_imm_long
|= SE_LONG
;
3625 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_NONE
, tag_action
, NULL
,
3626 0, sense_len
, sizeof(*scsi_cmd
), timeout
);
3630 * Read Tape Position command.
3633 scsi_read_position(struct ccb_scsiio
*csio
, u_int32_t retries
,
3634 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3635 u_int8_t tag_action
, int hardsoft
,
3636 struct scsi_tape_position_data
*sbp
,
3637 u_int8_t sense_len
, u_int32_t timeout
)
3639 struct scsi_tape_read_position
*scmd
;
3641 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_IN
, tag_action
,
3642 (u_int8_t
*)sbp
, sizeof (*sbp
), sense_len
, sizeof(*scmd
), timeout
);
3643 scmd
= (struct scsi_tape_read_position
*)&csio
->cdb_io
.cdb_bytes
;
3644 bzero(scmd
, sizeof(*scmd
));
3645 scmd
->opcode
= READ_POSITION
;
3646 scmd
->byte1
= hardsoft
;
3650 * Set Tape Position command.
3653 scsi_set_position(struct ccb_scsiio
*csio
, u_int32_t retries
,
3654 void (*cbfcnp
)(struct cam_periph
*, union ccb
*),
3655 u_int8_t tag_action
, int hardsoft
, u_int32_t blkno
,
3656 u_int8_t sense_len
, u_int32_t timeout
)
3658 struct scsi_tape_locate
*scmd
;
3660 cam_fill_csio(csio
, retries
, cbfcnp
, CAM_DIR_NONE
, tag_action
,
3661 NULL
, 0, sense_len
, sizeof(*scmd
), timeout
);
3662 scmd
= (struct scsi_tape_locate
*)&csio
->cdb_io
.cdb_bytes
;
3663 bzero(scmd
, sizeof(*scmd
));
3664 scmd
->opcode
= LOCATE
;
3666 scmd
->byte1
|= SA_SPOS_BT
;
3667 scsi_ulto4b(blkno
, scmd
->blkaddr
);