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