scsi: zfcp: implicitly refresh config-data diagnostics when reading sysfs
authorBenjamin Block <bblock@linux.ibm.com>
Fri, 25 Oct 2019 16:12:50 +0000 (18:12 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 29 Oct 2019 02:16:15 +0000 (22:16 -0400)
Adds implicit updates of cached diagnostics via Exchange Config Data when
reading sysfs attributes interfacing them. Right now this only affects the
new B2B-Credit diagnostic attribute.

This uses the same mechanism previously also used for cached diagnostics
of Exchange Port Data.

Link: https://lore.kernel.org/r/60a94f55f2630b74b468fed5f39880208abb2679.1572018132.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>
drivers/s390/scsi/zfcp_diag.c
drivers/s390/scsi/zfcp_diag.h
drivers/s390/scsi/zfcp_sysfs.c

index 9c5a0f3..5ef7b32 100644 (file)
@@ -176,6 +176,36 @@ int zfcp_diag_update_port_data_buffer(struct zfcp_adapter *const adapter)
        return rc;
 }
 
+/**
+ * zfcp_diag_update_config_data_buffer() - Implementation of
+ *                                        &typedef zfcp_diag_update_buffer_func
+ *                                        to collect and update Config Data.
+ * @adapter: Adapter to collect Config Data from.
+ *
+ * This call is SYNCHRONOUS ! It blocks till the respective command has
+ * finished completely, or has failed in some way.
+ *
+ * Return:
+ * * 0         - Successfully retrieved new Diagnostics and Updated the buffer;
+ *               this also includes cases where data was retrieved, but
+ *               incomplete; you'll have to check the flag ``incomplete``
+ *               of &struct zfcp_diag_header.
+ * * see zfcp_fsf_exchange_config_data_sync() for possible error-codes (
+ *   excluding -EAGAIN)
+ */
+int zfcp_diag_update_config_data_buffer(struct zfcp_adapter *const adapter)
+{
+       int rc;
+
+       rc = zfcp_fsf_exchange_config_data_sync(adapter->qdio, NULL);
+       if (rc == -EAGAIN)
+               rc = 0; /* signaling incomplete via struct zfcp_diag_header */
+
+       /* buffer-data was updated in zfcp_fsf_exchange_config_data_handler() */
+
+       return rc;
+}
+
 static int __zfcp_diag_update_buffer(struct zfcp_adapter *const adapter,
                                     struct zfcp_diag_header *const hdr,
                                     zfcp_diag_update_buffer_func buffer_update,
index 7ff8fb0..cf2947c 100644 (file)
@@ -77,6 +77,7 @@ void zfcp_diag_update_xdata(struct zfcp_diag_header *const hdr,
  */
 typedef int (*zfcp_diag_update_buffer_func)(struct zfcp_adapter *const adapter);
 
+int zfcp_diag_update_config_data_buffer(struct zfcp_adapter *const adapter);
 int zfcp_diag_update_port_data_buffer(struct zfcp_adapter *const adapter);
 int zfcp_diag_update_buffer_limited(struct zfcp_adapter *const adapter,
                                    struct zfcp_diag_header *const hdr,
index 376d76b..ae8e913 100644 (file)
@@ -687,6 +687,11 @@ static ssize_t zfcp_sysfs_adapter_diag_b2b_credit_show(
 
        diag_hdr = &adapter->diagnostics->config_data.header;
 
+       rc = zfcp_diag_update_buffer_limited(
+               adapter, diag_hdr, zfcp_diag_update_config_data_buffer);
+       if (rc != 0)
+               goto out;
+
        spin_lock_irqsave(&diag_hdr->access_lock, flags);
        /* nport_serv_param doesn't contain the ELS_Command code */
        nsp = (struct fc_els_flogi *)((unsigned long)