freebsd-dev/sys/cam/scsi/scsi_sa.c

3748 lines
100 KiB
C
Raw Normal View History

/*-
* Implementation of SCSI Sequential Access Peripheral driver for CAM.
*
* Copyright (c) 1999, 2000 Matthew Jacob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
2003-06-10 18:14:05 +00:00
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/queue.h>
#ifdef _KERNEL
#include <sys/systm.h>
#include <sys/kernel.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/bio.h>
#include <sys/limits.h>
#include <sys/malloc.h>
#include <sys/mtio.h>
#ifdef _KERNEL
#include <sys/conf.h>
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#endif
#include <sys/fcntl.h>
#include <sys/devicestat.h>
#ifndef _KERNEL
#include <stdio.h>
#include <string.h>
#endif
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/cam_periph.h>
#include <cam/cam_xpt_periph.h>
#include <cam/cam_debug.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_sa.h>
#ifdef _KERNEL
#include <opt_sa.h>
#ifndef SA_IO_TIMEOUT
#define SA_IO_TIMEOUT 4
#endif
#ifndef SA_SPACE_TIMEOUT
#define SA_SPACE_TIMEOUT 1 * 60
#endif
#ifndef SA_REWIND_TIMEOUT
#define SA_REWIND_TIMEOUT 2 * 60
#endif
#ifndef SA_ERASE_TIMEOUT
#define SA_ERASE_TIMEOUT 4 * 60
#endif
#define SCSIOP_TIMEOUT (60 * 1000) /* not an option */
#define IO_TIMEOUT (SA_IO_TIMEOUT * 60 * 1000)
#define REWIND_TIMEOUT (SA_REWIND_TIMEOUT * 60 * 1000)
#define ERASE_TIMEOUT (SA_ERASE_TIMEOUT * 60 * 1000)
#define SPACE_TIMEOUT (SA_SPACE_TIMEOUT * 60 * 1000)
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
* Additional options that can be set for config: SA_1FM_AT_EOT
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
*/
#ifndef UNUSED_PARAMETER
#define UNUSED_PARAMETER(x) x = x
#endif
#define QFRLS(ccb) \
if (((ccb)->ccb_h.status & CAM_DEV_QFRZN) != 0) \
cam_release_devq((ccb)->ccb_h.path, 0, 0, 0, FALSE)
/*
* Driver states
*/
static MALLOC_DEFINE(M_SCSISA, "SCSI sa", "SCSI sequential access buffers");
typedef enum {
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
SA_STATE_NORMAL, SA_STATE_ABNORMAL
} sa_state;
#define ccb_pflags ppriv_field0
#define ccb_bp ppriv_ptr1
/* bits in ccb_pflags */
#define SA_POSITION_UPDATED 0x1
typedef enum {
SA_FLAG_OPEN = 0x0001,
SA_FLAG_FIXED = 0x0002,
SA_FLAG_TAPE_LOCKED = 0x0004,
SA_FLAG_TAPE_MOUNTED = 0x0008,
SA_FLAG_TAPE_WP = 0x0010,
SA_FLAG_TAPE_WRITTEN = 0x0020,
SA_FLAG_EOM_PENDING = 0x0040,
SA_FLAG_EIO_PENDING = 0x0080,
SA_FLAG_EOF_PENDING = 0x0100,
SA_FLAG_ERR_PENDING = (SA_FLAG_EOM_PENDING|SA_FLAG_EIO_PENDING|
SA_FLAG_EOF_PENDING),
SA_FLAG_INVALID = 0x0200,
SA_FLAG_COMP_ENABLED = 0x0400,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
SA_FLAG_COMP_SUPP = 0x0800,
SA_FLAG_COMP_UNSUPP = 0x1000,
SA_FLAG_TAPE_FROZEN = 0x2000
} sa_flags;
typedef enum {
SA_MODE_REWIND = 0x00,
SA_MODE_NOREWIND = 0x01,
SA_MODE_OFFLINE = 0x02
} sa_mode;
typedef enum {
SA_PARAM_NONE = 0x00,
SA_PARAM_BLOCKSIZE = 0x01,
SA_PARAM_DENSITY = 0x02,
SA_PARAM_COMPRESSION = 0x04,
SA_PARAM_BUFF_MODE = 0x08,
SA_PARAM_NUMBLOCKS = 0x10,
SA_PARAM_WP = 0x20,
SA_PARAM_SPEED = 0x40,
SA_PARAM_ALL = 0x7f
} sa_params;
typedef enum {
SA_QUIRK_NONE = 0x00,
SA_QUIRK_NOCOMP = 0x01, /* Can't deal with compression at all */
SA_QUIRK_FIXED = 0x02, /* Force fixed mode */
SA_QUIRK_VARIABLE = 0x04, /* Force variable mode */
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
SA_QUIRK_2FM = 0x08, /* Needs Two File Marks at EOD */
SA_QUIRK_1FM = 0x10, /* No more than 1 File Mark at EOD */
SA_QUIRK_NODREAD = 0x20, /* Don't try and dummy read density */
SA_QUIRK_NO_MODESEL = 0x40, /* Don't do mode select at all */
SA_QUIRK_NO_CPAGE = 0x80 /* Don't use DEVICE COMPRESSION page */
} sa_quirks;
#define SA_QUIRK_BIT_STRING \
"\020" \
"\001NOCOMP" \
"\002FIXED" \
"\003VARIABLE" \
"\0042FM" \
"\0051FM" \
"\006NODREAD" \
"\007NO_MODESEL" \
"\010NO_CPAGE"
#define SAMODE(z) (dev2unit(z) & 0x3)
#define SADENSITY(z) ((dev2unit(z) >> 2) & 0x3)
#define SA_IS_CTRL(z) (dev2unit(z) & (1 << 4))
#define SA_NOT_CTLDEV 0
#define SA_CTLDEV 1
#define SA_ATYPE_R 0
#define SA_ATYPE_NR 1
#define SA_ATYPE_ER 2
#define SAMINOR(ctl, mode, access) \
((ctl << 4) | (mode << 2) | (access & 0x3))
#define SA_NUM_MODES 4
struct sa_devs {
struct cdev *ctl_dev;
struct sa_mode_devs {
struct cdev *r_dev;
struct cdev *nr_dev;
struct cdev *er_dev;
} mode_devs[SA_NUM_MODES];
};
struct sa_softc {
sa_state state;
sa_flags flags;
sa_quirks quirks;
u_int si_flags;
struct bio_queue_head bio_queue;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
int queue_count;
struct devstat *device_stats;
struct sa_devs devs;
int blk_gran;
int blk_mask;
int blk_shift;
u_int32_t max_blk;
u_int32_t min_blk;
u_int32_t maxio;
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
u_int32_t cpi_maxio;
int allow_io_split;
u_int32_t comp_algorithm;
u_int32_t saved_comp_algorithm;
u_int32_t media_blksize;
u_int32_t last_media_blksize;
u_int32_t media_numblks;
u_int8_t media_density;
u_int8_t speed;
u_int8_t scsi_rev;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
u_int8_t dsreg; /* mtio mt_dsreg, redux */
int buffer_mode;
int filemarks;
union ccb saved_ccb;
int last_resid_was_io;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
* Relative to BOT Location.
*/
daddr_t fileno;
daddr_t blkno;
/*
* Latched Error Info
*/
struct {
struct scsi_sense_data _last_io_sense;
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
u_int64_t _last_io_resid;
u_int8_t _last_io_cdb[CAM_MAX_CDBLEN];
struct scsi_sense_data _last_ctl_sense;
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
u_int64_t _last_ctl_resid;
u_int8_t _last_ctl_cdb[CAM_MAX_CDBLEN];
#define last_io_sense errinfo._last_io_sense
#define last_io_resid errinfo._last_io_resid
#define last_io_cdb errinfo._last_io_cdb
#define last_ctl_sense errinfo._last_ctl_sense
#define last_ctl_resid errinfo._last_ctl_resid
#define last_ctl_cdb errinfo._last_ctl_cdb
} errinfo;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
* Misc other flags/state
*/
u_int32_t
: 29,
open_rdonly : 1, /* open read-only */
open_pending_mount : 1, /* open pending mount */
ctrl_mode : 1; /* control device open */
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
struct task sysctl_task;
struct sysctl_ctx_list sysctl_ctx;
struct sysctl_oid *sysctl_tree;
};
struct sa_quirk_entry {
struct scsi_inquiry_pattern inq_pat; /* matching pattern */
sa_quirks quirks; /* specific quirk type */
u_int32_t prefblk; /* preferred blocksize when in fixed mode */
};
static struct sa_quirk_entry sa_quirk_table[] =
{
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "OnStream",
"ADR*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_NODREAD |
SA_QUIRK_1FM|SA_QUIRK_NO_MODESEL, 32768
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
"Python 06408*", "*"}, SA_QUIRK_NODREAD, 0
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
"Python 25601*", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_NODREAD, 0
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
"Python*", "*"}, SA_QUIRK_NODREAD, 0
},
1998-12-28 19:21:12 +00:00
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
"VIPER 150*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
"VIPER 2525 25462", "-011"},
SA_QUIRK_NOCOMP|SA_QUIRK_1FM|SA_QUIRK_NODREAD, 0
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
"VIPER 2525*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024
},
#if 0
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
"C15*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_NO_CPAGE, 0,
},
#endif
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
"C56*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
},
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
"T20*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
1998-12-28 19:21:12 +00:00
},
1999-01-11 18:26:25 +00:00
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
"T4000*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
"HP-88780*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "KENNEDY",
"*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "M4 DATA",
"123107 SCSI*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
},
{ /* jreynold@primenet.com */
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "Seagate",
"STT8000N*", "*"}, SA_QUIRK_1FM, 0
},
{ /* mike@sentex.net */
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "Seagate",
"STT20000*", "*"}, SA_QUIRK_1FM, 0
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "SEAGATE",
"DAT 06241-XXX", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
" TDC 3600", "U07:"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
1999-01-11 18:26:25 +00:00
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
" TDC 3800", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
" TDC 4100", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
" TDC 4200", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
},
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
" SLR*", "*"}, SA_QUIRK_1FM, 0
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK",
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
"5525ES*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
},
{
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK",
"51000*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024
}
};
static d_open_t saopen;
static d_close_t saclose;
static d_strategy_t sastrategy;
static d_ioctl_t saioctl;
static periph_init_t sainit;
static periph_ctor_t saregister;
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
static periph_oninv_t saoninvalidate;
static periph_dtor_t sacleanup;
static periph_start_t sastart;
static void saasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg);
static void sadone(struct cam_periph *periph,
union ccb *start_ccb);
static int saerror(union ccb *ccb, u_int32_t cam_flags,
u_int32_t sense_flags);
2000-10-31 22:34:51 +00:00
static int samarkswanted(struct cam_periph *);
static int sacheckeod(struct cam_periph *periph);
static int sagetparams(struct cam_periph *periph,
sa_params params_to_get,
u_int32_t *blocksize, u_int8_t *density,
u_int32_t *numblocks, int *buff_mode,
u_int8_t *write_protect, u_int8_t *speed,
int *comp_supported, int *comp_enabled,
u_int32_t *comp_algorithm,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
sa_comp_t *comp_page);
static int sasetparams(struct cam_periph *periph,
sa_params params_to_set,
u_int32_t blocksize, u_int8_t density,
u_int32_t comp_algorithm,
u_int32_t sense_flags);
static void saprevent(struct cam_periph *periph, int action);
static int sarewind(struct cam_periph *periph);
static int saspace(struct cam_periph *periph, int count,
scsi_space_code code);
static int samount(struct cam_periph *, int, struct cdev *);
static int saretension(struct cam_periph *periph);
static int sareservereleaseunit(struct cam_periph *periph,
int reserve);
static int saloadunload(struct cam_periph *periph, int load);
static int saerase(struct cam_periph *periph, int longerase);
static int sawritefilemarks(struct cam_periph *periph,
int nmarks, int setmarks);
static int sardpos(struct cam_periph *periph, int, u_int32_t *);
static int sasetpos(struct cam_periph *periph, int, u_int32_t *);
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
#ifndef SA_DEFAULT_IO_SPLIT
#define SA_DEFAULT_IO_SPLIT 0
#endif
static int sa_allow_io_split = SA_DEFAULT_IO_SPLIT;
/*
* Tunable to allow the user to set a global allow_io_split value. Note
* that this WILL GO AWAY in FreeBSD 11.0. Silently splitting the I/O up
* is bad behavior, because it hides the true tape block size from the
* application.
*/
static SYSCTL_NODE(_kern_cam, OID_AUTO, sa, CTLFLAG_RD, 0,
"CAM Sequential Access Tape Driver");
SYSCTL_INT(_kern_cam_sa, OID_AUTO, allow_io_split, CTLFLAG_RDTUN,
&sa_allow_io_split, 0, "Default I/O split value");
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
static struct periph_driver sadriver =
{
sainit, "sa",
TAILQ_HEAD_INITIALIZER(sadriver.units), /* generation */ 0
};
PERIPHDRIVER_DECLARE(sa, sadriver);
/* For 2.2-stable support */
#ifndef D_TAPE
#define D_TAPE 0
#endif
static struct cdevsw sa_cdevsw = {
.d_version = D_VERSION,
.d_open = saopen,
.d_close = saclose,
.d_read = physread,
.d_write = physwrite,
.d_ioctl = saioctl,
.d_strategy = sastrategy,
.d_name = "sa",
.d_flags = D_TAPE,
};
static int
saopen(struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct cam_periph *periph;
struct sa_softc *softc;
int error;
periph = (struct cam_periph *)dev->si_drv1;
if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
return (ENXIO);
}
cam_periph_lock(periph);
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO,
("saopen(%s): softc=0x%x\n", devtoname(dev), softc->flags));
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (SA_IS_CTRL(dev)) {
softc->ctrl_mode = 1;
cam_periph_unlock(periph);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
return (0);
}
if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
cam_periph_unlock(periph);
cam_periph_release(periph);
return (error);
}
if (softc->flags & SA_FLAG_OPEN) {
error = EBUSY;
} else if (softc->flags & SA_FLAG_INVALID) {
error = ENXIO;
} else {
/*
* Preserve whether this is a read_only open.
*/
softc->open_rdonly = (flags & O_RDWR) == O_RDONLY;
/*
* The function samount ensures media is loaded and ready.
* It also does a device RESERVE if the tape isn't yet mounted.
*
* If the mount fails and this was a non-blocking open,
* make this a 'open_pending_mount' action.
*/
error = samount(periph, flags, dev);
if (error && (flags & O_NONBLOCK)) {
softc->flags |= SA_FLAG_OPEN;
softc->open_pending_mount = 1;
cam_periph_unhold(periph);
cam_periph_unlock(periph);
return (0);
}
}
if (error) {
cam_periph_unhold(periph);
cam_periph_unlock(periph);
cam_periph_release(periph);
return (error);
}
saprevent(periph, PR_PREVENT);
softc->flags |= SA_FLAG_OPEN;
cam_periph_unhold(periph);
cam_periph_unlock(periph);
return (error);
}
static int
saclose(struct cdev *dev, int flag, int fmt, struct thread *td)
{
struct cam_periph *periph;
struct sa_softc *softc;
int mode, error, writing, tmp;
int closedbits = SA_FLAG_OPEN;
mode = SAMODE(dev);
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return (ENXIO);
cam_periph_lock(periph);
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO,
("saclose(%s): softc=0x%x\n", devtoname(dev), softc->flags));
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->open_rdonly = 0;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (SA_IS_CTRL(dev)) {
softc->ctrl_mode = 0;
cam_periph_unlock(periph);
cam_periph_release(periph);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
return (0);
}
if (softc->open_pending_mount) {
softc->flags &= ~SA_FLAG_OPEN;
softc->open_pending_mount = 0;
cam_periph_unlock(periph);
cam_periph_release(periph);
return (0);
}
if ((error = cam_periph_hold(periph, PRIBIO)) != 0) {
cam_periph_unlock(periph);
return (error);
}
/*
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
* Were we writing the tape?
*/
writing = (softc->flags & SA_FLAG_TAPE_WRITTEN) != 0;
/*
* See whether or not we need to write filemarks. If this
* fails, we probably have to assume we've lost tape
* position.
*/
error = sacheckeod(periph);
if (error) {
xpt_print(periph->path,
"failed to write terminating filemark(s)\n");
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->flags |= SA_FLAG_TAPE_FROZEN;
}
/*
* Whatever we end up doing, allow users to eject tapes from here on.
*/
saprevent(periph, PR_ALLOW);
/*
* Decide how to end...
*/
if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) {
closedbits |= SA_FLAG_TAPE_FROZEN;
} else switch (mode) {
case SA_MODE_OFFLINE:
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* An 'offline' close is an unconditional release of
* frozen && mount conditions, irrespective of whether
* these operations succeeded. The reason for this is
* to allow at least some kind of programmatic way
* around our state getting all fouled up. If somebody
* issues an 'offline' command, that will be allowed
* to clear state.
*/
(void) sarewind(periph);
(void) saloadunload(periph, FALSE);
closedbits |= SA_FLAG_TAPE_MOUNTED|SA_FLAG_TAPE_FROZEN;
break;
case SA_MODE_REWIND:
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* If the rewind fails, return an error- if anyone cares,
* but not overwriting any previous error.
*
* We don't clear the notion of mounted here, but we do
* clear the notion of frozen if we successfully rewound.
*/
tmp = sarewind(periph);
if (tmp) {
if (error != 0)
error = tmp;
} else {
closedbits |= SA_FLAG_TAPE_FROZEN;
}
break;
case SA_MODE_NOREWIND:
/*
* If we're not rewinding/unloading the tape, find out
* whether we need to back up over one of two filemarks
* we wrote (if we wrote two filemarks) so that appends
* from this point on will be sane.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (error == 0 && writing && (softc->quirks & SA_QUIRK_2FM)) {
tmp = saspace(periph, -1, SS_FILEMARKS);
if (tmp) {
xpt_print(periph->path, "unable to backspace "
"over one of double filemarks at end of "
"tape\n");
xpt_print(periph->path, "it is possible that "
"this device needs a SA_QUIRK_1FM quirk set"
"for it\n");
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->flags |= SA_FLAG_TAPE_FROZEN;
}
}
break;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
default:
xpt_print(periph->path, "unknown mode 0x%x in saclose\n", mode);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/* NOTREACHED */
break;
}
/*
* We wish to note here that there are no more filemarks to be written.
*/
softc->filemarks = 0;
softc->flags &= ~SA_FLAG_TAPE_WRITTEN;
/*
* And we are no longer open for business.
*/
softc->flags &= ~closedbits;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* Inform users if tape state if frozen....
*/
if (softc->flags & SA_FLAG_TAPE_FROZEN) {
xpt_print(periph->path, "tape is now frozen- use an OFFLINE, "
"REWIND or MTEOM command to clear this state.\n");
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
}
/* release the device if it is no longer mounted */
if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0)
sareservereleaseunit(periph, FALSE);
cam_periph_unhold(periph);
cam_periph_unlock(periph);
cam_periph_release(periph);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
return (error);
}
/*
* Actually translate the requested transfer into one the physical driver
* can understand. The transfer is described by a buf and will include
* only one physical transfer.
*/
static void
sastrategy(struct bio *bp)
{
struct cam_periph *periph;
struct sa_softc *softc;
bp->bio_resid = bp->bio_bcount;
if (SA_IS_CTRL(bp->bio_dev)) {
biofinish(bp, NULL, EINVAL);
return;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
}
periph = (struct cam_periph *)bp->bio_dev->si_drv1;
if (periph == NULL) {
biofinish(bp, NULL, ENXIO);
return;
}
cam_periph_lock(periph);
softc = (struct sa_softc *)periph->softc;
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
if (softc->flags & SA_FLAG_INVALID) {
cam_periph_unlock(periph);
biofinish(bp, NULL, ENXIO);
return;
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (softc->flags & SA_FLAG_TAPE_FROZEN) {
cam_periph_unlock(periph);
biofinish(bp, NULL, EPERM);
return;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
}
/*
* This should actually never occur as the write(2)
* system call traps attempts to write to a read-only
* file descriptor.
*/
if (bp->bio_cmd == BIO_WRITE && softc->open_rdonly) {
cam_periph_unlock(periph);
biofinish(bp, NULL, EBADF);
return;
}
if (softc->open_pending_mount) {
int error = samount(periph, 0, bp->bio_dev);
if (error) {
cam_periph_unlock(periph);
biofinish(bp, NULL, ENXIO);
return;
}
saprevent(periph, PR_PREVENT);
softc->open_pending_mount = 0;
}
/*
* If it's a null transfer, return immediately
*/
if (bp->bio_bcount == 0) {
cam_periph_unlock(periph);
biodone(bp);
return;
}
/* valid request? */
if (softc->flags & SA_FLAG_FIXED) {
/*
* Fixed block device. The byte count must
* be a multiple of our block size.
*/
if (((softc->blk_mask != ~0) &&
((bp->bio_bcount & softc->blk_mask) != 0)) ||
((softc->blk_mask == ~0) &&
((bp->bio_bcount % softc->min_blk) != 0))) {
xpt_print(periph->path, "Invalid request. Fixed block "
"device requests must be a multiple of %d bytes\n",
softc->min_blk);
cam_periph_unlock(periph);
biofinish(bp, NULL, EINVAL);
return;
}
} else if ((bp->bio_bcount > softc->max_blk) ||
(bp->bio_bcount < softc->min_blk) ||
(bp->bio_bcount & softc->blk_mask) != 0) {
xpt_print_path(periph->path);
printf("Invalid request. Variable block "
"device requests must be ");
if (softc->blk_mask != 0) {
printf("a multiple of %d ", (0x1 << softc->blk_gran));
}
printf("between %d and %d bytes\n", softc->min_blk,
softc->max_blk);
cam_periph_unlock(periph);
biofinish(bp, NULL, EINVAL);
return;
}
/*
* Place it at the end of the queue.
*/
bioq_insert_tail(&softc->bio_queue, bp);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->queue_count++;
#if 0
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
("sastrategy: queuing a %ld %s byte %s\n", bp->bio_bcount,
(softc->flags & SA_FLAG_FIXED)? "fixed" : "variable",
(bp->bio_cmd == BIO_READ)? "read" : "write"));
#endif
if (softc->queue_count > 1) {
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
("sastrategy: queue count now %d\n", softc->queue_count));
}
/*
* Schedule ourselves for performing the work.
*/
xpt_schedule(periph, CAM_PRIORITY_NORMAL);
cam_periph_unlock(periph);
return;
}
#define PENDING_MOUNT_CHECK(softc, periph, dev) \
if (softc->open_pending_mount) { \
error = samount(periph, 0, dev); \
if (error) { \
break; \
} \
saprevent(periph, PR_PREVENT); \
softc->open_pending_mount = 0; \
}
static int
saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
{
struct cam_periph *periph;
struct sa_softc *softc;
scsi_space_code spaceop;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
int didlockperiph = 0;
int mode;
int error = 0;
mode = SAMODE(dev);
error = 0; /* shut up gcc */
spaceop = 0; /* shut up gcc */
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return (ENXIO);
cam_periph_lock(periph);
softc = (struct sa_softc *)periph->softc;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
* Check for control mode accesses. We allow MTIOCGET and
* MTIOCERRSTAT (but need to be the only one open in order
* to clear latched status), and MTSETBSIZE, MTSETDNSTY
* and MTCOMP (but need to be the only one accessing this
* device to run those).
*/
if (SA_IS_CTRL(dev)) {
switch (cmd) {
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
case MTIOCGETEOTMODEL:
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
case MTIOCGET:
break;
case MTIOCERRSTAT:
/*
* If the periph isn't already locked, lock it
* so our MTIOCERRSTAT can reset latched error stats.
*
* If the periph is already locked, skip it because
* we're just getting status and it'll be up to the
* other thread that has this device open to do
* an MTIOCERRSTAT that would clear latched status.
*/
if ((periph->flags & CAM_PERIPH_LOCKED) == 0) {
error = cam_periph_hold(periph, PRIBIO|PCATCH);
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
if (error != 0) {
cam_periph_unlock(periph);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
return (error);
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
}
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
didlockperiph = 1;
}
break;
case MTIOCTOP:
{
struct mtop *mt = (struct mtop *) arg;
/*
* Check to make sure it's an OP we can perform
* with no media inserted.
*/
switch (mt->mt_op) {
case MTSETBSIZ:
case MTSETDNSTY:
case MTCOMP:
mt = NULL;
/* FALLTHROUGH */
default:
break;
}
if (mt != NULL) {
break;
}
/* FALLTHROUGH */
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
case MTIOCSETEOTMODEL:
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
* We need to acquire the peripheral here rather
* than at open time because we are sharing writable
* access to data structures.
*/
error = cam_periph_hold(periph, PRIBIO|PCATCH);
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
if (error != 0) {
cam_periph_unlock(periph);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
return (error);
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
}
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
didlockperiph = 1;
break;
default:
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
cam_periph_unlock(periph);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
return (EINVAL);
}
}
/*
* Find the device that the user is talking about
*/
switch (cmd) {
case MTIOCGET:
{
struct mtget *g = (struct mtget *)arg;
/*
* If this isn't the control mode device, actually go out
* and ask the drive again what it's set to.
*/
if (!SA_IS_CTRL(dev) && !softc->open_pending_mount) {
u_int8_t write_protect;
int comp_enabled, comp_supported;
error = sagetparams(periph, SA_PARAM_ALL,
&softc->media_blksize, &softc->media_density,
&softc->media_numblks, &softc->buffer_mode,
&write_protect, &softc->speed, &comp_supported,
&comp_enabled, &softc->comp_algorithm, NULL);
if (error)
break;
if (write_protect)
softc->flags |= SA_FLAG_TAPE_WP;
else
softc->flags &= ~SA_FLAG_TAPE_WP;
softc->flags &= ~(SA_FLAG_COMP_SUPP|
SA_FLAG_COMP_ENABLED|SA_FLAG_COMP_UNSUPP);
if (comp_supported) {
if (softc->saved_comp_algorithm == 0)
softc->saved_comp_algorithm =
softc->comp_algorithm;
softc->flags |= SA_FLAG_COMP_SUPP;
if (comp_enabled)
softc->flags |= SA_FLAG_COMP_ENABLED;
} else
softc->flags |= SA_FLAG_COMP_UNSUPP;
}
bzero(g, sizeof(struct mtget));
g->mt_type = MT_ISAR;
if (softc->flags & SA_FLAG_COMP_UNSUPP) {
g->mt_comp = MT_COMP_UNSUPP;
g->mt_comp0 = MT_COMP_UNSUPP;
g->mt_comp1 = MT_COMP_UNSUPP;
g->mt_comp2 = MT_COMP_UNSUPP;
g->mt_comp3 = MT_COMP_UNSUPP;
} else {
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if ((softc->flags & SA_FLAG_COMP_ENABLED) == 0) {
g->mt_comp = MT_COMP_DISABLED;
} else {
g->mt_comp = softc->comp_algorithm;
}
g->mt_comp0 = softc->comp_algorithm;
g->mt_comp1 = softc->comp_algorithm;
g->mt_comp2 = softc->comp_algorithm;
g->mt_comp3 = softc->comp_algorithm;
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
g->mt_density = softc->media_density;
g->mt_density0 = softc->media_density;
g->mt_density1 = softc->media_density;
g->mt_density2 = softc->media_density;
g->mt_density3 = softc->media_density;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
g->mt_blksiz = softc->media_blksize;
g->mt_blksiz0 = softc->media_blksize;
g->mt_blksiz1 = softc->media_blksize;
g->mt_blksiz2 = softc->media_blksize;
g->mt_blksiz3 = softc->media_blksize;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
g->mt_fileno = softc->fileno;
g->mt_blkno = softc->blkno;
g->mt_dsreg = (short) softc->dsreg;
/*
* Yes, we know that this is likely to overflow
*/
if (softc->last_resid_was_io) {
if ((g->mt_resid = (short) softc->last_io_resid) != 0) {
if (SA_IS_CTRL(dev) == 0 || didlockperiph) {
softc->last_io_resid = 0;
}
}
} else {
if ((g->mt_resid = (short)softc->last_ctl_resid) != 0) {
if (SA_IS_CTRL(dev) == 0 || didlockperiph) {
softc->last_ctl_resid = 0;
}
}
}
error = 0;
break;
}
case MTIOCERRSTAT:
{
struct scsi_tape_errors *sep =
&((union mterrstat *)arg)->scsi_errstat;
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
("saioctl: MTIOCERRSTAT\n"));
bzero(sep, sizeof(*sep));
sep->io_resid = softc->last_io_resid;
bcopy((caddr_t) &softc->last_io_sense, sep->io_sense,
sizeof (sep->io_sense));
bcopy((caddr_t) &softc->last_io_cdb, sep->io_cdb,
sizeof (sep->io_cdb));
sep->ctl_resid = softc->last_ctl_resid;
bcopy((caddr_t) &softc->last_ctl_sense, sep->ctl_sense,
sizeof (sep->ctl_sense));
bcopy((caddr_t) &softc->last_ctl_cdb, sep->ctl_cdb,
sizeof (sep->ctl_cdb));
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if ((SA_IS_CTRL(dev) == 0 && softc->open_pending_mount) ||
didlockperiph)
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
bzero((caddr_t) &softc->errinfo,
sizeof (softc->errinfo));
error = 0;
break;
}
case MTIOCTOP:
{
struct mtop *mt;
int count;
PENDING_MOUNT_CHECK(softc, periph, dev);
mt = (struct mtop *)arg;
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
("saioctl: op=0x%x count=0x%x\n",
mt->mt_op, mt->mt_count));
count = mt->mt_count;
switch (mt->mt_op) {
case MTWEOF: /* write an end-of-file marker */
2000-10-31 22:34:51 +00:00
/*
* We don't need to clear the SA_FLAG_TAPE_WRITTEN
* flag because by keeping track of filemarks
* we have last written we know ehether or not
* we need to write more when we close the device.
*/
error = sawritefilemarks(periph, count, FALSE);
break;
case MTWSS: /* write a setmark */
error = sawritefilemarks(periph, count, TRUE);
break;
case MTBSR: /* backward space record */
case MTFSR: /* forward space record */
case MTBSF: /* backward space file */
case MTFSF: /* forward space file */
case MTBSS: /* backward space setmark */
case MTFSS: /* forward space setmark */
case MTEOD: /* space to end of recorded medium */
{
int nmarks;
spaceop = SS_FILEMARKS;
nmarks = softc->filemarks;
error = sacheckeod(periph);
if (error) {
xpt_print(periph->path,
"EOD check prior to spacing failed\n");
softc->flags |= SA_FLAG_EIO_PENDING;
break;
}
nmarks -= softc->filemarks;
switch(mt->mt_op) {
case MTBSR:
count = -count;
/* FALLTHROUGH */
case MTFSR:
spaceop = SS_BLOCKS;
break;
case MTBSF:
count = -count;
/* FALLTHROUGH */
case MTFSF:
break;
case MTBSS:
count = -count;
/* FALLTHROUGH */
case MTFSS:
spaceop = SS_SETMARKS;
break;
case MTEOD:
spaceop = SS_EOD;
count = 0;
nmarks = 0;
break;
default:
error = EINVAL;
break;
}
if (error)
break;
nmarks = softc->filemarks;
/*
* XXX: Why are we checking again?
*/
error = sacheckeod(periph);
if (error)
break;
nmarks -= softc->filemarks;
error = saspace(periph, count - nmarks, spaceop);
/*
* At this point, clear that we've written the tape
* and that we've written any filemarks. We really
* don't know what the applications wishes to do next-
* the sacheckeod's will make sure we terminated the
* tape correctly if we'd been writing, but the next
* action the user application takes will set again
* whether we need to write filemarks.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->flags &=
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
softc->filemarks = 0;
break;
}
case MTREW: /* rewind */
PENDING_MOUNT_CHECK(softc, periph, dev);
(void) sacheckeod(periph);
error = sarewind(periph);
/* see above */
softc->flags &=
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
softc->flags &= ~SA_FLAG_ERR_PENDING;
softc->filemarks = 0;
break;
case MTERASE: /* erase */
PENDING_MOUNT_CHECK(softc, periph, dev);
error = saerase(periph, count);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->flags &=
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
softc->flags &= ~SA_FLAG_ERR_PENDING;
break;
case MTRETENS: /* re-tension tape */
PENDING_MOUNT_CHECK(softc, periph, dev);
error = saretension(periph);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->flags &=
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
softc->flags &= ~SA_FLAG_ERR_PENDING;
break;
case MTOFFL: /* rewind and put the drive offline */
PENDING_MOUNT_CHECK(softc, periph, dev);
(void) sacheckeod(periph);
/* see above */
softc->flags &= ~SA_FLAG_TAPE_WRITTEN;
softc->filemarks = 0;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
error = sarewind(periph);
/* clear the frozen flag anyway */
softc->flags &= ~SA_FLAG_TAPE_FROZEN;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* Be sure to allow media removal before ejecting.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
saprevent(periph, PR_ALLOW);
if (error == 0) {
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
error = saloadunload(periph, FALSE);
if (error == 0) {
softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
}
}
break;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
case MTNOP: /* no operation, sets status only */
case MTCACHE: /* enable controller cache */
case MTNOCACHE: /* disable controller cache */
error = 0;
break;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
case MTSETBSIZ: /* Set block size for device */
PENDING_MOUNT_CHECK(softc, periph, dev);
error = sasetparams(periph, SA_PARAM_BLOCKSIZE, count,
0, 0, 0);
if (error == 0) {
softc->last_media_blksize =
softc->media_blksize;
softc->media_blksize = count;
if (count) {
softc->flags |= SA_FLAG_FIXED;
if (powerof2(count)) {
softc->blk_shift =
ffs(count) - 1;
softc->blk_mask = count - 1;
} else {
softc->blk_mask = ~0;
softc->blk_shift = 0;
}
/*
* Make the user's desire 'persistent'.
*/
softc->quirks &= ~SA_QUIRK_VARIABLE;
softc->quirks |= SA_QUIRK_FIXED;
} else {
softc->flags &= ~SA_FLAG_FIXED;
if (softc->max_blk == 0) {
softc->max_blk = ~0;
}
softc->blk_shift = 0;
if (softc->blk_gran != 0) {
softc->blk_mask =
softc->blk_gran - 1;
} else {
softc->blk_mask = 0;
}
/*
* Make the user's desire 'persistent'.
*/
softc->quirks |= SA_QUIRK_VARIABLE;
softc->quirks &= ~SA_QUIRK_FIXED;
}
}
break;
case MTSETDNSTY: /* Set density for device and mode */
PENDING_MOUNT_CHECK(softc, periph, dev);
if (count > UCHAR_MAX) {
error = EINVAL;
break;
} else {
error = sasetparams(periph, SA_PARAM_DENSITY,
0, count, 0, 0);
}
break;
case MTCOMP: /* enable compression */
PENDING_MOUNT_CHECK(softc, periph, dev);
/*
* Some devices don't support compression, and
* don't like it if you ask them for the
* compression page.
*/
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if ((softc->quirks & SA_QUIRK_NOCOMP) ||
(softc->flags & SA_FLAG_COMP_UNSUPP)) {
error = ENODEV;
break;
}
error = sasetparams(periph, SA_PARAM_COMPRESSION,
0, 0, count, SF_NO_PRINT);
break;
default:
error = EINVAL;
}
break;
}
case MTIOCIEOT:
case MTIOCEEOT:
error = 0;
break;
case MTIOCRDSPOS:
PENDING_MOUNT_CHECK(softc, periph, dev);
error = sardpos(periph, 0, (u_int32_t *) arg);
break;
case MTIOCRDHPOS:
PENDING_MOUNT_CHECK(softc, periph, dev);
error = sardpos(periph, 1, (u_int32_t *) arg);
break;
case MTIOCSLOCATE:
PENDING_MOUNT_CHECK(softc, periph, dev);
error = sasetpos(periph, 0, (u_int32_t *) arg);
break;
case MTIOCHLOCATE:
PENDING_MOUNT_CHECK(softc, periph, dev);
error = sasetpos(periph, 1, (u_int32_t *) arg);
break;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
case MTIOCGETEOTMODEL:
error = 0;
if (softc->quirks & SA_QUIRK_1FM)
mode = 1;
else
mode = 2;
*((u_int32_t *) arg) = mode;
break;
case MTIOCSETEOTMODEL:
error = 0;
switch (*((u_int32_t *) arg)) {
case 1:
softc->quirks &= ~SA_QUIRK_2FM;
softc->quirks |= SA_QUIRK_1FM;
break;
case 2:
softc->quirks &= ~SA_QUIRK_1FM;
softc->quirks |= SA_QUIRK_2FM;
break;
default:
error = EINVAL;
break;
}
break;
default:
error = cam_periph_ioctl(periph, cmd, arg, saerror);
break;
}
/*
* Check to see if we cleared a frozen state
*/
if (error == 0 && (softc->flags & SA_FLAG_TAPE_FROZEN)) {
switch(cmd) {
case MTIOCRDSPOS:
case MTIOCRDHPOS:
case MTIOCSLOCATE:
case MTIOCHLOCATE:
softc->fileno = (daddr_t) -1;
softc->blkno = (daddr_t) -1;
softc->flags &= ~SA_FLAG_TAPE_FROZEN;
xpt_print(periph->path,
"tape state now unfrozen.\n");
break;
default:
break;
}
}
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (didlockperiph) {
cam_periph_unhold(periph);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
}
cam_periph_unlock(periph);
return (error);
}
static void
sainit(void)
{
cam_status status;
/*
* Install a global async callback.
*/
status = xpt_register_async(AC_FOUND_DEVICE, saasync, NULL, NULL);
if (status != CAM_REQ_CMP) {
printf("sa: Failed to attach master async callback "
"due to status 0x%x!\n", status);
}
}
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
static void
saoninvalidate(struct cam_periph *periph)
{
struct sa_softc *softc;
softc = (struct sa_softc *)periph->softc;
/*
* De-register any async callbacks.
*/
xpt_register_async(0, saasync, periph, periph->path);
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
softc->flags |= SA_FLAG_INVALID;
/*
* Return all queued I/O with ENXIO.
* XXX Handle any transactions queued to the card
* with XPT_ABORT_CCB.
*/
bioq_flush(&softc->bio_queue, NULL, ENXIO);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->queue_count = 0;
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
}
static void
sacleanup(struct cam_periph *periph)
{
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
struct sa_softc *softc;
int i;
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
softc = (struct sa_softc *)periph->softc;
devstat_remove_entry(softc->device_stats);
cam_periph_unlock(periph);
destroy_dev(softc->devs.ctl_dev);
for (i = 0; i < SA_NUM_MODES; i++) {
destroy_dev(softc->devs.mode_devs[i].r_dev);
destroy_dev(softc->devs.mode_devs[i].nr_dev);
destroy_dev(softc->devs.mode_devs[i].er_dev);
}
cam_periph_lock(periph);
free(softc, M_SCSISA);
}
static void
saasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg)
{
struct cam_periph *periph;
periph = (struct cam_periph *)callback_arg;
switch (code) {
case AC_FOUND_DEVICE:
{
struct ccb_getdev *cgd;
cam_status status;
cgd = (struct ccb_getdev *)arg;
if (cgd == NULL)
break;
Separate the parallel scsi knowledge out of the core of the XPT, and modularize it so that new transports can be created. Add a transport for SATA Add a periph+protocol layer for ATA Add a driver for AHCI-compliant hardware. Add a maxio field to CAM so that drivers can advertise their max I/O capability. Modify various drivers so that they are insulated from the value of MAXPHYS. The new ATA/SATA code supports AHCI-compliant hardware, and will override the classic ATA driver if it is loaded as a module at boot time or compiled into the kernel. The stack now support NCQ (tagged queueing) for increased performance on modern SATA drives. It also supports port multipliers. ATA drives are accessed via 'ada' device nodes. ATAPI drives are accessed via 'cd' device nodes. They can all be enumerated and manipulated via camcontrol, just like SCSI drives. SCSI commands are not translated to their ATA equivalents; ATA native commands are used throughout the entire stack, including camcontrol. See the camcontrol manpage for further details. Testing this code may require that you update your fstab, and possibly modify your BIOS to enable AHCI functionality, if available. This code is very experimental at the moment. The userland ABI/API has changed, so applications will need to be recompiled. It may change further in the near future. The 'ada' device name may also change as more infrastructure is completed in this project. The goal is to eventually put all CAM busses and devices until newbus, allowing for interesting topology and management options. Few functional changes will be seen with existing SCSI/SAS/FC drivers, though the userland ABI has still changed. In the future, transports specific modules for SAS and FC may appear in order to better support the topologies and capabilities of these technologies. The modularization of CAM and the addition of the ATA/SATA modules is meant to break CAM out of the mold of being specific to SCSI, letting it grow to be a framework for arbitrary transports and protocols. It also allows drivers to be written to support discrete hardware without jeopardizing the stability of non-related hardware. While only an AHCI driver is provided now, a Silicon Image driver is also in the works. Drivers for ICH1-4, ICH5-6, PIIX, classic IDE, and any other hardware is possible and encouraged. Help with new transports is also encouraged. Submitted by: scottl, mav Approved by: re
2009-07-10 08:18:08 +00:00
if (cgd->protocol != PROTO_SCSI)
break;
if (SID_TYPE(&cgd->inq_data) != T_SEQUENTIAL)
break;
/*
* Allocate a peripheral instance for
* this device and start the probe
* process.
*/
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
status = cam_periph_alloc(saregister, saoninvalidate,
sacleanup, sastart,
Merge CAM locking changes from the projects/camlock branch to radically reduce lock congestion and improve SMP scalability of the SCSI/ATA stack, preparing the ground for the coming next GEOM direct dispatch support. Replace big per-SIM locks with bunch of smaller ones: - per-LUN locks to protect device and peripheral drivers state; - per-target locks to protect list of LUNs on target; - per-bus locks to protect reference counting; - per-send queue locks to protect queue of CCBs to be sent; - per-done queue locks to protect queue of completed CCBs; - remaining per-SIM locks now protect only HBA driver internals. While holding LUN lock it is allowed (while not recommended for performance reasons) to take SIM lock. The opposite acquisition order is forbidden. All the other locks are leaf locks, that can be taken anywhere, but should not be cascaded. Many functions, such as: xpt_action(), xpt_done(), xpt_async(), xpt_create_path(), etc. are no longer require (but allow) SIM lock to be held. To keep compatibility and solve cases where SIM lock can't be dropped, all xpt_async() calls in addition to xpt_done() calls are queued to completion threads for async processing in clean environment without SIM lock held. Instead of single CAM SWI thread, used for commands completion processing before, use multiple (depending on number of CPUs) threads. Load balanced between them using "hash" of the device B:T:L address. HBA drivers that can drop SIM lock during completion processing and have sufficient number of completion threads to efficiently scale to multiple CPUs can use new function xpt_done_direct() to avoid extra context switch. Make ahci(4) driver to use this mechanism depending on hardware setup. Sponsored by: iXsystems, Inc. MFC after: 2 months
2013-10-21 12:00:26 +00:00
"sa", CAM_PERIPH_BIO, path,
saasync, AC_FOUND_DEVICE, cgd);
if (status != CAM_REQ_CMP
&& status != CAM_REQ_INPROG)
printf("saasync: Unable to probe new device "
"due to status 0x%x\n", status);
break;
}
default:
cam_periph_async(periph, code, path, arg);
break;
}
}
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
static void
sasysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct sa_softc *softc;
char tmpstr[80], tmpstr2[80];
periph = (struct cam_periph *)context;
/*
* If the periph is invalid, no need to setup the sysctls.
*/
if (periph->flags & CAM_PERIPH_INVALID)
goto bailout;
softc = (struct sa_softc *)periph->softc;
snprintf(tmpstr, sizeof(tmpstr), "CAM SA unit %d", periph->unit_number);
snprintf(tmpstr2, sizeof(tmpstr2), "%u", periph->unit_number);
sysctl_ctx_init(&softc->sysctl_ctx);
softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
SYSCTL_STATIC_CHILDREN(_kern_cam_sa), OID_AUTO, tmpstr2,
CTLFLAG_RD, 0, tmpstr);
if (softc->sysctl_tree == NULL)
goto bailout;
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "allow_io_split", CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
&softc->allow_io_split, 0, "Allow Splitting I/O");
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "maxio", CTLFLAG_RD,
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
&softc->maxio, 0, "Maximum I/O size");
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "cpi_maxio", CTLFLAG_RD,
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
&softc->cpi_maxio, 0, "Maximum Controller I/O size");
bailout:
/*
* Release the reference that was held when this task was enqueued.
*/
cam_periph_release(periph);
}
static cam_status
saregister(struct cam_periph *periph, void *arg)
{
struct sa_softc *softc;
struct ccb_getdev *cgd;
struct ccb_pathinq cpi;
caddr_t match;
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
char tmpstr[80];
int i;
cgd = (struct ccb_getdev *)arg;
if (cgd == NULL) {
printf("saregister: no getdev CCB, can't register device\n");
return (CAM_REQ_CMP_ERR);
}
softc = (struct sa_softc *)
malloc(sizeof (*softc), M_SCSISA, M_NOWAIT | M_ZERO);
if (softc == NULL) {
printf("saregister: Unable to probe new device. "
"Unable to allocate softc\n");
return (CAM_REQ_CMP_ERR);
}
softc->scsi_rev = SID_ANSI_REV(&cgd->inq_data);
softc->state = SA_STATE_NORMAL;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->fileno = (daddr_t) -1;
softc->blkno = (daddr_t) -1;
bioq_init(&softc->bio_queue);
periph->softc = softc;
/*
* See if this device has any quirks.
*/
match = cam_quirkmatch((caddr_t)&cgd->inq_data,
(caddr_t)sa_quirk_table,
sizeof(sa_quirk_table)/sizeof(*sa_quirk_table),
sizeof(*sa_quirk_table), scsi_inquiry_match);
if (match != NULL) {
softc->quirks = ((struct sa_quirk_entry *)match)->quirks;
softc->last_media_blksize =
((struct sa_quirk_entry *)match)->prefblk;
} else
softc->quirks = SA_QUIRK_NONE;
bzero(&cpi, sizeof(cpi));
xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
cpi.ccb_h.func_code = XPT_PATH_INQ;
xpt_action((union ccb *)&cpi);
/*
* The SA driver supports a blocksize, but we don't know the
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
* blocksize until we media is inserted. So, set a flag to
* indicate that the blocksize is unavailable right now.
*/
cam_periph_unlock(periph);
softc->device_stats = devstat_new_entry("sa", periph->unit_number, 0,
DEVSTAT_BS_UNAVAILABLE, SID_TYPE(&cgd->inq_data) |
XPORT_DEVSTAT_TYPE(cpi.transport), DEVSTAT_PRIORITY_TAPE);
/*
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
* Load the default value that is either compiled in, or loaded
* in the global kern.cam.sa.allow_io_split tunable.
*/
softc->allow_io_split = sa_allow_io_split;
/*
* Load a per-instance tunable, if it exists. NOTE that this
* tunable WILL GO AWAY in FreeBSD 11.0.
*/
snprintf(tmpstr, sizeof(tmpstr), "kern.cam.sa.%u.allow_io_split",
periph->unit_number);
TUNABLE_INT_FETCH(tmpstr, &softc->allow_io_split);
/*
* If maxio isn't set, we fall back to DFLTPHYS. Otherwise we take
* the smaller of cpi.maxio or MAXPHYS.
*/
if (cpi.maxio == 0)
softc->maxio = DFLTPHYS;
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
else if (cpi.maxio > MAXPHYS)
softc->maxio = MAXPHYS;
else
softc->maxio = cpi.maxio;
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
/*
* Record the controller's maximum I/O size so we can report it to
* the user later.
*/
softc->cpi_maxio = cpi.maxio;
/*
* By default we tell physio that we do not want our I/O split.
* The user needs to have a 1:1 mapping between the size of his
* write to a tape character device and the size of the write
* that actually goes down to the drive.
*/
if (softc->allow_io_split == 0)
softc->si_flags = SI_NOSPLIT;
else
softc->si_flags = 0;
TASK_INIT(&softc->sysctl_task, 0, sasysctlinit, periph);
/*
* If the SIM supports unmapped I/O, let physio know that we can
* handle unmapped buffers.
*/
if (cpi.hba_misc & PIM_UNMAPPED)
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
softc->si_flags |= SI_UNMAPPED;
softc->devs.ctl_dev = make_dev(&sa_cdevsw, SAMINOR(SA_CTLDEV,
0, SA_ATYPE_R), UID_ROOT, GID_OPERATOR,
0660, "%s%d.ctl", periph->periph_name, periph->unit_number);
softc->devs.ctl_dev->si_drv1 = periph;
softc->devs.ctl_dev->si_iosize_max = softc->maxio;
softc->devs.ctl_dev->si_flags |= softc->si_flags;
for (i = 0; i < SA_NUM_MODES; i++) {
softc->devs.mode_devs[i].r_dev = make_dev(&sa_cdevsw,
SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_R),
UID_ROOT, GID_OPERATOR, 0660, "%s%d.%d",
periph->periph_name, periph->unit_number, i);
softc->devs.mode_devs[i].r_dev->si_drv1 = periph;
softc->devs.mode_devs[i].r_dev->si_iosize_max = softc->maxio;
softc->devs.mode_devs[i].r_dev->si_flags |= softc->si_flags;
softc->devs.mode_devs[i].nr_dev = make_dev(&sa_cdevsw,
SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_NR),
UID_ROOT, GID_OPERATOR, 0660, "n%s%d.%d",
periph->periph_name, periph->unit_number, i);
softc->devs.mode_devs[i].nr_dev->si_drv1 = periph;
softc->devs.mode_devs[i].nr_dev->si_iosize_max = softc->maxio;
softc->devs.mode_devs[i].nr_dev->si_flags |= softc->si_flags;
softc->devs.mode_devs[i].er_dev = make_dev(&sa_cdevsw,
SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_ER),
UID_ROOT, GID_OPERATOR, 0660, "e%s%d.%d",
periph->periph_name, periph->unit_number, i);
softc->devs.mode_devs[i].er_dev->si_drv1 = periph;
softc->devs.mode_devs[i].er_dev->si_iosize_max = softc->maxio;
softc->devs.mode_devs[i].er_dev->si_flags |= softc->si_flags;
/*
* Make the (well known) aliases for the first mode.
*/
if (i == 0) {
struct cdev *alias;
alias = make_dev_alias(softc->devs.mode_devs[i].r_dev,
"%s%d", periph->periph_name, periph->unit_number);
alias->si_drv1 = periph;
alias->si_iosize_max = softc->maxio;
alias->si_flags |= softc->si_flags;
alias = make_dev_alias(softc->devs.mode_devs[i].nr_dev,
"n%s%d", periph->periph_name, periph->unit_number);
alias->si_drv1 = periph;
alias->si_iosize_max = softc->maxio;
alias->si_flags |= softc->si_flags;
alias = make_dev_alias(softc->devs.mode_devs[i].er_dev,
"e%s%d", periph->periph_name, periph->unit_number);
alias->si_drv1 = periph;
alias->si_iosize_max = softc->maxio;
alias->si_flags |= softc->si_flags;
}
}
2007-04-19 18:14:33 +00:00
cam_periph_lock(periph);
Add support to physio(9) for devices that don't want I/O split and configure sa(4) to request no I/O splitting by default. For tape devices, the user needs to be able to clearly understand what blocksize is actually being used when writing to a tape device. The previous behavior of physio(9) was that it would split up any I/O that was too large for the device, or too large to fit into MAXPHYS. This means that if, for instance, the user wrote a 1MB block to a tape device, and MAXPHYS was 128KB, the 1MB write would be split into 8 128K chunks. This would be done without informing the user. This has suboptimal effects, especially when trying to communicate status to the user. In the event of an error writing to a tape (e.g. physical end of tape) in the middle of a 1MB block that has been split into 8 pieces, the user could have the first two 128K pieces written successfully, the third returned with an error, and the last 5 returned with 0 bytes written. If the user is using a standard write(2) system call, all he will see is the ENOSPC error. He won't have a clue how much actually got written. (With a writev(2) system call, he should be able to determine how much got written in addition to the error.) The solution is to prevent physio(9) from splitting the I/O. The new cdev flag, SI_NOSPLIT, tells physio that the driver does not want I/O to be split beforehand. Although the sa(4) driver now enables SI_NOSPLIT by default, that can be disabled by two loader tunables for now. It will not be configurable starting in FreeBSD 11.0. kern.cam.sa.allow_io_split allows the user to configure I/O splitting for all sa(4) driver instances. kern.cam.sa.%d.allow_io_split allows the user to configure I/O splitting for a specific sa(4) instance. There are also now three sa(4) driver sysctl variables that let the users see some sa(4) driver values. kern.cam.sa.%d.allow_io_split shows whether I/O splitting is turned on. kern.cam.sa.%d.maxio shows the maximum I/O size allowed by kernel configuration parameters (e.g. MAXPHYS, DFLTPHYS) and the capabilities of the controller. kern.cam.sa.%d.cpi_maxio shows the maximum I/O size supported by the controller. Note that a better long term solution would be to implement support for chaining buffers, so that that MAXPHYS is no longer a limiting factor for I/O size to tape and disk devices. At that point, the controller and the tape drive would become the limiting factors. sys/conf.h: Add a new cdev flag, SI_NOSPLIT, that allows a driver to tell physio not to split up I/O. sys/param.h: Bump __FreeBSD_version to 1000049 for the addition of the SI_NOSPLIT cdev flag. kern_physio.c: If the SI_NOSPLIT flag is set on the cdev, return any I/O that is larger than si_iosize_max or MAXPHYS, has more than one segment, or would have to be split because of misalignment with EFBIG. (File too large). In the event of an error, print a console message to give the user a clue about what happened. scsi_sa.c: Set the SI_NOSPLIT cdev flag on the devices created for the sa(4) driver by default. Add tunables to control whether we allow I/O splitting in physio(9). Explain in the comments that allowing I/O splitting will be deprecated for the sa(4) driver in FreeBSD 11.0. Add sysctl variables to display the maximum I/O size we can do (which could be further limited by read block limits) and the maximum I/O size that the controller can do. Limit our maximum I/O size (recorded in the cdev's si_iosize_max) by MAXPHYS. This isn't strictly necessary, because physio(9) will limit it to MAXPHYS, but it will provide some clarity for the application. Record the controller's maximum I/O size reported in the Path Inquiry CCB. sa.4: Document the block size behavior, and explain that the option of allowing physio(9) to split the I/O will disappear in FreeBSD 11.0. Sponsored by: Spectra Logic
2013-08-24 04:52:22 +00:00
/*
* Bump the peripheral refcount for the sysctl thread, in case we
* get invalidated before the thread has a chance to run.
*/
cam_periph_acquire(periph);
taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task);
/*
* Add an async callback so that we get
* notified if this device goes away.
*/
xpt_register_async(AC_LOST_DEVICE, saasync, periph, periph->path);
xpt_announce_periph(periph, NULL);
xpt_announce_quirks(periph, softc->quirks, SA_QUIRK_BIT_STRING);
return (CAM_REQ_CMP);
}
static void
sastart(struct cam_periph *periph, union ccb *start_ccb)
{
struct sa_softc *softc;
softc = (struct sa_softc *)periph->softc;
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sastart\n"));
switch (softc->state) {
case SA_STATE_NORMAL:
{
/* Pull a buffer from the queue and get going on it */
struct bio *bp;
/*
* See if there is a buf with work for us to do..
*/
bp = bioq_first(&softc->bio_queue);
Merge CAM locking changes from the projects/camlock branch to radically reduce lock congestion and improve SMP scalability of the SCSI/ATA stack, preparing the ground for the coming next GEOM direct dispatch support. Replace big per-SIM locks with bunch of smaller ones: - per-LUN locks to protect device and peripheral drivers state; - per-target locks to protect list of LUNs on target; - per-bus locks to protect reference counting; - per-send queue locks to protect queue of CCBs to be sent; - per-done queue locks to protect queue of completed CCBs; - remaining per-SIM locks now protect only HBA driver internals. While holding LUN lock it is allowed (while not recommended for performance reasons) to take SIM lock. The opposite acquisition order is forbidden. All the other locks are leaf locks, that can be taken anywhere, but should not be cascaded. Many functions, such as: xpt_action(), xpt_done(), xpt_async(), xpt_create_path(), etc. are no longer require (but allow) SIM lock to be held. To keep compatibility and solve cases where SIM lock can't be dropped, all xpt_async() calls in addition to xpt_done() calls are queued to completion threads for async processing in clean environment without SIM lock held. Instead of single CAM SWI thread, used for commands completion processing before, use multiple (depending on number of CPUs) threads. Load balanced between them using "hash" of the device B:T:L address. HBA drivers that can drop SIM lock during completion processing and have sufficient number of completion threads to efficiently scale to multiple CPUs can use new function xpt_done_direct() to avoid extra context switch. Make ahci(4) driver to use this mechanism depending on hardware setup. Sponsored by: iXsystems, Inc. MFC after: 2 months
2013-10-21 12:00:26 +00:00
if (bp == NULL) {
xpt_release_ccb(start_ccb);
} else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) {
struct bio *done_bp;
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
again:
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->queue_count--;
bioq_remove(&softc->bio_queue, bp);
bp->bio_resid = bp->bio_bcount;
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
done_bp = bp;
if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) {
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
/*
* We now just clear errors in this case
* and let the residual be the notifier.
*/
bp->bio_error = 0;
} else if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) {
/*
* This can only happen if we're reading
* in fixed length mode. In this case,
* we dump the rest of the list the
* same way.
*/
bp->bio_error = 0;
if (bioq_first(&softc->bio_queue) != NULL) {
biodone(done_bp);
goto again;
}
} else if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) {
bp->bio_error = EIO;
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
bp->bio_flags |= BIO_ERROR;
}
bp = bioq_first(&softc->bio_queue);
/*
* Only if we have no other buffers queued up
* do we clear the pending error flag.
*/
if (bp == NULL)
softc->flags &= ~SA_FLAG_ERR_PENDING;
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
("sastart- ERR_PENDING now 0x%x, bp is %sNULL, "
"%d more buffers queued up\n",
(softc->flags & SA_FLAG_ERR_PENDING),
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
(bp != NULL)? "not " : " ", softc->queue_count));
xpt_release_ccb(start_ccb);
biodone(done_bp);
} else {
u_int32_t length;
bioq_remove(&softc->bio_queue, bp);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->queue_count--;
if ((softc->flags & SA_FLAG_FIXED) != 0) {
if (softc->blk_shift != 0) {
length =
bp->bio_bcount >> softc->blk_shift;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
} else if (softc->media_blksize != 0) {
length = bp->bio_bcount /
softc->media_blksize;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
} else {
bp->bio_error = EIO;
xpt_print(periph->path, "zero blocksize"
" for FIXED length writes?\n");
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
biodone(bp);
break;
}
#if 0
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
("issuing a %d fixed record %s\n",
length, (bp->bio_cmd == BIO_READ)? "read" :
"write"));
#endif
} else {
length = bp->bio_bcount;
#if 0
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
("issuing a %d variable byte %s\n",
length, (bp->bio_cmd == BIO_READ)? "read" :
"write"));
#endif
}
devstat_start_transaction_bio(softc->device_stats, bp);
/*
* Some people have theorized that we should
* suppress illegal length indication if we are
* running in variable block mode so that we don't
* have to request sense every time our requested
* block size is larger than the written block.
* The residual information from the ccb allows
* us to identify this situation anyway. The only
* problem with this is that we will not get
* information about blocks that are larger than
* our read buffer unless we set the block size
* in the mode page to something other than 0.
*
* I believe that this is a non-issue. If user apps
* don't adjust their read size to match our record
* size, that's just life. Anyway, the typical usage
* would be to issue, e.g., 64KB reads and occasionally
* have to do deal with 512 byte or 1KB intermediate
* records.
*/
softc->dsreg = (bp->bio_cmd == BIO_READ)?
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
MTIO_DSREG_RD : MTIO_DSREG_WR;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
scsi_sa_read_write(&start_ccb->csio, 0, sadone,
MSG_SIMPLE_Q_TAG, (bp->bio_cmd == BIO_READ ?
SCSI_RW_READ : SCSI_RW_WRITE) |
((bp->bio_flags & BIO_UNMAPPED) != 0 ?
SCSI_RW_BIO : 0), FALSE,
(softc->flags & SA_FLAG_FIXED) != 0, length,
(bp->bio_flags & BIO_UNMAPPED) != 0 ? (void *)bp :
bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE,
IO_TIMEOUT);
start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED;
start_ccb->ccb_h.ccb_bp = bp;
bp = bioq_first(&softc->bio_queue);
xpt_action(start_ccb);
}
if (bp != NULL) {
/* Have more work to do, so ensure we stay scheduled */
xpt_schedule(periph, CAM_PRIORITY_NORMAL);
}
break;
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
case SA_STATE_ABNORMAL:
default:
panic("state 0x%x in sastart", softc->state);
break;
}
}
static void
sadone(struct cam_periph *periph, union ccb *done_ccb)
{
struct sa_softc *softc;
struct ccb_scsiio *csio;
struct bio *bp;
int error;
softc = (struct sa_softc *)periph->softc;
csio = &done_ccb->csio;
softc->dsreg = MTIO_DSREG_REST;
bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
error = 0;
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if ((error = saerror(done_ccb, 0, 0)) == ERESTART) {
/*
* A retry was scheduled, so just return.
*/
return;
}
}
if (error == EIO) {
/*
* Catastrophic error. Mark the tape as frozen
* (we no longer know tape position).
*
* Return all queued I/O with EIO, and unfreeze
* our queue so that future transactions that
* attempt to fix this problem can get to the
* device.
*
*/
softc->flags |= SA_FLAG_TAPE_FROZEN;
bioq_flush(&softc->bio_queue, NULL, EIO);
}
if (error != 0) {
bp->bio_resid = bp->bio_bcount;
bp->bio_error = error;
bp->bio_flags |= BIO_ERROR;
/*
* In the error case, position is updated in saerror.
*/
} else {
bp->bio_resid = csio->resid;
bp->bio_error = 0;
if (csio->resid != 0) {
bp->bio_flags |= BIO_ERROR;
}
if (bp->bio_cmd == BIO_WRITE) {
softc->flags |= SA_FLAG_TAPE_WRITTEN;
softc->filemarks = 0;
}
if (!(csio->ccb_h.ccb_pflags & SA_POSITION_UPDATED) &&
(softc->blkno != (daddr_t) -1)) {
if ((softc->flags & SA_FLAG_FIXED) != 0) {
u_int32_t l;
if (softc->blk_shift != 0) {
l = bp->bio_bcount >>
softc->blk_shift;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
} else {
l = bp->bio_bcount /
softc->media_blksize;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
}
softc->blkno += (daddr_t) l;
} else {
softc->blkno++;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
}
}
}
/*
* If we had an error (immediate or pending),
* release the device queue now.
*/
if (error || (softc->flags & SA_FLAG_ERR_PENDING))
cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0);
if (error || bp->bio_resid) {
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
("error %d resid %ld count %ld\n", error,
bp->bio_resid, bp->bio_bcount));
}
biofinish(bp, softc->device_stats, 0);
xpt_release_ccb(done_ccb);
}
/*
* Mount the tape (make sure it's ready for I/O).
*/
static int
samount(struct cam_periph *periph, int oflags, struct cdev *dev)
{
struct sa_softc *softc;
union ccb *ccb;
int error;
/*
* oflags can be checked for 'kind' of open (read-only check) - later
* dev can be checked for a control-mode or compression open - later
*/
UNUSED_PARAMETER(oflags);
UNUSED_PARAMETER(dev);
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* This should determine if something has happend since the last
* open/mount that would invalidate the mount. We do *not* want
* to retry this command- we just want the status. But we only
* do this if we're mounted already- if we're not mounted,
* we don't care about the unit read state and can instead use
* this opportunity to attempt to reserve the tape unit.
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
*/
if (softc->flags & SA_FLAG_TAPE_MOUNTED) {
ccb = cam_periph_getccb(periph, 1);
scsi_test_unit_ready(&ccb->csio, 0, sadone,
MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, IO_TIMEOUT);
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
softc->device_stats);
if (error == ENXIO) {
softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
scsi_test_unit_ready(&ccb->csio, 0, sadone,
MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, IO_TIMEOUT);
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
softc->device_stats);
} else if (error) {
/*
* We don't need to freeze the tape because we
* will now attempt to rewind/load it.
*/
softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
xpt_print(periph->path,
"error %d on TUR in samount\n", error);
}
}
} else {
error = sareservereleaseunit(periph, TRUE);
if (error) {
return (error);
}
ccb = cam_periph_getccb(periph, 1);
scsi_test_unit_ready(&ccb->csio, 0, sadone,
MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, IO_TIMEOUT);
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
softc->device_stats);
}
if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) {
struct scsi_read_block_limits_data *rblim = NULL;
int comp_enabled, comp_supported;
u_int8_t write_protect, guessing = 0;
/*
* Clear out old state.
*/
softc->flags &= ~(SA_FLAG_TAPE_WP|SA_FLAG_TAPE_WRITTEN|
SA_FLAG_ERR_PENDING|SA_FLAG_COMP_ENABLED|
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
SA_FLAG_COMP_SUPP|SA_FLAG_COMP_UNSUPP);
softc->filemarks = 0;
/*
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
* *Very* first off, make sure we're loaded to BOT.
*/
scsi_load_unload(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE,
FALSE, FALSE, 1, SSD_FULL_SIZE, REWIND_TIMEOUT);
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
* In case this doesn't work, do a REWIND instead
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
*/
if (error) {
scsi_rewind(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG,
FALSE, SSD_FULL_SIZE, REWIND_TIMEOUT);
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
}
if (error) {
xpt_release_ccb(ccb);
goto exit;
}
/*
* Do a dummy test read to force access to the
* media so that the drive will really know what's
* there. We actually don't really care what the
* blocksize on tape is and don't expect to really
* read a full record.
*/
rblim = (struct scsi_read_block_limits_data *)
malloc(8192, M_SCSISA, M_NOWAIT);
if (rblim == NULL) {
xpt_print(periph->path, "no memory for test read\n");
xpt_release_ccb(ccb);
error = ENOMEM;
goto exit;
}
if ((softc->quirks & SA_QUIRK_NODREAD) == 0) {
scsi_sa_read_write(&ccb->csio, 0, sadone,
MSG_SIMPLE_Q_TAG, 1, FALSE, 0, 8192,
(void *) rblim, 8192, SSD_FULL_SIZE,
IO_TIMEOUT);
(void) cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
softc->device_stats);
scsi_rewind(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG,
FALSE, SSD_FULL_SIZE, REWIND_TIMEOUT);
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
error = cam_periph_runccb(ccb, saerror, CAM_RETRY_SELTO,
SF_NO_PRINT | SF_RETRY_UA,
softc->device_stats);
if (error) {
xpt_print(periph->path,
"unable to rewind after test read\n");
xpt_release_ccb(ccb);
goto exit;
}
}
/*
* Next off, determine block limits.
*/
scsi_read_block_limits(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG,
rblim, SSD_FULL_SIZE, SCSIOP_TIMEOUT);
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
error = cam_periph_runccb(ccb, saerror, CAM_RETRY_SELTO,
SF_NO_PRINT | SF_RETRY_UA, softc->device_stats);
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
xpt_release_ccb(ccb);
if (error != 0) {
/*
* If it's less than SCSI-2, READ BLOCK LIMITS is not
* a MANDATORY command. Anyway- it doesn't matter-
* we can proceed anyway.
*/
softc->blk_gran = 0;
softc->max_blk = ~0;
softc->min_blk = 0;
} else {
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
if (softc->scsi_rev >= SCSI_REV_SPC) {
softc->blk_gran = RBL_GRAN(rblim);
} else {
softc->blk_gran = 0;
}
/*
* We take max_blk == min_blk to mean a default to
* fixed mode- but note that whatever we get out of
* sagetparams below will actually determine whether
* we are actually *in* fixed mode.
*/
softc->max_blk = scsi_3btoul(rblim->maximum);
softc->min_blk = scsi_2btoul(rblim->minimum);
}
/*
* Next, perform a mode sense to determine
* current density, blocksize, compression etc.
*/
error = sagetparams(periph, SA_PARAM_ALL,
&softc->media_blksize,
&softc->media_density,
&softc->media_numblks,
&softc->buffer_mode, &write_protect,
&softc->speed, &comp_supported,
&comp_enabled, &softc->comp_algorithm,
NULL);
if (error != 0) {
/*
* We could work a little harder here. We could
* adjust our attempts to get information. It
* might be an ancient tape drive. If someone
* nudges us, we'll do that.
*/
goto exit;
}
/*
* If no quirk has determined that this is a device that is
* preferred to be in fixed or variable mode, now is the time
* to find out.
*/
if ((softc->quirks & (SA_QUIRK_FIXED|SA_QUIRK_VARIABLE)) == 0) {
guessing = 1;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
* This could be expensive to find out. Luckily we
* only need to do this once. If we start out in
* 'default' mode, try and set ourselves to one
* of the densities that would determine a wad
* of other stuff. Go from highest to lowest.
*/
if (softc->media_density == SCSI_DEFAULT_DENSITY) {
int i;
static u_int8_t ctry[] = {
SCSI_DENSITY_HALFINCH_PE,
SCSI_DENSITY_HALFINCH_6250C,
SCSI_DENSITY_HALFINCH_6250,
SCSI_DENSITY_HALFINCH_1600,
SCSI_DENSITY_HALFINCH_800,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
SCSI_DENSITY_QIC_4GB,
SCSI_DENSITY_QIC_2GB,
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
SCSI_DENSITY_QIC_525_320,
SCSI_DENSITY_QIC_150,
SCSI_DENSITY_QIC_120,
SCSI_DENSITY_QIC_24,
SCSI_DENSITY_QIC_11_9TRK,
SCSI_DENSITY_QIC_11_4TRK,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
SCSI_DENSITY_QIC_1320,
SCSI_DENSITY_QIC_3080,
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
0
};
for (i = 0; ctry[i]; i++) {
error = sasetparams(periph,
SA_PARAM_DENSITY, 0, ctry[i],
0, SF_NO_PRINT);
if (error == 0) {
softc->media_density = ctry[i];
break;
}
}
}
switch (softc->media_density) {
case SCSI_DENSITY_QIC_11_4TRK:
case SCSI_DENSITY_QIC_11_9TRK:
case SCSI_DENSITY_QIC_24:
case SCSI_DENSITY_QIC_120:
case SCSI_DENSITY_QIC_150:
case SCSI_DENSITY_QIC_525_320:
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
case SCSI_DENSITY_QIC_1320:
case SCSI_DENSITY_QIC_3080:
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->quirks &= ~SA_QUIRK_2FM;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->quirks |= SA_QUIRK_FIXED|SA_QUIRK_1FM;
softc->last_media_blksize = 512;
break;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
case SCSI_DENSITY_QIC_4GB:
case SCSI_DENSITY_QIC_2GB:
softc->quirks &= ~SA_QUIRK_2FM;
softc->quirks |= SA_QUIRK_FIXED|SA_QUIRK_1FM;
softc->last_media_blksize = 1024;
break;
default:
softc->last_media_blksize =
softc->media_blksize;
softc->quirks |= SA_QUIRK_VARIABLE;
break;
}
}
/*
* If no quirk has determined that this is a device that needs
* to have 2 Filemarks at EOD, now is the time to find out.
*/
if ((softc->quirks & SA_QUIRK_2FM) == 0) {
switch (softc->media_density) {
case SCSI_DENSITY_HALFINCH_800:
case SCSI_DENSITY_HALFINCH_1600:
case SCSI_DENSITY_HALFINCH_6250:
case SCSI_DENSITY_HALFINCH_6250C:
case SCSI_DENSITY_HALFINCH_PE:
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->quirks &= ~SA_QUIRK_1FM;
softc->quirks |= SA_QUIRK_2FM;
break;
default:
break;
}
}
/*
* Now validate that some info we got makes sense.
*/
if ((softc->max_blk < softc->media_blksize) ||
(softc->min_blk > softc->media_blksize &&
softc->media_blksize)) {
xpt_print(periph->path,
"BLOCK LIMITS (%d..%d) could not match current "
"block settings (%d)- adjusting\n", softc->min_blk,
softc->max_blk, softc->media_blksize);
softc->max_blk = softc->min_blk =
softc->media_blksize;
}
/*
* Now put ourselves into the right frame of mind based
* upon quirks...
*/
tryagain:
/*
* If we want to be in FIXED mode and our current blocksize
* is not equal to our last blocksize (if nonzero), try and
* set ourselves to this last blocksize (as the 'preferred'
* block size). The initial quirkmatch at registry sets the
* initial 'last' blocksize. If, for whatever reason, this
* 'last' blocksize is zero, set the blocksize to 512,
* or min_blk if that's larger.
*/
if ((softc->quirks & SA_QUIRK_FIXED) &&
(softc->quirks & SA_QUIRK_NO_MODESEL) == 0 &&
(softc->media_blksize != softc->last_media_blksize)) {
softc->media_blksize = softc->last_media_blksize;
if (softc->media_blksize == 0) {
softc->media_blksize = 512;
if (softc->media_blksize < softc->min_blk) {
softc->media_blksize = softc->min_blk;
}
}
error = sasetparams(periph, SA_PARAM_BLOCKSIZE,
softc->media_blksize, 0, 0, SF_NO_PRINT);
if (error) {
xpt_print(periph->path,
"unable to set fixed blocksize to %d\n",
softc->media_blksize);
goto exit;
}
}
if ((softc->quirks & SA_QUIRK_VARIABLE) &&
(softc->media_blksize != 0)) {
softc->last_media_blksize = softc->media_blksize;
softc->media_blksize = 0;
error = sasetparams(periph, SA_PARAM_BLOCKSIZE,
0, 0, 0, SF_NO_PRINT);
if (error) {
/*
* If this fails and we were guessing, just
* assume that we got it wrong and go try
* fixed block mode. Don't even check against
* density code at this point.
*/
if (guessing) {
softc->quirks &= ~SA_QUIRK_VARIABLE;
softc->quirks |= SA_QUIRK_FIXED;
if (softc->last_media_blksize == 0)
softc->last_media_blksize = 512;
goto tryagain;
}
xpt_print(periph->path,
"unable to set variable blocksize\n");
goto exit;
}
}
/*
* Now that we have the current block size,
* set up some parameters for sastart's usage.
*/
if (softc->media_blksize) {
softc->flags |= SA_FLAG_FIXED;
if (powerof2(softc->media_blksize)) {
softc->blk_shift =
ffs(softc->media_blksize) - 1;
softc->blk_mask = softc->media_blksize - 1;
} else {
softc->blk_mask = ~0;
softc->blk_shift = 0;
}
} else {
/*
* The SCSI-3 spec allows 0 to mean "unspecified".
* The SCSI-1 spec allows 0 to mean 'infinite'.
*
* Either works here.
*/
if (softc->max_blk == 0) {
softc->max_blk = ~0;
}
softc->blk_shift = 0;
if (softc->blk_gran != 0) {
softc->blk_mask = softc->blk_gran - 1;
} else {
softc->blk_mask = 0;
}
}
if (write_protect)
softc->flags |= SA_FLAG_TAPE_WP;
if (comp_supported) {
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (softc->saved_comp_algorithm == 0)
softc->saved_comp_algorithm =
softc->comp_algorithm;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->flags |= SA_FLAG_COMP_SUPP;
if (comp_enabled)
softc->flags |= SA_FLAG_COMP_ENABLED;
} else
softc->flags |= SA_FLAG_COMP_UNSUPP;
if ((softc->buffer_mode == SMH_SA_BUF_MODE_NOBUF) &&
(softc->quirks & SA_QUIRK_NO_MODESEL) == 0) {
error = sasetparams(periph, SA_PARAM_BUFF_MODE, 0,
0, 0, SF_NO_PRINT);
if (error == 0) {
softc->buffer_mode = SMH_SA_BUF_MODE_SIBUF;
} else {
xpt_print(periph->path,
"unable to set buffered mode\n");
}
error = 0; /* not an error */
}
if (error == 0) {
softc->flags |= SA_FLAG_TAPE_MOUNTED;
}
exit:
if (rblim != NULL)
2007-05-14 21:48:53 +00:00
free(rblim, M_SCSISA);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (error != 0) {
softc->dsreg = MTIO_DSREG_NIL;
} else {
softc->fileno = softc->blkno = 0;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
}
#ifdef SA_1FM_AT_EOD
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if ((softc->quirks & SA_QUIRK_2FM) == 0)
softc->quirks |= SA_QUIRK_1FM;
#else
if ((softc->quirks & SA_QUIRK_1FM) == 0)
softc->quirks |= SA_QUIRK_2FM;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
#endif
} else
xpt_release_ccb(ccb);
/*
* If we return an error, we're not mounted any more,
* so release any device reservation.
*/
if (error != 0) {
(void) sareservereleaseunit(periph, FALSE);
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
} else {
/*
* Clear I/O residual.
*/
softc->last_io_resid = 0;
softc->last_ctl_resid = 0;
}
return (error);
}
2000-10-31 22:34:51 +00:00
/*
* How many filemarks do we need to write if we were to terminate the
* tape session right now? Note that this can be a negative number
*/
static int
2000-10-31 22:34:51 +00:00
samarkswanted(struct cam_periph *periph)
{
int markswanted;
struct sa_softc *softc;
softc = (struct sa_softc *)periph->softc;
markswanted = 0;
if ((softc->flags & SA_FLAG_TAPE_WRITTEN) != 0) {
markswanted++;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (softc->quirks & SA_QUIRK_2FM)
markswanted++;
}
2000-10-31 22:34:51 +00:00
markswanted -= softc->filemarks;
return (markswanted);
}
static int
sacheckeod(struct cam_periph *periph)
{
int error;
int markswanted;
markswanted = samarkswanted(periph);
2000-10-31 22:34:51 +00:00
if (markswanted > 0) {
error = sawritefilemarks(periph, markswanted, FALSE);
} else {
error = 0;
}
return (error);
}
static int
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
{
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
static const char *toobig =
"%d-byte tape record bigger than supplied buffer\n";
struct cam_periph *periph;
struct sa_softc *softc;
struct ccb_scsiio *csio;
struct scsi_sense_data *sense;
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
uint64_t resid = 0;
int64_t info = 0;
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
cam_status status;
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
int error_code, sense_key, asc, ascq, error, aqvalid, stream_valid;
int sense_len;
uint8_t stream_bits;
periph = xpt_path_periph(ccb->ccb_h.path);
softc = (struct sa_softc *)periph->softc;
csio = &ccb->csio;
sense = &csio->sense_data;
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
sense_len = csio->sense_len - csio->sense_resid;
scsi_extract_sense_len(sense, sense_len, &error_code, &sense_key,
&asc, &ascq, /*show_errors*/ 1);
if (asc != -1 && ascq != -1)
aqvalid = 1;
else
aqvalid = 0;
if (scsi_get_stream_info(sense, sense_len, NULL, &stream_bits) == 0)
stream_valid = 1;
else
stream_valid = 0;
error = 0;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
status = csio->ccb_h.status & CAM_STATUS_MASK;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
* Calculate/latch up, any residuals... We do this in a funny 2-step
* so we can print stuff here if we have CAM_DEBUG enabled for this
* unit.
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
*/
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
if (status == CAM_SCSI_STATUS_ERROR) {
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &resid,
&info) == 0) {
if ((softc->flags & SA_FLAG_FIXED) != 0)
resid *= softc->media_blksize;
} else {
resid = csio->dxfer_len;
info = resid;
if ((softc->flags & SA_FLAG_FIXED) != 0) {
if (softc->media_blksize)
info /= softc->media_blksize;
}
}
if (csio->cdb_io.cdb_bytes[0] == SA_READ ||
csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
bcopy((caddr_t) sense, (caddr_t) &softc->last_io_sense,
sizeof (struct scsi_sense_data));
bcopy(csio->cdb_io.cdb_bytes, softc->last_io_cdb,
(int) csio->cdb_len);
softc->last_io_resid = resid;
softc->last_resid_was_io = 1;
} else {
bcopy((caddr_t) sense, (caddr_t) &softc->last_ctl_sense,
sizeof (struct scsi_sense_data));
bcopy(csio->cdb_io.cdb_bytes, softc->last_ctl_cdb,
(int) csio->cdb_len);
softc->last_ctl_resid = resid;
softc->last_resid_was_io = 0;
}
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("CDB[0]=0x%x Key 0x%x "
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
"ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %jd "
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
"dxfer_len %d\n", csio->cdb_io.cdb_bytes[0] & 0xff,
sense_key, asc, ascq, status,
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
(stream_valid) ? stream_bits : 0, (intmax_t)resid,
csio->dxfer_len));
} else {
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
("Cam Status 0x%x\n", status));
}
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
switch (status) {
case CAM_REQ_CMP:
return (0);
case CAM_SCSI_STATUS_ERROR:
/*
* If a read/write command, we handle it here.
*/
Merge CAM locking changes from the projects/camlock branch to radically reduce lock congestion and improve SMP scalability of the SCSI/ATA stack, preparing the ground for the coming next GEOM direct dispatch support. Replace big per-SIM locks with bunch of smaller ones: - per-LUN locks to protect device and peripheral drivers state; - per-target locks to protect list of LUNs on target; - per-bus locks to protect reference counting; - per-send queue locks to protect queue of CCBs to be sent; - per-done queue locks to protect queue of completed CCBs; - remaining per-SIM locks now protect only HBA driver internals. While holding LUN lock it is allowed (while not recommended for performance reasons) to take SIM lock. The opposite acquisition order is forbidden. All the other locks are leaf locks, that can be taken anywhere, but should not be cascaded. Many functions, such as: xpt_action(), xpt_done(), xpt_async(), xpt_create_path(), etc. are no longer require (but allow) SIM lock to be held. To keep compatibility and solve cases where SIM lock can't be dropped, all xpt_async() calls in addition to xpt_done() calls are queued to completion threads for async processing in clean environment without SIM lock held. Instead of single CAM SWI thread, used for commands completion processing before, use multiple (depending on number of CPUs) threads. Load balanced between them using "hash" of the device B:T:L address. HBA drivers that can drop SIM lock during completion processing and have sufficient number of completion threads to efficiently scale to multiple CPUs can use new function xpt_done_direct() to avoid extra context switch. Make ahci(4) driver to use this mechanism depending on hardware setup. Sponsored by: iXsystems, Inc. MFC after: 2 months
2013-10-21 12:00:26 +00:00
if (csio->cdb_io.cdb_bytes[0] == SA_READ ||
csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
break;
}
/*
* If this was just EOM/EOP, Filemark, Setmark or ILI detected
* on a non read/write command, we assume it's not an error
* and propagate the residule and return.
*/
if ((aqvalid && asc == 0 && ascq > 0 && ascq <= 5) ||
(aqvalid == 0 && sense_key == SSD_KEY_NO_SENSE)) {
csio->resid = resid;
QFRLS(ccb);
return (0);
}
/*
* Otherwise, we let the common code handle this.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb));
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
* XXX: To Be Fixed
* We cannot depend upon CAM honoring retry counts for these.
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
*/
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
case CAM_SCSI_BUS_RESET:
case CAM_BDR_SENT:
if (ccb->ccb_h.retry_count <= 0) {
return (EIO);
}
/* FALLTHROUGH */
default:
return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb));
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
}
/*
* Handle filemark, end of tape, mismatched record sizes....
* From this point out, we're only handling read/write cases.
* Handle writes && reads differently.
*/
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
if (sense_key == SSD_KEY_VOLUME_OVERFLOW) {
csio->resid = resid;
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
error = ENOSPC;
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
} else if ((stream_valid != 0) && (stream_bits & SSD_EOM)) {
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
softc->flags |= SA_FLAG_EOM_PENDING;
/*
* Grotesque as it seems, the few times
* I've actually seen a non-zero resid,
* the tape drive actually lied and had
* written all the data!.
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
*/
csio->resid = 0;
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
} else {
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
csio->resid = resid;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (sense_key == SSD_KEY_BLANK_CHECK) {
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
if (softc->quirks & SA_QUIRK_1FM) {
error = 0;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->flags |= SA_FLAG_EOM_PENDING;
} else {
error = EIO;
}
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
} else if ((stream_valid != 0) && (stream_bits & SSD_FILEMARK)){
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
if (softc->flags & SA_FLAG_FIXED) {
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
error = -1;
softc->flags |= SA_FLAG_EOF_PENDING;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
}
/*
* Unconditionally, if we detected a filemark on a read,
* mark that we've run moved a file ahead.
*/
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (softc->fileno != (daddr_t) -1) {
softc->fileno++;
softc->blkno = 0;
csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
}
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
}
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* Incorrect Length usually applies to read, but can apply to writes.
*/
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
if (error == 0 && (stream_valid != 0) && (stream_bits & SSD_ILI)) {
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (info < 0) {
xpt_print(csio->ccb_h.path, toobig,
csio->dxfer_len - info);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
csio->resid = csio->dxfer_len;
error = EIO;
} else {
csio->resid = resid;
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
if (softc->flags & SA_FLAG_FIXED) {
softc->flags |= SA_FLAG_EIO_PENDING;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
}
/*
* Bump the block number if we hadn't seen a filemark.
* Do this independent of errors (we've moved anyway).
*/
Add descriptor sense support to CAM, and honor sense residuals properly in CAM. Desriptor sense is a new sense data format that originated in SPC-3. Among other things, it allows for an 8-byte info field, which is necessary to pass back block numbers larger than 4 bytes. This change adds a number of new functions to scsi_all.c (and therefore libcam) that abstract out most access to sense data. This includes a bump of CAM_VERSION, because the CCB ABI has changed. Userland programs that use the CAM pass(4) driver will need to be recompiled. camcontrol.c: Change uses of scsi_extract_sense() to use scsi_extract_sense_len(). Use scsi_get_sks() instead of accessing sense key specific data directly. scsi_modes: Update the control mode page to the latest version (SPC-4). scsi_cmds.c, scsi_target.c: Change references to struct scsi_sense_data to struct scsi_sense_data_fixed. This should be changed to allow the user to specify fixed or descriptor sense, and then use scsi_set_sense_data() to build the sense data. ps3cdrom.c: Use scsi_set_sense_data() instead of setting sense data manually. cam_periph.c: Use scsi_extract_sense_len() instead of using scsi_extract_sense() or accessing sense data directly. cam_ccb.h: Bump the CAM_VERSION from 0x15 to 0x16. The change of struct scsi_sense_data from 32 to 252 bytes changes the size of struct ccb_scsiio, but not the size of union ccb. So the version must be bumped to prevent structure mis-matches. scsi_all.h: Lots of updated SCSI sense data and other structures. Add function prototypes for the new sense data functions. Take out the inline implementation of scsi_extract_sense(). It is now too large to put in a header file. Add macros to calculate whether fields are present and filled in fixed and descriptor sense data scsi_all.c: In scsi_op_desc(), allow the user to pass in NULL inquiry data, and we'll assume a direct access device in that case. Changed the SCSI RESERVED sense key name and description to COMPLETED, as it is now defined in the spec. Change the error recovery action for a number of read errors to prevent lots of retries when the drive has said that the block isn't accessible. This speeds up reconstruction of the block by any RAID software running on top of the drive (e.g. ZFS). In scsi_sense_desc(), allow for invalid sense key numbers. This allows calling this routine without checking the input values first. Change scsi_error_action() to use scsi_extract_sense_len(), and handle things when invalid asc/ascq values are encountered. Add a new routine, scsi_desc_iterate(), that will call the supplied function for every descriptor in descriptor format sense data. Add scsi_set_sense_data(), and scsi_set_sense_data_va(), which build descriptor and fixed format sense data. They currently default to fixed format sense data. Add a number of scsi_get_*() functions, which get different types of sense data fields from either fixed or descriptor format sense data, if the data is present. Add a number of scsi_*_sbuf() functions, which print formatted versions of various sense data fields. These functions work for either fixed or descriptor sense. Add a number of scsi_sense_*_sbuf() functions, which have a standard calling interface and print the indicated field. These functions take descriptors only. Add scsi_sense_desc_sbuf(), which will print a formatted version of the given sense descriptor. Pull out a majority of the scsi_sense_sbuf() function and put it into scsi_sense_only_sbuf(). This allows callers that don't use struct ccb_scsiio to easily utilize the printing routines. Revamp that function to handle descriptor sense and use the new sense fetching and printing routines. Move scsi_extract_sense() into scsi_all.c, and implement it in terms of the new function, scsi_extract_sense_len(). The _len() version takes a length (which should be the sense length - residual) and can indicate which fields are present and valid in the sense data. Add a couple of new scsi_get_*() routines to get the sense key, asc, and ascq only. mly.c: Rename struct scsi_sense_data to struct scsi_sense_data_fixed. sbp_targ.c: Use the new sense fetching routines to get sense data instead of accessing it directly. sbp.c: Change the firewire/SCSI sense data transformation code to use struct scsi_sense_data_fixed instead of struct scsi_sense_data. This should be changed later to use scsi_set_sense_data(). ciss.c: Calculate the sense residual properly. Use scsi_get_sense_key() to fetch the sense key. mps_sas.c, mpt_cam.c: Set the sense residual properly. iir.c: Use scsi_set_sense_data() instead of building sense data by hand. iscsi_subr.c: Use scsi_extract_sense_len() instead of grabbing sense data directly. umass.c: Use scsi_set_sense_data() to build sense data. Grab the sense key using scsi_get_sense_key(). Calculate the sense residual properly. isp_freebsd.h: Use scsi_get_*() routines to grab asc, ascq, and sense key values. Calculate and set the sense residual. MFC after: 3 days Sponsored by: Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
if ((stream_valid == 0) ||
(stream_bits & SSD_FILEMARK) == 0) {
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (softc->blkno != (daddr_t) -1) {
softc->blkno++;
csio->ccb_h.ccb_pflags |=
SA_POSITION_UPDATED;
}
}
}
}
2001-07-30 00:22:57 +00:00
Clear SA_FLAG_ERR_PENDING for MTREW, MTERASE and MTRETENS ioctl cases. Clear residual counts after a successful samount (the user doesn't care that we got an N-kbyte residual on our test read). Change a lot of error handling code. 1. If we end up in saerror, check more carefully about the kind of error. If it is a CAM_SCSI_STATUS_ERROR and it is a read/write command, we'll be handling this in saerror. If it isn't a read/write command, check to see whether this is just an EOM/EOP check condition- if it is, just set residual and return normally. A residual and then a NO SENSE check condiftion with the ASC of 0 and ASCQ of between 1 and 4 are normal 'signifying' events, not errors per se, and we shouldn't give the command to cam_periph_error to do something relatively unpredictable with. 2. If we get a Bus Reset, had a BDR sent, or get the cam status of CAM_REQUEUE_REQ, check the retry count on the command. The default error handler, cam_periph_error, doesn't honor retry count in these cases. This may change in the future, but for now, make sure we set EIO and return without calling cam_periph_error if the retry count for the command with an error is zero. 3. Clean up the pending error case goop and handle cases more sensibly. The rules are: If command was a Write: If we got a SSD_KEY_VOLUME_OVERFLOW, the resid is propagated and we set ENOSPC as the error. Else if we got an EOM condition- just mark EOM pending. And set a residual of zero. For the longest time I was just propagating residual from the sense data- but my tape comparison tests were always failing because all drives I tested with actually *do* write the data anyway- the EOM (early warning) condition occurred *prior* to all of the data going out to media- that is, it was still buffered by the drive. This case is described in SCSI-2, 10.2.14, paragraph #d for the meaning of 'information field'. A better fix for this would be to issue a WFM command of zero to cause the drive to flush any buffered data, but this would require a fairly extensive rewrite. Else if the command was a READ: If we got a SSD_KEY_BLANK_CHECK- If we have a One Filemark EOT model- mark EOM as pending, otherwise set EIO as the erorr. Else if we found a Filemark- If we're in Fixed Block mode- mark EOF pending. If we had an ILI (Incorrect Length Indicator)- If the residual is less than zero, whine about tape record being too big for user's buffer, otherwise if we were in Fixed Block mode, mark EIO as pending. All 'pending' conditions mean that the command in question completes without error indication. It had succeeded, but a signifying event occurred during its execution which will apply to the *next* command that would be exexcuted. Except for the one EOM case above, we always propagate residual. Now, way back in sastart- if we notice any of the PENDING bits set, we don't run the command we've just pulled off the wait queue. Instead, we then figure out it's disposition based upon a previous command's association with a signifying event. If SA_FLAG_EOM_PENDING is set, we don't set an error. We just complete the command with residual set to the request count (not data moved, but no error). We continue on. If SA_FLAG_EOF_PENDING- if we have this, it's only because we're in Fixed Block mode- in which case we traverse all waiting buffers (which we can get in fixed block mode because physio has split things up) and mark them all as no error, but no data moved and complete them. If SA_FLAG_EIO_PENDING, just mark the buffer with an EIO error and complete it. Then we clear all of the pending state bits- we're done. MFC after: 4 weeks
2001-08-30 16:25:24 +00:00
if (error <= 0) {
/*
* Unfreeze the queue if frozen as we're not returning anything
* to our waiters that would indicate an I/O error has occurred
* (yet).
*/
QFRLS(ccb);
error = 0;
}
return (error);
}
static int
sagetparams(struct cam_periph *periph, sa_params params_to_get,
u_int32_t *blocksize, u_int8_t *density, u_int32_t *numblocks,
int *buff_mode, u_int8_t *write_protect, u_int8_t *speed,
int *comp_supported, int *comp_enabled, u_int32_t *comp_algorithm,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
sa_comp_t *tcs)
{
union ccb *ccb;
void *mode_buffer;
struct scsi_mode_header_6 *mode_hdr;
struct scsi_mode_blk_desc *mode_blk;
int mode_buffer_len;
struct sa_softc *softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
u_int8_t cpage;
int error;
cam_status status;
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
ccb = cam_periph_getccb(periph, 1);
if (softc->quirks & SA_QUIRK_NO_CPAGE)
cpage = SA_DEVICE_CONFIGURATION_PAGE;
else
cpage = SA_DATA_COMPRESSION_PAGE;
retry:
mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk);
if (params_to_get & SA_PARAM_COMPRESSION) {
if (softc->quirks & SA_QUIRK_NOCOMP) {
*comp_supported = FALSE;
params_to_get &= ~SA_PARAM_COMPRESSION;
} else
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
mode_buffer_len += sizeof (sa_comp_t);
}
2007-06-16 18:13:26 +00:00
/* XXX Fix M_NOWAIT */
mode_buffer = malloc(mode_buffer_len, M_SCSISA, M_NOWAIT | M_ZERO);
if (mode_buffer == NULL) {
xpt_release_ccb(ccb);
return (ENOMEM);
}
mode_hdr = (struct scsi_mode_header_6 *)mode_buffer;
mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
/* it is safe to retry this */
scsi_mode_sense(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE,
SMS_PAGE_CTRL_CURRENT, (params_to_get & SA_PARAM_COMPRESSION) ?
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cpage : SMS_VENDOR_SPECIFIC_PAGE, mode_buffer, mode_buffer_len,
SSD_FULL_SIZE, SCSIOP_TIMEOUT);
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
softc->device_stats);
status = ccb->ccb_h.status & CAM_STATUS_MASK;
if (error == EINVAL && (params_to_get & SA_PARAM_COMPRESSION) != 0) {
/*
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
* Hmm. Let's see if we can try another page...
* If we've already done that, give up on compression
* for this device and remember this for the future
* and attempt the request without asking for compression
* info.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (cpage == SA_DATA_COMPRESSION_PAGE) {
cpage = SA_DEVICE_CONFIGURATION_PAGE;
goto retry;
}
softc->quirks |= SA_QUIRK_NOCOMP;
2007-05-14 21:48:53 +00:00
free(mode_buffer, M_SCSISA);
goto retry;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
} else if (status == CAM_SCSI_STATUS_ERROR) {
/* Tell the user about the fatal error. */
scsi_sense_print(&ccb->csio);
goto sagetparamsexit;
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* If the user only wants the compression information, and
* the device doesn't send back the block descriptor, it's
* no big deal. If the user wants more than just
* compression, though, and the device doesn't pass back the
* block descriptor, we need to send another mode sense to
* get the block descriptor.
*/
if ((mode_hdr->blk_desc_len == 0) &&
(params_to_get & SA_PARAM_COMPRESSION) &&
(params_to_get & ~(SA_PARAM_COMPRESSION))) {
/*
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
* Decrease the mode buffer length by the size of
* the compression page, to make sure the data
* there doesn't get overwritten.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
mode_buffer_len -= sizeof (sa_comp_t);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* Now move the compression page that we presumably
* got back down the memory chunk a little bit so
* it doesn't get spammed.
*/
bcopy(&mode_hdr[0], &mode_hdr[1], sizeof (sa_comp_t));
bzero(&mode_hdr[0], sizeof (mode_hdr[0]));
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* Now, we issue another mode sense and just ask
* for the block descriptor, etc.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
scsi_mode_sense(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE,
SMS_PAGE_CTRL_CURRENT, SMS_VENDOR_SPECIFIC_PAGE,
mode_buffer, mode_buffer_len, SSD_FULL_SIZE,
SCSIOP_TIMEOUT);
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
softc->device_stats);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (error != 0)
goto sagetparamsexit;
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (params_to_get & SA_PARAM_BLOCKSIZE)
*blocksize = scsi_3btoul(mode_blk->blklen);
if (params_to_get & SA_PARAM_NUMBLOCKS)
*numblocks = scsi_3btoul(mode_blk->nblocks);
if (params_to_get & SA_PARAM_BUFF_MODE)
*buff_mode = mode_hdr->dev_spec & SMH_SA_BUF_MODE_MASK;
if (params_to_get & SA_PARAM_DENSITY)
*density = mode_blk->density;
if (params_to_get & SA_PARAM_WP)
*write_protect = (mode_hdr->dev_spec & SMH_SA_WP)? TRUE : FALSE;
if (params_to_get & SA_PARAM_SPEED)
*speed = mode_hdr->dev_spec & SMH_SA_SPEED_MASK;
if (params_to_get & SA_PARAM_COMPRESSION) {
sa_comp_t *ntcs = (sa_comp_t *) &mode_blk[1];
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (cpage == SA_DATA_COMPRESSION_PAGE) {
struct scsi_data_compression_page *cp = &ntcs->dcomp;
*comp_supported =
(cp->dce_and_dcc & SA_DCP_DCC)? TRUE : FALSE;
*comp_enabled =
(cp->dce_and_dcc & SA_DCP_DCE)? TRUE : FALSE;
*comp_algorithm = scsi_4btoul(cp->comp_algorithm);
} else {
struct scsi_dev_conf_page *cp = &ntcs->dconf;
/*
* We don't really know whether this device supports
* Data Compression if the algorithm field is
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
* zero. Just say we do.
*/
*comp_supported = TRUE;
*comp_enabled =
(cp->sel_comp_alg != SA_COMP_NONE)? TRUE : FALSE;
*comp_algorithm = cp->sel_comp_alg;
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (tcs != NULL)
bcopy(ntcs, tcs, sizeof (sa_comp_t));
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
}
if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
int idx;
char *xyz = mode_buffer;
xpt_print_path(periph->path);
printf("Mode Sense Data=");
for (idx = 0; idx < mode_buffer_len; idx++)
printf(" 0x%02x", xyz[idx] & 0xff);
printf("\n");
}
sagetparamsexit:
xpt_release_ccb(ccb);
2007-05-14 21:48:53 +00:00
free(mode_buffer, M_SCSISA);
return (error);
}
/*
* The purpose of this function is to set one of four different parameters
* for a tape drive:
* - blocksize
* - density
* - compression / compression algorithm
* - buffering mode
*
* The assumption is that this will be called from saioctl(), and therefore
* from a process context. Thus the waiting malloc calls below. If that
* assumption ever changes, the malloc calls should be changed to be
* NOWAIT mallocs.
*
* Any or all of the four parameters may be set when this function is
* called. It should handle setting more than one parameter at once.
*/
static int
sasetparams(struct cam_periph *periph, sa_params params_to_set,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
u_int32_t blocksize, u_int8_t density, u_int32_t calg,
u_int32_t sense_flags)
{
struct sa_softc *softc;
u_int32_t current_blocksize;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
u_int32_t current_calg;
u_int8_t current_density;
u_int8_t current_speed;
int comp_enabled, comp_supported;
void *mode_buffer;
int mode_buffer_len;
struct scsi_mode_header_6 *mode_hdr;
struct scsi_mode_blk_desc *mode_blk;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
sa_comp_t *ccomp, *cpage;
int buff_mode;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
union ccb *ccb = NULL;
int error;
softc = (struct sa_softc *)periph->softc;
ccomp = malloc(sizeof (sa_comp_t), M_SCSISA, M_NOWAIT);
if (ccomp == NULL)
return (ENOMEM);
/*
* Since it doesn't make sense to set the number of blocks, or
* write protection, we won't try to get the current value. We
* always want to get the blocksize, so we can set it back to the
* proper value.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
error = sagetparams(periph,
params_to_set | SA_PARAM_BLOCKSIZE | SA_PARAM_SPEED,
&current_blocksize, &current_density, NULL, &buff_mode, NULL,
&current_speed, &comp_supported, &comp_enabled,
&current_calg, ccomp);
if (error != 0) {
2007-05-14 21:48:53 +00:00
free(ccomp, M_SCSISA);
return (error);
}
mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk);
if (params_to_set & SA_PARAM_COMPRESSION)
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
mode_buffer_len += sizeof (sa_comp_t);
mode_buffer = malloc(mode_buffer_len, M_SCSISA, M_NOWAIT | M_ZERO);
if (mode_buffer == NULL) {
free(ccomp, M_SCSISA);
return (ENOMEM);
}
mode_hdr = (struct scsi_mode_header_6 *)mode_buffer;
mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
ccb = cam_periph_getccb(periph, 1);
retry:
if (params_to_set & SA_PARAM_COMPRESSION) {
if (mode_blk) {
cpage = (sa_comp_t *)&mode_blk[1];
} else {
cpage = (sa_comp_t *)&mode_hdr[1];
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
bcopy(ccomp, cpage, sizeof (sa_comp_t));
cpage->hdr.pagecode &= ~0x80;
} else
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cpage = NULL;
/*
* If the caller wants us to set the blocksize, use the one they
* pass in. Otherwise, use the blocksize we got back from the
* mode select above.
*/
if (mode_blk) {
if (params_to_set & SA_PARAM_BLOCKSIZE)
scsi_ulto3b(blocksize, mode_blk->blklen);
else
scsi_ulto3b(current_blocksize, mode_blk->blklen);
/*
* Set density if requested, else preserve old density.
* SCSI_SAME_DENSITY only applies to SCSI-2 or better
* devices, else density we've latched up in our softc.
*/
if (params_to_set & SA_PARAM_DENSITY) {
mode_blk->density = density;
} else if (softc->scsi_rev > SCSI_REV_CCS) {
mode_blk->density = SCSI_SAME_DENSITY;
} else {
mode_blk->density = softc->media_density;
}
}
/*
* For mode selects, these two fields must be zero.
*/
mode_hdr->data_length = 0;
mode_hdr->medium_type = 0;
/* set the speed to the current value */
mode_hdr->dev_spec = current_speed;
/* if set, set single-initiator buffering mode */
if (softc->buffer_mode == SMH_SA_BUF_MODE_SIBUF) {
mode_hdr->dev_spec |= SMH_SA_BUF_MODE_SIBUF;
}
if (mode_blk)
mode_hdr->blk_desc_len = sizeof(struct scsi_mode_blk_desc);
else
mode_hdr->blk_desc_len = 0;
/*
* First, if the user wants us to set the compression algorithm or
* just turn compression on, check to make sure that this drive
* supports compression.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (params_to_set & SA_PARAM_COMPRESSION) {
/*
* If the compression algorithm is 0, disable compression.
* If the compression algorithm is non-zero, enable
* compression and set the compression type to the
* specified compression algorithm, unless the algorithm is
* MT_COMP_ENABLE. In that case, we look at the
* compression algorithm that is currently set and if it is
* non-zero, we leave it as-is. If it is zero, and we have
* saved a compression algorithm from a time when
* compression was enabled before, set the compression to
* the saved value.
*/
switch (ccomp->hdr.pagecode & ~0x80) {
case SA_DEVICE_CONFIGURATION_PAGE:
{
struct scsi_dev_conf_page *dcp = &cpage->dconf;
if (calg == 0) {
dcp->sel_comp_alg = SA_COMP_NONE;
break;
}
if (calg != MT_COMP_ENABLE) {
dcp->sel_comp_alg = calg;
} else if (dcp->sel_comp_alg == SA_COMP_NONE &&
softc->saved_comp_algorithm != 0) {
dcp->sel_comp_alg = softc->saved_comp_algorithm;
}
break;
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
case SA_DATA_COMPRESSION_PAGE:
if (ccomp->dcomp.dce_and_dcc & SA_DCP_DCC) {
struct scsi_data_compression_page *dcp = &cpage->dcomp;
if (calg == 0) {
/*
* Disable compression, but leave the
* decompression and the capability bit
* alone.
*/
dcp->dce_and_dcc = SA_DCP_DCC;
dcp->dde_and_red |= SA_DCP_DDE;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
break;
}
/* enable compression && decompression */
dcp->dce_and_dcc = SA_DCP_DCE | SA_DCP_DCC;
dcp->dde_and_red |= SA_DCP_DDE;
/*
* If there, use compression algorithm from caller.
* Otherwise, if there's a saved compression algorithm
* and there is no current algorithm, use the saved
* algorithm. Else parrot back what we got and hope
* for the best.
*/
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (calg != MT_COMP_ENABLE) {
scsi_ulto4b(calg, dcp->comp_algorithm);
scsi_ulto4b(calg, dcp->decomp_algorithm);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
} else if (scsi_4btoul(dcp->comp_algorithm) == 0 &&
softc->saved_comp_algorithm != 0) {
scsi_ulto4b(softc->saved_comp_algorithm,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
dcp->comp_algorithm);
scsi_ulto4b(softc->saved_comp_algorithm,
dcp->decomp_algorithm);
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
break;
}
/*
* Compression does not appear to be supported-
* at least via the DATA COMPRESSION page. It
* would be too much to ask us to believe that
* the page itself is supported, but incorrectly
* reports an ability to manipulate data compression,
* so we'll assume that this device doesn't support
* compression. We can just fall through for that.
*/
/* FALLTHROUGH */
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
default:
/*
* The drive doesn't seem to support compression,
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
* so turn off the set compression bit.
*/
params_to_set &= ~SA_PARAM_COMPRESSION;
xpt_print(periph->path,
"device does not seem to support compression\n");
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* If that was the only thing the user wanted us to set,
* clean up allocated resources and return with
* 'operation not supported'.
*/
if (params_to_set == SA_PARAM_NONE) {
2007-05-14 21:48:53 +00:00
free(mode_buffer, M_SCSISA);
xpt_release_ccb(ccb);
return (ENODEV);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
}
/*
* That wasn't the only thing the user wanted us to set.
* So, decrease the stated mode buffer length by the
* size of the compression mode page.
*/
mode_buffer_len -= sizeof(sa_comp_t);
}
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/* It is safe to retry this operation */
scsi_mode_select(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG,
(params_to_set & SA_PARAM_COMPRESSION)? TRUE : FALSE,
FALSE, mode_buffer, mode_buffer_len, SSD_FULL_SIZE, SCSIOP_TIMEOUT);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
error = cam_periph_runccb(ccb, saerror, 0,
sense_flags, softc->device_stats);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
int idx;
char *xyz = mode_buffer;
xpt_print_path(periph->path);
printf("Err%d, Mode Select Data=", error);
for (idx = 0; idx < mode_buffer_len; idx++)
printf(" 0x%02x", xyz[idx] & 0xff);
printf("\n");
}
if (error) {
/*
* If we can, try without setting density/blocksize.
*/
if (mode_blk) {
if ((params_to_set &
(SA_PARAM_DENSITY|SA_PARAM_BLOCKSIZE)) == 0) {
mode_blk = NULL;
goto retry;
}
} else {
mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
cpage = (sa_comp_t *)&mode_blk[1];
}
/*
* If we were setting the blocksize, and that failed, we
* want to set it to its original value. If we weren't
* setting the blocksize, we don't want to change it.
*/
scsi_ulto3b(current_blocksize, mode_blk->blklen);
/*
* Set density if requested, else preserve old density.
* SCSI_SAME_DENSITY only applies to SCSI-2 or better
* devices, else density we've latched up in our softc.
*/
if (params_to_set & SA_PARAM_DENSITY) {
mode_blk->density = current_density;
} else if (softc->scsi_rev > SCSI_REV_CCS) {
mode_blk->density = SCSI_SAME_DENSITY;
} else {
mode_blk->density = softc->media_density;
}
if (params_to_set & SA_PARAM_COMPRESSION)
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
bcopy(ccomp, cpage, sizeof (sa_comp_t));
/*
* The retry count is the only CCB field that might have been
* changed that we care about, so reset it back to 1.
*/
ccb->ccb_h.retry_count = 1;
cam_periph_runccb(ccb, saerror, 0, sense_flags,
softc->device_stats);
}
xpt_release_ccb(ccb);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
if (ccomp != NULL)
2007-05-14 21:48:53 +00:00
free(ccomp, M_SCSISA);
if (params_to_set & SA_PARAM_COMPRESSION) {
if (error) {
softc->flags &= ~SA_FLAG_COMP_ENABLED;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
/*
* Even if we get an error setting compression,
* do not say that we don't support it. We could
* have been wrong, or it may be media specific.
* softc->flags &= ~SA_FLAG_COMP_SUPP;
*/
softc->saved_comp_algorithm = softc->comp_algorithm;
softc->comp_algorithm = 0;
} else {
softc->flags |= SA_FLAG_COMP_ENABLED;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
softc->comp_algorithm = calg;
}
}
2007-05-14 21:48:53 +00:00
free(mode_buffer, M_SCSISA);
return (error);
}
static void
saprevent(struct cam_periph *periph, int action)
{
struct sa_softc *softc;
union ccb *ccb;
int error, sf;
softc = (struct sa_softc *)periph->softc;
if ((action == PR_ALLOW) && (softc->flags & SA_FLAG_TAPE_LOCKED) == 0)
return;
if ((action == PR_PREVENT) && (softc->flags & SA_FLAG_TAPE_LOCKED) != 0)
return;
/*
* We can be quiet about illegal requests.
*/
if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
sf = 0;
} else
sf = SF_QUIET_IR;
ccb = cam_periph_getccb(periph, 1);
/* It is safe to retry this operation */
scsi_prevent(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, action,
SSD_FULL_SIZE, SCSIOP_TIMEOUT);
error = cam_periph_runccb(ccb, saerror, 0, sf, softc->device_stats);
if (error == 0) {
if (action == PR_ALLOW)
softc->flags &= ~SA_FLAG_TAPE_LOCKED;
else
softc->flags |= SA_FLAG_TAPE_LOCKED;
}
xpt_release_ccb(ccb);
}
static int
sarewind(struct cam_periph *periph)
{
union ccb *ccb;
struct sa_softc *softc;
int error;
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
ccb = cam_periph_getccb(periph, 1);
/* It is safe to retry this operation */
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
scsi_rewind(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE,
SSD_FULL_SIZE, REWIND_TIMEOUT);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REW;
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
xpt_release_ccb(ccb);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (error == 0)
softc->fileno = softc->blkno = (daddr_t) 0;
else
softc->fileno = softc->blkno = (daddr_t) -1;
return (error);
}
static int
saspace(struct cam_periph *periph, int count, scsi_space_code code)
{
union ccb *ccb;
struct sa_softc *softc;
int error;
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
ccb = cam_periph_getccb(periph, 1);
/* This cannot be retried */
scsi_space(&ccb->csio, 0, sadone, MSG_SIMPLE_Q_TAG, code, count,
SSD_FULL_SIZE, SPACE_TIMEOUT);
/*
* Clear residual because we will be using it.
*/
softc->last_ctl_resid = 0;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = (count < 0)? MTIO_DSREG_REV : MTIO_DSREG_FWD;
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
xpt_release_ccb(ccb);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
* If a spacing operation has failed, we need to invalidate
* this mount.
*
* If the spacing operation was setmarks or to end of recorded data,
* we no longer know our relative position.
*
* If the spacing operations was spacing files in reverse, we
* take account of the residual, but still check against less
* than zero- if we've gone negative, we must have hit BOT.
*
* If the spacing operations was spacing records in reverse and
* we have a residual, we've either hit BOT or hit a filemark.
* In the former case, we know our new record number (0). In
* the latter case, we have absolutely no idea what the real
* record number is- we've stopped between the end of the last
* record in the previous file and the filemark that stopped
* our spacing backwards.
*/
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (error) {
softc->fileno = softc->blkno = (daddr_t) -1;
} else if (code == SS_SETMARKS || code == SS_EOD) {
softc->fileno = softc->blkno = (daddr_t) -1;
} else if (code == SS_FILEMARKS && softc->fileno != (daddr_t) -1) {
softc->fileno += (count - softc->last_ctl_resid);
if (softc->fileno < 0) /* we must of hit BOT */
softc->fileno = 0;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->blkno = 0;
} else if (code == SS_BLOCKS && softc->blkno != (daddr_t) -1) {
softc->blkno += (count - softc->last_ctl_resid);
if (count < 0) {
if (softc->last_ctl_resid || softc->blkno < 0) {
if (softc->fileno == 0) {
softc->blkno = 0;
} else {
softc->blkno = (daddr_t) -1;
}
}
}
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
}
return (error);
}
static int
sawritefilemarks(struct cam_periph *periph, int nmarks, int setmarks)
{
union ccb *ccb;
struct sa_softc *softc;
int error, nwm = 0;
softc = (struct sa_softc *)periph->softc;
if (softc->open_rdonly)
return (EBADF);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
ccb = cam_periph_getccb(periph, 1);
/*
* Clear residual because we will be using it.
*/
softc->last_ctl_resid = 0;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_FMK;
/* this *must* not be retried */
scsi_write_filemarks(&ccb->csio, 0, sadone, MSG_SIMPLE_Q_TAG,
FALSE, setmarks, nmarks, SSD_FULL_SIZE, IO_TIMEOUT);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
if (error == 0 && nmarks) {
struct sa_softc *softc = (struct sa_softc *)periph->softc;
nwm = nmarks - softc->last_ctl_resid;
softc->filemarks += nwm;
}
xpt_release_ccb(ccb);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
/*
* Update relative positions (if we're doing that).
*/
if (error) {
softc->fileno = softc->blkno = (daddr_t) -1;
} else if (softc->fileno != (daddr_t) -1) {
softc->fileno += nwm;
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->blkno = 0;
}
return (error);
}
static int
sardpos(struct cam_periph *periph, int hard, u_int32_t *blkptr)
{
struct scsi_tape_position_data loc;
union ccb *ccb;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
struct sa_softc *softc = (struct sa_softc *)periph->softc;
int error;
/*
* We try and flush any buffered writes here if we were writing
* and we're trying to get hardware block position. It eats
* up performance substantially, but I'm wary of drive firmware.
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
*
* I think that *logical* block position is probably okay-
* but hardware block position might have to wait for data
* to hit media to be valid. Caveat Emptor.
*/
if (hard && (softc->flags & SA_FLAG_TAPE_WRITTEN)) {
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
error = sawritefilemarks(periph, 0, 0);
if (error && error != EACCES)
return (error);
}
ccb = cam_periph_getccb(periph, 1);
scsi_read_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG,
hard, &loc, SSD_FULL_SIZE, SCSIOP_TIMEOUT);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_RBSY;
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
if (error == 0) {
if (loc.flags & SA_RPOS_UNCERTAIN) {
error = EINVAL; /* nothing is certain */
} else {
*blkptr = scsi_4btoul(loc.firstblk);
}
}
xpt_release_ccb(ccb);
return (error);
}
static int
sasetpos(struct cam_periph *periph, int hard, u_int32_t *blkptr)
{
union ccb *ccb;
struct sa_softc *softc;
int error;
/*
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
* We used to try and flush any buffered writes here.
* Now we push this onto user applications to either
* flush the pending writes themselves (via a zero count
* WRITE FILEMARKS command) or they can trust their tape
* drive to do this correctly for them.
*/
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
ccb = cam_periph_getccb(periph, 1);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
scsi_set_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG,
hard, *blkptr, SSD_FULL_SIZE, SPACE_TIMEOUT);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_POS;
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
xpt_release_ccb(ccb);
/*
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
* Note relative file && block number position as now unknown.
*/
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->fileno = softc->blkno = (daddr_t) -1;
return (error);
}
static int
saretension(struct cam_periph *periph)
{
union ccb *ccb;
struct sa_softc *softc;
int error;
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
ccb = cam_periph_getccb(periph, 1);
/* It is safe to retry this operation */
scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE,
FALSE, TRUE, TRUE, SSD_FULL_SIZE, ERASE_TIMEOUT);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_TEN;
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
xpt_release_ccb(ccb);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (error == 0)
softc->fileno = softc->blkno = (daddr_t) 0;
else
softc->fileno = softc->blkno = (daddr_t) -1;
return (error);
}
static int
sareservereleaseunit(struct cam_periph *periph, int reserve)
{
union ccb *ccb;
struct sa_softc *softc;
int error;
softc = (struct sa_softc *)periph->softc;
ccb = cam_periph_getccb(periph, 1);
/* It is safe to retry this operation */
scsi_reserve_release_unit(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG,
FALSE, 0, SSD_FULL_SIZE, SCSIOP_TIMEOUT, reserve);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_RBSY;
error = cam_periph_runccb(ccb, saerror, 0,
SF_RETRY_UA | SF_NO_PRINT, softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
xpt_release_ccb(ccb);
/*
* If the error was Illegal Request, then the device doesn't support
* RESERVE/RELEASE. This is not an error.
*/
if (error == EINVAL) {
error = 0;
}
return (error);
}
static int
saloadunload(struct cam_periph *periph, int load)
{
union ccb *ccb;
struct sa_softc *softc;
int error;
softc = (struct sa_softc *)periph->softc;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
ccb = cam_periph_getccb(periph, 1);
/* It is safe to retry this operation */
scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE,
FALSE, FALSE, load, SSD_FULL_SIZE, REWIND_TIMEOUT);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = (load)? MTIO_DSREG_LD : MTIO_DSREG_UNL;
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
xpt_release_ccb(ccb);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
if (error || load == 0)
softc->fileno = softc->blkno = (daddr_t) -1;
else if (error == 0)
softc->fileno = softc->blkno = (daddr_t) 0;
return (error);
}
static int
saerase(struct cam_periph *periph, int longerase)
{
union ccb *ccb;
struct sa_softc *softc;
int error;
softc = (struct sa_softc *)periph->softc;
if (softc->open_rdonly)
return (EBADF);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
ccb = cam_periph_getccb(periph, 1);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
scsi_erase(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, FALSE, longerase,
SSD_FULL_SIZE, ERASE_TIMEOUT);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_ZER;
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
Extend unit numbers to a full 10 bits (split into sections of the minor). Establish and use a control mode open. Control mode opens may open the device without locking, but are prohibited from all but some ioctls. MTIOCGET always works. MTIOCERRSTAT works, but the clearing of latched error status is contingent upon whether another application has the device open, in which case an interruptible perip acquire is done. MTSETBSIZ, MTSETDNSTY and MTCOMP also require a periph aquire. Relative fileno and blkno are tracked. Note that just about any error will make these undefined, and if you space to EOD or use hardware block positioning, these are also lost until the next UNLOAD or REWIND. Driver state is also tracked and recorded in the unit softc to be passed back in mt_dsreg for a MTIOCGET call. Thanks to Dan Strick for suggesting this. Reintroduce 2 filemarks at EOD for all but QIC devices. I really think it's wrong, but there is a lot of 3rd party software that depends upon this (not the least of which is tcopy). Introduce a SA_QUIRK_1FM to ensure that some devices can be marked as only being able to do 1 FM at EOD. At samount time force a load to BOT if we aren't mounted. If the LOAD command fails, use the REWIND command (e.g., for the IBM 3590 which for some gawdawful reason doesn't support the LOAD (to BOT) command). Also at samount time, if you don't know fixed or variable, try to *set* to one of the known fixed (or variable, for special case) density codes. We only have to do this once per boot, so it's not that painful. This is another way to try and figure out the wierd QIC devices without having to quirk everything in the universe. A substantial amount of cleanup as to what operations can and what operations cannot be retried. Don't retry space operations if they fail- it'll just lead to lossage. Not yet done is invalidating mounts correctly after errors. ENOTIME.
1999-02-05 07:32:52 +00:00
softc->dsreg = MTIO_DSREG_REST;
xpt_release_ccb(ccb);
return (error);
}
#endif /* _KERNEL */
/*
* Read tape block limits command.
*/
void
scsi_read_block_limits(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action,
struct scsi_read_block_limits_data *rlimit_buf,
u_int8_t sense_len, u_int32_t timeout)
{
struct scsi_read_block_limits *scsi_cmd;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_IN, tag_action,
(u_int8_t *)rlimit_buf, sizeof(*rlimit_buf), sense_len,
sizeof(*scsi_cmd), timeout);
scsi_cmd = (struct scsi_read_block_limits *)&csio->cdb_io.cdb_bytes;
bzero(scsi_cmd, sizeof(*scsi_cmd));
scsi_cmd->opcode = READ_BLOCK_LIMITS;
}
void
scsi_sa_read_write(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int readop, int sli,
int fixed, u_int32_t length, u_int8_t *data_ptr,
u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout)
{
struct scsi_sa_rw *scsi_cmd;
int read;
read = (readop & SCSI_RW_DIRMASK) == SCSI_RW_READ;
scsi_cmd = (struct scsi_sa_rw *)&csio->cdb_io.cdb_bytes;
scsi_cmd->opcode = read ? SA_READ : SA_WRITE;
scsi_cmd->sli_fixed = 0;
if (sli && read)
scsi_cmd->sli_fixed |= SAR_SLI;
if (fixed)
scsi_cmd->sli_fixed |= SARW_FIXED;
scsi_ulto3b(length, scsi_cmd->length);
scsi_cmd->control = 0;
cam_fill_csio(csio, retries, cbfcnp, (read ? CAM_DIR_IN : CAM_DIR_OUT) |
((readop & SCSI_RW_BIO) != 0 ? CAM_DATA_BIO : 0),
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
tag_action, data_ptr, dxfer_len, sense_len,
sizeof(*scsi_cmd), timeout);
}
void
scsi_load_unload(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int immediate, int eot,
int reten, int load, u_int8_t sense_len,
u_int32_t timeout)
{
struct scsi_load_unload *scsi_cmd;
scsi_cmd = (struct scsi_load_unload *)&csio->cdb_io.cdb_bytes;
bzero(scsi_cmd, sizeof(*scsi_cmd));
scsi_cmd->opcode = LOAD_UNLOAD;
if (immediate)
scsi_cmd->immediate = SLU_IMMED;
if (eot)
scsi_cmd->eot_reten_load |= SLU_EOT;
if (reten)
scsi_cmd->eot_reten_load |= SLU_RETEN;
if (load)
scsi_cmd->eot_reten_load |= SLU_LOAD;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action,
NULL, 0, sense_len, sizeof(*scsi_cmd), timeout);
}
void
scsi_rewind(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int immediate, u_int8_t sense_len,
u_int32_t timeout)
{
struct scsi_rewind *scsi_cmd;
scsi_cmd = (struct scsi_rewind *)&csio->cdb_io.cdb_bytes;
bzero(scsi_cmd, sizeof(*scsi_cmd));
scsi_cmd->opcode = REWIND;
if (immediate)
scsi_cmd->immediate = SREW_IMMED;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
0, sense_len, sizeof(*scsi_cmd), timeout);
}
void
scsi_space(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, scsi_space_code code,
u_int32_t count, u_int8_t sense_len, u_int32_t timeout)
{
struct scsi_space *scsi_cmd;
scsi_cmd = (struct scsi_space *)&csio->cdb_io.cdb_bytes;
scsi_cmd->opcode = SPACE;
scsi_cmd->code = code;
scsi_ulto3b(count, scsi_cmd->count);
scsi_cmd->control = 0;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
0, sense_len, sizeof(*scsi_cmd), timeout);
}
void
scsi_write_filemarks(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int immediate, int setmark,
u_int32_t num_marks, u_int8_t sense_len,
u_int32_t timeout)
{
struct scsi_write_filemarks *scsi_cmd;
scsi_cmd = (struct scsi_write_filemarks *)&csio->cdb_io.cdb_bytes;
bzero(scsi_cmd, sizeof(*scsi_cmd));
scsi_cmd->opcode = WRITE_FILEMARKS;
if (immediate)
scsi_cmd->byte2 |= SWFMRK_IMMED;
if (setmark)
scsi_cmd->byte2 |= SWFMRK_WSMK;
scsi_ulto3b(num_marks, scsi_cmd->num_marks);
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
0, sense_len, sizeof(*scsi_cmd), timeout);
}
/*
* The reserve and release unit commands differ only by their opcodes.
*/
void
scsi_reserve_release_unit(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int third_party,
int third_party_id, u_int8_t sense_len,
u_int32_t timeout, int reserve)
{
struct scsi_reserve_release_unit *scsi_cmd;
scsi_cmd = (struct scsi_reserve_release_unit *)&csio->cdb_io.cdb_bytes;
bzero(scsi_cmd, sizeof(*scsi_cmd));
if (reserve)
scsi_cmd->opcode = RESERVE_UNIT;
else
scsi_cmd->opcode = RELEASE_UNIT;
if (third_party) {
scsi_cmd->lun_thirdparty |= SRRU_3RD_PARTY;
scsi_cmd->lun_thirdparty |=
((third_party_id << SRRU_3RD_SHAMT) & SRRU_3RD_MASK);
}
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
0, sense_len, sizeof(*scsi_cmd), timeout);
}
void
scsi_erase(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int immediate, int long_erase,
u_int8_t sense_len, u_int32_t timeout)
{
struct scsi_erase *scsi_cmd;
scsi_cmd = (struct scsi_erase *)&csio->cdb_io.cdb_bytes;
bzero(scsi_cmd, sizeof(*scsi_cmd));
scsi_cmd->opcode = ERASE;
if (immediate)
scsi_cmd->lun_imm_long |= SE_IMMED;
if (long_erase)
scsi_cmd->lun_imm_long |= SE_LONG;
Add a SA_FLAG_COMP_SUPP flag (to quirk compression as SUPPORTED). Add a SA_FLAG_TAPE_FROZEN for (see below). Add a queue_count field to softc. Add HP T20* Travan-5 like tape device as a FIXED/512 type device. Works for me. Add TANDBERG SLR5 as a variable SA_QUIRK_1FM device. Change VIPER 2525 to 1024 byte blocksize. It's possible other drives should change too, but see below.. Change argument to sagetparams to be pointer to a sa_comp_t union- this can be either a DATA COMPRESSION or a DEVICE CONFIGURATION page. In general compression now tries to use the DATA COMPRESSION page and if that fails tries the DEVICE CONFIGURATION page. Change close routine to not rewind tape if there's a failure in either writing filemarks or in backing over one of two filemarks for a 2FM at EOT tape- instead mark the tape as 'frozen' and print a message saying that either an OFFLINE or REWIND or an MTEOM command is needed to clear this state (all bring certainty back to tape position). Fix sastrategy to not allow I/O to a frozen tape. Add MTIOCGETEOTMODEL/MTIOCSETEOTMODEL ioctls that get and set the EOT model for a tape drive (you can now dynamically change whether it's a 2 FM @ EOT or 1FM at EOT tape device). This ought to give folks something to handle the QIC drives we don't know about. Correctly propagate record of compression algorithm back. Clear FROZEN flag for EOM, REWIND and OFFLINE (and RETENSION and ERASE) cases. Fix an egregious bug in sadone that had left the device queue frozen for deferred (for fixed mode case) errors. Add comment in samount about how useless the test unit ready is for invalidating a mount (this has to be fixed later). Fix residual calculation (per Eivind) in saerror so that negative values for tape records being too large for the supplied buffer get caught. Do some other saerrro cleanup. Per Ken && Justin, add my name to copyright comment.
1999-05-11 04:01:35 +00:00
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
0, sense_len, sizeof(*scsi_cmd), timeout);
}
/*
* Read Tape Position command.
*/
void
scsi_read_position(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int hardsoft,
struct scsi_tape_position_data *sbp,
u_int8_t sense_len, u_int32_t timeout)
{
struct scsi_tape_read_position *scmd;
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_IN, tag_action,
(u_int8_t *)sbp, sizeof (*sbp), sense_len, sizeof(*scmd), timeout);
scmd = (struct scsi_tape_read_position *)&csio->cdb_io.cdb_bytes;
bzero(scmd, sizeof(*scmd));
scmd->opcode = READ_POSITION;
scmd->byte1 = hardsoft;
}
/*
* Set Tape Position command.
*/
void
scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int hardsoft, u_int32_t blkno,
u_int8_t sense_len, u_int32_t timeout)
{
struct scsi_tape_locate *scmd;
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action,
(u_int8_t *)NULL, 0, sense_len, sizeof(*scmd), timeout);
scmd = (struct scsi_tape_locate *)&csio->cdb_io.cdb_bytes;
bzero(scmd, sizeof(*scmd));
scmd->opcode = LOCATE;
if (hardsoft)
scmd->byte1 |= SA_SPOS_BT;
scsi_ulto4b(blkno, scmd->blkaddr);
}