zfcp_sysfs.c 18.8 KB
Newer Older
1 2 3 4 5
/*
 * zfcp device driver
 *
 * sysfs attributes.
 *
6
 * Copyright IBM Corp. 2008, 2010
7 8
 */

9 10 11
#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

12
#include <linux/slab.h>
13 14 15 16 17 18 19 20 21 22
#include "zfcp_ext.h"

#define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \
struct device_attribute dev_attr_##_feat##_##_name = __ATTR(_name, _mode,\
							    _show, _store)
#define ZFCP_DEFINE_ATTR(_feat_def, _feat, _name, _format, _value)	       \
static ssize_t zfcp_sysfs_##_feat##_##_name##_show(struct device *dev,	       \
						   struct device_attribute *at,\
						   char *buf)		       \
{									       \
23
	struct _feat_def *_feat = container_of(dev, struct _feat_def, dev);    \
24 25 26 27 28 29
									       \
	return sprintf(buf, _format, _value);				       \
}									       \
static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO,				       \
		     zfcp_sysfs_##_feat##_##_name##_show, NULL);

30 31 32 33 34 35 36 37 38 39
#define ZFCP_DEFINE_ATTR_CONST(_feat, _name, _format, _value)		       \
static ssize_t zfcp_sysfs_##_feat##_##_name##_show(struct device *dev,	       \
						   struct device_attribute *at,\
						   char *buf)		       \
{									       \
	return sprintf(buf, _format, _value);				       \
}									       \
static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO,				       \
		     zfcp_sysfs_##_feat##_##_name##_show, NULL);

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
#define ZFCP_DEFINE_A_ATTR(_name, _format, _value)			     \
static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev,	     \
						 struct device_attribute *at,\
						 char *buf)		     \
{									     \
	struct ccw_device *cdev = to_ccwdev(dev);			     \
	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);	     \
	int i;								     \
									     \
	if (!adapter)							     \
		return -ENODEV;						     \
									     \
	i = sprintf(buf, _format, _value);				     \
	zfcp_ccw_adapter_put(adapter);					     \
	return i;							     \
}									     \
static ZFCP_DEV_ATTR(adapter, _name, S_IRUGO,				     \
		     zfcp_sysfs_adapter_##_name##_show, NULL);

ZFCP_DEFINE_A_ATTR(status, "0x%08x\n", atomic_read(&adapter->status));
ZFCP_DEFINE_A_ATTR(peer_wwnn, "0x%016llx\n",
		   (unsigned long long) adapter->peer_wwnn);
ZFCP_DEFINE_A_ATTR(peer_wwpn, "0x%016llx\n",
		   (unsigned long long) adapter->peer_wwpn);
ZFCP_DEFINE_A_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
ZFCP_DEFINE_A_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
ZFCP_DEFINE_A_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
ZFCP_DEFINE_A_ATTR(hardware_version, "0x%08x\n", adapter->hardware_version);
ZFCP_DEFINE_A_ATTR(in_recovery, "%d\n", (atomic_read(&adapter->status) &
					 ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
70 71 72 73 74 75

ZFCP_DEFINE_ATTR(zfcp_port, port, status, "0x%08x\n",
		 atomic_read(&port->status));
ZFCP_DEFINE_ATTR(zfcp_port, port, in_recovery, "%d\n",
		 (atomic_read(&port->status) &
		  ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
76
ZFCP_DEFINE_ATTR_CONST(port, access_denied, "%d\n", 0);
77 78

ZFCP_DEFINE_ATTR(zfcp_unit, unit, status, "0x%08x\n",
79
		 zfcp_unit_sdev_status(unit));
80
ZFCP_DEFINE_ATTR(zfcp_unit, unit, in_recovery, "%d\n",
81
		 (zfcp_unit_sdev_status(unit) &
82 83
		  ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_denied, "%d\n",
84
		 (zfcp_unit_sdev_status(unit) &
85
		  ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);
86 87
ZFCP_DEFINE_ATTR_CONST(unit, access_shared, "%d\n", 0);
ZFCP_DEFINE_ATTR_CONST(unit, access_readonly, "%d\n", 0);
88

89 90 91 92 93
static ssize_t zfcp_sysfs_port_failed_show(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
94

95 96 97 98 99 100 101 102 103 104 105 106 107
	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
		return sprintf(buf, "1\n");

	return sprintf(buf, "0\n");
}

static ssize_t zfcp_sysfs_port_failed_store(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
	unsigned long val;

108
	if (kstrtoul(buf, 0, &val) || val != 0)
109 110
		return -EINVAL;

111
	zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_RUNNING);
112
	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2");
113 114 115 116 117 118 119 120 121 122 123 124 125
	zfcp_erp_wait(port->adapter);

	return count;
}
static ZFCP_DEV_ATTR(port, failed, S_IWUSR | S_IRUGO,
		     zfcp_sysfs_port_failed_show,
		     zfcp_sysfs_port_failed_store);

static ssize_t zfcp_sysfs_unit_failed_show(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
126 127 128 129 130 131 132 133 134
	struct scsi_device *sdev;
	unsigned int status, failed = 1;

	sdev = zfcp_unit_sdev(unit);
	if (sdev) {
		status = atomic_read(&sdev_to_zfcp(sdev)->status);
		failed = status & ZFCP_STATUS_COMMON_ERP_FAILED ? 1 : 0;
		scsi_device_put(sdev);
	}
135

136
	return sprintf(buf, "%d\n", failed);
137 138 139 140 141 142 143 144
}

static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
	unsigned long val;
145
	struct scsi_device *sdev;
146

147
	if (kstrtoul(buf, 0, &val) || val != 0)
148 149
		return -EINVAL;

150 151
	sdev = zfcp_unit_sdev(unit);
	if (sdev) {
152
		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
153
		zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
154
				    "syufai2");
155 156 157
		zfcp_erp_wait(unit->port->adapter);
	} else
		zfcp_unit_scsi_scan(unit);
158 159 160 161 162 163

	return count;
}
static ZFCP_DEV_ATTR(unit, failed, S_IWUSR | S_IRUGO,
		     zfcp_sysfs_unit_failed_show,
		     zfcp_sysfs_unit_failed_store);
164

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
static ssize_t zfcp_sysfs_adapter_failed_show(struct device *dev,
					      struct device_attribute *attr,
					      char *buf)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
	int i;

	if (!adapter)
		return -ENODEV;

	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
		i = sprintf(buf, "1\n");
	else
		i = sprintf(buf, "0\n");

	zfcp_ccw_adapter_put(adapter);
	return i;
}

static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev,
					       struct device_attribute *attr,
					       const char *buf, size_t count)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
	unsigned long val;
	int retval = 0;

	if (!adapter)
		return -ENODEV;

197
	if (kstrtoul(buf, 0, &val) || val != 0) {
198 199 200 201
		retval = -EINVAL;
		goto out;
	}

202
	zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
203
	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
204
				"syafai2");
205 206 207 208 209 210 211 212 213
	zfcp_erp_wait(adapter);
out:
	zfcp_ccw_adapter_put(adapter);
	return retval ? retval : (ssize_t) count;
}
static ZFCP_DEV_ATTR(adapter, failed, S_IWUSR | S_IRUGO,
		     zfcp_sysfs_adapter_failed_show,
		     zfcp_sysfs_adapter_failed_store);

