1/* 2 * zfcp device driver 3 * 4 * sysfs attributes. 5 * 6 * Copyright IBM Corporation 2008, 2010 7 */ 8 9#define KMSG_COMPONENT "zfcp" 10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 11 12#include <linux/slab.h> 13#include "zfcp_ext.h" 14 15#define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \ 16struct device_attribute dev_attr_##_feat##_##_name = __ATTR(_name, _mode,\ 17 _show, _store) 18#define ZFCP_DEFINE_ATTR(_feat_def, _feat, _name, _format, _value) \ 19static ssize_t zfcp_sysfs_##_feat##_##_name##_show(struct device *dev, \ 20 struct device_attribute *at,\ 21 char *buf) \ 22{ \ 23 struct _feat_def *_feat = container_of(dev, struct _feat_def, dev); \ 24 \ 25 return sprintf(buf, _format, _value); \ 26} \ 27static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO, \ 28 zfcp_sysfs_##_feat##_##_name##_show, NULL); 29 30#define ZFCP_DEFINE_A_ATTR(_name, _format, _value) \ 31static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, \ 32 struct device_attribute *at,\ 33 char *buf) \ 34{ \ 35 struct ccw_device *cdev = to_ccwdev(dev); \ 36 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); \ 37 int i; \ 38 \ 39 if (!adapter) \ 40 return -ENODEV; \ 41 \ 42 i = sprintf(buf, _format, _value); \ 43 zfcp_ccw_adapter_put(adapter); \ 44 return i; \ 45} \ 46static ZFCP_DEV_ATTR(adapter, _name, S_IRUGO, \ 47 zfcp_sysfs_adapter_##_name##_show, NULL); 48 49ZFCP_DEFINE_A_ATTR(status, "0x%08x\n", atomic_read(&adapter->status)); 50ZFCP_DEFINE_A_ATTR(peer_wwnn, "0x%016llx\n", 51 (unsigned long long) adapter->peer_wwnn); 52ZFCP_DEFINE_A_ATTR(peer_wwpn, "0x%016llx\n", 53 (unsigned long long) adapter->peer_wwpn); 54ZFCP_DEFINE_A_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id); 55ZFCP_DEFINE_A_ATTR(card_version, "0x%04x\n", adapter->hydra_version); 56ZFCP_DEFINE_A_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version); 57ZFCP_DEFINE_A_ATTR(hardware_version, "0x%08x\n", adapter->hardware_version); 58ZFCP_DEFINE_A_ATTR(in_recovery, "%d\n", (atomic_read(&adapter->status) & 59 ZFCP_STATUS_COMMON_ERP_INUSE) != 0); 60 61ZFCP_DEFINE_ATTR(zfcp_port, port, status, "0x%08x\n", 62 atomic_read(&port->status)); 63ZFCP_DEFINE_ATTR(zfcp_port, port, in_recovery, "%d\n", 64 (atomic_read(&port->status) & 65 ZFCP_STATUS_COMMON_ERP_INUSE) != 0); 66ZFCP_DEFINE_ATTR(zfcp_port, port, access_denied, "%d\n", 67 (atomic_read(&port->status) & 68 ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0); 69 70ZFCP_DEFINE_ATTR(zfcp_unit, unit, status, "0x%08x\n", 71 atomic_read(&unit->status)); 72ZFCP_DEFINE_ATTR(zfcp_unit, unit, in_recovery, "%d\n", 73 (atomic_read(&unit->status) & 74 ZFCP_STATUS_COMMON_ERP_INUSE) != 0); 75ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_denied, "%d\n", 76 (atomic_read(&unit->status) & 77 ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0); 78ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_shared, "%d\n", 79 (atomic_read(&unit->status) & 80 ZFCP_STATUS_UNIT_SHARED) != 0); 81ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_readonly, "%d\n", 82 (atomic_read(&unit->status) & 83 ZFCP_STATUS_UNIT_READONLY) != 0); 84 85#define ZFCP_SYSFS_FAILED(_feat_def, _feat, _adapter, _mod_id, _reopen_id) \ 86static ssize_t zfcp_sysfs_##_feat##_failed_show(struct device *dev, \ 87 struct device_attribute *attr, \ 88 char *buf) \ 89{ \ 90 struct _feat_def *_feat = container_of(dev, struct _feat_def, dev); \ 91 \ 92 if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_ERP_FAILED) \ 93 return sprintf(buf, "1\n"); \ 94 else \ 95 return sprintf(buf, "0\n"); \ 96} \ 97static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \ 98 struct device_attribute *attr,\ 99 const char *buf, size_t count)\ 100{ \ 101 struct _feat_def *_feat = container_of(dev, struct _feat_def, dev); \ 102 unsigned long val; \ 103 int retval = 0; \ 104 \ 105 if (!(_feat && get_device(&_feat->dev))) \ 106 return -EBUSY; \ 107 \ 108 if (strict_strtoul(buf, 0, &val) || val != 0) { \ 109 retval = -EINVAL; \ 110 goto out; \ 111 } \ 112 \ 113 zfcp_erp_modify_##_feat##_status(_feat, _mod_id, NULL, \ 114 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);\ 115 zfcp_erp_##_feat##_reopen(_feat, ZFCP_STATUS_COMMON_ERP_FAILED, \ 116 _reopen_id, NULL); \ 117 zfcp_erp_wait(_adapter); \ 118out: \ 119 put_device(&_feat->dev); \ 120 return retval ? retval : (ssize_t) count; \ 121} \ 122static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \ 123 zfcp_sysfs_##_feat##_failed_show, \ 124 zfcp_sysfs_##_feat##_failed_store); 125 126ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, "sypfai1", "sypfai2"); 127ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, "syufai1", "syufai2"); 128 129static ssize_t zfcp_sysfs_adapter_failed_show(struct device *dev, 130 struct device_attribute *attr, 131 char *buf) 132{ 133 struct ccw_device *cdev = to_ccwdev(dev); 134 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 135 int i; 136 137 if (!adapter) 138 return -ENODEV; 139 140 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) 141 i = sprintf(buf, "1\n"); 142 else 143 i = sprintf(buf, "0\n"); 144 145 zfcp_ccw_adapter_put(adapter); 146 return i; 147} 148 149static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev, 150 struct device_attribute *attr, 151 const char *buf, size_t count) 152{ 153 struct ccw_device *cdev = to_ccwdev(dev); 154 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 155 unsigned long val; 156 int retval = 0; 157 158 if (!adapter) 159 return -ENODEV; 160 161 if (strict_strtoul(buf, 0, &val) || val != 0) { 162 retval = -EINVAL; 163 goto out; 164 } 165 166 zfcp_erp_modify_adapter_status(adapter, "syafai1", NULL, 167 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); 168 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 169 "syafai2", NULL); 170 zfcp_erp_wait(adapter); 171out: 172 zfcp_ccw_adapter_put(adapter); 173 return retval ? retval : (ssize_t) count; 174} 175static ZFCP_DEV_ATTR(adapter, failed, S_IWUSR | S_IRUGO, 176 zfcp_sysfs_adapter_failed_show, 177 zfcp_sysfs_adapter_failed_store); 178 179static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev, 180 struct device_attribute *attr, 181 const char *buf, size_t count) 182{ 183 struct ccw_device *cdev = to_ccwdev(dev); 184 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 185 186 if (!adapter) 187 return -ENODEV; 188 189 /* sync the user-space- with the kernel-invocation of scan_work */ 190 queue_work(adapter->work_queue, &adapter->scan_work); 191 flush_work(&adapter->scan_work); 192 zfcp_ccw_adapter_put(adapter); 193 194 return (ssize_t) count; 195} 196static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL, 197 zfcp_sysfs_port_rescan_store); 198 199static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, 200 struct device_attribute *attr, 201 const char *buf, size_t count) 202{ 203 struct ccw_device *cdev = to_ccwdev(dev); 204 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 205 struct zfcp_port *port; 206 u64 wwpn; 207 int retval = -EINVAL; 208 209 if (!adapter) 210 return -ENODEV; 211 212 if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) 213 goto out; 214 215 port = zfcp_get_port_by_wwpn(adapter, wwpn); 216 if (!port) 217 goto out; 218 else 219 retval = 0; 220 221 write_lock_irq(&adapter->port_list_lock); 222 list_del(&port->list); 223 write_unlock_irq(&adapter->port_list_lock); 224 225 put_device(&port->dev); 226 227 zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL); 228 zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); 229 out: 230 zfcp_ccw_adapter_put(adapter); 231 return retval ? retval : (ssize_t) count; 232} 233static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL, 234 zfcp_sysfs_port_remove_store); 235 236static struct attribute *zfcp_adapter_attrs[] = { 237 &dev_attr_adapter_failed.attr, 238 &dev_attr_adapter_in_recovery.attr, 239 &dev_attr_adapter_port_remove.attr, 240 &dev_attr_adapter_port_rescan.attr, 241 &dev_attr_adapter_peer_wwnn.attr, 242 &dev_attr_adapter_peer_wwpn.attr, 243 &dev_attr_adapter_peer_d_id.attr, 244 &dev_attr_adapter_card_version.attr, 245 &dev_attr_adapter_lic_version.attr, 246 &dev_attr_adapter_status.attr, 247 &dev_attr_adapter_hardware_version.attr, 248 NULL 249}; 250 251struct attribute_group zfcp_sysfs_adapter_attrs = { 252 .attrs = zfcp_adapter_attrs, 253}; 254 255static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, 256 struct device_attribute *attr, 257 const char *buf, size_t count) 258{ 259 struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); 260 struct zfcp_unit *unit; 261 u64 fcp_lun; 262 int retval = -EINVAL; 263 264 if (!(port && get_device(&port->dev))) 265 return -EBUSY; 266 267 if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) 268 goto out; 269 270 unit = zfcp_unit_enqueue(port, fcp_lun); 271 if (IS_ERR(unit)) 272 goto out; 273 else 274 retval = 0; 275 276 zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); 277 zfcp_erp_wait(unit->port->adapter); 278 zfcp_scsi_scan(unit); 279out: 280 put_device(&port->dev); 281 return retval ? retval : (ssize_t) count; 282} 283static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store); 284 285static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, 286 struct device_attribute *attr, 287 const char *buf, size_t count) 288{ 289 struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); 290 struct zfcp_unit *unit; 291 u64 fcp_lun; 292 int retval = -EINVAL; 293 struct scsi_device *sdev; 294 295 if (!(port && get_device(&port->dev))) 296 return -EBUSY; 297 298 if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) 299 goto out; 300 301 unit = zfcp_get_unit_by_lun(port, fcp_lun); 302 if (!unit) 303 goto out; 304 else 305 retval = 0; 306 307 sdev = scsi_device_lookup(port->adapter->scsi_host, 0, 308 port->starget_id, 309 scsilun_to_int((struct scsi_lun *)&fcp_lun)); 310 if (sdev) { 311 scsi_remove_device(sdev); 312 scsi_device_put(sdev); 313 } 314 315 write_lock_irq(&port->unit_list_lock); 316 list_del(&unit->list); 317 write_unlock_irq(&port->unit_list_lock); 318 319 put_device(&unit->dev); 320 321 zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); 322 zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); 323out: 324 put_device(&port->dev); 325 return retval ? retval : (ssize_t) count; 326} 327static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); 328 329static struct attribute *zfcp_port_attrs[] = { 330 &dev_attr_unit_add.attr, 331 &dev_attr_unit_remove.attr, 332 &dev_attr_port_failed.attr, 333 &dev_attr_port_in_recovery.attr, 334 &dev_attr_port_status.attr, 335 &dev_attr_port_access_denied.attr, 336 NULL 337}; 338 339/** 340 * zfcp_sysfs_port_attrs - sysfs attributes for all other ports 341 */ 342struct attribute_group zfcp_sysfs_port_attrs = { 343 .attrs = zfcp_port_attrs, 344}; 345 346static struct attribute *zfcp_unit_attrs[] = { 347 &dev_attr_unit_failed.attr, 348 &dev_attr_unit_in_recovery.attr, 349 &dev_attr_unit_status.attr, 350 &dev_attr_unit_access_denied.attr, 351 &dev_attr_unit_access_shared.attr, 352 &dev_attr_unit_access_readonly.attr, 353 NULL 354}; 355 356struct attribute_group zfcp_sysfs_unit_attrs = { 357 .attrs = zfcp_unit_attrs, 358}; 359 360#define ZFCP_DEFINE_LATENCY_ATTR(_name) \ 361static ssize_t \ 362zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \ 363 struct device_attribute *attr, \ 364 char *buf) { \ 365 struct scsi_device *sdev = to_scsi_device(dev); \ 366 struct zfcp_unit *unit = sdev->hostdata; \ 367 struct zfcp_latencies *lat = &unit->latencies; \ 368 struct zfcp_adapter *adapter = unit->port->adapter; \ 369 unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \ 370 \ 371 spin_lock_bh(&lat->lock); \ 372 fsum = lat->_name.fabric.sum * adapter->timer_ticks; \ 373 fmin = lat->_name.fabric.min * adapter->timer_ticks; \ 374 fmax = lat->_name.fabric.max * adapter->timer_ticks; \ 375 csum = lat->_name.channel.sum * adapter->timer_ticks; \ 376 cmin = lat->_name.channel.min * adapter->timer_ticks; \ 377 cmax = lat->_name.channel.max * adapter->timer_ticks; \ 378 cc = lat->_name.counter; \ 379 spin_unlock_bh(&lat->lock); \ 380 \ 381 do_div(fsum, 1000); \ 382 do_div(fmin, 1000); \ 383 do_div(fmax, 1000); \ 384 do_div(csum, 1000); \ 385 do_div(cmin, 1000); \ 386 do_div(cmax, 1000); \ 387 \ 388 return sprintf(buf, "%llu %llu %llu %llu %llu %llu %llu\n", \ 389 fmin, fmax, fsum, cmin, cmax, csum, cc); \ 390} \ 391static ssize_t \ 392zfcp_sysfs_unit_##_name##_latency_store(struct device *dev, \ 393 struct device_attribute *attr, \ 394 const char *buf, size_t count) \ 395{ \ 396 struct scsi_device *sdev = to_scsi_device(dev); \ 397 struct zfcp_unit *unit = sdev->hostdata; \ 398 struct zfcp_latencies *lat = &unit->latencies; \ 399 unsigned long flags; \ 400 \ 401 spin_lock_irqsave(&lat->lock, flags); \ 402 lat->_name.fabric.sum = 0; \ 403 lat->_name.fabric.min = 0xFFFFFFFF; \ 404 lat->_name.fabric.max = 0; \ 405 lat->_name.channel.sum = 0; \ 406 lat->_name.channel.min = 0xFFFFFFFF; \ 407 lat->_name.channel.max = 0; \ 408 lat->_name.counter = 0; \ 409 spin_unlock_irqrestore(&lat->lock, flags); \ 410 \ 411 return (ssize_t) count; \ 412} \ 413static DEVICE_ATTR(_name##_latency, S_IWUSR | S_IRUGO, \ 414 zfcp_sysfs_unit_##_name##_latency_show, \ 415 zfcp_sysfs_unit_##_name##_latency_store); 416 417ZFCP_DEFINE_LATENCY_ATTR(read); 418ZFCP_DEFINE_LATENCY_ATTR(write); 419ZFCP_DEFINE_LATENCY_ATTR(cmd); 420 421#define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value) \ 422static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \ 423 struct device_attribute *attr,\ 424 char *buf) \ 425{ \ 426 struct scsi_device *sdev = to_scsi_device(dev); \ 427 struct zfcp_unit *unit = sdev->hostdata; \ 428 \ 429 return sprintf(buf, _format, _value); \ 430} \ 431static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL); 432 433ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", 434 dev_name(&unit->port->adapter->ccw_device->dev)); 435ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", 436 (unsigned long long) unit->port->wwpn); 437ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", 438 (unsigned long long) unit->fcp_lun); 439 440struct device_attribute *zfcp_sysfs_sdev_attrs[] = { 441 &dev_attr_fcp_lun, 442 &dev_attr_wwpn, 443 &dev_attr_hba_id, 444 &dev_attr_read_latency, 445 &dev_attr_write_latency, 446 &dev_attr_cmd_latency, 447 NULL 448}; 449 450static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev, 451 struct device_attribute *attr, 452 char *buf) 453{ 454 struct Scsi_Host *scsi_host = dev_to_shost(dev); 455 struct fsf_qtcb_bottom_port *qtcb_port; 456 struct zfcp_adapter *adapter; 457 int retval; 458 459 adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; 460 if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) 461 return -EOPNOTSUPP; 462 463 qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL); 464 if (!qtcb_port) 465 return -ENOMEM; 466 467 retval = zfcp_fsf_exchange_port_data_sync(adapter->qdio, qtcb_port); 468 if (!retval) 469 retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util, 470 qtcb_port->cb_util, qtcb_port->a_util); 471 kfree(qtcb_port); 472 return retval; 473} 474static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL); 475 476static int zfcp_sysfs_adapter_ex_config(struct device *dev, 477 struct fsf_statistics_info *stat_inf) 478{ 479 struct Scsi_Host *scsi_host = dev_to_shost(dev); 480 struct fsf_qtcb_bottom_config *qtcb_config; 481 struct zfcp_adapter *adapter; 482 int retval; 483 484 adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; 485 if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) 486 return -EOPNOTSUPP; 487 488 qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config), 489 GFP_KERNEL); 490 if (!qtcb_config) 491 return -ENOMEM; 492 493 retval = zfcp_fsf_exchange_config_data_sync(adapter->qdio, qtcb_config); 494 if (!retval) 495 *stat_inf = qtcb_config->stat_info; 496 497 kfree(qtcb_config); 498 return retval; 499} 500 501#define ZFCP_SHOST_ATTR(_name, _format, _arg...) \ 502static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, \ 503 struct device_attribute *attr,\ 504 char *buf) \ 505{ \ 506 struct fsf_statistics_info stat_info; \ 507 int retval; \ 508 \ 509 retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); \ 510 if (retval) \ 511 return retval; \ 512 \ 513 return sprintf(buf, _format, ## _arg); \ 514} \ 515static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_adapter_##_name##_show, NULL); 516 517ZFCP_SHOST_ATTR(requests, "%llu %llu %llu\n", 518 (unsigned long long) stat_info.input_req, 519 (unsigned long long) stat_info.output_req, 520 (unsigned long long) stat_info.control_req); 521 522ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n", 523 (unsigned long long) stat_info.input_mb, 524 (unsigned long long) stat_info.output_mb); 525 526ZFCP_SHOST_ATTR(seconds_active, "%llu\n", 527 (unsigned long long) stat_info.seconds_act); 528 529static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev, 530 struct device_attribute *attr, 531 char *buf) 532{ 533 struct Scsi_Host *scsi_host = class_to_shost(dev); 534 struct zfcp_qdio *qdio = 535 ((struct zfcp_adapter *) scsi_host->hostdata[0])->qdio; 536 u64 util; 537 538 spin_lock_bh(&qdio->stat_lock); 539 util = qdio->req_q_util; 540 spin_unlock_bh(&qdio->stat_lock); 541 542 return sprintf(buf, "%d %llu\n", atomic_read(&qdio->req_q_full), 543 (unsigned long long)util); 544} 545static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL); 546 547struct device_attribute *zfcp_sysfs_shost_attrs[] = { 548 &dev_attr_utilization, 549 &dev_attr_requests, 550 &dev_attr_megabytes, 551 &dev_attr_seconds_active, 552 &dev_attr_queue_full, 553 NULL 554}; 555