aboutsummaryrefslogtreecommitdiff
path: root/include/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/scsi.h412
-rw-r--r--include/scsi/scsi_cmnd.h165
-rw-r--r--include/scsi/scsi_dbg.h21
-rw-r--r--include/scsi/scsi_device.h282
-rw-r--r--include/scsi/scsi_devinfo.h31
-rw-r--r--include/scsi/scsi_driver.h31
-rw-r--r--include/scsi/scsi_eh.h63
-rw-r--r--include/scsi/scsi_host.h642
-rw-r--r--include/scsi/scsi_ioctl.h50
-rw-r--r--include/scsi/scsi_request.h73
-rw-r--r--include/scsi/scsi_tcq.h134
-rw-r--r--include/scsi/scsi_transport.h48
-rw-r--r--include/scsi/scsi_transport_fc.h442
-rw-r--r--include/scsi/scsi_transport_iscsi.h178
-rw-r--r--include/scsi/scsi_transport_spi.h135
-rw-r--r--include/scsi/scsicam.h19
-rw-r--r--include/scsi/sg.h326
17 files changed, 3052 insertions, 0 deletions
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
new file mode 100644
index 00000000000..1d54c063ae5
--- /dev/null
+++ b/include/scsi/scsi.h
@@ -0,0 +1,412 @@
+/*
+ * This header file contains public constants and structures used by
+ * the scsi code for linux.
+ *
+ * For documentation on the OPCODES, MESSAGES, and SENSE values,
+ * please consult the SCSI standard.
+ */
+#ifndef _SCSI_SCSI_H
+#define _SCSI_SCSI_H
+
+#include <linux/types.h>
+
+/*
+ * The maximum sg list length SCSI can cope with
+ * (currently must be a power of 2 between 32 and 256)
+ */
+#define SCSI_MAX_PHYS_SEGMENTS MAX_PHYS_SEGMENTS
+
+
+/*
+ * SCSI command lengths
+ */
+
+extern const unsigned char scsi_command_size[8];
+#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
+
+/*
+ * SCSI device types
+ */
+
+#define MAX_SCSI_DEVICE_CODE 14
+extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
+
+/*
+ * SCSI opcodes
+ */
+
+#define TEST_UNIT_READY 0x00
+#define REZERO_UNIT 0x01
+#define REQUEST_SENSE 0x03
+#define FORMAT_UNIT 0x04
+#define READ_BLOCK_LIMITS 0x05
+#define REASSIGN_BLOCKS 0x07
+#define READ_6 0x08
+#define WRITE_6 0x0a
+#define SEEK_6 0x0b
+#define READ_REVERSE 0x0f
+#define WRITE_FILEMARKS 0x10
+#define SPACE 0x11
+#define INQUIRY 0x12
+#define RECOVER_BUFFERED_DATA 0x14
+#define MODE_SELECT 0x15
+#define RESERVE 0x16
+#define RELEASE 0x17
+#define COPY 0x18
+#define ERASE 0x19
+#define MODE_SENSE 0x1a
+#define START_STOP 0x1b
+#define RECEIVE_DIAGNOSTIC 0x1c
+#define SEND_DIAGNOSTIC 0x1d
+#define ALLOW_MEDIUM_REMOVAL 0x1e
+
+#define SET_WINDOW 0x24
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+#define WRITE_10 0x2a
+#define SEEK_10 0x2b
+#define WRITE_VERIFY 0x2e
+#define VERIFY 0x2f
+#define SEARCH_HIGH 0x30
+#define SEARCH_EQUAL 0x31
+#define SEARCH_LOW 0x32
+#define SET_LIMITS 0x33
+#define PRE_FETCH 0x34
+#define READ_POSITION 0x34
+#define SYNCHRONIZE_CACHE 0x35
+#define LOCK_UNLOCK_CACHE 0x36
+#define READ_DEFECT_DATA 0x37
+#define MEDIUM_SCAN 0x38
+#define COMPARE 0x39
+#define COPY_VERIFY 0x3a
+#define WRITE_BUFFER 0x3b
+#define READ_BUFFER 0x3c
+#define UPDATE_BLOCK 0x3d
+#define READ_LONG 0x3e
+#define WRITE_LONG 0x3f
+#define CHANGE_DEFINITION 0x40
+#define WRITE_SAME 0x41
+#define READ_TOC 0x43
+#define LOG_SELECT 0x4c
+#define LOG_SENSE 0x4d
+#define MODE_SELECT_10 0x55
+#define RESERVE_10 0x56
+#define RELEASE_10 0x57
+#define MODE_SENSE_10 0x5a
+#define PERSISTENT_RESERVE_IN 0x5e
+#define PERSISTENT_RESERVE_OUT 0x5f
+#define REPORT_LUNS 0xa0
+#define MOVE_MEDIUM 0xa5
+#define READ_12 0xa8
+#define WRITE_12 0xaa
+#define WRITE_VERIFY_12 0xae
+#define SEARCH_HIGH_12 0xb0
+#define SEARCH_EQUAL_12 0xb1
+#define SEARCH_LOW_12 0xb2
+#define READ_ELEMENT_STATUS 0xb8
+#define SEND_VOLUME_TAG 0xb6
+#define WRITE_LONG_2 0xea
+#define READ_16 0x88
+#define WRITE_16 0x8a
+#define VERIFY_16 0x8f
+#define SERVICE_ACTION_IN 0x9e
+/* values for service action in */
+#define SAI_READ_CAPACITY_16 0x10
+
+
+/*
+ * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
+ * T10/1561-D Revision 4 Draft dated 7th November 2002.
+ */
+#define SAM_STAT_GOOD 0x00
+#define SAM_STAT_CHECK_CONDITION 0x02
+#define SAM_STAT_CONDITION_MET 0x04
+#define SAM_STAT_BUSY 0x08
+#define SAM_STAT_INTERMEDIATE 0x10
+#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14
+#define SAM_STAT_RESERVATION_CONFLICT 0x18
+#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */
+#define SAM_STAT_TASK_SET_FULL 0x28
+#define SAM_STAT_ACA_ACTIVE 0x30
+#define SAM_STAT_TASK_ABORTED 0x40
+
+/** scsi_status_is_good - check the status return.
+ *
+ * @status: the status passed up from the driver (including host and
+ * driver components)
+ *
+ * This returns true for known good conditions that may be treated as
+ * command completed normally
+ */
+static inline int scsi_status_is_good(int status)
+{
+ /*
+ * FIXME: bit0 is listed as reserved in SCSI-2, but is
+ * significant in SCSI-3. For now, we follow the SCSI-2
+ * behaviour and ignore reserved bits.
+ */
+ status &= 0xfe;
+ return ((status == SAM_STAT_GOOD) ||
+ (status == SAM_STAT_INTERMEDIATE) ||
+ (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) ||
+ /* FIXME: this is obsolete in SAM-3 */
+ (status == SAM_STAT_COMMAND_TERMINATED));
+}
+
+/*
+ * Status codes. These are deprecated as they are shifted 1 bit right
+ * from those found in the SCSI standards. This causes confusion for
+ * applications that are ported to several OSes. Prefer SAM Status codes
+ * above.
+ */
+
+#define GOOD 0x00
+#define CHECK_CONDITION 0x01
+#define CONDITION_GOOD 0x02
+#define BUSY 0x04
+#define INTERMEDIATE_GOOD 0x08
+#define INTERMEDIATE_C_GOOD 0x0a
+#define RESERVATION_CONFLICT 0x0c
+#define COMMAND_TERMINATED 0x11
+#define QUEUE_FULL 0x14
+#define ACA_ACTIVE 0x18
+#define TASK_ABORTED 0x20
+
+#define STATUS_MASK 0xfe
+
+/*
+ * SENSE KEYS
+ */
+
+#define NO_SENSE 0x00
+#define RECOVERED_ERROR 0x01
+#define NOT_READY 0x02
+#define MEDIUM_ERROR 0x03
+#define HARDWARE_ERROR 0x04
+#define ILLEGAL_REQUEST 0x05
+#define UNIT_ATTENTION 0x06
+#define DATA_PROTECT 0x07
+#define BLANK_CHECK 0x08
+#define COPY_ABORTED 0x0a
+#define ABORTED_COMMAND 0x0b
+#define VOLUME_OVERFLOW 0x0d
+#define MISCOMPARE 0x0e
+
+
+/*
+ * DEVICE TYPES
+ */
+
+#define TYPE_DISK 0x00
+#define TYPE_TAPE 0x01
+#define TYPE_PRINTER 0x02
+#define TYPE_PROCESSOR 0x03 /* HP scanners use this */
+#define TYPE_WORM 0x04 /* Treated as ROM by our system */
+#define TYPE_ROM 0x05
+#define TYPE_SCANNER 0x06
+#define TYPE_MOD 0x07 /* Magneto-optical disk -
+ * - treated as TYPE_DISK */
+#define TYPE_MEDIUM_CHANGER 0x08
+#define TYPE_COMM 0x09 /* Communications device */
+#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */
+#define TYPE_RAID 0x0c
+#define TYPE_NO_LUN 0x7f
+
+/*
+ * standard mode-select header prepended to all mode-select commands
+ */
+
+struct ccs_modesel_head {
+ __u8 _r1; /* reserved */
+ __u8 medium; /* device-specific medium type */
+ __u8 _r2; /* reserved */
+ __u8 block_desc_length; /* block descriptor length */
+ __u8 density; /* device-specific density code */
+ __u8 number_blocks_hi; /* number of blocks in this block desc */
+ __u8 number_blocks_med;
+ __u8 number_blocks_lo;
+ __u8 _r3;
+ __u8 block_length_hi; /* block length for blocks in this desc */
+ __u8 block_length_med;
+ __u8 block_length_lo;
+};
+
+/*
+ * ScsiLun: 8 byte LUN.
+ */
+struct scsi_lun {
+ __u8 scsi_lun[8];
+};
+
+/*
+ * MESSAGE CODES
+ */
+
+#define COMMAND_COMPLETE 0x00
+#define EXTENDED_MESSAGE 0x01
+#define EXTENDED_MODIFY_DATA_POINTER 0x00
+#define EXTENDED_SDTR 0x01
+#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */
+#define EXTENDED_WDTR 0x03
+#define EXTENDED_PPR 0x04
+#define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05
+#define SAVE_POINTERS 0x02
+#define RESTORE_POINTERS 0x03
+#define DISCONNECT 0x04
+#define INITIATOR_ERROR 0x05
+#define ABORT_TASK_SET 0x06
+#define MESSAGE_REJECT 0x07
+#define NOP 0x08
+#define MSG_PARITY_ERROR 0x09
+#define LINKED_CMD_COMPLETE 0x0a
+#define LINKED_FLG_CMD_COMPLETE 0x0b
+#define TARGET_RESET 0x0c
+#define ABORT_TASK 0x0d
+#define CLEAR_TASK_SET 0x0e
+#define INITIATE_RECOVERY 0x0f /* SCSI-II only */
+#define RELEASE_RECOVERY 0x10 /* SCSI-II only */
+#define CLEAR_ACA 0x16
+#define LOGICAL_UNIT_RESET 0x17
+#define SIMPLE_QUEUE_TAG 0x20
+#define HEAD_OF_QUEUE_TAG 0x21
+#define ORDERED_QUEUE_TAG 0x22
+#define IGNORE_WIDE_RESIDUE 0x23
+#define ACA 0x24
+#define QAS_REQUEST 0x55
+
+/* Old SCSI2 names, don't use in new code */
+#define BUS_DEVICE_RESET TARGET_RESET
+#define ABORT ABORT_TASK_SET
+
+/*
+ * Host byte codes
+ */
+
+#define DID_OK 0x00 /* NO error */
+#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */
+#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */
+#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */
+#define DID_BAD_TARGET 0x04 /* BAD target. */
+#define DID_ABORT 0x05 /* Told to abort for some other reason */
+#define DID_PARITY 0x06 /* Parity error */
+#define DID_ERROR 0x07 /* Internal error */
+#define DID_RESET 0x08 /* Reset by somebody. */
+#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */
+#define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */
+#define DID_SOFT_ERROR 0x0b /* The low level driver just wish a retry */
+#define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */
+#define DRIVER_OK 0x00 /* Driver status */
+
+/*
+ * These indicate the error that occurred, and what is available.
+ */
+
+#define DRIVER_BUSY 0x01
+#define DRIVER_SOFT 0x02
+#define DRIVER_MEDIA 0x03
+#define DRIVER_ERROR 0x04
+
+#define DRIVER_INVALID 0x05
+#define DRIVER_TIMEOUT 0x06
+#define DRIVER_HARD 0x07
+#define DRIVER_SENSE 0x08
+
+#define SUGGEST_RETRY 0x10
+#define SUGGEST_ABORT 0x20
+#define SUGGEST_REMAP 0x30
+#define SUGGEST_DIE 0x40
+#define SUGGEST_SENSE 0x80
+#define SUGGEST_IS_OK 0xff
+
+#define DRIVER_MASK 0x0f
+#define SUGGEST_MASK 0xf0
+
+/*
+ * Internal return values.
+ */
+
+#define NEEDS_RETRY 0x2001
+#define SUCCESS 0x2002
+#define FAILED 0x2003
+#define QUEUED 0x2004
+#define SOFT_ERROR 0x2005
+#define ADD_TO_MLQUEUE 0x2006
+#define TIMEOUT_ERROR 0x2007
+
+/*
+ * Midlevel queue return values.
+ */
+#define SCSI_MLQUEUE_HOST_BUSY 0x1055
+#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
+#define SCSI_MLQUEUE_EH_RETRY 0x1057
+
+/*
+ * Use these to separate status msg and our bytes
+ *
+ * These are set by:
+ *
+ * status byte = set from target device
+ * msg_byte = return status from host adapter itself.
+ * host_byte = set by low-level driver to indicate status.
+ * driver_byte = set by mid-level.
+ */
+#define status_byte(result) (((result) >> 1) & 0x7f)
+#define msg_byte(result) (((result) >> 8) & 0xff)
+#define host_byte(result) (((result) >> 16) & 0xff)
+#define driver_byte(result) (((result) >> 24) & 0xff)
+#define suggestion(result) (driver_byte(result) & SUGGEST_MASK)
+
+#define sense_class(sense) (((sense) >> 4) & 0x7)
+#define sense_error(sense) ((sense) & 0xf)
+#define sense_valid(sense) ((sense) & 0x80);
+
+
+#define IDENTIFY_BASE 0x80
+#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\
+ ((can_disconnect) ? 0x40 : 0) |\
+ ((lun) & 0x07))
+
+/*
+ * struct scsi_device::scsi_level values. For SCSI devices other than those
+ * prior to SCSI-2 (i.e. over 12 years old) this value is (resp[2] + 1)
+ * where "resp" is a byte array of the response to an INQUIRY. The scsi_level
+ * variable is visible to the user via sysfs.
+ */
+
+#define SCSI_UNKNOWN 0
+#define SCSI_1 1
+#define SCSI_1_CCS 2
+#define SCSI_2 3
+#define SCSI_3 4 /* SPC */
+#define SCSI_SPC_2 5
+#define SCSI_SPC_3 6
+
+/*
+ * INQ PERIPHERAL QUALIFIERS
+ */
+#define SCSI_INQ_PQ_CON 0x00
+#define SCSI_INQ_PQ_NOT_CON 0x01
+#define SCSI_INQ_PQ_NOT_CAP 0x03
+
+
+/*
+ * Here are some scsi specific ioctl commands which are sometimes useful.
+ *
+ * Note that include/linux/cdrom.h also defines IOCTL 0x5300 - 0x5395
+ */
+
+/* Used to obtain PUN and LUN info. Conflicts with CDROMAUDIOBUFSIZ */
+#define SCSI_IOCTL_GET_IDLUN 0x5382
+
+/* 0x5383 and 0x5384 were used for SCSI_IOCTL_TAGGED_{ENABLE,DISABLE} */
+
+/* Used to obtain the host number of a device. */
+#define SCSI_IOCTL_PROBE_HOST 0x5385
+
+/* Used to obtain the bus number for a device */
+#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
+
+/* Used to obtain the PCI location of a device */
+#define SCSI_IOCTL_GET_PCI 0x5387
+
+#endif /* _SCSI_SCSI_H */
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
new file mode 100644
index 00000000000..9d9871c28ab
--- /dev/null
+++ b/include/scsi/scsi_cmnd.h
@@ -0,0 +1,165 @@
+#ifndef _SCSI_SCSI_CMND_H
+#define _SCSI_SCSI_CMND_H
+
+#include <linux/dma-mapping.h>
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct request;
+struct scatterlist;
+struct scsi_device;
+struct scsi_request;
+
+
+/* embedded in scsi_cmnd */
+struct scsi_pointer {
+ char *ptr; /* data pointer */
+ int this_residual; /* left in this buffer */
+ struct scatterlist *buffer; /* which buffer */
+ int buffers_residual; /* how many buffers left */
+
+ dma_addr_t dma_handle;
+
+ volatile int Status;
+ volatile int Message;
+ volatile int have_data_in;
+ volatile int sent_command;
+ volatile int phase;
+};
+
+struct scsi_cmnd {
+ int sc_magic;
+
+ struct scsi_device *device;
+ unsigned short state;
+ unsigned short owner;
+ struct scsi_request *sc_request;
+
+ struct list_head list; /* scsi_cmnd participates in queue lists */
+
+ struct list_head eh_entry; /* entry for the host eh_cmd_q */
+ int eh_state; /* Used for state tracking in error handlr */
+ int eh_eflags; /* Used by error handlr */
+ void (*done) (struct scsi_cmnd *); /* Mid-level done function */
+
+ /*
+ * A SCSI Command is assigned a nonzero serial_number when internal_cmnd
+ * passes it to the driver's queue command function. The serial_number
+ * is cleared when scsi_done is entered indicating that the command has
+ * been completed. If a timeout occurs, the serial number at the moment
+ * of timeout is copied into serial_number_at_timeout. By subsequently
+ * comparing the serial_number and serial_number_at_timeout fields
+ * during abort or reset processing, we can detect whether the command
+ * has already completed. This also detects cases where the command has
+ * completed and the SCSI Command structure has already being reused
+ * for another command, so that we can avoid incorrectly aborting or
+ * resetting the new command.
+ * The serial number is only unique per host.
+ */
+ unsigned long serial_number;
+ unsigned long serial_number_at_timeout;
+
+ int retries;
+ int allowed;
+ int timeout_per_command;
+ int timeout_total;
+ int timeout;
+
+ /*
+ * We handle the timeout differently if it happens when a reset,
+ * abort, etc are in process.
+ */
+ unsigned volatile char internal_timeout;
+
+ unsigned char cmd_len;
+ unsigned char old_cmd_len;
+ enum dma_data_direction sc_data_direction;
+ enum dma_data_direction sc_old_data_direction;
+
+ /* These elements define the operation we are about to perform */
+#define MAX_COMMAND_SIZE 16
+ unsigned char cmnd[MAX_COMMAND_SIZE];
+ unsigned request_bufflen; /* Actual request size */
+
+ struct timer_list eh_timeout; /* Used to time out the command. */
+ void *request_buffer; /* Actual requested buffer */
+
+ /* These elements define the operation we ultimately want to perform */
+ unsigned char data_cmnd[MAX_COMMAND_SIZE];
+ unsigned short old_use_sg; /* We save use_sg here when requesting
+ * sense info */
+ unsigned short use_sg; /* Number of pieces of scatter-gather */
+ unsigned short sglist_len; /* size of malloc'd scatter-gather list */
+ unsigned short abort_reason; /* If the mid-level code requests an
+ * abort, this is the reason. */
+ unsigned bufflen; /* Size of data buffer */
+ void *buffer; /* Data buffer */
+
+ unsigned underflow; /* Return error if less than
+ this amount is transferred */
+ unsigned old_underflow; /* save underflow here when reusing the
+ * command for error handling */
+
+ unsigned transfersize; /* How much we are guaranteed to
+ transfer with each SCSI transfer
+ (ie, between disconnect /
+ reconnects. Probably == sector
+ size */
+
+ int resid; /* Number of bytes requested to be
+ transferred less actual number
+ transferred (0 if not supported) */
+
+ struct request *request; /* The command we are
+ working on */
+
+#define SCSI_SENSE_BUFFERSIZE 96
+ unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE]; /* obtained by REQUEST SENSE
+ * when CHECK CONDITION is
+ * received on original command
+ * (auto-sense) */
+
+ /* Low-level done function - can be used by low-level driver to point
+ * to completion function. Not used by mid/upper level code. */
+ void (*scsi_done) (struct scsi_cmnd *);
+
+ /*
+ * The following fields can be written to by the host specific code.
+ * Everything else should be left alone.
+ */
+ struct scsi_pointer SCp; /* Scratchpad used by some host adapters */
+
+ unsigned char *host_scribble; /* The host adapter is allowed to
+ * call scsi_malloc and get some memory
+ * and hang it here. The host adapter
+ * is also expected to call scsi_free
+ * to release this memory. (The memory
+ * obtained by scsi_malloc is guaranteed
+ * to be at an address < 16Mb). */
+
+ int result; /* Status code from lower level driver */
+
+ unsigned char tag; /* SCSI-II queued command tag */
+ unsigned long pid; /* Process ID, starts at 0. Unique per host. */
+};
+
+/*
+ * These are the values that scsi_cmd->state can take.
+ */
+#define SCSI_STATE_TIMEOUT 0x1000
+#define SCSI_STATE_FINISHED 0x1001
+#define SCSI_STATE_FAILED 0x1002
+#define SCSI_STATE_QUEUED 0x1003
+#define SCSI_STATE_UNUSED 0x1006
+#define SCSI_STATE_DISCONNECTING 0x1008
+#define SCSI_STATE_INITIALIZING 0x1009
+#define SCSI_STATE_BHQUEUE 0x100a
+#define SCSI_STATE_MLQUEUE 0x100b
+
+
+extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, int);
+extern void scsi_put_command(struct scsi_cmnd *);
+extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
+extern void scsi_finish_command(struct scsi_cmnd *cmd);
+
+#endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
new file mode 100644
index 00000000000..12e90934a7a
--- /dev/null
+++ b/include/scsi/scsi_dbg.h
@@ -0,0 +1,21 @@
+#ifndef _SCSI_SCSI_DBG_H
+#define _SCSI_SCSI_DBG_H
+
+struct scsi_cmnd;
+struct scsi_request;
+
+extern void scsi_print_command(struct scsi_cmnd *);
+extern void __scsi_print_command(unsigned char *);
+extern void scsi_print_sense(const char *, struct scsi_cmnd *);
+extern void scsi_print_req_sense(const char *, struct scsi_request *);
+extern void __scsi_print_sense(const char *name,
+ const unsigned char *sense_buffer,
+ int sense_len);
+extern void scsi_print_driverbyte(int);
+extern void scsi_print_hostbyte(int);
+extern void scsi_print_status(unsigned char);
+extern int scsi_print_msg(const unsigned char *);
+extern const char *scsi_sense_key_string(unsigned char);
+extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
+
+#endif /* _SCSI_SCSI_DBG_H */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
new file mode 100644
index 00000000000..07d974051b0
--- /dev/null
+++ b/include/scsi/scsi_device.h
@@ -0,0 +1,282 @@
+#ifndef _SCSI_SCSI_DEVICE_H
+#define _SCSI_SCSI_DEVICE_H
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+
+struct request_queue;
+struct scsi_cmnd;
+struct scsi_mode_data;
+
+
+/*
+ * sdev state: If you alter this, you also need to alter scsi_sysfs.c
+ * (for the ascii descriptions) and the state model enforcer:
+ * scsi_lib:scsi_device_set_state().
+ */
+enum scsi_device_state {
+ SDEV_CREATED = 1, /* device created but not added to sysfs
+ * Only internal commands allowed (for inq) */
+ SDEV_RUNNING, /* device properly configured
+ * All commands allowed */
+ SDEV_CANCEL, /* beginning to delete device
+ * Only error handler commands allowed */
+ SDEV_DEL, /* device deleted
+ * no commands allowed */
+ SDEV_QUIESCE, /* Device quiescent. No block commands
+ * will be accepted, only specials (which
+ * originate in the mid-layer) */
+ SDEV_OFFLINE, /* Device offlined (by error handling or
+ * user request */
+ SDEV_BLOCK, /* Device blocked by scsi lld. No scsi
+ * commands from user or midlayer should be issued
+ * to the scsi lld. */
+};
+
+struct scsi_device {
+ struct Scsi_Host *host;
+ struct request_queue *request_queue;
+
+ /* the next two are protected by the host->host_lock */
+ struct list_head siblings; /* list of all devices on this host */
+ struct list_head same_target_siblings; /* just the devices sharing same target id */
+
+ volatile unsigned short device_busy; /* commands actually active on low-level */
+ spinlock_t sdev_lock; /* also the request queue_lock */
+ spinlock_t list_lock;
+ struct list_head cmd_list; /* queue of in use SCSI Command structures */
+ struct list_head starved_entry;
+ struct scsi_cmnd *current_cmnd; /* currently active command */
+ unsigned short queue_depth; /* How deep of a queue we want */
+ unsigned short last_queue_full_depth; /* These two are used by */
+ unsigned short last_queue_full_count; /* scsi_track_queue_full() */
+ unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
+ jiffie count on our counter, they
+ could all be from the same event. */
+
+ unsigned int id, lun, channel;
+
+ unsigned int manufacturer; /* Manufacturer of device, for using
+ * vendor-specific cmd's */
+ unsigned sector_size; /* size in bytes */
+
+ void *hostdata; /* available to low-level driver */
+ char devfs_name[256]; /* devfs junk */
+ char type;
+ char scsi_level;
+ char inq_periph_qual; /* PQ from INQUIRY data */
+ unsigned char inquiry_len; /* valid bytes in 'inquiry' */
+ unsigned char * inquiry; /* INQUIRY response data */
+ char * vendor; /* [back_compat] point into 'inquiry' ... */
+ char * model; /* ... after scan; point to static string */
+ char * rev; /* ... "nullnullnullnull" before scan */
+ unsigned char current_tag; /* current tag */
+ struct scsi_target *sdev_target; /* used only for single_lun */
+
+ unsigned int sdev_bflags; /* black/white flags as also found in
+ * scsi_devinfo.[hc]. For now used only to
+ * pass settings from slave_alloc to scsi
+ * core. */
+ unsigned writeable:1;
+ unsigned removable:1;
+ unsigned changed:1; /* Data invalid due to media change */
+ unsigned busy:1; /* Used to prevent races */
+ unsigned lockable:1; /* Able to prevent media removal */
+ unsigned locked:1; /* Media removal disabled */
+ unsigned borken:1; /* Tell the Seagate driver to be
+ * painfully slow on this device */
+ unsigned disconnect:1; /* can disconnect */
+ unsigned soft_reset:1; /* Uses soft reset option */
+ unsigned sdtr:1; /* Device supports SDTR messages */
+ unsigned wdtr:1; /* Device supports WDTR messages */
+ unsigned ppr:1; /* Device supports PPR messages */
+ unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */
+ unsigned simple_tags:1; /* simple queue tag messages are enabled */
+ unsigned ordered_tags:1;/* ordered queue tag messages are enabled */
+ unsigned single_lun:1; /* Indicates we should only allow I/O to
+ * one of the luns for the device at a
+ * time. */
+ unsigned was_reset:1; /* There was a bus reset on the bus for
+ * this device */
+ unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
+ * because we did a bus reset. */
+ unsigned use_10_for_rw:1; /* first try 10-byte read / write */
+ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
+ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */
+ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */
+ unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
+ unsigned no_start_on_add:1; /* do not issue start on add */
+ unsigned allow_restart:1; /* issue START_UNIT in error handler */
+ unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
+ unsigned select_no_atn:1;
+ unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
+ unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
+
+ unsigned int device_blocked; /* Device returned QUEUE_FULL. */
+
+ unsigned int max_device_blocked; /* what device_blocked counts down from */
+#define SCSI_DEFAULT_DEVICE_BLOCKED 3
+
+ atomic_t iorequest_cnt;
+ atomic_t iodone_cnt;
+ atomic_t ioerr_cnt;
+
+ int timeout;
+
+ struct device sdev_gendev;
+ struct class_device sdev_classdev;
+
+ enum scsi_device_state sdev_state;
+ unsigned long sdev_data[0];
+} __attribute__((aligned(sizeof(unsigned long))));
+#define to_scsi_device(d) \
+ container_of(d, struct scsi_device, sdev_gendev)
+#define class_to_sdev(d) \
+ container_of(d, struct scsi_device, sdev_classdev)
+#define transport_class_to_sdev(class_dev) \
+ to_scsi_device(class_dev->dev)
+
+/*
+ * scsi_target: representation of a scsi target, for now, this is only
+ * used for single_lun devices. If no one has active IO to the target,
+ * starget_sdev_user is NULL, else it points to the active sdev.
+ */
+struct scsi_target {
+ struct scsi_device *starget_sdev_user;
+ struct list_head siblings;
+ struct list_head devices;
+ struct device dev;
+ unsigned int reap_ref; /* protected by the host lock */
+ unsigned int channel;
+ unsigned int id; /* target id ... replace
+ * scsi_device.id eventually */
+ unsigned long create:1; /* signal that it needs to be added */
+ unsigned long starget_data[0];
+} __attribute__((aligned(sizeof(unsigned long))));
+
+#define to_scsi_target(d) container_of(d, struct scsi_target, dev)
+static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
+{
+ return to_scsi_target(sdev->sdev_gendev.parent);
+}
+#define transport_class_to_starget(class_dev) \
+ to_scsi_target(class_dev->dev)
+
+extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
+ uint, uint, uint, void *hostdata);
+#define scsi_add_device(host, channel, target, lun) \
+ __scsi_add_device(host, channel, target, lun, NULL)
+extern void scsi_remove_device(struct scsi_device *);
+extern int scsi_device_cancel(struct scsi_device *, int);
+
+extern int scsi_device_get(struct scsi_device *);
+extern void scsi_device_put(struct scsi_device *);
+extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,
+ uint, uint, uint);
+extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *,
+ uint, uint, uint);
+extern struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *,
+ uint);
+extern struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *,
+ uint);
+extern void starget_for_each_device(struct scsi_target *, void *,
+ void (*fn)(struct scsi_device *, void *));
+
+/* only exposed to implement shost_for_each_device */
+extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
+ struct scsi_device *);
+
+/**
+ * shost_for_each_device - iterate over all devices of a host
+ * @sdev: iterator
+ * @host: host whiches devices we want to iterate over
+ *
+ * This traverses over each devices of @shost. The devices have
+ * a reference that must be released by scsi_host_put when breaking
+ * out of the loop.
+ */
+#define shost_for_each_device(sdev, shost) \
+ for ((sdev) = __scsi_iterate_devices((shost), NULL); \
+ (sdev); \
+ (sdev) = __scsi_iterate_devices((shost), (sdev)))
+
+/**
+ * __shost_for_each_device - iterate over all devices of a host (UNLOCKED)
+ * @sdev: iterator
+ * @host: host whiches devices we want to iterate over
+ *
+ * This traverses over each devices of @shost. It does _not_ take a
+ * reference on the scsi_device, thus it the whole loop must be protected
+ * by shost->host_lock.
+ *
+ * Note: The only reason why drivers would want to use this is because
+ * they're need to access the device list in irq context. Otherwise you
+ * really want to use shost_for_each_device instead.
+ */
+#define __shost_for_each_device(sdev, shost) \
+ list_for_each_entry((sdev), &((shost)->__devices), siblings)
+
+extern void scsi_adjust_queue_depth(struct scsi_device *, int, int);
+extern int scsi_track_queue_full(struct scsi_device *, int);
+
+extern int scsi_set_medium_removal(struct scsi_device *, char);
+
+extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
+ unsigned char *buffer, int len, int timeout,
+ int retries, struct scsi_mode_data *data);
+extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,
+ int retries);
+extern int scsi_device_set_state(struct scsi_device *sdev,
+ enum scsi_device_state state);
+extern int scsi_device_quiesce(struct scsi_device *sdev);
+extern void scsi_device_resume(struct scsi_device *sdev);
+extern void scsi_target_quiesce(struct scsi_target *);
+extern void scsi_target_resume(struct scsi_target *);
+extern void scsi_scan_target(struct device *parent, unsigned int channel,
+ unsigned int id, unsigned int lun, int rescan);
+extern void scsi_target_reap(struct scsi_target *);
+extern void scsi_target_block(struct device *);
+extern void scsi_target_unblock(struct device *);
+extern void scsi_remove_target(struct device *);
+extern const char *scsi_device_state_name(enum scsi_device_state);
+extern int scsi_is_sdev_device(const struct device *);
+extern int scsi_is_target_device(const struct device *);
+static inline int scsi_device_online(struct scsi_device *sdev)
+{
+ return sdev->sdev_state != SDEV_OFFLINE;
+}
+
+/* accessor functions for the SCSI parameters */
+static inline int scsi_device_sync(struct scsi_device *sdev)
+{
+ return sdev->sdtr;
+}
+static inline int scsi_device_wide(struct scsi_device *sdev)
+{
+ return sdev->wdtr;
+}
+static inline int scsi_device_dt(struct scsi_device *sdev)
+{
+ return sdev->ppr;
+}
+static inline int scsi_device_dt_only(struct scsi_device *sdev)
+{
+ if (sdev->inquiry_len < 57)
+ return 0;
+ return (sdev->inquiry[56] & 0x0c) == 0x04;
+}
+static inline int scsi_device_ius(struct scsi_device *sdev)
+{
+ if (sdev->inquiry_len < 57)
+ return 0;
+ return sdev->inquiry[56] & 0x01;
+}
+static inline int scsi_device_qas(struct scsi_device *sdev)
+{
+ if (sdev->inquiry_len < 57)
+ return 0;
+ return sdev->inquiry[56] & 0x02;
+}
+#endif /* _SCSI_SCSI_DEVICE_H */
diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h
new file mode 100644
index 00000000000..174101b2069
--- /dev/null
+++ b/include/scsi/scsi_devinfo.h
@@ -0,0 +1,31 @@
+#ifndef _SCSI_SCSI_DEVINFO_H
+#define _SCSI_SCSI_DEVINFO_H
+/*
+ * Flags for SCSI devices that need special treatment
+ */
+#define BLIST_NOLUN 0x001 /* Only scan LUN 0 */
+#define BLIST_FORCELUN 0x002 /* Known to have LUNs, force scanning,
+ deprecated: Use max_luns=N */
+#define BLIST_BORKEN 0x004 /* Flag for broken handshaking */
+#define BLIST_KEY 0x008 /* unlock by special command */
+#define BLIST_SINGLELUN 0x010 /* Do not use LUNs in parallel */
+#define BLIST_NOTQ 0x020 /* Buggy Tagged Command Queuing */
+#define BLIST_SPARSELUN 0x040 /* Non consecutive LUN numbering */
+#define BLIST_MAX5LUN 0x080 /* Avoid LUNS >= 5 */
+#define BLIST_ISROM 0x100 /* Treat as (removable) CD-ROM */
+#define BLIST_LARGELUN 0x200 /* LUNs past 7 on a SCSI-2 device */
+#define BLIST_INQUIRY_36 0x400 /* override additional length field */
+#define BLIST_INQUIRY_58 0x800 /* ... for broken inquiry responses */
+#define BLIST_NOSTARTONADD 0x1000 /* do not do automatic start on add */
+#define BLIST_MS_SKIP_PAGE_08 0x2000 /* do not send ms page 0x08 */