Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (102 commits) [SCSI] scsi_dh: fix kconfig related build errors [SCSI] sym53c8xx: Fix bogus sym_que_entry re-implementation of container_of [SCSI] scsi_cmnd.h: remove double inclusion of linux/blkdev.h [SCSI] make struct scsi_{host,target}_type static [SCSI] fix locking in host use of blk_plug_device() [SCSI] zfcp: Cleanup external header file [SCSI] zfcp: Cleanup code in zfcp_erp.c [SCSI] zfcp: zfcp_fsf cleanup. [SCSI] zfcp: consolidate sysfs things into one file. [SCSI] zfcp: Cleanup of code in zfcp_aux.c [SCSI] zfcp: Cleanup of code in zfcp_scsi.c [SCSI] zfcp: Move status accessors from zfcp to SCSI include file. [SCSI] zfcp: Small QDIO cleanups [SCSI] zfcp: Adapter reopen for large number of unsolicited status [SCSI] zfcp: Fix error checking for ELS ADISC requests [SCSI] zfcp: wait until adapter is finished with ERP during auto-port [SCSI] ibmvfc: IBM Power Virtual Fibre Channel Adapter Client Driver [SCSI] sg: Add target reset support [SCSI] lib: Add support for the T10 (SCSI) Data Integrity Field CRC [SCSI] sd: Move scsi_disk() accessor function to sd.h ...
This commit is contained in:
@@ -50,6 +50,7 @@ enum iscsi_uevent_e {
|
||||
ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15,
|
||||
ISCSI_UEVENT_SET_HOST_PARAM = UEVENT_BASE + 16,
|
||||
ISCSI_UEVENT_UNBIND_SESSION = UEVENT_BASE + 17,
|
||||
ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18,
|
||||
|
||||
/* up events */
|
||||
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
|
||||
@@ -78,6 +79,12 @@ struct iscsi_uevent {
|
||||
uint16_t cmds_max;
|
||||
uint16_t queue_depth;
|
||||
} c_session;
|
||||
struct msg_create_bound_session {
|
||||
uint64_t ep_handle;
|
||||
uint32_t initial_cmdsn;
|
||||
uint16_t cmds_max;
|
||||
uint16_t queue_depth;
|
||||
} c_bound_session;
|
||||
struct msg_destroy_session {
|
||||
uint32_t sid;
|
||||
} d_session;
|
||||
@@ -250,42 +257,49 @@ enum iscsi_param {
|
||||
|
||||
ISCSI_PARAM_PING_TMO,
|
||||
ISCSI_PARAM_RECV_TMO,
|
||||
|
||||
ISCSI_PARAM_IFACE_NAME,
|
||||
ISCSI_PARAM_ISID,
|
||||
ISCSI_PARAM_INITIATOR_NAME,
|
||||
/* must always be last */
|
||||
ISCSI_PARAM_MAX,
|
||||
};
|
||||
|
||||
#define ISCSI_MAX_RECV_DLENGTH (1 << ISCSI_PARAM_MAX_RECV_DLENGTH)
|
||||
#define ISCSI_MAX_XMIT_DLENGTH (1 << ISCSI_PARAM_MAX_XMIT_DLENGTH)
|
||||
#define ISCSI_HDRDGST_EN (1 << ISCSI_PARAM_HDRDGST_EN)
|
||||
#define ISCSI_DATADGST_EN (1 << ISCSI_PARAM_DATADGST_EN)
|
||||
#define ISCSI_INITIAL_R2T_EN (1 << ISCSI_PARAM_INITIAL_R2T_EN)
|
||||
#define ISCSI_MAX_R2T (1 << ISCSI_PARAM_MAX_R2T)
|
||||
#define ISCSI_IMM_DATA_EN (1 << ISCSI_PARAM_IMM_DATA_EN)
|
||||
#define ISCSI_FIRST_BURST (1 << ISCSI_PARAM_FIRST_BURST)
|
||||
#define ISCSI_MAX_BURST (1 << ISCSI_PARAM_MAX_BURST)
|
||||
#define ISCSI_PDU_INORDER_EN (1 << ISCSI_PARAM_PDU_INORDER_EN)
|
||||
#define ISCSI_DATASEQ_INORDER_EN (1 << ISCSI_PARAM_DATASEQ_INORDER_EN)
|
||||
#define ISCSI_ERL (1 << ISCSI_PARAM_ERL)
|
||||
#define ISCSI_IFMARKER_EN (1 << ISCSI_PARAM_IFMARKER_EN)
|
||||
#define ISCSI_OFMARKER_EN (1 << ISCSI_PARAM_OFMARKER_EN)
|
||||
#define ISCSI_EXP_STATSN (1 << ISCSI_PARAM_EXP_STATSN)
|
||||
#define ISCSI_TARGET_NAME (1 << ISCSI_PARAM_TARGET_NAME)
|
||||
#define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT)
|
||||
#define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS)
|
||||
#define ISCSI_PERSISTENT_PORT (1 << ISCSI_PARAM_PERSISTENT_PORT)
|
||||
#define ISCSI_SESS_RECOVERY_TMO (1 << ISCSI_PARAM_SESS_RECOVERY_TMO)
|
||||
#define ISCSI_CONN_PORT (1 << ISCSI_PARAM_CONN_PORT)
|
||||
#define ISCSI_CONN_ADDRESS (1 << ISCSI_PARAM_CONN_ADDRESS)
|
||||
#define ISCSI_USERNAME (1 << ISCSI_PARAM_USERNAME)
|
||||
#define ISCSI_USERNAME_IN (1 << ISCSI_PARAM_USERNAME_IN)
|
||||
#define ISCSI_PASSWORD (1 << ISCSI_PARAM_PASSWORD)
|
||||
#define ISCSI_PASSWORD_IN (1 << ISCSI_PARAM_PASSWORD_IN)
|
||||
#define ISCSI_FAST_ABORT (1 << ISCSI_PARAM_FAST_ABORT)
|
||||
#define ISCSI_ABORT_TMO (1 << ISCSI_PARAM_ABORT_TMO)
|
||||
#define ISCSI_LU_RESET_TMO (1 << ISCSI_PARAM_LU_RESET_TMO)
|
||||
#define ISCSI_HOST_RESET_TMO (1 << ISCSI_PARAM_HOST_RESET_TMO)
|
||||
#define ISCSI_PING_TMO (1 << ISCSI_PARAM_PING_TMO)
|
||||
#define ISCSI_RECV_TMO (1 << ISCSI_PARAM_RECV_TMO)
|
||||
#define ISCSI_MAX_RECV_DLENGTH (1ULL << ISCSI_PARAM_MAX_RECV_DLENGTH)
|
||||
#define ISCSI_MAX_XMIT_DLENGTH (1ULL << ISCSI_PARAM_MAX_XMIT_DLENGTH)
|
||||
#define ISCSI_HDRDGST_EN (1ULL << ISCSI_PARAM_HDRDGST_EN)
|
||||
#define ISCSI_DATADGST_EN (1ULL << ISCSI_PARAM_DATADGST_EN)
|
||||
#define ISCSI_INITIAL_R2T_EN (1ULL << ISCSI_PARAM_INITIAL_R2T_EN)
|
||||
#define ISCSI_MAX_R2T (1ULL << ISCSI_PARAM_MAX_R2T)
|
||||
#define ISCSI_IMM_DATA_EN (1ULL << ISCSI_PARAM_IMM_DATA_EN)
|
||||
#define ISCSI_FIRST_BURST (1ULL << ISCSI_PARAM_FIRST_BURST)
|
||||
#define ISCSI_MAX_BURST (1ULL << ISCSI_PARAM_MAX_BURST)
|
||||
#define ISCSI_PDU_INORDER_EN (1ULL << ISCSI_PARAM_PDU_INORDER_EN)
|
||||
#define ISCSI_DATASEQ_INORDER_EN (1ULL << ISCSI_PARAM_DATASEQ_INORDER_EN)
|
||||
#define ISCSI_ERL (1ULL << ISCSI_PARAM_ERL)
|
||||
#define ISCSI_IFMARKER_EN (1ULL << ISCSI_PARAM_IFMARKER_EN)
|
||||
#define ISCSI_OFMARKER_EN (1ULL << ISCSI_PARAM_OFMARKER_EN)
|
||||
#define ISCSI_EXP_STATSN (1ULL << ISCSI_PARAM_EXP_STATSN)
|
||||
#define ISCSI_TARGET_NAME (1ULL << ISCSI_PARAM_TARGET_NAME)
|
||||
#define ISCSI_TPGT (1ULL << ISCSI_PARAM_TPGT)
|
||||
#define ISCSI_PERSISTENT_ADDRESS (1ULL << ISCSI_PARAM_PERSISTENT_ADDRESS)
|
||||
#define ISCSI_PERSISTENT_PORT (1ULL << ISCSI_PARAM_PERSISTENT_PORT)
|
||||
#define ISCSI_SESS_RECOVERY_TMO (1ULL << ISCSI_PARAM_SESS_RECOVERY_TMO)
|
||||
#define ISCSI_CONN_PORT (1ULL << ISCSI_PARAM_CONN_PORT)
|
||||
#define ISCSI_CONN_ADDRESS (1ULL << ISCSI_PARAM_CONN_ADDRESS)
|
||||
#define ISCSI_USERNAME (1ULL << ISCSI_PARAM_USERNAME)
|
||||
#define ISCSI_USERNAME_IN (1ULL << ISCSI_PARAM_USERNAME_IN)
|
||||
#define ISCSI_PASSWORD (1ULL << ISCSI_PARAM_PASSWORD)
|
||||
#define ISCSI_PASSWORD_IN (1ULL << ISCSI_PARAM_PASSWORD_IN)
|
||||
#define ISCSI_FAST_ABORT (1ULL << ISCSI_PARAM_FAST_ABORT)
|
||||
#define ISCSI_ABORT_TMO (1ULL << ISCSI_PARAM_ABORT_TMO)
|
||||
#define ISCSI_LU_RESET_TMO (1ULL << ISCSI_PARAM_LU_RESET_TMO)
|
||||
#define ISCSI_HOST_RESET_TMO (1ULL << ISCSI_PARAM_HOST_RESET_TMO)
|
||||
#define ISCSI_PING_TMO (1ULL << ISCSI_PARAM_PING_TMO)
|
||||
#define ISCSI_RECV_TMO (1ULL << ISCSI_PARAM_RECV_TMO)
|
||||
#define ISCSI_IFACE_NAME (1ULL << ISCSI_PARAM_IFACE_NAME)
|
||||
#define ISCSI_ISID (1ULL << ISCSI_PARAM_ISID)
|
||||
#define ISCSI_INITIATOR_NAME (1ULL << ISCSI_PARAM_INITIATOR_NAME)
|
||||
|
||||
/* iSCSI HBA params */
|
||||
enum iscsi_host_param {
|
||||
@@ -296,20 +310,13 @@ enum iscsi_host_param {
|
||||
ISCSI_HOST_PARAM_MAX,
|
||||
};
|
||||
|
||||
#define ISCSI_HOST_HWADDRESS (1 << ISCSI_HOST_PARAM_HWADDRESS)
|
||||
#define ISCSI_HOST_INITIATOR_NAME (1 << ISCSI_HOST_PARAM_INITIATOR_NAME)
|
||||
#define ISCSI_HOST_NETDEV_NAME (1 << ISCSI_HOST_PARAM_NETDEV_NAME)
|
||||
#define ISCSI_HOST_IPADDRESS (1 << ISCSI_HOST_PARAM_IPADDRESS)
|
||||
#define ISCSI_HOST_HWADDRESS (1ULL << ISCSI_HOST_PARAM_HWADDRESS)
|
||||
#define ISCSI_HOST_INITIATOR_NAME (1ULL << ISCSI_HOST_PARAM_INITIATOR_NAME)
|
||||
#define ISCSI_HOST_NETDEV_NAME (1ULL << ISCSI_HOST_PARAM_NETDEV_NAME)
|
||||
#define ISCSI_HOST_IPADDRESS (1ULL << ISCSI_HOST_PARAM_IPADDRESS)
|
||||
|
||||
#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
|
||||
#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
|
||||
#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
|
||||
|
||||
/**
|
||||
* iscsi_hostdata - get LLD hostdata from scsi_host
|
||||
* @_hostdata: pointer to scsi host's hostdata
|
||||
**/
|
||||
#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))
|
||||
|
||||
/*
|
||||
* These flags presents iSCSI Data-Path capabilities.
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#define ISCSI_PROTO_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <scsi/scsi.h>
|
||||
|
||||
#define ISCSI_DRAFT20_VERSION 0x00
|
||||
|
||||
@@ -156,7 +157,7 @@ struct iscsi_ecdb_ahdr {
|
||||
uint8_t ahstype;
|
||||
uint8_t reserved;
|
||||
/* 4-byte aligned extended CDB spillover */
|
||||
uint8_t ecdb[260 - ISCSI_CDB_SIZE];
|
||||
uint8_t ecdb[SCSI_MAX_VARLEN_CDB_SIZE - ISCSI_CDB_SIZE];
|
||||
};
|
||||
|
||||
/* SCSI Response Header */
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#define LIBISCSI_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/workqueue.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <scsi/iscsi_if.h>
|
||||
|
||||
struct scsi_transport_template;
|
||||
struct scsi_host_template;
|
||||
struct scsi_device;
|
||||
struct Scsi_Host;
|
||||
struct scsi_cmnd;
|
||||
@@ -40,6 +42,7 @@ struct iscsi_cls_session;
|
||||
struct iscsi_cls_conn;
|
||||
struct iscsi_session;
|
||||
struct iscsi_nopin;
|
||||
struct device;
|
||||
|
||||
/* #define DEBUG_SCSI */
|
||||
#ifdef DEBUG_SCSI
|
||||
@@ -49,9 +52,7 @@ struct iscsi_nopin;
|
||||
#endif
|
||||
|
||||
#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */
|
||||
#define ISCSI_MGMT_CMDS_MAX 16 /* must be power of 2 */
|
||||
|
||||
#define ISCSI_MGMT_ITT_OFFSET 0xa00
|
||||
#define ISCSI_MGMT_CMDS_MAX 15
|
||||
|
||||
#define ISCSI_DEF_CMD_PER_LUN 32
|
||||
#define ISCSI_MAX_CMD_PER_LUN 128
|
||||
@@ -69,7 +70,10 @@ enum {
|
||||
/* Connection suspend "bit" */
|
||||
#define ISCSI_SUSPEND_BIT 1
|
||||
|
||||
#define ISCSI_ITT_MASK (0xfff)
|
||||
#define ISCSI_ITT_MASK (0x1fff)
|
||||
#define ISCSI_TOTAL_CMDS_MAX 4096
|
||||
/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */
|
||||
#define ISCSI_TOTAL_CMDS_MIN 16
|
||||
#define ISCSI_AGE_SHIFT 28
|
||||
#define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT)
|
||||
|
||||
@@ -82,18 +86,6 @@ enum {
|
||||
ISCSI_DIGEST_SIZE = sizeof(__u32),
|
||||
};
|
||||
|
||||
struct iscsi_mgmt_task {
|
||||
/*
|
||||
* Becuae LLDs allocate their hdr differently, this is a pointer to
|
||||
* that storage. It must be setup at session creation time.
|
||||
*/
|
||||
struct iscsi_hdr *hdr;
|
||||
char *data; /* mgmt payload */
|
||||
unsigned data_count; /* counts data to be sent */
|
||||
uint32_t itt; /* this ITT */
|
||||
void *dd_data; /* driver/transport data */
|
||||
struct list_head running;
|
||||
};
|
||||
|
||||
enum {
|
||||
ISCSI_TASK_COMPLETED,
|
||||
@@ -101,7 +93,7 @@ enum {
|
||||
ISCSI_TASK_RUNNING,
|
||||
};
|
||||
|
||||
struct iscsi_cmd_task {
|
||||
struct iscsi_task {
|
||||
/*
|
||||
* Because LLDs allocate their hdr differently, this is a pointer
|
||||
* and length to that storage. It must be setup at session
|
||||
@@ -118,6 +110,7 @@ struct iscsi_cmd_task {
|
||||
/* offset in unsolicited stream (bytes); */
|
||||
unsigned unsol_offset;
|
||||
unsigned data_count; /* remaining Data-Out */
|
||||
char *data; /* mgmt payload */
|
||||
struct scsi_cmnd *sc; /* associated SCSI cmd*/
|
||||
struct iscsi_conn *conn; /* used connection */
|
||||
|
||||
@@ -128,9 +121,9 @@ struct iscsi_cmd_task {
|
||||
void *dd_data; /* driver/transport data */
|
||||
};
|
||||
|
||||
static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask)
|
||||
static inline void* iscsi_next_hdr(struct iscsi_task *task)
|
||||
{
|
||||
return (void*)ctask->hdr + ctask->hdr_len;
|
||||
return (void*)task->hdr + task->hdr_len;
|
||||
}
|
||||
|
||||
/* Connection's states */
|
||||
@@ -145,11 +138,6 @@ struct iscsi_conn {
|
||||
struct iscsi_cls_conn *cls_conn; /* ptr to class connection */
|
||||
void *dd_data; /* iscsi_transport data */
|
||||
struct iscsi_session *session; /* parent session */
|
||||
/*
|
||||
* LLDs should set this lock. It protects the transport recv
|
||||
* code
|
||||
*/
|
||||
rwlock_t *recv_lock;
|
||||
/*
|
||||
* conn_stop() flag: stop to recover, stop to terminate
|
||||
*/
|
||||
@@ -159,7 +147,7 @@ struct iscsi_conn {
|
||||
unsigned long last_ping;
|
||||
int ping_timeout;
|
||||
int recv_timeout;
|
||||
struct iscsi_mgmt_task *ping_mtask;
|
||||
struct iscsi_task *ping_task;
|
||||
|
||||
/* iSCSI connection-wide sequencing */
|
||||
uint32_t exp_statsn;
|
||||
@@ -175,9 +163,8 @@ struct iscsi_conn {
|
||||
* should always fit in this buffer
|
||||
*/
|
||||
char *data;
|
||||
struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */
|
||||
struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */
|
||||
struct iscsi_cmd_task *ctask; /* xmit ctask in progress */
|
||||
struct iscsi_task *login_task; /* mtask used for login/text */
|
||||
struct iscsi_task *task; /* xmit task in progress */
|
||||
|
||||
/* xmit */
|
||||
struct list_head mgmtqueue; /* mgmt (control) xmit queue */
|
||||
@@ -208,9 +195,6 @@ struct iscsi_conn {
|
||||
/* remote portal currently connected to */
|
||||
int portal_port;
|
||||
char portal_address[ISCSI_ADDRESS_BUF_LEN];
|
||||
/* local address */
|
||||
int local_port;
|
||||
char local_address[ISCSI_ADDRESS_BUF_LEN];
|
||||
|
||||
/* MIB-statistics */
|
||||
uint64_t txdata_octets;
|
||||
@@ -246,6 +230,7 @@ enum {
|
||||
};
|
||||
|
||||
struct iscsi_session {
|
||||
struct iscsi_cls_session *cls_session;
|
||||
/*
|
||||
* Syncs up the scsi eh thread with the iscsi eh thread when sending
|
||||
* task management functions. This must be taken before the session
|
||||
@@ -281,10 +266,8 @@ struct iscsi_session {
|
||||
char *password;
|
||||
char *password_in;
|
||||
char *targetname;
|
||||
char *ifacename;
|
||||
char *initiatorname;
|
||||
/* hw address or netdev iscsi connection is bound to */
|
||||
char *hwaddress;
|
||||
char *netdev;
|
||||
/* control data */
|
||||
struct iscsi_transport *tt;
|
||||
struct Scsi_Host *host;
|
||||
@@ -298,12 +281,20 @@ struct iscsi_session {
|
||||
int state; /* session state */
|
||||
int age; /* counts session re-opens */
|
||||
|
||||
int scsi_cmds_max; /* max scsi commands */
|
||||
int cmds_max; /* size of cmds array */
|
||||
struct iscsi_cmd_task **cmds; /* Original Cmds arr */
|
||||
struct iscsi_task **cmds; /* Original Cmds arr */
|
||||
struct iscsi_pool cmdpool; /* PDU's pool */
|
||||
int mgmtpool_max; /* size of mgmt array */
|
||||
struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */
|
||||
struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */
|
||||
};
|
||||
|
||||
struct iscsi_host {
|
||||
char *initiatorname;
|
||||
/* hw address or netdev iscsi connection is bound to */
|
||||
char *hwaddress;
|
||||
char *netdev;
|
||||
/* local address */
|
||||
int local_port;
|
||||
char local_address[ISCSI_ADDRESS_BUF_LEN];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -316,42 +307,44 @@ extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
|
||||
extern int iscsi_queuecommand(struct scsi_cmnd *sc,
|
||||
void (*done)(struct scsi_cmnd *));
|
||||
|
||||
|
||||
/*
|
||||
* iSCSI host helpers.
|
||||
*/
|
||||
#define iscsi_host_priv(_shost) \
|
||||
(shost_priv(_shost) + sizeof(struct iscsi_host))
|
||||
|
||||
extern int iscsi_host_set_param(struct Scsi_Host *shost,
|
||||
enum iscsi_host_param param, char *buf,
|
||||
int buflen);
|
||||
extern int iscsi_host_get_param(struct Scsi_Host *shost,
|
||||
enum iscsi_host_param param, char *buf);
|
||||
extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
|
||||
extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
|
||||
int dd_data_size, uint16_t qdepth);
|
||||
extern void iscsi_host_remove(struct Scsi_Host *shost);
|
||||
extern void iscsi_host_free(struct Scsi_Host *shost);
|
||||
|
||||
/*
|
||||
* session management
|
||||
*/
|
||||
extern struct iscsi_cls_session *
|
||||
iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
|
||||
uint16_t, uint16_t, int, int, uint32_t, uint32_t *);
|
||||
iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
|
||||
uint16_t, int, uint32_t, unsigned int);
|
||||
extern void iscsi_session_teardown(struct iscsi_cls_session *);
|
||||
extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
|
||||
extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
|
||||
extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf, int buflen);
|
||||
extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
|
||||
enum iscsi_param param, char *buf);
|
||||
|
||||
#define session_to_cls(_sess) \
|
||||
hostdata_session(_sess->host->hostdata)
|
||||
|
||||
#define iscsi_session_printk(prefix, _sess, fmt, a...) \
|
||||
iscsi_cls_session_printk(prefix, \
|
||||
(struct iscsi_cls_session *)session_to_cls(_sess), fmt, ##a)
|
||||
iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a)
|
||||
|
||||
/*
|
||||
* connection management
|
||||
*/
|
||||
extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *,
|
||||
uint32_t);
|
||||
int, uint32_t);
|
||||
extern void iscsi_conn_teardown(struct iscsi_cls_conn *);
|
||||
extern int iscsi_conn_start(struct iscsi_cls_conn *);
|
||||
extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
|
||||
@@ -360,25 +353,29 @@ extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
|
||||
extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
|
||||
extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf);
|
||||
extern void iscsi_suspend_tx(struct iscsi_conn *conn);
|
||||
|
||||
#define iscsi_conn_printk(prefix, _c, fmt, a...) \
|
||||
iscsi_cls_conn_printk(prefix, _c->cls_conn, fmt, ##a)
|
||||
iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
|
||||
fmt, ##a)
|
||||
|
||||
/*
|
||||
* pdu and task processing
|
||||
*/
|
||||
extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *);
|
||||
extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *,
|
||||
extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *,
|
||||
struct iscsi_data *hdr);
|
||||
extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
|
||||
char *, uint32_t);
|
||||
extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
|
||||
char *, int);
|
||||
extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *,
|
||||
uint32_t *);
|
||||
extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
|
||||
extern void iscsi_free_mgmt_task(struct iscsi_conn *conn,
|
||||
struct iscsi_mgmt_task *mtask);
|
||||
extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
|
||||
char *, int);
|
||||
extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
|
||||
extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
|
||||
extern void iscsi_requeue_task(struct iscsi_task *task);
|
||||
extern void iscsi_put_task(struct iscsi_task *task);
|
||||
extern void __iscsi_get_task(struct iscsi_task *task);
|
||||
|
||||
/*
|
||||
* generic helpers
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#define _SCSI_SCSI_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
|
||||
/*
|
||||
* The maximum number of SG segments that we will put inside a
|
||||
@@ -400,6 +401,7 @@ struct scsi_lun {
|
||||
#define SOFT_ERROR 0x2005
|
||||
#define ADD_TO_MLQUEUE 0x2006
|
||||
#define TIMEOUT_ERROR 0x2007
|
||||
#define SCSI_RETURN_NOT_HANDLED 0x2008
|
||||
|
||||
/*
|
||||
* Midlevel queue return values.
|
||||
@@ -424,6 +426,22 @@ struct scsi_lun {
|
||||
#define driver_byte(result) (((result) >> 24) & 0xff)
|
||||
#define suggestion(result) (driver_byte(result) & SUGGEST_MASK)
|
||||
|
||||
static inline void set_msg_byte(struct scsi_cmnd *cmd, char status)
|
||||
{
|
||||
cmd->result |= status << 8;
|
||||
}
|
||||
|
||||
static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
|
||||
{
|
||||
cmd->result |= status << 16;
|
||||
}
|
||||
|
||||
static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)
|
||||
{
|
||||
cmd->result |= status << 24;
|
||||
}
|
||||
|
||||
|
||||
#define sense_class(sense) (((sense) >> 4) & 0x7)
|
||||
#define sense_error(sense) ((sense) & 0xf)
|
||||
#define sense_valid(sense) ((sense) & 0x80);
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
struct Scsi_Host;
|
||||
struct scsi_device;
|
||||
|
@@ -162,9 +162,29 @@ struct scsi_device {
|
||||
|
||||
struct execute_work ew; /* used to get process context on put */
|
||||
|
||||
struct scsi_dh_data *scsi_dh_data;
|
||||
enum scsi_device_state sdev_state;
|
||||
unsigned long sdev_data[0];
|
||||
} __attribute__((aligned(sizeof(unsigned long))));
|
||||
|
||||
struct scsi_device_handler {
|
||||
/* Used by the infrastructure */
|
||||
struct list_head list; /* list of scsi_device_handlers */
|
||||
struct notifier_block nb;
|
||||
|
||||
/* Filled by the hardware handler */
|
||||
struct module *module;
|
||||
const char *name;
|
||||
int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
|
||||
int (*activate)(struct scsi_device *);
|
||||
int (*prep_fn)(struct scsi_device *, struct request *);
|
||||
};
|
||||
|
||||
struct scsi_dh_data {
|
||||
struct scsi_device_handler *scsi_dh;
|
||||
char buf[0];
|
||||
};
|
||||
|
||||
#define to_scsi_device(d) \
|
||||
container_of(d, struct scsi_device, sdev_gendev)
|
||||
#define class_to_sdev(d) \
|
||||
@@ -231,7 +251,9 @@ extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
|
||||
uint, uint, uint, void *hostdata);
|
||||
extern int scsi_add_device(struct Scsi_Host *host, uint channel,
|
||||
uint target, uint lun);
|
||||
extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh);
|
||||
extern void scsi_remove_device(struct scsi_device *);
|
||||
extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh);
|
||||
|
||||
extern int scsi_device_get(struct scsi_device *);
|
||||
extern void scsi_device_put(struct scsi_device *);
|
||||
|
69
include/scsi/scsi_dh.h
Normal file
69
include/scsi/scsi_dh.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Header file for SCSI device handler infrastruture.
|
||||
*
|
||||
* Modified version of patches posted by Mike Christie <michaelc@cs.wisc.edu>
|
||||
*
|
||||
* 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 IBM Corporation, 2007
|
||||
* Authors:
|
||||
* Chandra Seetharaman <sekharan@us.ibm.com>
|
||||
* Mike Anderson <andmike@linux.vnet.ibm.com>
|
||||
*/
|
||||
|
||||
#include <scsi/scsi_device.h>
|
||||
|
||||
enum {
|
||||
SCSI_DH_OK = 0,
|
||||
/*
|
||||
* device errors
|
||||
*/
|
||||
SCSI_DH_DEV_FAILED, /* generic device error */
|
||||
SCSI_DH_DEV_TEMP_BUSY,
|
||||
SCSI_DH_DEVICE_MAX, /* max device blkerr definition */
|
||||
|
||||
/*
|
||||
* transport errors
|
||||
*/
|
||||
SCSI_DH_NOTCONN = SCSI_DH_DEVICE_MAX + 1,
|
||||
SCSI_DH_CONN_FAILURE,
|
||||
SCSI_DH_TRANSPORT_MAX, /* max transport blkerr definition */
|
||||
|
||||
/*
|
||||
* driver and generic errors
|
||||
*/
|
||||
SCSI_DH_IO = SCSI_DH_TRANSPORT_MAX + 1, /* generic error */
|
||||
SCSI_DH_INVALID_IO,
|
||||
SCSI_DH_RETRY, /* retry the req, but not immediately */
|
||||
SCSI_DH_IMM_RETRY, /* immediately retry the req */
|
||||
SCSI_DH_TIMED_OUT,
|
||||
SCSI_DH_RES_TEMP_UNAVAIL,
|
||||
SCSI_DH_DEV_OFFLINED,
|
||||
SCSI_DH_NOSYS,
|
||||
SCSI_DH_DRIVER_MAX,
|
||||
};
|
||||
#if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE)
|
||||
extern int scsi_dh_activate(struct request_queue *);
|
||||
extern int scsi_dh_handler_exist(const char *);
|
||||
#else
|
||||
static inline int scsi_dh_activate(struct request_queue *req)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int scsi_dh_handler_exist(const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@@ -30,11 +30,11 @@
|
||||
|
||||
struct scsi_transport_template;
|
||||
struct iscsi_transport;
|
||||
struct iscsi_endpoint;
|
||||
struct Scsi_Host;
|
||||
struct iscsi_cls_conn;
|
||||
struct iscsi_conn;
|
||||
struct iscsi_cmd_task;
|
||||
struct iscsi_mgmt_task;
|
||||
struct iscsi_task;
|
||||
struct sockaddr;
|
||||
|
||||
/**
|
||||
@@ -58,19 +58,22 @@ struct sockaddr;
|
||||
* @stop_conn: suspend/recover/terminate connection
|
||||
* @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text.
|
||||
* @session_recovery_timedout: notify LLD a block during recovery timed out
|
||||
* @init_cmd_task: Initialize a iscsi_cmd_task and any internal structs.
|
||||
* Called from queuecommand with session lock held.
|
||||
* @init_mgmt_task: Initialize a iscsi_mgmt_task and any internal structs.
|
||||
* Called from iscsi_conn_send_generic with xmitmutex.
|
||||
* @xmit_cmd_task: Requests LLD to transfer cmd task. Returns 0 or the
|
||||
* @init_task: Initialize a iscsi_task and any internal structs.
|
||||
* When offloading the data path, this is called from
|
||||
* queuecommand with the session lock, or from the
|
||||
* iscsi_conn_send_pdu context with the session lock.
|
||||
* When not offloading the data path, this is called
|
||||
* from the scsi work queue without the session lock.
|
||||
* @xmit_task Requests LLD to transfer cmd task. Returns 0 or the
|
||||
* the number of bytes transferred on success, and -Exyz
|
||||
* value on error.
|
||||
* @xmit_mgmt_task: Requests LLD to transfer mgmt task. Returns 0 or the
|
||||
* the number of bytes transferred on success, and -Exyz
|
||||
* value on error.
|
||||
* @cleanup_cmd_task: requests LLD to fail cmd task. Called with xmitmutex
|
||||
* and session->lock after the connection has been
|
||||
* suspended and terminated during recovery. If called
|
||||
* value on error. When offloading the data path, this
|
||||
* is called from queuecommand with the session lock, or
|
||||
* from the iscsi_conn_send_pdu context with the session
|
||||
* lock. When not offloading the data path, this is called
|
||||
* from the scsi work queue without the session lock.
|
||||
* @cleanup_task: requests LLD to fail task. Called with session lock
|
||||
* and after the connection has been suspended and
|
||||
* terminated during recovery. If called
|
||||
* from abort task then connection is not suspended
|
||||
* or terminated but sk_callback_lock is held
|
||||
*
|
||||
@@ -83,17 +86,9 @@ struct iscsi_transport {
|
||||
/* LLD sets this to indicate what values it can export to sysfs */
|
||||
uint64_t param_mask;
|
||||
uint64_t host_param_mask;
|
||||
struct scsi_host_template *host_template;
|
||||
/* LLD connection data size */
|
||||
int conndata_size;
|
||||
/* LLD session data size */
|
||||
int sessiondata_size;
|
||||
int max_lun;
|
||||
unsigned int max_conn;
|
||||
unsigned int max_cmd_len;
|
||||
struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it,
|
||||
struct scsi_transport_template *t, uint16_t, uint16_t,
|
||||
uint32_t sn, uint32_t *hn);
|
||||
struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep,
|
||||
uint16_t cmds_max, uint16_t qdepth,
|
||||
uint32_t sn, uint32_t *hn);
|
||||
void (*destroy_session) (struct iscsi_cls_session *session);
|
||||
struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
|
||||
uint32_t cid);
|
||||
@@ -118,20 +113,15 @@ struct iscsi_transport {
|
||||
char *data, uint32_t data_size);
|
||||
void (*get_stats) (struct iscsi_cls_conn *conn,
|
||||
struct iscsi_stats *stats);
|
||||
int (*init_cmd_task) (struct iscsi_cmd_task *ctask);
|
||||
void (*init_mgmt_task) (struct iscsi_conn *conn,
|
||||
struct iscsi_mgmt_task *mtask);
|
||||
int (*xmit_cmd_task) (struct iscsi_conn *conn,
|
||||
struct iscsi_cmd_task *ctask);
|
||||
void (*cleanup_cmd_task) (struct iscsi_conn *conn,
|
||||
struct iscsi_cmd_task *ctask);
|
||||
int (*xmit_mgmt_task) (struct iscsi_conn *conn,
|
||||
struct iscsi_mgmt_task *mtask);
|
||||
int (*init_task) (struct iscsi_task *task);
|
||||
int (*xmit_task) (struct iscsi_task *task);
|
||||
void (*cleanup_task) (struct iscsi_conn *conn,
|
||||
struct iscsi_task *task);
|
||||
void (*session_recovery_timedout) (struct iscsi_cls_session *session);
|
||||
int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking,
|
||||
uint64_t *ep_handle);
|
||||
int (*ep_poll) (uint64_t ep_handle, int timeout_ms);
|
||||
void (*ep_disconnect) (uint64_t ep_handle);
|
||||
struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr,
|
||||
int non_blocking);
|
||||
int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms);
|
||||
void (*ep_disconnect) (struct iscsi_endpoint *ep);
|
||||
int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
|
||||
uint32_t enable, struct sockaddr *dst_addr);
|
||||
};
|
||||
@@ -172,9 +162,10 @@ enum {
|
||||
ISCSI_SESSION_FREE,
|
||||
};
|
||||
|
||||
#define ISCSI_MAX_TARGET -1
|
||||
|
||||
struct iscsi_cls_session {
|
||||
struct list_head sess_list; /* item in session_list */
|
||||
struct list_head host_list;
|
||||
struct iscsi_transport *transport;
|
||||
spinlock_t lock;
|
||||
struct work_struct block_work;
|
||||
@@ -186,7 +177,7 @@ struct iscsi_cls_session {
|
||||
int recovery_tmo;
|
||||
struct delayed_work recovery_work;
|
||||
|
||||
int target_id;
|
||||
unsigned int target_id;
|
||||
|
||||
int state;
|
||||
int sid; /* session id */
|
||||
@@ -203,14 +194,22 @@ struct iscsi_cls_session {
|
||||
#define starget_to_session(_stgt) \
|
||||
iscsi_dev_to_session(_stgt->dev.parent)
|
||||
|
||||
struct iscsi_host {
|
||||
struct list_head sessions;
|
||||
struct iscsi_cls_host {
|
||||
atomic_t nr_scans;
|
||||
struct mutex mutex;
|
||||
struct workqueue_struct *scan_workq;
|
||||
char scan_workq_name[KOBJ_NAME_LEN];
|
||||
};
|
||||
|
||||
extern void iscsi_host_for_each_session(struct Scsi_Host *shost,
|
||||
void (*fn)(struct iscsi_cls_session *));
|
||||
|
||||
struct iscsi_endpoint {
|
||||
void *dd_data; /* LLD private data */
|
||||
struct device dev;
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
/*
|
||||
* session and connection functions that can be used by HW iSCSI LLDs
|
||||
*/
|
||||
@@ -222,22 +221,26 @@ struct iscsi_host {
|
||||
|
||||
extern int iscsi_session_chkready(struct iscsi_cls_session *session);
|
||||
extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost,
|
||||
struct iscsi_transport *transport);
|
||||
struct iscsi_transport *transport, int dd_size);
|
||||
extern int iscsi_add_session(struct iscsi_cls_session *session,
|
||||
unsigned int target_id);
|
||||
extern int iscsi_session_event(struct iscsi_cls_session *session,
|
||||
enum iscsi_uevent_e event);
|
||||
extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
|
||||
struct iscsi_transport *t,
|
||||
int dd_size,
|
||||
unsigned int target_id);
|
||||
extern void iscsi_remove_session(struct iscsi_cls_session *session);
|
||||
extern void iscsi_free_session(struct iscsi_cls_session *session);
|
||||
extern int iscsi_destroy_session(struct iscsi_cls_session *session);
|
||||
extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
|
||||
uint32_t cid);
|
||||
int dd_size, uint32_t cid);
|
||||
extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
|
||||
extern void iscsi_unblock_session(struct iscsi_cls_session *session);
|
||||
extern void iscsi_block_session(struct iscsi_cls_session *session);
|
||||
extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time);
|
||||
extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
|
||||
extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
|
||||
extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
|
||||
|
||||
#endif
|
||||
|
@@ -1,57 +0,0 @@
|
||||
#ifndef _SCSI_DISK_H
|
||||
#define _SCSI_DISK_H
|
||||
|
||||
/*
|
||||
* More than enough for everybody ;) The huge number of majors
|
||||
* is a leftover from 16bit dev_t days, we don't really need that
|
||||
* much numberspace.
|
||||
*/
|
||||
#define SD_MAJORS 16
|
||||
|
||||
/*
|
||||
* This is limited by the naming scheme enforced in sd_probe,
|
||||
* add another character to it if you really need more disks.
|
||||
*/
|
||||
#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26)
|
||||
|
||||
/*
|
||||
* Time out in seconds for disks and Magneto-opticals (which are slower).
|
||||
*/
|
||||
#define SD_TIMEOUT (30 * HZ)
|
||||
#define SD_MOD_TIMEOUT (75 * HZ)
|
||||
|
||||
/*
|
||||
* Number of allowed retries
|
||||
*/
|
||||
#define SD_MAX_RETRIES 5
|
||||
#define SD_PASSTHROUGH_RETRIES 1
|
||||
|
||||
/*
|
||||
* Size of the initial data buffer for mode and read capacity data
|
||||
*/
|
||||
#define SD_BUF_SIZE 512
|
||||
|
||||
struct scsi_disk {
|
||||
struct scsi_driver *driver; /* always &sd_template */
|
||||
struct scsi_device *device;
|
||||
struct device dev;
|
||||
struct gendisk *disk;
|
||||
unsigned int openers; /* protected by BKL for now, yuck */
|
||||
sector_t capacity; /* size in 512-byte sectors */
|
||||
u32 index;
|
||||
u8 media_present;
|
||||
u8 write_prot;
|
||||
unsigned previous_state : 1;
|
||||
unsigned WCE : 1; /* state of disk WCE bit */
|
||||
unsigned RCD : 1; /* state of disk RCD bit, unused */
|
||||
unsigned DPOFUA : 1; /* state of disk DPOFUA bit */
|
||||
};
|
||||
#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
|
||||
|
||||
#define sd_printk(prefix, sdsk, fmt, a...) \
|
||||
(sdsk)->disk ? \
|
||||
sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \
|
||||
(sdsk)->disk->disk_name, ##a) : \
|
||||
sdev_printk(prefix, (sdsk)->device, fmt, ##a)
|
||||
|
||||
#endif /* _SCSI_DISK_H */
|
@@ -206,6 +206,7 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
|
||||
#define SG_SCSI_RESET_DEVICE 1
|
||||
#define SG_SCSI_RESET_BUS 2
|
||||
#define SG_SCSI_RESET_HOST 3
|
||||
#define SG_SCSI_RESET_TARGET 4
|
||||
|
||||
/* synchronous SCSI command ioctl, (only in version 3 interface) */
|
||||
#define SG_IO 0x2285 /* similar effect as write() followed by read() */
|
||||
|
Reference in New Issue
Block a user