214 215 216 217
static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
218 219
	struct ccw_device *cdev = to_ccwdev(dev);
	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
220

221 222 223
	if (!adapter)
		return -ENODEV;

224 225 226
	/* sync the user-space- with the kernel-invocation of scan_work */
	queue_work(adapter->work_queue, &adapter->scan_work);
	flush_work(&adapter->scan_work);
227
	zfcp_ccw_adapter_put(adapter);
228

229
	return (ssize_t) count;
230 231 232 233
}
static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
		     zfcp_sysfs_port_rescan_store);

234 235
DEFINE_MUTEX(zfcp_sysfs_port_units_mutex);

236 237 238 239
static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
240 241
	struct ccw_device *cdev = to_ccwdev(dev);
	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
242
	struct zfcp_port *port;
243
	u64 wwpn;
244
	int retval = -EINVAL;
245

246 247 248
	if (!adapter)
		return -ENODEV;

249
	if (kstrtoull(buf, 0, (unsigned long long *) &wwpn))
250 251 252
		goto out;

	port = zfcp_get_port_by_wwpn(adapter, wwpn);
253
	if (!port)
254
		goto out;
255 256
	else
		retval = 0;
257

258 259 260 261 262 263 264 265 266 267
	mutex_lock(&zfcp_sysfs_port_units_mutex);
	if (atomic_read(&port->units) > 0) {
		retval = -EBUSY;
		mutex_unlock(&zfcp_sysfs_port_units_mutex);
		goto out;
	}
	/* port is about to be removed, so no more unit_add */
	atomic_set(&port->units, -1);
	mutex_unlock(&zfcp_sysfs_port_units_mutex);

