aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 17:53:36 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 17:53:36 -0700
commit39695224bd84dc4be29abad93a0ec232a16fc519 (patch)
tree2bfa5cb50788a4c8be9f2e9f4412e47a565f4508 /include
parentMerge branch 'docs-next' of git://git.lwn.net/linux-2.6 (diff)
parent[SCSI] fix oops during scsi scanning (diff)
downloadlinux-dev-39695224bd84dc4be29abad93a0ec232a16fc519.tar.xz
linux-dev-39695224bd84dc4be29abad93a0ec232a16fc519.zip
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: (209 commits) [SCSI] fix oops during scsi scanning [SCSI] libsrp: fix memory leak in srp_ring_free() [SCSI] libiscsi, bnx2i: make bound ep check common [SCSI] libiscsi: add completion function for drivers that do not need pdu processing [SCSI] scsi_dh_rdac: changes for rdac debug logging [SCSI] scsi_dh_rdac: changes to collect the rdac debug information during the initialization [SCSI] scsi_dh_rdac: move the init code from rdac_activate to rdac_bus_attach [SCSI] sg: fix oops in the error path in sg_build_indirect() [SCSI] mptsas : Bump version to 3.04.12 [SCSI] mptsas : FW event thread and scsi mid layer deadlock in SYNCHRONIZE CACHE command [SCSI] mptsas : Send DID_NO_CONNECT for pending IOs of removed device [SCSI] mptsas : PAE Kernel more than 4 GB kernel panic [SCSI] mptsas : NULL pointer on big endian systems causing Expander not to tear off [SCSI] mptsas : Sanity check for phyinfo is added [SCSI] scsi_dh_rdac: Add support for Sun StorageTek ST2500, ST2510 and ST2530 [SCSI] pmcraid: PMC-Sierra MaxRAID driver to support 6Gb/s SAS RAID controller [SCSI] qla2xxx: Update version number to 8.03.01-k6. [SCSI] qla2xxx: Properly delete rports attached to a vport. [SCSI] qla2xxx: Correct various NPIV issues. [SCSI] qla2xxx: Correct qla2x00_eh_wait_on_command() to wait correctly. ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/enclosure.h5
-rw-r--r--include/scsi/fc/fc_gs.h1
-rw-r--r--include/scsi/fc_encode.h60
-rw-r--r--include/scsi/fc_frame.h7
-rw-r--r--include/scsi/iscsi_if.h1
-rw-r--r--include/scsi/libfc.h244
-rw-r--r--include/scsi/libiscsi.h3
-rw-r--r--include/scsi/scsi_device.h3
-rw-r--r--include/scsi/scsi_dh.h5
9 files changed, 184 insertions, 145 deletions
diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
index 4332442b1b57..90d1c2184112 100644
--- a/include/linux/enclosure.h
+++ b/include/linux/enclosure.h
@@ -122,8 +122,9 @@ enclosure_component_register(struct enclosure_device *, unsigned int,
enum enclosure_component_type, const char *);
int enclosure_add_device(struct enclosure_device *enclosure, int component,
struct device *dev);
-int enclosure_remove_device(struct enclosure_device *enclosure, int component);
-struct enclosure_device *enclosure_find(struct device *dev);
+int enclosure_remove_device(struct enclosure_device *, struct device *);
+struct enclosure_device *enclosure_find(struct device *dev,
+ struct enclosure_device *start);
int enclosure_for_each_device(int (*fn)(struct enclosure_device *, void *),
void *data);
diff --git a/include/scsi/fc/fc_gs.h b/include/scsi/fc/fc_gs.h
index ffab0272c65a..324dd0e3c622 100644
--- a/include/scsi/fc/fc_gs.h
+++ b/include/scsi/fc/fc_gs.h
@@ -87,6 +87,7 @@ enum fc_ct_explan {
FC_FS_EXP_PNAM = 0x02, /* port name not registered */
FC_FS_EXP_NNAM = 0x03, /* node name not registered */
FC_FS_EXP_COS = 0x04, /* class of service not registered */
+ FC_FS_EXP_FTNR = 0x07, /* FC-4 types not registered */
/* definitions not complete */
};
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index a0ff61c3e935..27dad703824f 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -32,6 +32,7 @@ struct fc_ct_req {
struct fc_ns_gid_ft gid;
struct fc_ns_rn_id rn;
struct fc_ns_rft rft;
+ struct fc_ns_fid fid;
} payload;
};
@@ -57,6 +58,23 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
}
/**
+ * fc_adisc_fill() - Fill in adisc request frame
+ * @lport: local port.
+ * @fp: fc frame where payload will be placed.
+ */
+static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
+{
+ struct fc_els_adisc *adisc;
+
+ adisc = fc_frame_payload_get(fp, sizeof(*adisc));
+ memset(adisc, 0, sizeof(*adisc));
+ adisc->adisc_cmd = ELS_ADISC;
+ put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
+ put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
+ hton24(adisc->adisc_port_id, fc_host_port_id(lport->host));
+}
+
+/**
* fc_ct_hdr_fill- fills ct header and reset ct payload
* returns pointer to ct request.
*/
@@ -77,10 +95,17 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
}
/**
- * fc_ct_fill - Fill in a name service request frame
+ * fc_ct_fill() - Fill in a name service request frame
+ * @lport: local port.
+ * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
+ * @fp: frame to contain payload.
+ * @op: CT opcode.
+ * @r_ctl: pointer to FC header R_CTL.
+ * @fh_type: pointer to FC-4 type.
*/
-static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
- unsigned int op, enum fc_rctl *r_ctl, u32 *did,
+static inline int fc_ct_fill(struct fc_lport *lport,
+ u32 fc_id, struct fc_frame *fp,
+ unsigned int op, enum fc_rctl *r_ctl,
enum fc_fh_type *fh_type)
{
struct fc_ct_req *ct;
@@ -91,6 +116,11 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
break;
+ case FC_NS_GPN_ID:
+ ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid));
+ hton24(ct->payload.fid.fp_fid, fc_id);
+ break;
+
case FC_NS_RFT_ID:
ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft));
hton24(ct->payload.rft.fid.fp_fid,
@@ -110,7 +140,6 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
return -EINVAL;
}
*r_ctl = FC_RCTL_DD_UNSOL_CTL;
- *did = FC_FID_DIR_SERV;
*fh_type = FC_TYPE_CT;
return 0;
}
@@ -249,51 +278,42 @@ static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
/**
* fc_els_fill - Fill in an ELS request frame
*/
-static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport,
+static inline int fc_els_fill(struct fc_lport *lport,
+ u32 did,
struct fc_frame *fp, unsigned int op,
- enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type)
+ enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
{
switch (op) {
+ case ELS_ADISC:
+ fc_adisc_fill(lport, fp);
+ break;
+
case ELS_PLOGI:
fc_plogi_fill(lport, fp, ELS_PLOGI);
- *did = rport->port_id;
break;
case ELS_FLOGI:
fc_flogi_fill(lport, fp);
- *did = FC_FID_FLOGI;
break;
case ELS_LOGO:
fc_logo_fill(lport, fp);
- *did = FC_FID_FLOGI;
- /*
- * if rport is valid then it
- * is port logo, therefore
- * set did to rport id.
- */
- if (rport)
- *did = rport->port_id;
break;
case ELS_RTV:
fc_rtv_fill(lport, fp);
- *did = rport->port_id;
break;
case ELS_REC:
fc_rec_fill(lport, fp);
- *did = rport->port_id;
break;
case ELS_PRLI:
fc_prli_fill(lport, fp);
- *did = rport->port_id;
break;
case ELS_SCR:
fc_scr_fill(lport, fp);
- *did = FC_FID_FCTRL;
break;
default:
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index 59511057cee0..c35d2383cc26 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -37,13 +37,6 @@
#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */
#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */
-/*
- * Information about an individual fibre channel frame received or to be sent.
- * The buffer may be in up to 4 additional non-contiguous sections,
- * but the linear section must hold the frame header.
- */
-#define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */
-
#define fp_skb(fp) (&((fp)->skb))
#define fr_hdr(fp) ((fp)->skb.data)
#define fr_len(fp) ((fp)->skb.len)
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 4426f00da5ff..d67dda2b6aa0 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -262,6 +262,7 @@ enum iscsi_err {
ISCSI_ERR_NO_SCSI_CMD = ISCSI_ERR_BASE + 17,
ISCSI_ERR_INVALID_HOST = ISCSI_ERR_BASE + 18,
ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19,
+ ISCSI_ERR_TCP_CONN_CLOSE = ISCSI_ERR_BASE + 20,
};
/*
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index b92584a8843a..65dc9aacbf70 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -51,55 +51,49 @@ do { \
do { \
CMD; \
} while (0); \
-} while (0);
+} while (0)
#define FC_LIBFC_DBG(fmt, args...) \
FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \
- printk(KERN_INFO "libfc: " fmt, ##args);)
+ printk(KERN_INFO "libfc: " fmt, ##args))
#define FC_LPORT_DBG(lport, fmt, args...) \
FC_CHECK_LOGGING(FC_LPORT_LOGGING, \
- printk(KERN_INFO "lport: %6x: " fmt, \
- fc_host_port_id(lport->host), ##args);)
+ printk(KERN_INFO "host%u: lport %6x: " fmt, \
+ (lport)->host->host_no, \
+ fc_host_port_id((lport)->host), ##args))
#define FC_DISC_DBG(disc, fmt, args...) \
FC_CHECK_LOGGING(FC_DISC_LOGGING, \
- printk(KERN_INFO "disc: %6x: " fmt, \
- fc_host_port_id(disc->lport->host), \
- ##args);)
-
-#define FC_RPORT_DBG(rport, fmt, args...) \
-do { \
- struct fc_rport_libfc_priv *rdata = rport->dd_data; \
- struct fc_lport *lport = rdata->local_port; \
+ printk(KERN_INFO "host%u: disc: " fmt, \
+ (disc)->lport->host->host_no, \
+ ##args))
+
+#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...) \
FC_CHECK_LOGGING(FC_RPORT_LOGGING, \
- printk(KERN_INFO "rport: %6x: %6x: " fmt, \
- fc_host_port_id(lport->host), \
- rport->port_id, ##args);) \
-} while (0);
+ printk(KERN_INFO "host%u: rport %6x: " fmt, \
+ (lport)->host->host_no, \
+ (port_id), ##args))
+
+#define FC_RPORT_DBG(rdata, fmt, args...) \
+ FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
#define FC_FCP_DBG(pkt, fmt, args...) \
FC_CHECK_LOGGING(FC_FCP_LOGGING, \
- printk(KERN_INFO "fcp: %6x: %6x: " fmt, \
- fc_host_port_id(pkt->lp->host), \
- pkt->rport->port_id, ##args);)
-
-#define FC_EM_DBG(em, fmt, args...) \
- FC_CHECK_LOGGING(FC_EM_LOGGING, \
- printk(KERN_INFO "em: %6x: " fmt, \
- fc_host_port_id(em->lp->host), \
- ##args);)
+ printk(KERN_INFO "host%u: fcp: %6x: " fmt, \
+ (pkt)->lp->host->host_no, \
+ pkt->rport->port_id, ##args))
#define FC_EXCH_DBG(exch, fmt, args...) \
FC_CHECK_LOGGING(FC_EXCH_LOGGING, \
- printk(KERN_INFO "exch: %6x: %4x: " fmt, \
- fc_host_port_id(exch->lp->host), \
- exch->xid, ##args);)
+ printk(KERN_INFO "host%u: xid %4x: " fmt, \
+ (exch)->lp->host->host_no, \
+ exch->xid, ##args))
#define FC_SCSI_DBG(lport, fmt, args...) \
FC_CHECK_LOGGING(FC_SCSI_LOGGING, \
- printk(KERN_INFO "scsi: %6x: " fmt, \
- fc_host_port_id(lport->host), ##args);)
+ printk(KERN_INFO "host%u: scsi: " fmt, \
+ (lport)->host->host_no, ##args))
/*
* libfc error codes
@@ -125,7 +119,7 @@ do { \
* FC HBA status
*/
enum fc_lport_state {
- LPORT_ST_NONE = 0,
+ LPORT_ST_DISABLED = 0,
LPORT_ST_FLOGI,
LPORT_ST_DNS,
LPORT_ST_RPN_ID,
@@ -143,53 +137,74 @@ enum fc_disc_event {
};
enum fc_rport_state {
- RPORT_ST_NONE = 0,
RPORT_ST_INIT, /* initialized */
RPORT_ST_PLOGI, /* waiting for PLOGI completion */
RPORT_ST_PRLI, /* waiting for PRLI completion */
RPORT_ST_RTV, /* waiting for RTV completion */
RPORT_ST_READY, /* ready for use */
RPORT_ST_LOGO, /* port logout sent */
-};
-
-enum fc_rport_trans_state {
- FC_PORTSTATE_ROGUE,
- FC_PORTSTATE_REAL,
+ RPORT_ST_ADISC, /* Discover Address sent */
+ RPORT_ST_DELETE, /* port being deleted */
};
/**
* struct fc_disc_port - temporary discovery port to hold rport identifiers
- * @lp: Fibre Channel host port instance
- * @peers: node for list management during discovery and RSCN processing
- * @ids: identifiers structure to pass to fc_remote_port_add()
- * @rport_work: work struct for starting the rport state machine
+ * @lp: Fibre Channel host port instance
+ * @peers: Node for list management during discovery and RSCN processing
+ * @rport_work: Work struct for starting the rport state machine
+ * @port_id: Port ID of the discovered port
*/
struct fc_disc_port {
struct fc_lport *lp;
struct list_head peers;
- struct fc_rport_identifiers ids;
struct work_struct rport_work;
+ u32 port_id;
};
enum fc_rport_event {
RPORT_EV_NONE = 0,
- RPORT_EV_CREATED,
+ RPORT_EV_READY,
RPORT_EV_FAILED,
RPORT_EV_STOP,
RPORT_EV_LOGO
};
+struct fc_rport_priv;
+
struct fc_rport_operations {
- void (*event_callback)(struct fc_lport *, struct fc_rport *,
+ void (*event_callback)(struct fc_lport *, struct fc_rport_priv *,
enum fc_rport_event);
};
/**
* struct fc_rport_libfc_priv - libfc internal information about a remote port
* @local_port: Fibre Channel host port instance
+ * @rp_state: indicates READY for I/O or DELETE when blocked.
+ * @flags: REC and RETRY supported flags
+ * @e_d_tov: error detect timeout value (in msec)
+ * @r_a_tov: resource allocation timeout value (in msec)
+ */
+struct fc_rport_libfc_priv {
+ struct fc_lport *local_port;
+ enum fc_rport_state rp_state;
+ u16 flags;
+ #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)
+ #define FC_RP_FLAGS_RETRY (1 << 1)
+ unsigned int e_d_tov;
+ unsigned int r_a_tov;
+};
+
+/**
+ * struct fc_rport_priv - libfc rport and discovery info about a remote port
+ * @local_port: Fibre Channel host port instance
+ * @rport: transport remote port
+ * @kref: reference counter
* @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges
+ * @ids: remote port identifiers and roles
* @flags: REC and RETRY supported flags
* @max_seq: maximum number of concurrent sequences
+ * @disc_id: discovery identifier
+ * @maxframe_size: maximum frame size
* @retries: retry count in current state
* @e_d_tov: error detect timeout value (in msec)
* @r_a_tov: resource allocation timeout value (in msec)
@@ -197,38 +212,28 @@ struct fc_rport_operations {
* @retry_work:
* @event_callback: Callback for rport READY, FAILED or LOGO
*/
-struct fc_rport_libfc_priv {
+struct fc_rport_priv {
struct fc_lport *local_port;
+ struct fc_rport *rport;
+ struct kref kref;
enum fc_rport_state rp_state;
+ struct fc_rport_identifiers ids;
u16 flags;
- #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)
- #define FC_RP_FLAGS_RETRY (1 << 1)
u16 max_seq;
+ u16 disc_id;
+ u16 maxframe_size;
unsigned int retries;
unsigned int e_d_tov;
unsigned int r_a_tov;
- enum fc_rport_trans_state trans_state;
struct mutex rp_mutex;
struct delayed_work retry_work;
enum fc_rport_event event;
struct fc_rport_operations *ops;
struct list_head peers;
struct work_struct event_work;
+ u32 supported_classes;
};
-#define PRIV_TO_RPORT(x) \
- (struct fc_rport *)((void *)x - sizeof(struct fc_rport));
-#define RPORT_TO_PRIV(x) \
- (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport));
-
-struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *);
-
-static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn)
-{
- rport->node_name = wwnn;
- rport->port_name = wwpn;
-}
-
/*
* fcoe stats structure
*/
@@ -344,6 +349,8 @@ static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp)
*/
struct fc_exch_mgr;
+struct fc_exch_mgr_anchor;
+extern u16 fc_cpu_mask; /* cpu mask for possible cpus */
/*
* Sequence.
@@ -368,6 +375,7 @@ struct fc_seq {
*/
struct fc_exch {
struct fc_exch_mgr *em; /* exchange manager */
+ struct fc_exch_pool *pool; /* per cpu exches pool */
u32 state; /* internal driver state */
u16 xid; /* our exchange ID */
struct list_head ex_list; /* free or busy list linkage */
@@ -415,7 +423,7 @@ struct libfc_function_template {
* STATUS: OPTIONAL
*/
struct fc_seq *(*elsct_send)(struct fc_lport *lport,
- struct fc_rport *rport,
+ u32 did,
struct fc_frame *fp,
unsigned int op,
void (*resp)(struct fc_seq *,
@@ -519,25 +527,6 @@ struct libfc_function_template {
void (*exch_done)(struct fc_seq *sp);
/*
- * Assigns a EM and a free XID for an new exchange and then
- * allocates a new exchange and sequence pair.
- * The fp can be used to determine free XID.
- *
- * STATUS: OPTIONAL
- */
- struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp);
-
- /*
- * Release previously assigned XID by exch_get API.
- * The LLD may implement this if XID is assigned by LLD
- * in exch_get().
- *
- * STATUS: OPTIONAL
- */
- void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp,
- u16 ex_id);
-
- /*
* Start a new sequence on the same exchange/sequence tuple.
*
* STATUS: OPTIONAL
@@ -577,9 +566,11 @@ struct libfc_function_template {
int (*lport_reset)(struct fc_lport *);
/*
- * Create a remote port
+ * Create a remote port with a given port ID
+ *
+ * STATUS: OPTIONAL
*/
- struct fc_rport *(*rport_create)(struct fc_disc_port *);
+ struct fc_rport_priv *(*rport_create)(struct fc_lport *, u32);
/*
* Initiates the RP state machine. It is called from the LP module.
@@ -592,7 +583,7 @@ struct libfc_function_template {
*
* STATUS: OPTIONAL
*/
- int (*rport_login)(struct fc_rport *rport);
+ int (*rport_login)(struct fc_rport_priv *);
/*
* Logoff, and remove the rport from the transport if
@@ -600,7 +591,7 @@ struct libfc_function_template {
*
* STATUS: OPTIONAL
*/
- int (*rport_logoff)(struct fc_rport *rport);
+ int (*rport_logoff)(struct fc_rport_priv *);
/*
* Recieve a request from a remote port.
@@ -608,14 +599,20 @@ struct libfc_function_template {
* STATUS: OPTIONAL
*/
void (*rport_recv_req)(struct fc_seq *, struct fc_frame *,
- struct fc_rport *);
+ struct fc_lport *);
/*
* lookup an rport by it's port ID.
*
* STATUS: OPTIONAL
*/
- struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32);
+ struct fc_rport_priv *(*rport_lookup)(const struct fc_lport *, u32);
+
+ /*
+ * Destroy an rport after final kref_put().
+ * The argument is a pointer to the kref inside the fc_rport_priv.
+ */
+ void (*rport_destroy)(struct kref *);
/*
* Send a fcp cmd from fsp pkt.
@@ -681,18 +678,16 @@ struct libfc_function_template {
/* information used by the discovery layer */
struct fc_disc {
unsigned char retry_count;
- unsigned char delay;
unsigned char pending;
unsigned char requested;
unsigned short seq_count;
unsigned char buf_len;
- enum fc_disc_event event;
+ u16 disc_id;
void (*disc_callback)(struct fc_lport *,
enum fc_disc_event);
struct list_head rports;
- struct list_head rogue_rports;
struct fc_lport *lport;
struct mutex disc_mutex;
struct fc_gpn_ft_resp partial_buf; /* partial name buffer */
@@ -704,9 +699,9 @@ struct fc_lport {
/* Associations */
struct Scsi_Host *host;
- struct fc_exch_mgr *emp;
- struct fc_rport *dns_rp;
- struct fc_rport *ptp_rp;
+ struct list_head ema_list;
+ struct fc_rport_priv *dns_rp;
+ struct fc_rport_priv *ptp_rp;
void *scsi_priv;
struct fc_disc disc;
@@ -960,6 +955,28 @@ int fc_elsct_init(struct fc_lport *lp);
int fc_exch_init(struct fc_lport *lp);
/*
+ * Adds Exchange Manager (EM) mp to lport.
+ *
+ * Adds specified mp to lport using struct fc_exch_mgr_anchor,
+ * the struct fc_exch_mgr_anchor allows same EM sharing by
+ * more than one lport with their specified match function,
+ * the match function is used in allocating exchange from
+ * added mp.
+ */
+struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
+ struct fc_exch_mgr *mp,
+ bool (*match)(struct fc_frame *));
+
+/*
+ * Deletes Exchange Manager (EM) from lport by removing
+ * its anchor ema from lport.
+ *
+ * If removed anchor ema was the last user of its associated EM
+ * then also destroys associated EM.
+ */
+void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema);
+
+/*
* Allocates an Exchange Manager (EM).
*
* The EM manages exchanges for their allocation and
@@ -974,27 +991,25 @@ int fc_exch_init(struct fc_lport *lp);
* a new exchange.
* The LLD may choose to have multiple EMs,
* e.g. one EM instance per CPU receive thread in LLD.
- * The LLD can use exch_get() of struct libfc_function_template
- * to specify XID for a new exchange within
- * a specified EM instance.
*
- * The em_idx to uniquely identify an EM instance.
+ * Specified match function is used in allocating exchanges
+ * from newly allocated EM.
*/
struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
enum fc_class class,
u16 min_xid,
- u16 max_xid);
+ u16 max_xid,
+ bool (*match)(struct fc_frame *));
/*
- * Free an exchange manager.
+ * Free all exchange managers of a lport.
*/
-void fc_exch_mgr_free(struct fc_exch_mgr *mp);
+void fc_exch_mgr_free(struct fc_lport *lport);
/*
* Receive a frame on specified local port and exchange manager.
*/
-void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
- struct fc_frame *fp);
+void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp);
/*
* This function is for exch_seq_send function pointer in
@@ -1036,28 +1051,20 @@ int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec);
void fc_exch_done(struct fc_seq *sp);
/*
- * Assigns a EM and XID for a frame and then allocates
- * a new exchange and sequence pair.
- * The fp can be used to determine free XID.
- */
-struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp);
-
-/*
* Allocate a new exchange and sequence pair.
- * if ex_id is zero then next free exchange id
- * from specified exchange manger mp will be assigned.
*/
-struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
- struct fc_frame *fp, u16 ex_id);
+struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp);
/*
* Start a new sequence on the same exchange as the supplied sequence.
*/
struct fc_seq *fc_seq_start_next(struct fc_seq *sp);
+
/*
- * Reset an exchange manager, completing all sequences and exchanges.
- * If s_id is non-zero, reset only exchanges originating from that FID.
- * If d_id is non-zero, reset only exchanges sending to that FID.
+ * Reset all EMs of a lport, releasing its all sequences and
+ * exchanges. If sid is non-zero, then reset only exchanges
+ * we sourced from that FID. If did is non-zero, reset only
+ * exchanges destined to that FID.
*/
void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id);
@@ -1078,4 +1085,9 @@ void fc_destroy_exch_mgr(void);
int fc_setup_rport(void);
void fc_destroy_rport(void);
+/*
+ * Internal libfc functions.
+ */
+const char *fc_els_resp_type(struct fc_frame *);
+
#endif /* _LIBFC_H_ */
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 61afeb59a836..887e57e3e223 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -390,6 +390,7 @@ extern void iscsi_session_failure(struct iscsi_session *session,
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);
+extern void iscsi_suspend_queue(struct iscsi_conn *conn);
extern void iscsi_conn_queue_work(struct iscsi_conn *conn);
#define iscsi_conn_printk(prefix, _c, fmt, a...) \
@@ -415,6 +416,8 @@ extern struct iscsi_task *iscsi_itt_to_task(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);
+extern void iscsi_complete_scsi_task(struct iscsi_task *task,
+ uint32_t exp_cmdsn, uint32_t max_cmdsn);
/*
* generic helpers
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 3f566af3f101..9af48cbf0036 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -187,10 +187,13 @@ struct scsi_device_handler {
void (*detach)(struct scsi_device *);
int (*activate)(struct scsi_device *);
int (*prep_fn)(struct scsi_device *, struct request *);
+ int (*set_params)(struct scsi_device *, const char *);
};
struct scsi_dh_data {
struct scsi_device_handler *scsi_dh;
+ struct scsi_device *sdev;
+ struct kref kref;
char buf[0];
};
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h
index 33efce20c26c..ff2407405b42 100644
--- a/include/scsi/scsi_dh.h
+++ b/include/scsi/scsi_dh.h
@@ -60,6 +60,7 @@ extern int scsi_dh_activate(struct request_queue *);
extern int scsi_dh_handler_exist(const char *);
extern int scsi_dh_attach(struct request_queue *, const char *);
extern void scsi_dh_detach(struct request_queue *);
+extern int scsi_dh_set_params(struct request_queue *, const char *);
#else
static inline int scsi_dh_activate(struct request_queue *req)
{
@@ -77,4 +78,8 @@ static inline void scsi_dh_detach(struct request_queue *q)
{
return;
}
+static inline int scsi_dh_set_params(struct request_queue *req, const char *params)
+{
+ return -SCSI_DH_NOSYS;
+}
#endif