Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) };