268 269 270 271
	write_lock_irq(&adapter->port_list_lock);
	list_del(&port->list);
	write_unlock_irq(&adapter->port_list_lock);

272
	put_device(&port->dev);
273

274
	zfcp_erp_port_shutdown(port, 0, "syprs_1");
275
	device_unregister(&port->dev);
276
 out:
277
	zfcp_ccw_adapter_put(adapter);
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
	return retval ? retval : (ssize_t) count;
}
static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL,
		     zfcp_sysfs_port_remove_store);

static struct attribute *zfcp_adapter_attrs[] = {
	&dev_attr_adapter_failed.attr,
	&dev_attr_adapter_in_recovery.attr,
	&dev_attr_adapter_port_remove.attr,
	&dev_attr_adapter_port_rescan.attr,
	&dev_attr_adapter_peer_wwnn.attr,
	&dev_attr_adapter_peer_wwpn.attr,
	&dev_attr_adapter_peer_d_id.attr,
	&dev_attr_adapter_card_version.attr,
	&dev_attr_adapter_lic_version.attr,
	&dev_attr_adapter_status.attr,
	&dev_attr_adapter_hardware_version.attr,
	NULL
};

struct attribute_group zfcp_sysfs_adapter_attrs = {
	.attrs = zfcp_adapter_attrs,
};

static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t count)
{
306
	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
307
	u64 fcp_lun;
308
	int retval;
309

310
	if (kstrtoull(buf, 0, (unsigned long long *) &fcp_lun))
311
		return -EINVAL;
312

313 314 315
	retval = zfcp_unit_add(port, fcp_lun);
	if (retval)
		return retval;
316

317
	return count;
318 319 320 321 322 323 324
}
static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);

static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
325
	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
326
	u64 fcp_lun;
327

328
	if (kstrtoull(buf, 0, (unsigned long long *) &fcp_lun))
329
		return -EINVAL;
330

331 332
	if (zfcp_unit_remove(port, fcp_lun))
		return -EINVAL;
333

334
	return count;
335 336 337
}
static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);

338
static struct attribute *zfcp_port_attrs[] = {
339 340 341 342 343 344 345 346
	&dev_attr_unit_add.attr,
	&dev_attr_unit_remove.attr,
	&dev_attr_port_failed.attr,
	&dev_attr_port_in_recovery.attr,
	&dev_attr_port_status.attr,
	&dev_attr_port_access_denied.attr,
	NULL
};
347
static struct attribute_group zfcp_port_attr_group = {
348
	.attrs = zfcp_port_attrs,
349
};
350 351 352 353
const struct attribute_group *zfcp_port_attr_groups[] = {
	&zfcp_port_attr_group,
	NULL,
};
354 355 356 357 358 359

static struct attribute *zfcp_unit_attrs[] = {
	&dev_attr_unit_failed.attr,
	&dev_attr_unit_in_recovery.attr,
	&dev_attr_unit_status.attr,
	&dev_attr_unit_access_denied.attr,
360 361
	&dev_attr_unit_access_shared.attr,
	&dev_attr_unit_access_readonly.attr,
362 363
	NULL
};
364
static struct attribute_group zfcp_unit_attr_group = {
365 366
	.attrs = zfcp_unit_attrs,
};
367 368 369 370
const struct attribute_group *zfcp_unit_attr_groups[] = {
	&zfcp_unit_attr_group,
	NULL,
};
371 372 373 374 375 376 377

#define ZFCP_DEFINE_LATENCY_ATTR(_name) 				\
static ssize_t								\
zfcp_sysfs_unit_##_name##_latency_show(struct device *dev,		\
				       struct device_attribute *attr,	\
				       char *buf) {			\
	struct scsi_device *sdev = to_scsi_device(dev);			\
378 379 380
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);		\
	struct zfcp_latencies *lat = &zfcp_sdev->latencies;		\
	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;	\
381 382
	unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc;	\
									\
383
	spin_lock_bh(&lat->lock);					\
