summaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_scsi.c
diff options
context:
space:
mode:
authorBenjamin Block <bblock@linux.ibm.com>2020-05-08 19:23:29 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2020-05-11 23:19:47 -0400
commitbd1684817d7d8d1a3b95a4347166246ad1f7670b (patch)
tree06a8429cc5fb8e5e5f66cb844d57d7587e40a0ac /drivers/s390/scsi/zfcp_scsi.c
parent978857c7e367d6841f71c4ded5a8c244520f5e22 (diff)
downloadlinux-stable-bd1684817d7d8d1a3b95a4347166246ad1f7670b.tar.gz
linux-stable-bd1684817d7d8d1a3b95a4347166246ad1f7670b.tar.bz2
linux-stable-bd1684817d7d8d1a3b95a4347166246ad1f7670b.zip
scsi: zfcp: Move shost updates during xconfig data handling into fenced function
When executing exchange config data for a FCP device for the first time, or after an adapter recovery, we update several properties of the scsi host or fibre channel host object that represent that FCP device. When moving the scsi host object allocation and registration - and thus also the fibre channel host object allocation - to after the first exchange config and exchange port data, this is not possible for the former case. Move all these update into separate, and fenced function that first checks whether the scsi host object already exists or not, before making the updates. During the first ever exchange config data in the adapter life cycle this will make the exchange config data handler skip over this update step, but we can repeat it later, after we allocated the scsi host object. For any further recovery of that adapter the work flow is only changed slightly because then the scsi host object already exists and we don't free it until we release the adapter completely at the end of its life cycle. Link: https://lore.kernel.org/r/5fc3f4d38d4334f7aa595497c6f7865fb1102e0f.1588956679.git.bblock@linux.ibm.com Reviewed-by: Steffen Maier <maier@linux.ibm.com> Signed-off-by: Benjamin Block <bblock@linux.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 13d873f806e4..e1281a1ce488 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -4,7 +4,7 @@
*
* Interface to Linux SCSI midlayer.
*
- * Copyright IBM Corp. 2002, 2018
+ * Copyright IBM Corp. 2002, 2020
*/
#define KMSG_COMPONENT "zfcp"
@@ -841,6 +841,76 @@ void zfcp_scsi_dif_sense_error(struct scsi_cmnd *scmd, int ascq)
set_host_byte(scmd, DID_SOFT_ERROR);
}
+void zfcp_scsi_shost_update_config_data(
+ struct zfcp_adapter *const adapter,
+ const struct fsf_qtcb_bottom_config *const bottom,
+ const bool bottom_incomplete)
+{
+ struct Scsi_Host *const shost = adapter->scsi_host;
+ const struct fc_els_flogi *nsp, *plogi;
+
+ if (shost == NULL)
+ return;
+
+ snprintf(fc_host_firmware_version(shost), FC_VERSION_STRING_SIZE,
+ "0x%08x", bottom->lic_version);
+
+ if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
+ snprintf(fc_host_hardware_version(shost),
+ FC_VERSION_STRING_SIZE,
+ "0x%08x", bottom->hardware_version);
+ memcpy(fc_host_serial_number(shost), bottom->serial_number,
+ min(FC_SERIAL_NUMBER_SIZE, 17));
+ EBCASC(fc_host_serial_number(shost),
+ min(FC_SERIAL_NUMBER_SIZE, 17));
+ }
+
+ /* adjust pointers for missing command code */
+ nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param
+ - sizeof(u32));
+ plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload
+ - sizeof(u32));
+
+ snprintf(fc_host_manufacturer(shost), FC_SERIAL_NUMBER_SIZE, "%s",
+ "IBM");
+ fc_host_port_name(shost) = be64_to_cpu(nsp->fl_wwpn);
+ fc_host_node_name(shost) = be64_to_cpu(nsp->fl_wwnn);
+ fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
+
+ zfcp_scsi_set_prot(adapter);
+
+ /* do not evaluate invalid fields */
+ if (bottom_incomplete)
+ return;
+
+ fc_host_port_id(shost) = ntoh24(bottom->s_id);
+ fc_host_speed(shost) =
+ zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
+
+ snprintf(fc_host_model(shost), FC_SYMBOLIC_NAME_SIZE, "0x%04x",
+ bottom->adapter_type);
+
+ switch (bottom->fc_topology) {
+ case FSF_TOPO_P2P:
+ fc_host_port_type(shost) = FC_PORTTYPE_PTP;
+ fc_host_fabric_name(shost) = 0;
+ break;
+ case FSF_TOPO_FABRIC:
+ fc_host_fabric_name(shost) = be64_to_cpu(plogi->fl_wwnn);
+ if (bottom->connection_features & FSF_FEATURE_NPIV_MODE)
+ fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
+ else
+ fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
+ break;
+ case FSF_TOPO_AL:
+ fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
+ fallthrough;
+ default:
+ fc_host_fabric_name(shost) = 0;
+ break;
+ }
+}
+
struct fc_function_template zfcp_transport_functions = {
.show_starget_port_id = 1,
.show_starget_port_name = 1,