^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * zfcp device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * sysfs attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright IBM Corp. 2008, 2020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define KMSG_COMPONENT "zfcp"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "zfcp_diag.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "zfcp_ext.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct device_attribute dev_attr_##_feat##_##_name = __ATTR(_name, _mode,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) _show, _store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define ZFCP_DEFINE_ATTR(_feat_def, _feat, _name, _format, _value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static ssize_t zfcp_sysfs_##_feat##_##_name##_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct device_attribute *at,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct _feat_def *_feat = container_of(dev, struct _feat_def, dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return sprintf(buf, _format, _value); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) zfcp_sysfs_##_feat##_##_name##_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define ZFCP_DEFINE_ATTR_CONST(_feat, _name, _format, _value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static ssize_t zfcp_sysfs_##_feat##_##_name##_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct device_attribute *at,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return sprintf(buf, _format, _value); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) zfcp_sysfs_##_feat##_##_name##_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ZFCP_DEFINE_A_ATTR(_name, _format, _value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct device_attribute *at,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct ccw_device *cdev = to_ccwdev(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (!adapter) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return -ENODEV; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) i = sprintf(buf, _format, _value); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) zfcp_ccw_adapter_put(adapter); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static ZFCP_DEV_ATTR(adapter, _name, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) zfcp_sysfs_adapter_##_name##_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ZFCP_DEFINE_A_ATTR(status, "0x%08x\n", atomic_read(&adapter->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ZFCP_DEFINE_A_ATTR(peer_wwnn, "0x%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) (unsigned long long) adapter->peer_wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ZFCP_DEFINE_A_ATTR(peer_wwpn, "0x%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) (unsigned long long) adapter->peer_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ZFCP_DEFINE_A_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ZFCP_DEFINE_A_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ZFCP_DEFINE_A_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ZFCP_DEFINE_A_ATTR(hardware_version, "0x%08x\n", adapter->hardware_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ZFCP_DEFINE_A_ATTR(in_recovery, "%d\n", (atomic_read(&adapter->status) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ZFCP_DEFINE_ATTR(zfcp_port, port, status, "0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) atomic_read(&port->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ZFCP_DEFINE_ATTR(zfcp_port, port, in_recovery, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) (atomic_read(&port->status) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ZFCP_DEFINE_ATTR_CONST(port, access_denied, "%d\n", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ZFCP_DEFINE_ATTR(zfcp_unit, unit, status, "0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) zfcp_unit_sdev_status(unit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ZFCP_DEFINE_ATTR(zfcp_unit, unit, in_recovery, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) (zfcp_unit_sdev_status(unit) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_denied, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) (zfcp_unit_sdev_status(unit) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ZFCP_DEFINE_ATTR_CONST(unit, access_shared, "%d\n", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ZFCP_DEFINE_ATTR_CONST(unit, access_readonly, "%d\n", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static ssize_t zfcp_sysfs_port_failed_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return sprintf(buf, "1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return sprintf(buf, "0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static ssize_t zfcp_sysfs_port_failed_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (kstrtoul(buf, 0, &val) || val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) zfcp_erp_wait(port->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static ZFCP_DEV_ATTR(port, failed, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) zfcp_sysfs_port_failed_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) zfcp_sysfs_port_failed_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static ssize_t zfcp_sysfs_unit_failed_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned int status, failed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) sdev = zfcp_unit_sdev(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (sdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) status = atomic_read(&sdev_to_zfcp(sdev)->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) failed = status & ZFCP_STATUS_COMMON_ERP_FAILED ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) scsi_device_put(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return sprintf(buf, "%d\n", failed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (kstrtoul(buf, 0, &val) || val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) sdev = zfcp_unit_sdev(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (sdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) "syufai2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) zfcp_erp_wait(unit->port->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) zfcp_unit_scsi_scan(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static ZFCP_DEV_ATTR(unit, failed, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) zfcp_sysfs_unit_failed_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) zfcp_sysfs_unit_failed_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static ssize_t zfcp_sysfs_adapter_failed_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct ccw_device *cdev = to_ccwdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (!adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) i = sprintf(buf, "1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) i = sprintf(buf, "0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) zfcp_ccw_adapter_put(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct ccw_device *cdev = to_ccwdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (!adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (kstrtoul(buf, 0, &val) || val != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) zfcp_erp_adapter_reset_sync(adapter, "syafai2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) zfcp_ccw_adapter_put(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return retval ? retval : (ssize_t) count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static ZFCP_DEV_ATTR(adapter, failed, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) zfcp_sysfs_adapter_failed_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) zfcp_sysfs_adapter_failed_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct ccw_device *cdev = to_ccwdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * If `scsi_host` is missing, we can't schedule `scan_work`, as it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * makes use of the corresponding fc_host object. But this state is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * only possible if xconfig/xport data has never completed yet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * and we couldn't successfully scan for ports anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (adapter->scsi_host == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Users wish is our command: immediately schedule and flush a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * worker to conduct a synchronous port scan, that is, neither
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * a random delay nor a rate limit is applied here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) queue_delayed_work(adapter->work_queue, &adapter->scan_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) flush_delayed_work(&adapter->scan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) zfcp_ccw_adapter_put(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return retval ? retval : (ssize_t) count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) zfcp_sysfs_port_rescan_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) DEFINE_MUTEX(zfcp_sysfs_port_units_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static void zfcp_sysfs_port_set_removing(struct zfcp_port *const port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) atomic_set(&port->units, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return atomic_read(&port->units) == -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct zfcp_adapter *const adapter = port->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) bool in_use = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) mutex_lock(&zfcp_sysfs_port_units_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (atomic_read(&port->units) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) goto unlock_port_units_mutex; /* zfcp_unit(s) under port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) __shost_for_each_device(sdev, adapter->scsi_host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) const struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (sdev->sdev_state == SDEV_DEL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) sdev->sdev_state == SDEV_CANCEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (zsdev->port != port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* alive scsi_device under port of interest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) goto unlock_host_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* port is about to be removed, so no more unit_add or slave_alloc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) zfcp_sysfs_port_set_removing(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) in_use = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unlock_host_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) unlock_port_units_mutex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) mutex_unlock(&zfcp_sysfs_port_units_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct ccw_device *cdev = to_ccwdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct zfcp_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u64 wwpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (kstrtoull(buf, 0, (unsigned long long *) &wwpn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) port = zfcp_get_port_by_wwpn(adapter, wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (zfcp_sysfs_port_in_use(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) retval = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) write_lock_irq(&adapter->port_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) list_del(&port->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) write_unlock_irq(&adapter->port_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) put_device(&port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) zfcp_erp_port_shutdown(port, 0, "syprs_1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) device_unregister(&port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) zfcp_ccw_adapter_put(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return retval ? retval : (ssize_t) count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) zfcp_sysfs_port_remove_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) zfcp_sysfs_adapter_diag_max_age_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(to_ccwdev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (!adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* ceil(log(2^64 - 1) / log(10)) = 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) rc = scnprintf(buf, 20 + 2, "%lu\n", adapter->diagnostics->max_age);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) zfcp_ccw_adapter_put(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) zfcp_sysfs_adapter_diag_max_age_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(to_ccwdev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unsigned long max_age;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) rc = kstrtoul(buf, 10, &max_age);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) adapter->diagnostics->max_age = max_age;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) zfcp_ccw_adapter_put(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static ZFCP_DEV_ATTR(adapter, diag_max_age, 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) zfcp_sysfs_adapter_diag_max_age_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) zfcp_sysfs_adapter_diag_max_age_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static ssize_t zfcp_sysfs_adapter_fc_security_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct ccw_device *cdev = to_ccwdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (!adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * Adapter status COMMON_OPEN implies xconf data and xport data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * was done. Adapter FC Endpoint Security capability remains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * unchanged in case of COMMON_ERP_FAILED (e.g. due to local link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * down).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) status = atomic_read(&adapter->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (0 == (status & ZFCP_STATUS_COMMON_OPEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) i = sprintf(buf, "unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) else if (!(adapter->adapter_features & FSF_FEATURE_FC_SECURITY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) i = sprintf(buf, "unsupported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) i = zfcp_fsf_scnprint_fc_security(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) buf, PAGE_SIZE - 1, adapter->fc_security_algorithms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ZFCP_FSF_PRINT_FMT_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) i += scnprintf(buf + i, PAGE_SIZE - i, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) zfcp_ccw_adapter_put(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static ZFCP_DEV_ATTR(adapter, fc_security, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) zfcp_sysfs_adapter_fc_security_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static struct attribute *zfcp_adapter_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) &dev_attr_adapter_failed.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) &dev_attr_adapter_in_recovery.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) &dev_attr_adapter_port_remove.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) &dev_attr_adapter_port_rescan.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) &dev_attr_adapter_peer_wwnn.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) &dev_attr_adapter_peer_wwpn.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) &dev_attr_adapter_peer_d_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) &dev_attr_adapter_card_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) &dev_attr_adapter_lic_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) &dev_attr_adapter_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) &dev_attr_adapter_hardware_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) &dev_attr_adapter_diag_max_age.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) &dev_attr_adapter_fc_security.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct attribute_group zfcp_sysfs_adapter_attrs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .attrs = zfcp_adapter_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) u64 fcp_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (kstrtoull(buf, 0, (unsigned long long *) &fcp_lun))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) retval = zfcp_unit_add(port, fcp_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) u64 fcp_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (kstrtoull(buf, 0, (unsigned long long *) &fcp_lun))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (zfcp_unit_remove(port, fcp_lun))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static ssize_t zfcp_sysfs_port_fc_security_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct zfcp_adapter *adapter = port->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) unsigned int status = atomic_read(&port->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (0 == (status & ZFCP_STATUS_COMMON_OPEN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 0 == (status & ZFCP_STATUS_COMMON_UNBLOCKED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 0 == (status & ZFCP_STATUS_PORT_PHYS_OPEN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 0 != (status & ZFCP_STATUS_PORT_LINK_TEST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 0 != (status & ZFCP_STATUS_COMMON_ERP_FAILED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 0 != (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) i = sprintf(buf, "unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) else if (!(adapter->adapter_features & FSF_FEATURE_FC_SECURITY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) i = sprintf(buf, "unsupported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) i = zfcp_fsf_scnprint_fc_security(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) buf, PAGE_SIZE - 1, port->connection_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ZFCP_FSF_PRINT_FMT_SINGLEITEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) i += scnprintf(buf + i, PAGE_SIZE - i, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static ZFCP_DEV_ATTR(port, fc_security, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) zfcp_sysfs_port_fc_security_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static struct attribute *zfcp_port_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) &dev_attr_unit_add.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) &dev_attr_unit_remove.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) &dev_attr_port_failed.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) &dev_attr_port_in_recovery.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) &dev_attr_port_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) &dev_attr_port_access_denied.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) &dev_attr_port_fc_security.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static struct attribute_group zfcp_port_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .attrs = zfcp_port_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) const struct attribute_group *zfcp_port_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) &zfcp_port_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static struct attribute *zfcp_unit_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) &dev_attr_unit_failed.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) &dev_attr_unit_in_recovery.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) &dev_attr_unit_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) &dev_attr_unit_access_denied.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) &dev_attr_unit_access_shared.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) &dev_attr_unit_access_readonly.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static struct attribute_group zfcp_unit_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .attrs = zfcp_unit_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) const struct attribute_group *zfcp_unit_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) &zfcp_unit_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) #define ZFCP_DEFINE_LATENCY_ATTR(_name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) char *buf) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct scsi_device *sdev = to_scsi_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct zfcp_latencies *lat = &zfcp_sdev->latencies; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) spin_lock_bh(&lat->lock); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) fsum = lat->_name.fabric.sum * adapter->timer_ticks; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) fmin = lat->_name.fabric.min * adapter->timer_ticks; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) fmax = lat->_name.fabric.max * adapter->timer_ticks; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) csum = lat->_name.channel.sum * adapter->timer_ticks; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) cmin = lat->_name.channel.min * adapter->timer_ticks; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) cmax = lat->_name.channel.max * adapter->timer_ticks; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) cc = lat->_name.counter; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) spin_unlock_bh(&lat->lock); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) do_div(fsum, 1000); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) do_div(fmin, 1000); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) do_div(fmax, 1000); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) do_div(csum, 1000); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) do_div(cmin, 1000); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) do_div(cmax, 1000); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return sprintf(buf, "%llu %llu %llu %llu %llu %llu %llu\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) fmin, fmax, fsum, cmin, cmax, csum, cc); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) zfcp_sysfs_unit_##_name##_latency_store(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) const char *buf, size_t count) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct scsi_device *sdev = to_scsi_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct zfcp_latencies *lat = &zfcp_sdev->latencies; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) unsigned long flags; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) spin_lock_irqsave(&lat->lock, flags); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) lat->_name.fabric.sum = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) lat->_name.fabric.min = 0xFFFFFFFF; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) lat->_name.fabric.max = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) lat->_name.channel.sum = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) lat->_name.channel.min = 0xFFFFFFFF; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) lat->_name.channel.max = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) lat->_name.counter = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) spin_unlock_irqrestore(&lat->lock, flags); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return (ssize_t) count; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static DEVICE_ATTR(_name##_latency, S_IWUSR | S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) zfcp_sysfs_unit_##_name##_latency_show, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) zfcp_sysfs_unit_##_name##_latency_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ZFCP_DEFINE_LATENCY_ATTR(read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ZFCP_DEFINE_LATENCY_ATTR(write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ZFCP_DEFINE_LATENCY_ATTR(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) #define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct device_attribute *attr,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct scsi_device *sdev = to_scsi_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return sprintf(buf, _format, _value); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) dev_name(&zfcp_sdev->port->adapter->ccw_device->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) (unsigned long long) zfcp_sdev->port->wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static ssize_t zfcp_sysfs_scsi_fcp_lun_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct scsi_device *sdev = to_scsi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return sprintf(buf, "0x%016llx\n", zfcp_scsi_dev_lun(sdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static DEVICE_ATTR(fcp_lun, S_IRUGO, zfcp_sysfs_scsi_fcp_lun_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ZFCP_DEFINE_SCSI_ATTR(zfcp_access_denied, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) (atomic_read(&zfcp_sdev->status) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static ssize_t zfcp_sysfs_scsi_zfcp_failed_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct scsi_device *sdev = to_scsi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) unsigned int status = atomic_read(&sdev_to_zfcp(sdev)->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) unsigned int failed = status & ZFCP_STATUS_COMMON_ERP_FAILED ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return sprintf(buf, "%d\n", failed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static ssize_t zfcp_sysfs_scsi_zfcp_failed_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct scsi_device *sdev = to_scsi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (kstrtoul(buf, 0, &val) || val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) "syufai3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) zfcp_erp_wait(sdev_to_zfcp(sdev)->port->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static DEVICE_ATTR(zfcp_failed, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) zfcp_sysfs_scsi_zfcp_failed_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) zfcp_sysfs_scsi_zfcp_failed_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ZFCP_DEFINE_SCSI_ATTR(zfcp_in_recovery, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) (atomic_read(&zfcp_sdev->status) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ZFCP_DEFINE_SCSI_ATTR(zfcp_status, "0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) atomic_read(&zfcp_sdev->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) &dev_attr_fcp_lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) &dev_attr_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) &dev_attr_hba_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) &dev_attr_read_latency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) &dev_attr_write_latency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) &dev_attr_cmd_latency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) &dev_attr_zfcp_access_denied,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) &dev_attr_zfcp_failed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) &dev_attr_zfcp_in_recovery,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) &dev_attr_zfcp_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct Scsi_Host *scsi_host = dev_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct fsf_qtcb_bottom_port *qtcb_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct zfcp_adapter *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (!qtcb_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) retval = zfcp_fsf_exchange_port_data_sync(adapter->qdio, qtcb_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (retval == 0 || retval == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) qtcb_port->cb_util, qtcb_port->a_util);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) kfree(qtcb_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static int zfcp_sysfs_adapter_ex_config(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct fsf_statistics_info *stat_inf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct Scsi_Host *scsi_host = dev_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct fsf_qtcb_bottom_config *qtcb_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct zfcp_adapter *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (!qtcb_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) retval = zfcp_fsf_exchange_config_data_sync(adapter->qdio, qtcb_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (retval == 0 || retval == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) *stat_inf = qtcb_config->stat_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) kfree(qtcb_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) #define ZFCP_SHOST_ATTR(_name, _format, _arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct device_attribute *attr,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct fsf_statistics_info stat_info; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) int retval; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (retval) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return retval; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return sprintf(buf, _format, ## _arg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_adapter_##_name##_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ZFCP_SHOST_ATTR(requests, "%llu %llu %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) (unsigned long long) stat_info.input_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) (unsigned long long) stat_info.output_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) (unsigned long long) stat_info.control_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) (unsigned long long) stat_info.input_mb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) (unsigned long long) stat_info.output_mb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ZFCP_SHOST_ATTR(seconds_active, "%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) (unsigned long long) stat_info.seconds_act);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct Scsi_Host *scsi_host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct zfcp_qdio *qdio =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ((struct zfcp_adapter *) scsi_host->hostdata[0])->qdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) u64 util;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) spin_lock_bh(&qdio->stat_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) util = qdio->req_q_util;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) spin_unlock_bh(&qdio->stat_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return sprintf(buf, "%d %llu\n", atomic_read(&qdio->req_q_full),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) (unsigned long long)util);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct device_attribute *zfcp_sysfs_shost_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) &dev_attr_utilization,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) &dev_attr_requests,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) &dev_attr_megabytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) &dev_attr_seconds_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) &dev_attr_queue_full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) static ssize_t zfcp_sysfs_adapter_diag_b2b_credit_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(to_ccwdev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct zfcp_diag_header *diag_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct fc_els_flogi *nsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ssize_t rc = -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (!adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) status = atomic_read(&adapter->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (0 == (status & ZFCP_STATUS_COMMON_OPEN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 0 == (status & ZFCP_STATUS_COMMON_UNBLOCKED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 0 != (status & ZFCP_STATUS_COMMON_ERP_FAILED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) diag_hdr = &adapter->diagnostics->config_data.header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) rc = zfcp_diag_update_buffer_limited(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) adapter, diag_hdr, zfcp_diag_update_config_data_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) spin_lock_irqsave(&diag_hdr->access_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* nport_serv_param doesn't contain the ELS_Command code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) nsp = (struct fc_els_flogi *)((unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) adapter->diagnostics->config_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .data.nport_serv_param -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) rc = scnprintf(buf, 5 + 2, "%hu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) be16_to_cpu(nsp->fl_csp.sp_bb_cred));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) spin_unlock_irqrestore(&diag_hdr->access_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) zfcp_ccw_adapter_put(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static ZFCP_DEV_ATTR(adapter_diag, b2b_credit, 0400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) zfcp_sysfs_adapter_diag_b2b_credit_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) #define ZFCP_DEFINE_DIAG_SFP_ATTR(_name, _qtcb_member, _prtsize, _prtfmt) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static ssize_t zfcp_sysfs_adapter_diag_sfp_##_name##_show( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct device *dev, struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct zfcp_adapter *const adapter = \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) zfcp_ccw_adapter_by_cdev(to_ccwdev(dev)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct zfcp_diag_header *diag_hdr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) ssize_t rc = -ENOLINK; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) unsigned long flags; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) unsigned int status; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (!adapter) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return -ENODEV; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) status = atomic_read(&adapter->status); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (0 == (status & ZFCP_STATUS_COMMON_OPEN) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 0 == (status & ZFCP_STATUS_COMMON_UNBLOCKED) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 0 != (status & ZFCP_STATUS_COMMON_ERP_FAILED)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) goto out; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (!zfcp_diag_support_sfp(adapter)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) rc = -EOPNOTSUPP; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) goto out; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) diag_hdr = &adapter->diagnostics->port_data.header; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) rc = zfcp_diag_update_buffer_limited( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) adapter, diag_hdr, zfcp_diag_update_port_data_buffer); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (rc != 0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) goto out; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) spin_lock_irqsave(&diag_hdr->access_lock, flags); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) rc = scnprintf( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) buf, (_prtsize) + 2, _prtfmt "\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) adapter->diagnostics->port_data.data._qtcb_member); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) spin_unlock_irqrestore(&diag_hdr->access_lock, flags); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) out: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) zfcp_ccw_adapter_put(adapter); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return rc; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static ZFCP_DEV_ATTR(adapter_diag_sfp, _name, 0400, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) zfcp_sysfs_adapter_diag_sfp_##_name##_show, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ZFCP_DEFINE_DIAG_SFP_ATTR(temperature, temperature, 6, "%hd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ZFCP_DEFINE_DIAG_SFP_ATTR(vcc, vcc, 5, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ZFCP_DEFINE_DIAG_SFP_ATTR(tx_bias, tx_bias, 5, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ZFCP_DEFINE_DIAG_SFP_ATTR(tx_power, tx_power, 5, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) ZFCP_DEFINE_DIAG_SFP_ATTR(rx_power, rx_power, 5, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ZFCP_DEFINE_DIAG_SFP_ATTR(port_tx_type, sfp_flags.port_tx_type, 2, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ZFCP_DEFINE_DIAG_SFP_ATTR(optical_port, sfp_flags.optical_port, 1, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ZFCP_DEFINE_DIAG_SFP_ATTR(sfp_invalid, sfp_flags.sfp_invalid, 1, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) ZFCP_DEFINE_DIAG_SFP_ATTR(connector_type, sfp_flags.connector_type, 1, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) ZFCP_DEFINE_DIAG_SFP_ATTR(fec_active, sfp_flags.fec_active, 1, "%hu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) static struct attribute *zfcp_sysfs_diag_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) &dev_attr_adapter_diag_sfp_temperature.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) &dev_attr_adapter_diag_sfp_vcc.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) &dev_attr_adapter_diag_sfp_tx_bias.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) &dev_attr_adapter_diag_sfp_tx_power.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) &dev_attr_adapter_diag_sfp_rx_power.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) &dev_attr_adapter_diag_sfp_port_tx_type.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) &dev_attr_adapter_diag_sfp_optical_port.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) &dev_attr_adapter_diag_sfp_sfp_invalid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) &dev_attr_adapter_diag_sfp_connector_type.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) &dev_attr_adapter_diag_sfp_fec_active.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) &dev_attr_adapter_diag_b2b_credit.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) const struct attribute_group zfcp_sysfs_diag_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .name = "diagnostics",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .attrs = zfcp_sysfs_diag_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) };