384 385 386 387 388 389 390
	fsum = lat->_name.fabric.sum * adapter->timer_ticks;		\
	fmin = lat->_name.fabric.min * adapter->timer_ticks;		\
	fmax = lat->_name.fabric.max * adapter->timer_ticks;		\
	csum = lat->_name.channel.sum * adapter->timer_ticks;		\
	cmin = lat->_name.channel.min * adapter->timer_ticks;		\
	cmax = lat->_name.channel.max * adapter->timer_ticks;		\
	cc  = lat->_name.counter;					\
391
	spin_unlock_bh(&lat->lock);					\
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
									\
	do_div(fsum, 1000);						\
	do_div(fmin, 1000);						\
	do_div(fmax, 1000);						\
	do_div(csum, 1000);						\
	do_div(cmin, 1000);						\
	do_div(cmax, 1000);						\
									\
	return sprintf(buf, "%llu %llu %llu %llu %llu %llu %llu\n",	\
		       fmin, fmax, fsum, cmin, cmax, csum, cc); 	\
}									\
static ssize_t								\
zfcp_sysfs_unit_##_name##_latency_store(struct device *dev,		\
					struct device_attribute *attr,	\
					const char *buf, size_t count)	\
{									\
	struct scsi_device *sdev = to_scsi_device(dev);			\
409 410
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);		\
	struct zfcp_latencies *lat = &zfcp_sdev->latencies;		\
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
	unsigned long flags;						\
									\
	spin_lock_irqsave(&lat->lock, flags);				\
	lat->_name.fabric.sum = 0;					\
	lat->_name.fabric.min = 0xFFFFFFFF;				\
	lat->_name.fabric.max = 0;					\
	lat->_name.channel.sum = 0;					\
	lat->_name.channel.min = 0xFFFFFFFF;				\
	lat->_name.channel.max = 0;					\
	lat->_name.counter = 0;						\
	spin_unlock_irqrestore(&lat->lock, flags);			\
									\
	return (ssize_t) count;						\
}									\
static DEVICE_ATTR(_name##_latency, S_IWUSR | S_IRUGO,			\
		   zfcp_sysfs_unit_##_name##_latency_show,		\
		   zfcp_sysfs_unit_##_name##_latency_store);

ZFCP_DEFINE_LATENCY_ATTR(read);
ZFCP_DEFINE_LATENCY_ATTR(write);
ZFCP_DEFINE_LATENCY_ATTR(cmd);

#define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value)			\
static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev,	\
					      struct device_attribute *attr,\
					      char *buf)                 \
{                                                                        \
438 439
	struct scsi_device *sdev = to_scsi_device(dev);			 \
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);		 \
440 441 442 443 444 445
									 \
	return sprintf(buf, _format, _value);                            \
}                                                                        \
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL);

ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n",
446
		      dev_name(&zfcp_sdev->port->adapter->ccw_device->dev));
447
ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n",
448
		      (unsigned long long) zfcp_sdev->port->wwpn);
449 450 451 452 453 454 455

static ssize_t zfcp_sysfs_scsi_fcp_lun_show(struct device *dev,
					    struct device_attribute *attr,
					    char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);

456
	return sprintf(buf, "0x%016llx\n", zfcp_scsi_dev_lun(sdev));
457 458
}
static DEVICE_ATTR(fcp_lun, S_IRUGO, zfcp_sysfs_scsi_fcp_lun_show, NULL);
459

460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
ZFCP_DEFINE_SCSI_ATTR(zfcp_access_denied, "%d\n",
		      (atomic_read(&zfcp_sdev->status) &
		       ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);

static ssize_t zfcp_sysfs_scsi_zfcp_failed_show(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	unsigned int status = atomic_read(&sdev_to_zfcp(sdev)->status);
	unsigned int failed = status & ZFCP_STATUS_COMMON_ERP_FAILED ? 1 : 0;

	return sprintf(buf, "%d\n", failed);
}

static ssize_t zfcp_sysfs_scsi_zfcp_failed_store(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	unsigned long val;

	if (kstrtoul(buf, 0, &val) || val != 0)
		return -EINVAL;

	zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
	zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
			    "syufai3");
	zfcp_erp_wait(sdev_to_zfcp(sdev)->port->adapter);

	return count;
}
static DEVICE_ATTR(zfcp_failed, S_IWUSR | S_IRUGO,
		   zfcp_sysfs_scsi_zfcp_failed_show,
		   zfcp_sysfs_scsi_zfcp_failed_store);

