You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
This commit is contained in:
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
#define BLIST_MS_SKIP_PAGE_3F 0x4000 /* do not send ms page 0x3f */
|
||||
#define BLIST_USE_10_BYTE_MS 0x8000 /* use 10 byte ms before 6 byte ms */
|
||||
#define BLIST_MS_192_BYTES_FOR_3F 0x10000 /* 192 byte ms page 0x3f request */
|
||||
#define BLIST_REPORTLUN2 0x20000 /* try REPORT_LUNS even for SCSI-2 devs
|
||||
(if HBA supports more than 8 LUNs) */
|
||||
#define BLIST_NOREPORTLUN 0x40000 /* don't try REPORT_LUNS scan (SCSI-3 devs) */
|
||||
#define BLIST_NOT_LOCKABLE 0x80000 /* don't use PREVENT-ALLOW commands */
|
||||
#define BLIST_NO_ULD_ATTACH 0x100000 /* device is actually for RAID config */
|
||||
#define BLIST_SELECT_NO_ATN 0x200000 /* select without ATN */
|
||||
#define BLIST_RETRY_HWERROR 0x400000 /* retry HARDWARE_ERROR */
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef _SCSI_SCSI_DRIVER_H
|
||||
#define _SCSI_SCSI_DRIVER_H
|
||||
|
||||
#include <linux/device.h>
|
||||
|
||||
struct module;
|
||||
struct scsi_cmnd;
|
||||
|
||||
|
||||
struct scsi_driver {
|
||||
struct module *owner;
|
||||
struct device_driver gendrv;
|
||||
|
||||
int (*init_command)(struct scsi_cmnd *);
|
||||
void (*rescan)(struct device *);
|
||||
int (*issue_flush)(struct device *, sector_t *);
|
||||
int (*prepare_flush)(struct request_queue *, struct request *);
|
||||
void (*end_flush)(struct request_queue *, struct request *);
|
||||
};
|
||||
#define to_scsi_driver(drv) \
|
||||
container_of((drv), struct scsi_driver, gendrv)
|
||||
|
||||
extern int scsi_register_driver(struct device_driver *);
|
||||
#define scsi_unregister_driver(drv) \
|
||||
driver_unregister(drv);
|
||||
|
||||
extern int scsi_register_interface(struct class_interface *);
|
||||
#define scsi_unregister_interface(intf) \
|
||||
class_interface_unregister(intf)
|
||||
|
||||
#endif /* _SCSI_SCSI_DRIVER_H */
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef _SCSI_SCSI_EH_H
|
||||
#define _SCSI_SCSI_EH_H
|
||||
|
||||
struct scsi_cmnd;
|
||||
struct scsi_device;
|
||||
struct scsi_request;
|
||||
struct Scsi_Host;
|
||||
|
||||
/*
|
||||
* This is a slightly modified SCSI sense "descriptor" format header.
|
||||
* The addition is to allow the 0x70 and 0x71 response codes. The idea
|
||||
* is to place the salient data from either "fixed" or "descriptor" sense
|
||||
* format into one structure to ease application processing.
|
||||
*
|
||||
* The original sense buffer should be kept around for those cases
|
||||
* in which more information is required (e.g. the LBA of a MEDIUM ERROR).
|
||||
*/
|
||||
struct scsi_sense_hdr { /* See SPC-3 section 4.5 */
|
||||
u8 response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
|
||||
u8 sense_key;
|
||||
u8 asc;
|
||||
u8 ascq;
|
||||
u8 byte4;
|
||||
u8 byte5;
|
||||
u8 byte6;
|
||||
u8 additional_length; /* always 0 for fixed sense format */
|
||||
};
|
||||
|
||||
|
||||
extern void scsi_add_timer(struct scsi_cmnd *, int,
|
||||
void (*)(struct scsi_cmnd *));
|
||||
extern int scsi_delete_timer(struct scsi_cmnd *);
|
||||
extern void scsi_report_bus_reset(struct Scsi_Host *, int);
|
||||
extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
|
||||
extern int scsi_block_when_processing_errors(struct scsi_device *);
|
||||
extern int scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
|
||||
struct scsi_sense_hdr *sshdr);
|
||||
extern int scsi_request_normalize_sense(struct scsi_request *sreq,
|
||||
struct scsi_sense_hdr *sshdr);
|
||||
extern int scsi_command_normalize_sense(struct scsi_cmnd *cmd,
|
||||
struct scsi_sense_hdr *sshdr);
|
||||
|
||||
static inline int scsi_sense_is_deferred(struct scsi_sense_hdr *sshdr)
|
||||
{
|
||||
return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1));
|
||||
}
|
||||
|
||||
extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
|
||||
int desc_type);
|
||||
|
||||
extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,
|
||||
u64 * info_out);
|
||||
|
||||
/*
|
||||
* Reset request from external source
|
||||
*/
|
||||
#define SCSI_TRY_RESET_DEVICE 1
|
||||
#define SCSI_TRY_RESET_BUS 2
|
||||
#define SCSI_TRY_RESET_HOST 3
|
||||
|
||||
extern int scsi_reset_provider(struct scsi_device *, int);
|
||||
|
||||
#endif /* _SCSI_SCSI_EH_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
#ifndef _SCSI_IOCTL_H
|
||||
#define _SCSI_IOCTL_H
|
||||
|
||||
#define SCSI_IOCTL_SEND_COMMAND 1
|
||||
#define SCSI_IOCTL_TEST_UNIT_READY 2
|
||||
#define SCSI_IOCTL_BENCHMARK_COMMAND 3
|
||||
#define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters */
|
||||
#define SCSI_IOCTL_START_UNIT 5
|
||||
#define SCSI_IOCTL_STOP_UNIT 6
|
||||
/* The door lock/unlock constants are compatible with Sun constants for
|
||||
the cdrom */
|
||||
#define SCSI_IOCTL_DOORLOCK 0x5380 /* lock the eject mechanism */
|
||||
#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* unlock the mechanism */
|
||||
|
||||
#define SCSI_REMOVAL_PREVENT 1
|
||||
#define SCSI_REMOVAL_ALLOW 0
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct scsi_device;
|
||||
|
||||
/*
|
||||
* Structures used for scsi_ioctl et al.
|
||||
*/
|
||||
|
||||
typedef struct scsi_ioctl_command {
|
||||
unsigned int inlen;
|
||||
unsigned int outlen;
|
||||
unsigned char data[0];
|
||||
} Scsi_Ioctl_Command;
|
||||
|
||||
typedef struct scsi_idlun {
|
||||
__u32 dev_id;
|
||||
__u32 host_unique_id;
|
||||
} Scsi_Idlun;
|
||||
|
||||
/* Fibre Channel WWN, port_id struct */
|
||||
typedef struct scsi_fctargaddress {
|
||||
__u32 host_port_id;
|
||||
unsigned char host_wwn[8]; // include NULL term.
|
||||
} Scsi_FCTargAddress;
|
||||
|
||||
extern int scsi_ioctl(struct scsi_device *, int, void __user *);
|
||||
extern int scsi_ioctl_send_command(struct scsi_device *,
|
||||
struct scsi_ioctl_command __user *);
|
||||
extern int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
|
||||
void __user *arg, struct file *filp);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _SCSI_IOCTL_H */
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef _SCSI_SCSI_REQUEST_H
|
||||
#define _SCSI_SCSI_REQUEST_H
|
||||
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
|
||||
struct request;
|
||||
struct scsi_cmnd;
|
||||
struct scsi_device;
|
||||
struct Scsi_Host;
|
||||
|
||||
|
||||
/*
|
||||
* This is essentially a slimmed down version of Scsi_Cmnd. The point of
|
||||
* having this is that requests that are injected into the queue as result
|
||||
* of things like ioctls and character devices shouldn't be using a
|
||||
* Scsi_Cmnd until such a time that the command is actually at the head
|
||||
* of the queue and being sent to the driver.
|
||||
*/
|
||||
struct scsi_request {
|
||||
int sr_magic;
|
||||
int sr_result; /* Status code from lower level driver */
|
||||
unsigned char sr_sense_buffer[SCSI_SENSE_BUFFERSIZE]; /* obtained by REQUEST SENSE
|
||||
* when CHECK CONDITION is
|
||||
* received on original command
|
||||
* (auto-sense) */
|
||||
|
||||
struct Scsi_Host *sr_host;
|
||||
struct scsi_device *sr_device;
|
||||
struct scsi_cmnd *sr_command;
|
||||
struct request *sr_request; /* A copy of the command we are
|
||||
working on */
|
||||
unsigned sr_bufflen; /* Size of data buffer */
|
||||
void *sr_buffer; /* Data buffer */
|
||||
int sr_allowed;
|
||||
enum dma_data_direction sr_data_direction;
|
||||
unsigned char sr_cmd_len;
|
||||
unsigned char sr_cmnd[MAX_COMMAND_SIZE];
|
||||
void (*sr_done) (struct scsi_cmnd *); /* Mid-level done function */
|
||||
int sr_timeout_per_command;
|
||||
unsigned short sr_use_sg; /* Number of pieces of scatter-gather */
|
||||
unsigned short sr_sglist_len; /* size of malloc'd scatter-gather list */
|
||||
unsigned sr_underflow; /* Return error if less than
|
||||
this amount is transferred */
|
||||
void *upper_private_data; /* reserved for owner (usually upper
|
||||
level driver) of this request */
|
||||
};
|
||||
|
||||
extern struct scsi_request *scsi_allocate_request(struct scsi_device *, int);
|
||||
extern void scsi_release_request(struct scsi_request *);
|
||||
extern void scsi_wait_req(struct scsi_request *, const void *cmnd,
|
||||
void *buffer, unsigned bufflen,
|
||||
int timeout, int retries);
|
||||
extern void scsi_do_req(struct scsi_request *, const void *cmnd,
|
||||
void *buffer, unsigned bufflen,
|
||||
void (*done) (struct scsi_cmnd *),
|
||||
int timeout, int retries);
|
||||
|
||||
struct scsi_mode_data {
|
||||
__u32 length;
|
||||
__u16 block_descriptor_length;
|
||||
__u8 medium_type;
|
||||
__u8 device_specific;
|
||||
__u8 header_length;
|
||||
__u8 longlba:1;
|
||||
};
|
||||
|
||||
extern int __scsi_mode_sense(struct scsi_request *SRpnt, int dbd,
|
||||
int modepage, unsigned char *buffer, int len,
|
||||
int timeout, int retries,
|
||||
struct scsi_mode_data *data);
|
||||
|
||||
|
||||
#endif /* _SCSI_SCSI_REQUEST_H */
|
||||
@@ -0,0 +1,134 @@
|
||||
#ifndef _SCSI_SCSI_TCQ_H
|
||||
#define _SCSI_SCSI_TCQ_H
|
||||
|
||||
#include <linux/blkdev.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
|
||||
|
||||
#define MSG_SIMPLE_TAG 0x20
|
||||
#define MSG_HEAD_TAG 0x21
|
||||
#define MSG_ORDERED_TAG 0x22
|
||||
|
||||
#define SCSI_NO_TAG (-1) /* identify no tag in use */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* scsi_get_tag_type - get the type of tag the device supports
|
||||
* @sdev: the scsi device
|
||||
*
|
||||
* Notes:
|
||||
* If the drive only supports simple tags, returns MSG_SIMPLE_TAG
|
||||
* if it supports all tag types, returns MSG_ORDERED_TAG.
|
||||
*/
|
||||
static inline int scsi_get_tag_type(struct scsi_device *sdev)
|
||||
{
|
||||
if (!sdev->tagged_supported)
|
||||
return 0;
|
||||
if (sdev->ordered_tags)
|
||||
return MSG_ORDERED_TAG;
|
||||
if (sdev->simple_tags)
|
||||
return MSG_SIMPLE_TAG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag)
|
||||
{
|
||||
switch (tag) {
|
||||
case MSG_ORDERED_TAG:
|
||||
sdev->ordered_tags = 1;
|
||||
/* fall through */
|
||||
case MSG_SIMPLE_TAG:
|
||||
sdev->simple_tags = 1;
|
||||
break;
|
||||
case 0:
|
||||
/* fall through */
|
||||
default:
|
||||
sdev->ordered_tags = 0;
|
||||
sdev->simple_tags = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* scsi_activate_tcq - turn on tag command queueing
|
||||
* @SDpnt: device to turn on TCQ for
|
||||
* @depth: queue depth
|
||||
*
|
||||
* Notes:
|
||||
* Eventually, I hope depth would be the maximum depth
|
||||
* the device could cope with and the real queue depth
|
||||
* would be adjustable from 0 to depth.
|
||||
**/
|
||||
static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth)
|
||||
{
|
||||
if (!sdev->tagged_supported)
|
||||
return;
|
||||
|
||||
if (!blk_queue_tagged(sdev->request_queue))
|
||||
blk_queue_init_tags(sdev->request_queue, depth, NULL);
|
||||
|
||||
scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* scsi_deactivate_tcq - turn off tag command queueing
|
||||
* @SDpnt: device to turn off TCQ for
|
||||
**/
|
||||
static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
|
||||
{
|
||||
if (blk_queue_tagged(sdev->request_queue))
|
||||
blk_queue_free_tags(sdev->request_queue);
|
||||
scsi_adjust_queue_depth(sdev, 0, depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* scsi_populate_tag_msg - place a tag message in a buffer
|
||||
* @SCpnt: pointer to the Scsi_Cmnd for the tag
|
||||
* @msg: pointer to the area to place the tag
|
||||
*
|
||||
* Notes:
|
||||
* designed to create the correct type of tag message for the
|
||||
* particular request. Returns the size of the tag message.
|
||||
* May return 0 if TCQ is disabled for this device.
|
||||
**/
|
||||
static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg)
|
||||
{
|
||||
struct request *req = cmd->request;
|
||||
struct scsi_device *sdev = cmd->device;
|
||||
|
||||
if (blk_rq_tagged(req)) {
|
||||
if (sdev->ordered_tags && req->flags & REQ_HARDBARRIER)
|
||||
*msg++ = MSG_ORDERED_TAG;
|
||||
else
|
||||
*msg++ = MSG_SIMPLE_TAG;
|
||||
*msg++ = req->tag;
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* scsi_find_tag - find a tagged command by device
|
||||
* @SDpnt: pointer to the ScSI device
|
||||
* @tag: the tag number
|
||||
*
|
||||
* Notes:
|
||||
* Only works with tags allocated by the generic blk layer.
|
||||
**/
|
||||
static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
|
||||
{
|
||||
|
||||
struct request *req;
|
||||
|
||||
if (tag != SCSI_NO_TAG) {
|
||||
req = blk_queue_find_tag(sdev->request_queue, tag);
|
||||
return req ? (struct scsi_cmnd *)req->special : NULL;
|
||||
}
|
||||
|
||||
/* single command, look in space */
|
||||
return sdev->current_cmnd;
|
||||
}
|
||||
|
||||
#endif /* _SCSI_SCSI_TCQ_H */
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Transport specific attributes.
|
||||
*
|
||||
* Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef SCSI_TRANSPORT_H
|
||||
#define SCSI_TRANSPORT_H
|
||||
|
||||
#include <linux/transport_class.h>
|
||||
|
||||
struct scsi_transport_template {
|
||||
/* the attribute containers */
|
||||
struct transport_container host_attrs;
|
||||
struct transport_container target_attrs;
|
||||
struct transport_container device_attrs;
|
||||
|
||||
/* The size of the specific transport attribute structure (a
|
||||
* space of this size will be left at the end of the
|
||||
* scsi_* structure */
|
||||
int device_size;
|
||||
int target_size;
|
||||
int host_size;
|
||||
|
||||
/*
|
||||
* True if the transport wants to use a host-based work-queue
|
||||
*/
|
||||
unsigned int create_work_queue : 1;
|
||||
};
|
||||
|
||||
#define transport_class_to_shost(tc) \
|
||||
dev_to_shost((tc)->dev)
|
||||
|
||||
|
||||
#endif /* SCSI_TRANSPORT_H */
|
||||
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* FiberChannel transport specific attributes exported to sysfs.
|
||||
*
|
||||
* Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* ========
|
||||
*
|
||||
* Copyright (C) 2004-2005 James Smart, Emulex Corporation
|
||||
* Rewrite for host, target, device, and remote port attributes,
|
||||
* statistics, and service functions...
|
||||
*
|
||||
*/
|
||||
#ifndef SCSI_TRANSPORT_FC_H
|
||||
#define SCSI_TRANSPORT_FC_H
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
struct scsi_transport_template;
|
||||
|
||||
|
||||
/*
|
||||
* FC Port definitions - Following FC HBAAPI guidelines
|
||||
*
|
||||
* Note: Not all binary values for the different fields match HBAAPI.
|
||||
* Instead, we use densely packed ordinal values or enums.
|
||||
* We get away with this as we never present the actual binary values
|
||||
* externally. For sysfs, we always present the string that describes
|
||||
* the value. Thus, an admin doesn't need a magic HBAAPI decoder ring
|
||||
* to understand the values. The HBAAPI user-space library is free to
|
||||
* convert the strings into the HBAAPI-specified binary values.
|
||||
*
|
||||
* Note: Not all HBAAPI-defined values are contained in the definitions
|
||||
* below. Those not appropriate to an fc_host (e.g. FCP initiator) have
|
||||
* been removed.
|
||||
*/
|
||||
|
||||
/*
|
||||
* fc_port_type: If you alter this, you also need to alter scsi_transport_fc.c
|
||||
* (for the ascii descriptions).
|
||||
*/
|
||||
enum fc_port_type {
|
||||
FC_PORTTYPE_UNKNOWN,
|
||||
FC_PORTTYPE_OTHER,
|
||||
FC_PORTTYPE_NOTPRESENT,
|
||||
FC_PORTTYPE_NPORT, /* Attached to FPort */
|
||||
FC_PORTTYPE_NLPORT, /* (Public) Loop w/ FLPort */
|
||||
FC_PORTTYPE_LPORT, /* (Private) Loop w/o FLPort */
|
||||
FC_PORTTYPE_PTP, /* Point to Point w/ another NPort */
|
||||
};
|
||||
|
||||
/*
|
||||
* fc_port_state: If you alter this, you also need to alter scsi_transport_fc.c
|
||||
* (for the ascii descriptions).
|
||||
*/
|
||||
enum fc_port_state {
|
||||
FC_PORTSTATE_UNKNOWN,
|
||||
FC_PORTSTATE_NOTPRESENT,
|
||||
FC_PORTSTATE_ONLINE,
|
||||
FC_PORTSTATE_OFFLINE, /* User has taken Port Offline */
|
||||
FC_PORTSTATE_BLOCKED,
|
||||
FC_PORTSTATE_BYPASSED,
|
||||
FC_PORTSTATE_DIAGNOSTICS,
|
||||
FC_PORTSTATE_LINKDOWN,
|
||||
FC_PORTSTATE_ERROR,
|
||||
FC_PORTSTATE_LOOPBACK,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* FC Classes of Service
|
||||
* Note: values are not enumerated, as they can be "or'd" together
|
||||
* for reporting (e.g. report supported_classes). If you alter this list,
|
||||
* you also need to alter scsi_transport_fc.c (for the ascii descriptions).
|
||||
*/
|
||||
#define FC_COS_UNSPECIFIED 0
|
||||
#define FC_COS_CLASS1 2
|
||||
#define FC_COS_CLASS2 4
|
||||
#define FC_COS_CLASS3 8
|
||||
#define FC_COS_CLASS4 0x10
|
||||
#define FC_COS_CLASS6 0x40
|
||||
|
||||
/*
|
||||
* FC Port Speeds
|
||||
* Note: values are not enumerated, as they can be "or'd" together
|
||||
* for reporting (e.g. report supported_speeds). If you alter this list,
|
||||
* you also need to alter scsi_transport_fc.c (for the ascii descriptions).
|
||||
*/
|
||||
#define FC_PORTSPEED_UNKNOWN 0 /* Unknown - transceiver
|
||||
incapable of reporting */
|
||||
#define FC_PORTSPEED_1GBIT 1
|
||||
#define FC_PORTSPEED_2GBIT 2
|
||||
#define FC_PORTSPEED_10GBIT 4
|
||||
#define FC_PORTSPEED_4GBIT 8
|
||||
#define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */
|
||||
|
||||
/*
|
||||
* fc_tgtid_binding_type: If you alter this, you also need to alter
|
||||
* scsi_transport_fc.c (for the ascii descriptions).
|
||||
*/
|
||||
enum fc_tgtid_binding_type {
|
||||
FC_TGTID_BIND_NONE,
|
||||
FC_TGTID_BIND_BY_WWPN,
|
||||
FC_TGTID_BIND_BY_WWNN,
|
||||
FC_TGTID_BIND_BY_ID,
|
||||
};
|
||||
|
||||
/*
|
||||
* FC Remote Port Roles
|
||||
* Note: values are not enumerated, as they can be "or'd" together
|
||||
* for reporting (e.g. report roles). If you alter this list,
|
||||
* you also need to alter scsi_transport_fc.c (for the ascii descriptions).
|
||||
*/
|
||||
#define FC_RPORT_ROLE_UNKNOWN 0x00
|
||||
#define FC_RPORT_ROLE_FCP_TARGET 0x01
|
||||
#define FC_RPORT_ROLE_FCP_INITIATOR 0x02
|
||||
#define FC_RPORT_ROLE_IP_PORT 0x04
|
||||
|
||||
|
||||
/*
|
||||
* fc_rport_identifiers: This set of data contains all elements
|
||||
* to uniquely identify a remote FC port. The driver uses this data
|
||||
* to report the existence of a remote FC port in the topology. Internally,
|
||||
* the transport uses this data for attributes and to manage consistent
|
||||
* target id bindings.
|
||||
*/
|
||||
struct fc_rport_identifiers {
|
||||
u64 node_name;
|
||||
u64 port_name;
|
||||
u32 port_id;
|
||||
u32 roles;
|
||||
};
|
||||
|
||||
/* Macro for use in defining Remote Port attributes */
|
||||
#define FC_RPORT_ATTR(_name,_mode,_show,_store) \
|
||||
struct class_device_attribute class_device_attr_rport_##_name = \
|
||||
__ATTR(_name,_mode,_show,_store)
|
||||
|
||||
|
||||
/*
|
||||
* FC Remote Port Attributes
|
||||
*
|
||||
* This structure exists for each remote FC port that a LLDD notifies
|
||||
* the subsystem of. A remote FC port may or may not be a SCSI Target,
|
||||
* also be a SCSI initiator, IP endpoint, etc. As such, the remote
|
||||
* port is considered a separate entity, independent of "role" (such
|
||||
* as scsi target).
|
||||
*
|
||||
* --
|
||||
*
|
||||
* Attributes are based on HBAAPI V2.0 definitions. Only those
|
||||
* attributes that are determinable by the local port (aka Host)
|
||||
* are contained.
|
||||
*
|
||||
* Fixed attributes are not expected to change. The driver is
|
||||
* expected to set these values after successfully calling
|
||||
* fc_remote_port_add(). The transport fully manages all get functions
|
||||
* w/o driver interaction.
|
||||
*
|
||||
* Dynamic attributes are expected to change. The driver participates
|
||||
* in all get/set operations via functions provided by the driver.
|
||||
*
|
||||
* Private attributes are transport-managed values. They are fully
|
||||
* managed by the transport w/o driver interaction.
|
||||
*/
|
||||
|
||||
struct fc_rport { /* aka fc_starget_attrs */
|
||||
/* Fixed Attributes */
|
||||
u32 maxframe_size;
|
||||
u32 supported_classes;
|
||||
|
||||
/* Dynamic Attributes */
|
||||
u32 dev_loss_tmo; /* Remote Port loss timeout in seconds. */
|
||||
|
||||
/* Private (Transport-managed) Attributes */
|
||||
u64 node_name;
|
||||
u64 port_name;
|
||||
u32 port_id;
|
||||
u32 roles;
|
||||
enum fc_port_state port_state; /* Will only be ONLINE or UNKNOWN */
|
||||
u32 scsi_target_id;
|
||||
|
||||
/* exported data */
|
||||
void *dd_data; /* Used for driver-specific storage */
|
||||
|
||||
/* internal data */
|
||||
unsigned int channel;
|
||||
u32 number;
|
||||
struct list_head peers;
|
||||
struct device dev;
|
||||
struct work_struct dev_loss_work;
|
||||
struct work_struct scan_work;
|
||||
} __attribute__((aligned(sizeof(unsigned long))));
|
||||
|
||||
#define dev_to_rport(d) \
|
||||
container_of(d, struct fc_rport, dev)
|
||||
#define transport_class_to_rport(classdev) \
|
||||
dev_to_rport(classdev->dev)
|
||||
#define rport_to_shost(r) \
|
||||
dev_to_shost(r->dev.parent)
|
||||
|
||||
/*
|
||||
* FC SCSI Target Attributes
|
||||
*
|
||||
* The SCSI Target is considered an extention of a remote port (as
|
||||
* a remote port can be more than a SCSI Target). Within the scsi
|
||||
* subsystem, we leave the Target as a separate entity. Doing so
|
||||
* provides backward compatibility with prior FC transport api's,
|
||||
* and lets remote ports be handled entirely within the FC transport
|
||||
* and independently from the scsi subsystem. The drawback is that
|
||||
* some data will be duplicated.
|
||||
*/
|
||||
|
||||
struct fc_starget_attrs { /* aka fc_target_attrs */
|
||||
/* Dynamic Attributes */
|
||||
u64 node_name;
|
||||
u64 port_name;
|
||||
u32 port_id;
|
||||
};
|
||||
|
||||
#define fc_starget_node_name(x) \
|
||||
(((struct fc_starget_attrs *)&(x)->starget_data)->node_name)
|
||||
#define fc_starget_port_name(x) \
|
||||
(((struct fc_starget_attrs *)&(x)->starget_data)->port_name)
|
||||
#define fc_starget_port_id(x) \
|
||||
(((struct fc_starget_attrs *)&(x)->starget_data)->port_id)
|
||||
|
||||
#define starget_to_rport(s) \
|
||||
scsi_is_fc_rport(s->dev.parent) ? dev_to_rport(s->dev.parent) : NULL
|
||||
|
||||
|
||||
/*
|
||||
* FC Local Port (Host) Statistics
|
||||
*/
|
||||
|
||||
/* FC Statistics - Following FC HBAAPI v2.0 guidelines */
|
||||
struct fc_host_statistics {
|
||||
/* port statistics */
|
||||
u64 seconds_since_last_reset;
|
||||
u64 tx_frames;
|
||||
u64 tx_words;
|
||||
u64 rx_frames;
|
||||
u64 rx_words;
|
||||
u64 lip_count;
|
||||
u64 nos_count;
|
||||
u64 error_frames;
|
||||
u64 dumped_frames;
|
||||
u64 link_failure_count;
|
||||
u64 loss_of_sync_count;
|
||||
u64 loss_of_signal_count;
|
||||
u64 prim_seq_protocol_err_count;
|
||||
u64 invalid_tx_word_count;
|
||||
u64 invalid_crc_count;
|
||||
|
||||
/* fc4 statistics (only FCP supported currently) */
|
||||
u64 fcp_input_requests;
|
||||
u64 fcp_output_requests;
|
||||
u64 fcp_control_requests;
|
||||
u64 fcp_input_megabytes;
|
||||
u64 fcp_output_megabytes;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* FC Local Port (Host) Attributes
|
||||
*
|
||||
* Attributes are based on HBAAPI V2.0 definitions.
|
||||
* Note: OSDeviceName is determined by user-space library
|
||||
*
|
||||
* Fixed attributes are not expected to change. The driver is
|
||||
* expected to set these values after successfully calling scsi_add_host().
|
||||
* The transport fully manages all get functions w/o driver interaction.
|
||||
*
|
||||
* Dynamic attributes are expected to change. The driver participates
|
||||
* in all get/set operations via functions provided by the driver.
|
||||
*
|
||||
* Private attributes are transport-managed values. They are fully
|
||||
* managed by the transport w/o driver interaction.
|
||||
*/
|
||||
|
||||
#define FC_FC4_LIST_SIZE 32
|
||||
#define FC_SYMBOLIC_NAME_SIZE 256
|
||||
#define FC_VERSION_STRING_SIZE 64
|
||||
#define FC_SERIAL_NUMBER_SIZE 80
|
||||
|
||||
struct fc_host_attrs {
|
||||
/* Fixed Attributes */
|
||||
u64 node_name;
|
||||
u64 port_name;
|
||||
u32 supported_classes;
|
||||
u8 supported_fc4s[FC_FC4_LIST_SIZE];
|
||||
char symbolic_name[FC_SYMBOLIC_NAME_SIZE];
|
||||
u32 supported_speeds;
|
||||
u32 maxframe_size;
|
||||
char serial_number[FC_SERIAL_NUMBER_SIZE];
|
||||
|
||||
/* Dynamic Attributes */
|
||||
u32 port_id;
|
||||
enum fc_port_type port_type;
|
||||
enum fc_port_state port_state;
|
||||
u8 active_fc4s[FC_FC4_LIST_SIZE];
|
||||
u32 speed;
|
||||
u64 fabric_name;
|
||||
|
||||
/* Private (Transport-managed) Attributes */
|
||||
enum fc_tgtid_binding_type tgtid_bind_type;
|
||||
|
||||
/* internal data */
|
||||
struct list_head rports;
|
||||
struct list_head rport_bindings;
|
||||
u32 next_rport_number;
|
||||
u32 next_target_id;
|
||||
};
|
||||
|
||||
#define fc_host_node_name(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->node_name)
|
||||
#define fc_host_port_name(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->port_name)
|
||||
#define fc_host_supported_classes(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->supported_classes)
|
||||
#define fc_host_supported_fc4s(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->supported_fc4s)
|
||||
#define fc_host_symbolic_name(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->symbolic_name)
|
||||
#define fc_host_supported_speeds(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->supported_speeds)
|
||||
#define fc_host_maxframe_size(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->maxframe_size)
|
||||
#define fc_host_serial_number(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->serial_number)
|
||||
#define fc_host_port_id(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->port_id)
|
||||
#define fc_host_port_type(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->port_type)
|
||||
#define fc_host_port_state(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->port_state)
|
||||
#define fc_host_active_fc4s(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->active_fc4s)
|
||||
#define fc_host_speed(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->speed)
|
||||
#define fc_host_fabric_name(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->fabric_name)
|
||||
#define fc_host_tgtid_bind_type(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->tgtid_bind_type)
|
||||
#define fc_host_rports(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->rports)
|
||||
#define fc_host_rport_bindings(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->rport_bindings)
|
||||
#define fc_host_next_rport_number(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->next_rport_number)
|
||||
#define fc_host_next_target_id(x) \
|
||||
(((struct fc_host_attrs *)(x)->shost_data)->next_target_id)
|
||||
|
||||
|
||||
/* The functions by which the transport class and the driver communicate */
|
||||
struct fc_function_template {
|
||||
void (*get_rport_dev_loss_tmo)(struct fc_rport *);
|
||||
void (*set_rport_dev_loss_tmo)(struct fc_rport *, u32);
|
||||
|
||||
void (*get_starget_node_name)(struct scsi_target *);
|
||||
void (*get_starget_port_name)(struct scsi_target *);
|
||||
void (*get_starget_port_id)(struct scsi_target *);
|
||||
|
||||
void (*get_host_port_id)(struct Scsi_Host *);
|
||||
void (*get_host_port_type)(struct Scsi_Host *);
|
||||
void (*get_host_port_state)(struct Scsi_Host *);
|
||||
void (*get_host_active_fc4s)(struct Scsi_Host *);
|
||||
void (*get_host_speed)(struct Scsi_Host *);
|
||||
void (*get_host_fabric_name)(struct Scsi_Host *);
|
||||
|
||||
struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *);
|
||||
void (*reset_fc_host_stats)(struct Scsi_Host *);
|
||||
|
||||
/* allocation lengths for host-specific data */
|
||||
u32 dd_fcrport_size;
|
||||
|
||||
/*
|
||||
* The driver sets these to tell the transport class it
|
||||
* wants the attributes displayed in sysfs. If the show_ flag
|
||||
* is not set, the attribute will be private to the transport
|
||||
* class
|
||||
*/
|
||||
|
||||
/* remote port fixed attributes */
|
||||
unsigned long show_rport_maxframe_size:1;
|
||||
unsigned long show_rport_supported_classes:1;
|
||||
unsigned long show_rport_dev_loss_tmo:1;
|
||||
|
||||
/*
|
||||
* target dynamic attributes
|
||||
* These should all be "1" if the driver uses the remote port
|
||||
* add/delete functions (so attributes reflect rport values).
|
||||
*/
|
||||
unsigned long show_starget_node_name:1;
|
||||
unsigned long show_starget_port_name:1;
|
||||
unsigned long show_starget_port_id:1;
|
||||
|
||||
/* host fixed attributes */
|
||||
unsigned long show_host_node_name:1;
|
||||
unsigned long show_host_port_name:1;
|
||||
unsigned long show_host_supported_classes:1;
|
||||
unsigned long show_host_supported_fc4s:1;
|
||||
unsigned long show_host_symbolic_name:1;
|
||||
unsigned long show_host_supported_speeds:1;
|
||||
unsigned long show_host_maxframe_size:1;
|
||||
unsigned long show_host_serial_number:1;
|
||||
/* host dynamic attributes */
|
||||
unsigned long show_host_port_id:1;
|
||||
unsigned long show_host_port_type:1;
|
||||
unsigned long show_host_port_state:1;
|
||||
unsigned long show_host_active_fc4s:1;
|
||||
unsigned long show_host_speed:1;
|
||||
unsigned long show_host_fabric_name:1;
|
||||
};
|
||||
|
||||
|
||||
struct scsi_transport_template *fc_attach_transport(
|
||||
struct fc_function_template *);
|
||||
void fc_release_transport(struct scsi_transport_template *);
|
||||
void fc_remove_host(struct Scsi_Host *);
|
||||
struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost,
|
||||
int channel, struct fc_rport_identifiers *ids);
|
||||
void fc_remote_port_delete(struct fc_rport *rport);
|
||||
void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles);
|
||||
int fc_remote_port_block(struct fc_rport *rport);
|
||||
void fc_remote_port_unblock(struct fc_rport *rport);
|
||||
int scsi_is_fc_rport(const struct device *);
|
||||
|
||||
#endif /* SCSI_TRANSPORT_FC_H */
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* iSCSI transport class definitions
|
||||
*
|
||||
* Copyright (C) IBM Corporation, 2004
|
||||
* Copyright (C) Mike Christie, 2004
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef SCSI_TRANSPORT_ISCSI_H
|
||||
#define SCSI_TRANSPORT_ISCSI_H
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/in.h>
|
||||
|
||||
struct scsi_transport_template;
|
||||
|
||||
struct iscsi_class_session {
|
||||
uint8_t isid[6];
|
||||
uint16_t tsih;
|
||||
int header_digest; /* 1 CRC32, 0 None */
|
||||
int data_digest; /* 1 CRC32, 0 None */
|
||||
uint16_t tpgt;
|
||||
union {
|
||||
struct in6_addr sin6_addr;
|
||||
struct in_addr sin_addr;
|
||||
} u;
|
||||
sa_family_t addr_type; /* must be AF_INET or AF_INET6 */
|
||||
uint16_t port; /* must be in network byte order */
|
||||
int initial_r2t; /* 1 Yes, 0 No */
|
||||
int immediate_data; /* 1 Yes, 0 No */
|
||||
uint32_t max_recv_data_segment_len;
|
||||
uint32_t max_burst_len;
|
||||
uint32_t first_burst_len;
|
||||
uint16_t def_time2wait;
|
||||
uint16_t def_time2retain;
|
||||
uint16_t max_outstanding_r2t;
|
||||
int data_pdu_in_order; /* 1 Yes, 0 No */
|
||||
int data_sequence_in_order; /* 1 Yes, 0 No */
|
||||
int erl;
|
||||
};
|
||||
|
||||
/*
|
||||
* accessor macros
|
||||
*/
|
||||
#define iscsi_isid(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->isid)
|
||||
#define iscsi_tsih(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->tsih)
|
||||
#define iscsi_header_digest(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->header_digest)
|
||||
#define iscsi_data_digest(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->data_digest)
|
||||
#define iscsi_port(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->port)
|
||||
#define iscsi_addr_type(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->addr_type)
|
||||
#define iscsi_sin_addr(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->u.sin_addr)
|
||||
#define iscsi_sin6_addr(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->u.sin6_addr)
|
||||
#define iscsi_tpgt(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->tpgt)
|
||||
#define iscsi_initial_r2t(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->initial_r2t)
|
||||
#define iscsi_immediate_data(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->immediate_data)
|
||||
#define iscsi_max_recv_data_segment_len(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->max_recv_data_segment_len)
|
||||
#define iscsi_max_burst_len(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->max_burst_len)
|
||||
#define iscsi_first_burst_len(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->first_burst_len)
|
||||
#define iscsi_def_time2wait(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->def_time2wait)
|
||||
#define iscsi_def_time2retain(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->def_time2retain)
|
||||
#define iscsi_max_outstanding_r2t(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->max_outstanding_r2t)
|
||||
#define iscsi_data_pdu_in_order(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->data_pdu_in_order)
|
||||
#define iscsi_data_sequence_in_order(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->data_sequence_in_order)
|
||||
#define iscsi_erl(x) \
|
||||
(((struct iscsi_class_session *)&(x)->starget_data)->erl)
|
||||
|
||||
/*
|
||||
* The functions by which the transport class and the driver communicate
|
||||
*/
|
||||
struct iscsi_function_template {
|
||||
/*
|
||||
* target attrs
|
||||
*/
|
||||
void (*get_isid)(struct scsi_target *);
|
||||
void (*get_tsih)(struct scsi_target *);
|
||||
void (*get_header_digest)(struct scsi_target *);
|
||||
void (*get_data_digest)(struct scsi_target *);
|
||||
void (*get_port)(struct scsi_target *);
|
||||
void (*get_tpgt)(struct scsi_target *);
|
||||
/*
|
||||
* In get_ip_address the lld must set the address and
|
||||
* the address type
|
||||
*/
|
||||
void (*get_ip_address)(struct scsi_target *);
|
||||
/*
|
||||
* The lld should snprintf the name or alias to the buffer
|
||||
*/
|
||||
ssize_t (*get_target_name)(struct scsi_target *, char *, ssize_t);
|
||||
ssize_t (*get_target_alias)(struct scsi_target *, char *, ssize_t);
|
||||
void (*get_initial_r2t)(struct scsi_target *);
|
||||
void (*get_immediate_data)(struct scsi_target *);
|
||||
void (*get_max_recv_data_segment_len)(struct scsi_target *);
|
||||
void (*get_max_burst_len)(struct scsi_target *);
|
||||
void (*get_first_burst_len)(struct scsi_target *);
|
||||
void (*get_def_time2wait)(struct scsi_target *);
|
||||
void (*get_def_time2retain)(struct scsi_target *);
|
||||
void (*get_max_outstanding_r2t)(struct scsi_target *);
|
||||
void (*get_data_pdu_in_order)(struct scsi_target *);
|
||||
void (*get_data_sequence_in_order)(struct scsi_target *);
|
||||
void (*get_erl)(struct scsi_target *);
|
||||
|
||||
/*
|
||||
* host atts
|
||||
*/
|
||||
|
||||
/*
|
||||
* The lld should snprintf the name or alias to the buffer
|
||||
*/
|
||||
ssize_t (*get_initiator_alias)(struct Scsi_Host *, char *, ssize_t);
|
||||
ssize_t (*get_initiator_name)(struct Scsi_Host *, char *, ssize_t);
|
||||
/*
|
||||
* The driver sets these to tell the transport class it
|
||||
* wants the attributes displayed in sysfs. If the show_ flag
|
||||
* is not set, the attribute will be private to the transport
|
||||
* class. We could probably just test if a get_ fn was set
|
||||
* since we only use the values for sysfs but this is how
|
||||
* fc does it too.
|
||||
*/
|
||||
unsigned long show_isid:1;
|
||||
unsigned long show_tsih:1;
|
||||
unsigned long show_header_digest:1;
|
||||
unsigned long show_data_digest:1;
|
||||
unsigned long show_port:1;
|
||||
unsigned long show_tpgt:1;
|
||||
unsigned long show_ip_address:1;
|
||||
unsigned long show_target_name:1;
|
||||
unsigned long show_target_alias:1;
|
||||
unsigned long show_initial_r2t:1;
|
||||
unsigned long show_immediate_data:1;
|
||||
unsigned long show_max_recv_data_segment_len:1;
|
||||
unsigned long show_max_burst_len:1;
|
||||
unsigned long show_first_burst_len:1;
|
||||
unsigned long show_def_time2wait:1;
|
||||
unsigned long show_def_time2retain:1;
|
||||
unsigned long show_max_outstanding_r2t:1;
|
||||
unsigned long show_data_pdu_in_order:1;
|
||||
unsigned long show_data_sequence_in_order:1;
|
||||
unsigned long show_erl:1;
|
||||
unsigned long show_initiator_name:1;
|
||||
unsigned long show_initiator_alias:1;
|
||||
};
|
||||
|
||||
struct scsi_transport_template *iscsi_attach_transport(struct iscsi_function_template *);
|
||||
void iscsi_release_transport(struct scsi_transport_template *);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Parallel SCSI (SPI) transport specific attributes exported to sysfs.
|
||||
*
|
||||
* Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef SCSI_TRANSPORT_SPI_H
|
||||
#define SCSI_TRANSPORT_SPI_H
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/transport_class.h>
|
||||
|
||||
struct scsi_transport_template;
|
||||
|
||||
struct spi_transport_attrs {
|
||||
int period; /* value in the PPR/SDTR command */
|
||||
int offset;
|
||||
unsigned int width:1; /* 0 - narrow, 1 - wide */
|
||||
unsigned int iu:1; /* Information Units enabled */
|
||||
unsigned int dt:1; /* DT clocking enabled */
|
||||
unsigned int qas:1; /* Quick Arbitration and Selection enabled */
|
||||
unsigned int wr_flow:1; /* Write Flow control enabled */
|
||||
unsigned int rd_strm:1; /* Read streaming enabled */
|
||||
unsigned int rti:1; /* Retain Training Information */
|
||||
unsigned int pcomp_en:1;/* Precompensation enabled */
|
||||
unsigned int initial_dv:1; /* DV done to this target yet */
|
||||
unsigned long flags; /* flags field for drivers to use */
|
||||
/* Device Properties fields */
|
||||
unsigned int support_sync:1; /* synchronous support */
|
||||
unsigned int support_wide:1; /* wide support */
|
||||
unsigned int support_dt:1; /* allows DT phases */
|
||||
unsigned int support_dt_only; /* disallows ST phases */
|
||||
unsigned int support_ius; /* support Information Units */
|
||||
unsigned int support_qas; /* supports quick arbitration and selection */
|
||||
/* Private Fields */
|
||||
unsigned int dv_pending:1; /* Internal flag */
|
||||
struct semaphore dv_sem; /* semaphore to serialise dv */
|
||||
};
|
||||
|
||||
enum spi_signal_type {
|
||||
SPI_SIGNAL_UNKNOWN = 1,
|
||||
SPI_SIGNAL_SE,
|
||||
SPI_SIGNAL_LVD,
|
||||
SPI_SIGNAL_HVD,
|
||||
};
|
||||
|
||||
struct spi_host_attrs {
|
||||
enum spi_signal_type signalling;
|
||||
};
|
||||
|
||||
/* accessor functions */
|
||||
#define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period)
|
||||
#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset)
|
||||
#define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width)
|
||||
#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu)
|
||||
#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt)
|
||||
#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas)
|
||||
#define spi_wr_flow(x) (((struct spi_transport_attrs *)&(x)->starget_data)->wr_flow)
|
||||
#define spi_rd_strm(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rd_strm)
|
||||
#define spi_rti(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rti)
|
||||
#define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->starget_data)->pcomp_en)
|
||||
#define spi_initial_dv(x) (((struct spi_transport_attrs *)&(x)->starget_data)->initial_dv)
|
||||
|
||||
#define spi_support_sync(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_sync)
|
||||
#define spi_support_wide(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_wide)
|
||||
#define spi_support_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_dt)
|
||||
#define spi_support_dt_only(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_dt_only)
|
||||
#define spi_support_ius(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_ius)
|
||||
#define spi_support_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_qas)
|
||||
|
||||
#define spi_flags(x) (((struct spi_transport_attrs *)&(x)->starget_data)->flags)
|
||||
#define spi_signalling(h) (((struct spi_host_attrs *)(h)->shost_data)->signalling)
|
||||
|
||||
|
||||
|
||||
/* The functions by which the transport class and the driver communicate */
|
||||
struct spi_function_template {
|
||||
void (*get_period)(struct scsi_target *);
|
||||
void (*set_period)(struct scsi_target *, int);
|
||||
void (*get_offset)(struct scsi_target *);
|
||||
void (*set_offset)(struct scsi_target *, int);
|
||||
void (*get_width)(struct scsi_target *);
|
||||
void (*set_width)(struct scsi_target *, int);
|
||||
void (*get_iu)(struct scsi_target *);
|
||||
void (*set_iu)(struct scsi_target *, int);
|
||||
void (*get_dt)(struct scsi_target *);
|
||||
void (*set_dt)(struct scsi_target *, int);
|
||||
void (*get_qas)(struct scsi_target *);
|
||||
void (*set_qas)(struct scsi_target *, int);
|
||||
void (*get_wr_flow)(struct scsi_target *);
|
||||
void (*set_wr_flow)(struct scsi_target *, int);
|
||||
void (*get_rd_strm)(struct scsi_target *);
|
||||
void (*set_rd_strm)(struct scsi_target *, int);
|
||||
void (*get_rti)(struct scsi_target *);
|
||||
void (*set_rti)(struct scsi_target *, int);
|
||||
void (*get_pcomp_en)(struct scsi_target *);
|
||||
void (*set_pcomp_en)(struct scsi_target *, int);
|
||||
void (*get_signalling)(struct Scsi_Host *);
|
||||
void (*set_signalling)(struct Scsi_Host *, enum spi_signal_type);
|
||||
/* The driver sets these to tell the transport class it
|
||||
* wants the attributes displayed in sysfs. If the show_ flag
|
||||
* is not set, the attribute will be private to the transport
|
||||
* class */
|
||||
unsigned long show_period:1;
|
||||
unsigned long show_offset:1;
|
||||
unsigned long show_width:1;
|
||||
unsigned long show_iu:1;
|
||||
unsigned long show_dt:1;
|
||||
unsigned long show_qas:1;
|
||||
unsigned long show_wr_flow:1;
|
||||
unsigned long show_rd_strm:1;
|
||||
unsigned long show_rti:1;
|
||||
unsigned long show_pcomp_en:1;
|
||||
};
|
||||
|
||||
struct scsi_transport_template *spi_attach_transport(struct spi_function_template *);
|
||||
void spi_release_transport(struct scsi_transport_template *);
|
||||
void spi_schedule_dv_device(struct scsi_device *);
|
||||
void spi_dv_device(struct scsi_device *);
|
||||
void spi_display_xfer_agreement(struct scsi_target *);
|
||||
|
||||
#endif /* SCSI_TRANSPORT_SPI_H */
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* scsicam.h - SCSI CAM support functions, use for HDIO_GETGEO, etc.
|
||||
*
|
||||
* Copyright 1993, 1994 Drew Eckhardt
|
||||
* Visionary Computing
|
||||
* (Unix and Linux consulting and custom programming)
|
||||
* drew@Colorado.EDU
|
||||
* +1 (303) 786-7975
|
||||
*
|
||||
* For more information, please consult the SCSI-CAM draft.
|
||||
*/
|
||||
|
||||
#ifndef SCSICAM_H
|
||||
#define SCSICAM_H
|
||||
extern int scsicam_bios_param (struct block_device *bdev, sector_t capacity, int *ip);
|
||||
extern int scsi_partsize(unsigned char *buf, unsigned long capacity,
|
||||
unsigned int *cyls, unsigned int *hds, unsigned int *secs);
|
||||
extern unsigned char *scsi_bios_ptable(struct block_device *bdev);
|
||||
#endif /* def SCSICAM_H */
|
||||
@@ -0,0 +1,326 @@
|
||||
#ifndef _SCSI_GENERIC_H
|
||||
#define _SCSI_GENERIC_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
/*
|
||||
History:
|
||||
Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user
|
||||
process control of SCSI devices.
|
||||
Development Sponsored by Killy Corp. NY NY
|
||||
Original driver (sg.h):
|
||||
* Copyright (C) 1992 Lawrence Foard
|
||||
Version 2 and 3 extensions to driver:
|
||||
* Copyright (C) 1998 - 2003 Douglas Gilbert
|
||||
|
||||
Version: 3.5.29 (20030529)
|
||||
This version is for 2.5 series kernels.
|
||||
|
||||
Changes since 3.5.28 (20030308)
|
||||
- fix bug introduced in version 3.1.24 (last segment of sgat list)
|
||||
Changes since 3.5.27 (20020812)
|
||||
- remove procfs entries: hosts, host_hdr + host_strs (now in sysfs)
|
||||
- add sysfs sg driver params: def_reserved_size, allow_dio, version
|
||||
- new boot option: "sg_allow_dio" and module parameter: "allow_dio"
|
||||
- multiple internal changes due to scsi subsystem rework
|
||||
Changes since 3.5.26 (20020708)
|
||||
- re-add direct IO using Kai Makisara's work
|
||||
- re-tab to 8, start using C99-isms
|
||||
- simplify memory management
|
||||
Changes since 3.5.25 (20020504)
|
||||
- driverfs additions
|
||||
- copy_to/from_user() fixes [William Stinson]
|
||||
- disable kiobufs support
|
||||
|
||||
For a full changelog see http://www.torque.net/sg
|
||||
|
||||
Map of SG verions to the Linux kernels in which they appear:
|
||||
---------- ----------------------------------
|
||||
original all kernels < 2.2.6
|
||||
2.1.40 2.2.20
|
||||
3.0.x optional version 3 sg driver for 2.2 series
|
||||
3.1.17++ 2.4.0++
|
||||
3.5.23++ 2.5.0++
|
||||
|
||||
Major new features in SG 3.x driver (cf SG 2.x drivers)
|
||||
- SG_IO ioctl() combines function if write() and read()
|
||||
- new interface (sg_io_hdr_t) but still supports old interface
|
||||
- scatter/gather in user space, direct IO, and mmap supported
|
||||
|
||||
The normal action of this driver is to use the adapter (HBA) driver to DMA
|
||||
data into kernel buffers and then use the CPU to copy the data into the
|
||||
user space (vice versa for writes). That is called "indirect" IO due to
|
||||
the double handling of data. There are two methods offered to remove the
|
||||
redundant copy: 1) direct IO which uses the kernel kiobuf mechanism and
|
||||
2) using the mmap() system call to map the reserve buffer (this driver has
|
||||
one reserve buffer per fd) into the user space. Both have their advantages.
|
||||
In terms of absolute speed mmap() is faster. If speed is not a concern,
|
||||
indirect IO should be fine. Read the documentation for more information.
|
||||
|
||||
** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' may be
|
||||
needed. That pseudo file's content is defaulted to 0. **
|
||||
|
||||
Historical note: this SCSI pass-through driver has been known as "sg" for
|
||||
a decade. In broader kernel discussions "sg" is used to refer to scatter
|
||||
gather techniques. The context should clarify which "sg" is referred to.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
A web site for the SG device driver can be found at:
|
||||
http://www.torque.net/sg [alternatively check the MAINTAINERS file]
|
||||
The documentation for the sg version 3 driver can be found at:
|
||||
http://www.torque.net/sg/p/sg_v3_ho.html
|
||||
This is a rendering from DocBook source [change the extension to "sgml"
|
||||
or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon).
|
||||
|
||||
The older, version 2 documents discuss the original sg interface in detail:
|
||||
http://www.torque.net/sg/p/scsi-generic.txt
|
||||
http://www.torque.net/sg/p/scsi-generic_long.txt
|
||||
A version of this document (potentially out of date) may also be found in
|
||||
the kernel source tree, probably at:
|
||||
Documentation/scsi/scsi-generic.txt .
|
||||
|
||||
Utility and test programs are available at the sg web site. They are
|
||||
bundled as sg_utils (for the lk 2.2 series) and sg3_utils (for the
|
||||
lk 2.4 series).
|
||||
|
||||
There is a HOWTO on the Linux SCSI subsystem in the lk 2.4 series at:
|
||||
http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO
|
||||
*/
|
||||
|
||||
|
||||
/* New interface introduced in the 3.x SG drivers follows */
|
||||
|
||||
typedef struct sg_iovec /* same structure as used by readv() Linux system */
|
||||
{ /* call. It defines one scatter-gather element. */
|
||||
void __user *iov_base; /* Starting address */
|
||||
size_t iov_len; /* Length in bytes */
|
||||
} sg_iovec_t;
|
||||
|
||||
|
||||
typedef struct sg_io_hdr
|
||||
{
|
||||
int interface_id; /* [i] 'S' for SCSI generic (required) */
|
||||
int dxfer_direction; /* [i] data transfer direction */
|
||||
unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
|
||||
unsigned char mx_sb_len; /* [i] max length to write to sbp */
|
||||
unsigned short iovec_count; /* [i] 0 implies no scatter gather */
|
||||
unsigned int dxfer_len; /* [i] byte count of data transfer */
|
||||
void __user *dxferp; /* [i], [*io] points to data transfer memory
|
||||
or scatter gather list */
|
||||
unsigned char __user *cmdp; /* [i], [*i] points to command to perform */
|
||||
void __user *sbp; /* [i], [*o] points to sense_buffer memory */
|
||||
unsigned int timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
|
||||
unsigned int flags; /* [i] 0 -> default, see SG_FLAG... */
|
||||
int pack_id; /* [i->o] unused internally (normally) */
|
||||
void __user * usr_ptr; /* [i->o] unused internally */
|
||||
unsigned char status; /* [o] scsi status */
|
||||
unsigned char masked_status;/* [o] shifted, masked scsi status */
|
||||
unsigned char msg_status; /* [o] messaging level data (optional) */
|
||||
unsigned char sb_len_wr; /* [o] byte count actually written to sbp */
|
||||
unsigned short host_status; /* [o] errors from host adapter */
|
||||
unsigned short driver_status;/* [o] errors from software driver */
|
||||
int resid; /* [o] dxfer_len - actual_transferred */
|
||||
unsigned int duration; /* [o] time taken by cmd (unit: millisec) */
|
||||
unsigned int info; /* [o] auxiliary information */
|
||||
} sg_io_hdr_t; /* 64 bytes long (on i386) */
|
||||
|
||||
#define SG_INTERFACE_ID_ORIG 'S'
|
||||
|
||||
/* Use negative values to flag difference from original sg_header structure */
|
||||
#define SG_DXFER_NONE (-1) /* e.g. a SCSI Test Unit Ready command */
|
||||
#define SG_DXFER_TO_DEV (-2) /* e.g. a SCSI WRITE command */
|
||||
#define SG_DXFER_FROM_DEV (-3) /* e.g. a SCSI READ command */
|
||||
#define SG_DXFER_TO_FROM_DEV (-4) /* treated like SG_DXFER_FROM_DEV with the
|
||||
additional property than during indirect
|
||||
IO the user buffer is copied into the
|
||||
kernel buffers before the transfer */
|
||||
#define SG_DXFER_UNKNOWN (-5) /* Unknown data direction */
|
||||
|
||||
/* following flag values can be "or"-ed together */
|
||||
#define SG_FLAG_DIRECT_IO 1 /* default is indirect IO */
|
||||
#define SG_FLAG_UNUSED_LUN_INHIBIT 2 /* default is overwrite lun in SCSI */
|
||||
/* command block (when <= SCSI_2) */
|
||||
#define SG_FLAG_MMAP_IO 4 /* request memory mapped IO */
|
||||
#define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */
|
||||
/* user space (debug indirect IO) */
|
||||
|
||||
/* following 'info' values are "or"-ed together */
|
||||
#define SG_INFO_OK_MASK 0x1
|
||||
#define SG_INFO_OK 0x0 /* no sense, host nor driver "noise" */
|
||||
#define SG_INFO_CHECK 0x1 /* something abnormal happened */
|
||||
|
||||
#define SG_INFO_DIRECT_IO_MASK 0x6
|
||||
#define SG_INFO_INDIRECT_IO 0x0 /* data xfer via kernel buffers (or no xfer) */
|
||||
#define SG_INFO_DIRECT_IO 0x2 /* direct IO requested and performed */
|
||||
#define SG_INFO_MIXED_IO 0x4 /* part direct, part indirect IO */
|
||||
|
||||
|
||||
typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */
|
||||
int host_no; /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */
|
||||
int channel;
|
||||
int scsi_id; /* scsi id of target device */
|
||||
int lun;
|
||||
int scsi_type; /* TYPE_... defined in scsi/scsi.h */
|
||||
short h_cmd_per_lun;/* host (adapter) maximum commands per lun */
|
||||
short d_queue_depth;/* device (or adapter) maximum queue length */
|
||||
int unused[2]; /* probably find a good use, set 0 for now */
|
||||
} sg_scsi_id_t; /* 32 bytes long on i386 */
|
||||
|
||||
typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
|
||||
char req_state; /* 0 -> not used, 1 -> written, 2 -> ready to read */
|
||||
char orphan; /* 0 -> normal request, 1 -> from interruped SG_IO */
|
||||
char sg_io_owned; /* 0 -> complete with read(), 1 -> owned by SG_IO */
|
||||
char problem; /* 0 -> no problem detected, 1 -> error to report */
|
||||
int pack_id; /* pack_id associated with request */
|
||||
void __user *usr_ptr; /* user provided pointer (in new interface) */
|
||||
unsigned int duration; /* millisecs elapsed since written (req_state==1)
|
||||
or request duration (req_state==2) */
|
||||
int unused;
|
||||
} sg_req_info_t; /* 20 bytes long on i386 */
|
||||
|
||||
|
||||
/* IOCTLs: Those ioctls that are relevant to the SG 3.x drivers follow.
|
||||
[Those that only apply to the SG 2.x drivers are at the end of the file.]
|
||||
(_GET_s yield result via 'int *' 3rd argument unless otherwise indicated) */
|
||||
|
||||
#define SG_EMULATED_HOST 0x2203 /* true for emulated host adapter (ATAPI) */
|
||||
|
||||
/* Used to configure SCSI command transformation layer for ATAPI devices */
|
||||
/* Only supported by the ide-scsi driver */
|
||||
#define SG_SET_TRANSFORM 0x2204 /* N.B. 3rd arg is not pointer but value: */
|
||||
/* 3rd arg = 0 to disable transform, 1 to enable it */
|
||||
#define SG_GET_TRANSFORM 0x2205
|
||||
|
||||
#define SG_SET_RESERVED_SIZE 0x2275 /* request a new reserved buffer size */
|
||||
#define SG_GET_RESERVED_SIZE 0x2272 /* actual size of reserved buffer */
|
||||
|
||||
/* The following ioctl has a 'sg_scsi_id_t *' object as its 3rd argument. */
|
||||
#define SG_GET_SCSI_ID 0x2276 /* Yields fd's bus, chan, dev, lun + type */
|
||||
/* SCSI id information can also be obtained from SCSI_IOCTL_GET_IDLUN */
|
||||
|
||||
/* Override host setting and always DMA using low memory ( <16MB on i386) */
|
||||
#define SG_SET_FORCE_LOW_DMA 0x2279 /* 0-> use adapter setting, 1-> force */
|
||||
#define SG_GET_LOW_DMA 0x227a /* 0-> use all ram for dma; 1-> low dma ram */
|
||||
|
||||
/* When SG_SET_FORCE_PACK_ID set to 1, pack_id is input to read() which
|
||||
tries to fetch a packet with a matching pack_id, waits, or returns EAGAIN.
|
||||
If pack_id is -1 then read oldest waiting. When ...FORCE_PACK_ID set to 0
|
||||
then pack_id ignored by read() and oldest readable fetched. */
|
||||
#define SG_SET_FORCE_PACK_ID 0x227b
|
||||
#define SG_GET_PACK_ID 0x227c /* Yields oldest readable pack_id (or -1) */
|
||||
|
||||
#define SG_GET_NUM_WAITING 0x227d /* Number of commands awaiting read() */
|
||||
|
||||
/* Yields max scatter gather tablesize allowed by current host adapter */
|
||||
#define SG_GET_SG_TABLESIZE 0x227F /* 0 implies can't do scatter gather */
|
||||
|
||||
#define SG_GET_VERSION_NUM 0x2282 /* Example: version 2.1.34 yields 20134 */
|
||||
|
||||
/* Returns -EBUSY if occupied. 3rd argument pointer to int (see next) */
|
||||
#define SG_SCSI_RESET 0x2284
|
||||
/* Associated values that can be given to SG_SCSI_RESET follow */
|
||||
#define SG_SCSI_RESET_NOTHING 0
|
||||
#define SG_SCSI_RESET_DEVICE 1
|
||||
#define SG_SCSI_RESET_BUS 2
|
||||
#define SG_SCSI_RESET_HOST 3
|
||||
|
||||
/* synchronous SCSI command ioctl, (only in version 3 interface) */
|
||||
#define SG_IO 0x2285 /* similar effect as write() followed by read() */
|
||||
|
||||
#define SG_GET_REQUEST_TABLE 0x2286 /* yields table of active requests */
|
||||
|
||||
/* How to treat EINTR during SG_IO ioctl(), only in SG 3.x series */
|
||||
#define SG_SET_KEEP_ORPHAN 0x2287 /* 1 -> hold for read(), 0 -> drop (def) */
|
||||
#define SG_GET_KEEP_ORPHAN 0x2288
|
||||
|
||||
/* yields scsi midlevel's access_count for this SCSI device */
|
||||
#define SG_GET_ACCESS_COUNT 0x2289
|
||||
|
||||
|
||||
#define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */
|
||||
/* Largest size (in bytes) a single scatter-gather list element can have.
|
||||
The value must be a power of 2 and <= (PAGE_SIZE * 32) [131072 bytes on
|
||||
i386]. The minimum value is PAGE_SIZE. If scatter-gather not supported
|
||||
by adapter then this value is the largest data block that can be
|
||||
read/written by a single scsi command. The user can find the value of
|
||||
PAGE_SIZE by calling getpagesize() defined in unistd.h . */
|
||||
|
||||
#define SG_DEFAULT_RETRIES 0
|
||||
|
||||
/* Defaults, commented if they differ from original sg driver */
|
||||
#define SG_DEF_FORCE_LOW_DMA 0 /* was 1 -> memory below 16MB on i386 */
|
||||
#define SG_DEF_FORCE_PACK_ID 0
|
||||
#define SG_DEF_KEEP_ORPHAN 0
|
||||
#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ /* load time option */
|
||||
|
||||
/* maximum outstanding requests, write() yields EDOM if exceeded */
|
||||
#define SG_MAX_QUEUE 16
|
||||
|
||||
#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE /* for backward compatibility */
|
||||
|
||||
/* Alternate style type names, "..._t" variants preferred */
|
||||
typedef struct sg_io_hdr Sg_io_hdr;
|
||||
typedef struct sg_io_vec Sg_io_vec;
|
||||
typedef struct sg_scsi_id Sg_scsi_id;
|
||||
typedef struct sg_req_info Sg_req_info;
|
||||
|
||||
|
||||
/* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
|
||||
/* The older SG interface based on the 'sg_header' structure follows. */
|
||||
/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
|
||||
|
||||
#define SG_MAX_SENSE 16 /* this only applies to the sg_header interface */
|
||||
|
||||
struct sg_header
|
||||
{
|
||||
int pack_len; /* [o] reply_len (ie useless), ignored as input */
|
||||
int reply_len; /* [i] max length of expected reply (inc. sg_header) */
|
||||
int pack_id; /* [io] id number of packet (use ints >= 0) */
|
||||
int result; /* [o] 0==ok, else (+ve) Unix errno (best ignored) */
|
||||
unsigned int twelve_byte:1;
|
||||
/* [i] Force 12 byte command length for group 6 & 7 commands */
|
||||
unsigned int target_status:5; /* [o] scsi status from target */
|
||||
unsigned int host_status:8; /* [o] host status (see "DID" codes) */
|
||||
unsigned int driver_status:8; /* [o] driver status+suggestion */
|
||||
unsigned int other_flags:10; /* unused */
|
||||
unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] Output in 3 cases:
|
||||
when target_status is CHECK_CONDITION or
|
||||
when target_status is COMMAND_TERMINATED or
|
||||
when (driver_status & DRIVER_SENSE) is true. */
|
||||
}; /* This structure is 36 bytes long on i386 */
|
||||
|
||||
|
||||
/* IOCTLs: The following are not required (or ignored) when the sg_io_hdr_t
|
||||
interface is used. They are kept for backward compatibility with
|
||||
the original and version 2 drivers. */
|
||||
|
||||
#define SG_SET_TIMEOUT 0x2201 /* unit: jiffies (10ms on i386) */
|
||||
#define SG_GET_TIMEOUT 0x2202 /* yield timeout as _return_ value */
|
||||
|
||||
/* Get/set command queuing state per fd (default is SG_DEF_COMMAND_Q.
|
||||
Each time a sg_io_hdr_t object is seen on this file descriptor, this
|
||||
command queuing flag is set on (overriding the previous setting). */
|
||||
#define SG_GET_COMMAND_Q 0x2270 /* Yields 0 (queuing off) or 1 (on) */
|
||||
#define SG_SET_COMMAND_Q 0x2271 /* Change queuing state with 0 or 1 */
|
||||
|
||||
/* Turn on/off error sense trace (1 and 0 respectively, default is off).
|
||||
Try using: "# cat /proc/scsi/sg/debug" instead in the v3 driver */
|
||||
#define SG_SET_DEBUG 0x227e /* 0 -> turn off debug */
|
||||
|
||||
#define SG_NEXT_CMD_LEN 0x2283 /* override SCSI command length with given
|
||||
number on the next write() on this file descriptor */
|
||||
|
||||
|
||||
/* Defaults, commented if they differ from original sg driver */
|
||||
#ifdef __KERNEL__
|
||||
#define SG_DEFAULT_TIMEOUT_USER (60*USER_HZ) /* HZ == 'jiffies in 1 second' */
|
||||
#else
|
||||
#define SG_DEFAULT_TIMEOUT (60*HZ) /* HZ == 'jiffies in 1 second' */
|
||||
#endif
|
||||
|
||||
#define SG_DEF_COMMAND_Q 0 /* command queuing is always on when
|
||||
the new interface is used */
|
||||
#define SG_DEF_UNDERRUN_FLAG 0
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user