summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Wuerthner <rwuerthn@de.ibm.com>2006-05-22 18:24:33 +0200
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-05-28 12:45:15 -0400
commit75bfc2837bbcc329193d51e8b7115184b78beae0 (patch)
tree6d1511fce28948bd134f7148a996c04dc04e9d32
parentb7a52fa7fff2309031a2f849bc489206afd2fa4a (diff)
downloadlinux-3.10-75bfc2837bbcc329193d51e8b7115184b78beae0.tar.gz
linux-3.10-75bfc2837bbcc329193d51e8b7115184b78beae0.tar.bz2
linux-3.10-75bfc2837bbcc329193d51e8b7115184b78beae0.zip
[SCSI] zfcp: evaluate plogi payload to set maxframe_size, supported_classes of rports
Signed-off-by: Ralph Wuerthner <rwuerthn@de.ibm.com> Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/s390/scsi/zfcp_aux.c21
-rw-r--r--drivers/s390/scsi/zfcp_def.h2
-rw-r--r--drivers/s390/scsi/zfcp_erp.c6
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c7
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c1
6 files changed, 34 insertions, 4 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index bdaad5535e2..9cd789b8acd 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -1748,4 +1748,25 @@ zfcp_handle_els_rjt(u32 sq, struct zfcp_ls_rjt_par *rjt_par)
return ret;
}
+/**
+ * zfcp_plogi_evaluate - evaluate PLOGI playload and copy important fields
+ * into zfcp_port structure
+ * @port: zfcp_port structure
+ * @plogi: plogi payload
+ */
+void
+zfcp_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi)
+{
+ port->maxframe_size = plogi->serv_param.common_serv_param[7] |
+ ((plogi->serv_param.common_serv_param[6] & 0x0F) << 8);
+ if (plogi->serv_param.class1_serv_param[0] & 0x80)
+ port->supported_classes |= FC_COS_CLASS1;
+ if (plogi->serv_param.class2_serv_param[0] & 0x80)
+ port->supported_classes |= FC_COS_CLASS2;
+ if (plogi->serv_param.class3_serv_param[0] & 0x80)
+ port->supported_classes |= FC_COS_CLASS3;
+ if (plogi->serv_param.class4_serv_param[0] & 0x80)
+ port->supported_classes |= FC_COS_CLASS4;
+}
+
#undef ZFCP_LOG_AREA
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index e93272f1882..a67d608388a 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -959,6 +959,8 @@ struct zfcp_port {
u32 handle; /* handle assigned by FSF */
struct zfcp_erp_action erp_action; /* pending error recovery */
atomic_t erp_counter;
+ u32 maxframe_size;
+ u32 supported_classes;
};
/* the struct device sysfs_device must be at the beginning of this structure.
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index ce852c0de12..05c47f6ca92 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -3257,8 +3257,12 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
"(adapter %s, wwpn=0x%016Lx)\n",
zfcp_get_busid_by_port(port),
port->wwpn);
- else
+ else {
scsi_flush_work(adapter->scsi_host);
+ port->rport->maxframe_size = port->maxframe_size;
+ port->rport->supported_classes =
+ port->supported_classes;
+ }
}
zfcp_port_put(port);
break;
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 6be2bb71c73..ab38b8ce27a 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -115,6 +115,7 @@ extern int zfcp_nameserver_enqueue(struct zfcp_adapter *);
extern int zfcp_ns_gid_pn_request(struct zfcp_erp_action *);
extern int zfcp_check_ct_response(struct ct_hdr *);
extern int zfcp_handle_els_rjt(u32, struct zfcp_ls_rjt_par *);
+extern void zfcp_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
/******************************* SCSI ****************************************/
extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 55785acf870..6335f922918 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2560,8 +2560,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
if (!atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, &port->status))
{
if (fsf_req->qtcb->bottom.support.els1_length <
- ((((unsigned long) &plogi->serv_param.wwpn) -
- ((unsigned long) plogi)) + sizeof (u64))) {
+ sizeof (struct fsf_plogi)) {
ZFCP_LOG_INFO(
"warning: insufficient length of "
"PLOGI payload (%i)\n",
@@ -2580,8 +2579,10 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
atomic_clear_mask(
ZFCP_STATUS_PORT_DID_DID,
&port->status);
- } else
+ } else {
port->wwnn = plogi->serv_param.wwnn;
+ zfcp_plogi_evaluate(port, plogi);
+ }
}
}
break;
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index f198814196a..30e87197f5f 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -805,6 +805,7 @@ struct fc_function_template zfcp_transport_functions = {
.show_starget_port_name = 1,
.show_starget_node_name = 1,
.show_rport_supported_classes = 1,
+ .show_rport_maxframe_size = 1,
.show_host_node_name = 1,
.show_host_port_name = 1,
.show_host_permanent_port_name = 1,