ZFCP_DEFINE_SCSI_ATTR(zfcp_in_recovery, "%d\n",
		      (atomic_read(&zfcp_sdev->status) &
		       ZFCP_STATUS_COMMON_ERP_INUSE) != 0);

ZFCP_DEFINE_SCSI_ATTR(zfcp_status, "0x%08x\n",
		      atomic_read(&zfcp_sdev->status));

503 504 505 506 507 508 509
struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
	&dev_attr_fcp_lun,
	&dev_attr_wwpn,
	&dev_attr_hba_id,
	&dev_attr_read_latency,
	&dev_attr_write_latency,
	&dev_attr_cmd_latency,
510 511 512 513
	&dev_attr_zfcp_access_denied,
	&dev_attr_zfcp_failed,
	&dev_attr_zfcp_in_recovery,
	&dev_attr_zfcp_status,
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
	NULL
};

static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev,
					    struct device_attribute *attr,
					    char *buf)
{
	struct Scsi_Host *scsi_host = dev_to_shost(dev);
	struct fsf_qtcb_bottom_port *qtcb_port;
	struct zfcp_adapter *adapter;
	int retval;

	adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
	if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
		return -EOPNOTSUPP;

	qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL);
	if (!qtcb_port)
		return -ENOMEM;

534
	retval = zfcp_fsf_exchange_port_data_sync(adapter->qdio, qtcb_port);
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
	if (!retval)
		retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util,
				 qtcb_port->cb_util, qtcb_port->a_util);
	kfree(qtcb_port);
	return retval;
}
static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL);

static int zfcp_sysfs_adapter_ex_config(struct device *dev,
					struct fsf_statistics_info *stat_inf)
{
	struct Scsi_Host *scsi_host = dev_to_shost(dev);
	struct fsf_qtcb_bottom_config *qtcb_config;
	struct zfcp_adapter *adapter;
	int retval;

	adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
	if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
		return -EOPNOTSUPP;

	qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
			      GFP_KERNEL);
	if (!qtcb_config)
		return -ENOMEM;

560
	retval = zfcp_fsf_exchange_config_data_sync(adapter->qdio, qtcb_config);
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
	if (!retval)
		*stat_inf = qtcb_config->stat_info;

	kfree(qtcb_config);
	return retval;
}

#define ZFCP_SHOST_ATTR(_name, _format, _arg...)			\
static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev,	\
						 struct device_attribute *attr,\
						 char *buf)		\
{									\
	struct fsf_statistics_info stat_info;				\
	int retval;							\
									\
	retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);		\
	if (retval)							\
		return retval;						\
									\
	return sprintf(buf, _format, ## _arg);				\
}									\
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_adapter_##_name##_show, NULL);

ZFCP_SHOST_ATTR(requests, "%llu %llu %llu\n",
		(unsigned long long) stat_info.input_req,
		(unsigned long long) stat_info.output_req,
		(unsigned long long) stat_info.control_req);

ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n",
		(unsigned long long) stat_info.input_mb,
		(unsigned long long) stat_info.output_mb);

ZFCP_SHOST_ATTR(seconds_active, "%llu\n",
		(unsigned long long) stat_info.seconds_act);

596 597 598 599 600
static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,
					      struct device_attribute *attr,
					      char *buf)
{
	struct Scsi_Host *scsi_host = class_to_shost(dev);
601 602
	struct zfcp_qdio *qdio =
		((struct zfcp_adapter *) scsi_host->hostdata[0])->qdio;
603 604
	u64 util;

605 606 607
	spin_lock_bh(&qdio->stat_lock);
	util = qdio->req_q_util;
	spin_unlock_bh(&qdio->stat_lock);
608

609
	return sprintf(buf, "%d %llu\n", atomic_read(&qdio->req_q_full),
610
		       (unsigned long long)util);
611 612 613
}
static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);

614 615 616 617 618
struct device_attribute *zfcp_sysfs_shost_attrs[] = {
	&dev_attr_utilization,
	&dev_attr_requests,
	&dev_attr_megabytes,
	&dev_attr_seconds_active,
619
	&dev_attr_queue_full,
620 621
	NULL
};