aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_diag.c
diff options
context:
space:
mode:
authorBenjamin Block <bblock@linux.ibm.com>2019-10-25 18:12:47 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2019-10-28 22:16:15 -0400
commit6028f7c4cd87cac13481255d7e35dd2c9207ecae (patch)
tree2d27607019029e3bbac319c3bcc8dbdbf94766fe /drivers/s390/scsi/zfcp_diag.c
parentscsi: zfcp: support retrieval of SFP Data via Exchange Port Data (diff)
downloadlinux-dev-6028f7c4cd87cac13481255d7e35dd2c9207ecae.tar.xz
linux-dev-6028f7c4cd87cac13481255d7e35dd2c9207ecae.zip
scsi: zfcp: introduce sysfs interface for diagnostics of local SFP transceiver
This adds an interface to read the diagnostics of the local SFP transceiver of an FCP-Channel from userspace. This comes in the form of new sysfs entries that are attached to the CCW device representing the FCP device. Each type of data gets its own sysfs entry; the whole collection of entries is pooled into a new child-directory of the CCW device node: "diagnostics". Adds sysfs entries for: * sfp_invalid: boolean value evaluating to whether the following 5 fields are invalid; {0, 1}; 1 - invalid * temperature: transceiver temp.; unit 1/256°C; range [-128°C, +128°C] * vcc: supply voltage; unit 100μV; range [0, 6.55V] * tx_bias: transmitter laser bias current; unit 2μA; range [0, 131mA] * tx_power: coupled TX output power; unit 0.1μW; range [0, 6.5mW] * rx_power: received optical power; unit 0.1μW; range [0, 6.5mW] * optical_port: boolean value evaluating to whether the FCP-Channel has an optical port; {0, 1}; 1 - optical * fec_active: boolean value evaluating to whether 16G FEC is active; {0, 1}; 1 - active * port_tx_type: nibble describing the port type; {0, 1, 2, 3}; 0 - unknown, 1 - short wave, 2 - long wave LC 1310nm, 3 - long wave LL 1550nm * connector_type: two bits describing the connector type; {0, 1}; 0 - unknown, 1 - SFP+ This is only supported if the FCP-Channel in turn supports reporting the SFP Diagnostic Data, otherwise read() on these new entries will return EOPNOTSUPP (this affects only adapters older than FICON Express8S, on Mainframe generations older than z14). Other possible errors for read() include ENOLINK, ENODEV and ENOMEM. With this patch the userspace-interface will only read data stored in the corresponding "diagnostic buffer" (that was stored during completion of an previous Exchange Port Data command). Implicit updating will follow later in this series. Link: https://lore.kernel.org/r/1f9cce7c829c881e7d71a3f10c5b57f3dd84ab32.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>
Diffstat (limited to 'drivers/s390/scsi/zfcp_diag.c')
-rw-r--r--drivers/s390/scsi/zfcp_diag.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_diag.c b/drivers/s390/scsi/zfcp_diag.c
index d7d2db85b32e..8df3ace6135d 100644
--- a/drivers/s390/scsi/zfcp_diag.c
+++ b/drivers/s390/scsi/zfcp_diag.c
@@ -10,6 +10,8 @@
#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <linux/string.h>
+#include <linux/kernfs.h>
+#include <linux/sysfs.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -78,6 +80,46 @@ void zfcp_diag_adapter_free(struct zfcp_adapter *const adapter)
}
/**
+ * zfcp_diag_sysfs_setup() - Setup the sysfs-group for adapter-diagnostics.
+ * @adapter: target adapter to which the group should be added.
+ *
+ * Return: 0 on success; Something else otherwise (see sysfs_create_group()).
+ */
+int zfcp_diag_sysfs_setup(struct zfcp_adapter *const adapter)
+{
+ int rc = sysfs_create_group(&adapter->ccw_device->dev.kobj,
+ &zfcp_sysfs_diag_attr_group);
+ if (rc == 0)
+ adapter->diagnostics->sysfs_established = 1;
+
+ return rc;
+}
+
+/**
+ * zfcp_diag_sysfs_destroy() - Remove the sysfs-group for adapter-diagnostics.
+ * @adapter: target adapter from which the group should be removed.
+ */
+void zfcp_diag_sysfs_destroy(struct zfcp_adapter *const adapter)
+{
+ if (adapter->diagnostics == NULL ||
+ !adapter->diagnostics->sysfs_established)
+ return;
+
+ /*
+ * We need this state-handling so we can prevent warnings being printed
+ * on the kernel-console in case we have to abort a halfway done
+ * zfcp_adapter_enqueue(), in which the sysfs-group was not yet
+ * established. sysfs_remove_group() does this checking as well, but
+ * still prints a warning in case we try to remove a group that has not
+ * been established before
+ */
+ adapter->diagnostics->sysfs_established = 0;
+ sysfs_remove_group(&adapter->ccw_device->dev.kobj,
+ &zfcp_sysfs_diag_attr_group);
+}
+
+
+/**
* zfcp_diag_update_xdata() - Update a diagnostics buffer.
* @hdr: the meta data to update.
* @data: data to use for the update.