[PATCH] zfcp: add statistics and other zfcp relatedinformation to sysfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Swen Schillig <swen@xxxxxxxxxxxx>

add statistics and other zfcp related information to sysfs

The zfcp adapter provides a variety of information which was never
published to the external world. This patch adds a few of those "statistics"
to the sysfs tree structure.

These are reflected in the following attributes

/sys/bus/ccw/drivers/zfcp/0.0.1707 
/* information for the virtual adapter */
        statistic_services/     
                requests        
                megabytes
                utilization
                seconds_active
/* LUN specific info for channel- and fabric-latency */
        0x500507630300c562/0x401040a600000000/  
                read_latency
                write_latency
                cmd_latency

Signed-off-by: Swen Schillig <swen@xxxxxxxxxxxx>
---
 drivers/s390/scsi/Makefile                |    2 
 drivers/s390/scsi/zfcp_aux.c              |   30 ++++
 drivers/s390/scsi/zfcp_def.h              |   58 +++++----
 drivers/s390/scsi/zfcp_ext.h              |   32 ++---
 drivers/s390/scsi/zfcp_fsf.c              |    1 
 drivers/s390/scsi/zfcp_fsf.h              |   29 ++++
 drivers/s390/scsi/zfcp_qdio.c             |   34 +++++
 drivers/s390/scsi/zfcp_sysfs_statistics.c |  191 ++++++++++++++++++++++++++++++
 drivers/s390/scsi/zfcp_sysfs_unit.c       |   63 +++++++++
 9 files changed, 394 insertions(+), 46 deletions(-)

Index: HEAD/drivers/s390/scsi/zfcp_def.h
===================================================================
--- HEAD.orig/drivers/s390/scsi/zfcp_def.h
+++ HEAD/drivers/s390/scsi/zfcp_def.h
@@ -1,23 +1,23 @@
-/* 
+/*
  * This file is part of the zfcp device driver for
  * FCP adapters for IBM System z9 and zSeries.
  *
  * (C) Copyright IBM Corp. 2002, 2006
- * 
- * This program is free software; you can redistribute it and/or modify 
- * it under the terms of the GNU General Public License as published by 
- * the Free Software Foundation; either version 2, or (at your option) 
- * any later version. 
- * 
- * This program is distributed in the hope that it will be useful, 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
- * GNU General Public License for more details. 
- * 
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
- */ 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #ifndef ZFCP_DEF_H
 #define ZFCP_DEF_H
@@ -90,7 +90,7 @@ zfcp_address_to_sg(void *address, struct
 #define ZFCP_DEVICE_TYPE        0x1732
 #define ZFCP_DEVICE_MODEL       0x03
 #define ZFCP_DEVICE_MODEL_PRIV	0x04
- 
+
 /* allow as many chained SBALs as are supported by hardware */
 #define ZFCP_MAX_SBALS_PER_REQ		FSF_MAX_SBALS_PER_REQ
 #define ZFCP_MAX_SBALS_PER_CT_REQ	FSF_MAX_SBALS_PER_REQ
@@ -508,7 +508,7 @@ struct zfcp_rc_entry {
 
 /*
  * this allows removal of logging code by the preprocessor
- * (the most detailed log level still to be compiled in is specified, 
+ * (the most detailed log level still to be compiled in is specified,
  * higher log levels are removed)
  */
 #define ZFCP_LOG_LEVEL_LIMIT	ZFCP_LOG_LEVEL_TRACE
@@ -546,7 +546,7 @@ do { \
 	if (ZFCP_LOG_CHECK(level)) \
 		_ZFCP_LOG(fmt, ##args); \
 } while (0)
-	
+
 #if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL
 # define ZFCP_LOG_NORMAL(fmt, args...)	do { } while (0)
 #else
@@ -583,8 +583,8 @@ do { \
 
 /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
 
-/* 
- * Note, the leftmost status byte is common among adapter, port 
+/*
+ * Note, the leftmost status byte is common among adapter, port
  * and unit
  */
 #define ZFCP_COMMON_FLAGS			0xfff00000
@@ -868,6 +868,17 @@ struct zfcp_erp_action {
 	struct timer_list timer;
 };
 
+struct latency_cont {
+	u32 channel;
+	u32 fabric;
+	u32 counter;
+};
+
+struct zfcp_latencies {
+	struct latency_cont read;
+	struct latency_cont write;
+	struct latency_cont cmd;
+};
 
 struct zfcp_adapter {
 	struct list_head	list;              /* list of adapters */
@@ -883,6 +894,7 @@ struct zfcp_adapter {
 	u32			adapter_features;  /* FCP channel features */
 	u32			connection_features; /* host connection features */
         u32			hardware_version;  /* of FCP channel */
+	u16			timer_ticks;       /* time int for a tick */
 	struct Scsi_Host	*scsi_host;	   /* Pointer to mid-layer */
 	struct list_head	port_list_head;	   /* remote port list */
 	struct list_head        port_remove_lh;    /* head of ports to be
@@ -930,6 +942,7 @@ struct zfcp_adapter {
 	struct zfcp_scsi_dbf_record	scsi_dbf_buf;
 	struct zfcp_adapter_mempool	pool;      /* Adapter memory pools */
 	struct qdio_initialize  qdio_init_data;    /* for qdio_establish */
+	struct device		stat_services;
 	struct device           generic_services;  /* directory for WKA ports */
 	struct fc_host_statistics *fc_stats;
 	struct fsf_qtcb_bottom_port *stats_reset_data;
@@ -986,6 +999,7 @@ struct zfcp_unit {
 						  all scsi_scan_target
 						  requests have been
 						  completed. */
+	struct zfcp_latencies	latencies;
 };
 
 /* FSF request */
@@ -1007,7 +1021,7 @@ struct zfcp_fsf_req {
 	u32		       fsf_command;    /* FSF Command copy */
 	struct fsf_qtcb	       *qtcb;	       /* address of associated QTCB */
 	u32		       seq_no;         /* Sequence number of request */
-        unsigned long          data;           /* private data of request */ 
+        unsigned long          data;           /* private data of request */
 	struct timer_list      timer;	       /* used for erp or scsi er */
 	struct zfcp_erp_action *erp_action;    /* used if this request is
 						  issued on behalf of erp */
Index: HEAD/drivers/s390/scsi/zfcp_fsf.c
===================================================================
--- HEAD.orig/drivers/s390/scsi/zfcp_fsf.c
+++ HEAD/drivers/s390/scsi/zfcp_fsf.c
@@ -2079,6 +2079,7 @@ zfcp_fsf_exchange_config_evaluate(struct
 		fc_host_supported_classes(shost) =
 				FC_COS_CLASS2 | FC_COS_CLASS3;
 		adapter->hydra_version = bottom->adapter_type;
+		adapter->timer_ticks = bottom->timer_interval;
 		if (fc_host_permanent_port_name(shost) == -1)
 			fc_host_permanent_port_name(shost) =
 				fc_host_port_name(shost);
Index: HEAD/drivers/s390/scsi/zfcp_fsf.h
===================================================================
--- HEAD.orig/drivers/s390/scsi/zfcp_fsf.h
+++ HEAD/drivers/s390/scsi/zfcp_fsf.h
@@ -213,6 +213,7 @@
 #define FSF_FEATURE_HBAAPI_MANAGEMENT           0x00000010
 #define FSF_FEATURE_ELS_CT_CHAINED_SBALS        0x00000020
 #define FSF_FEATURE_UPDATE_ALERT		0x00000100
+#define FSF_FEATURE_MEASUREMENT_DATA		0x00000200
 
 /* host connection features */
 #define FSF_FEATURE_NPIV_MODE			0x00000001
@@ -322,11 +323,18 @@ struct fsf_link_down_info {
 	u8 vendor_specific_code;
 } __attribute__ ((packed));
 
+struct fsf_qual_latency_info {
+	u32 channel_lat;
+	u32 fabric_lat;
+	u8 res1[8];
+} __attribute__ ((packed));
+
 union fsf_prot_status_qual {
 	u64 doubleword[FSF_PROT_STATUS_QUAL_SIZE / sizeof(u64)];
 	struct fsf_qual_version_error   version_error;
 	struct fsf_qual_sequence_error  sequence_error;
 	struct fsf_link_down_info link_down_info;
+	struct fsf_qual_latency_info latency_info;
 } __attribute__ ((packed));
 
 struct fsf_qtcb_prefix {
@@ -340,6 +348,15 @@ struct fsf_qtcb_prefix {
 	u8  res1[20];
 } __attribute__ ((packed));
 
+struct fsf_statistics_info {
+	u64 input_req;
+	u64 output_req;
+	u64 control_req;
+	u64 input_mb;
+	u64 output_mb;
+	u64 seconds_act;
+} __attribute__ ((packed));
+
 union fsf_status_qual {
 	u8  byte[FSF_STATUS_QUALIFIER_SIZE];
 	u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)];
@@ -427,7 +444,9 @@ struct fsf_qtcb_bottom_config {
 	u32 fc_link_speed;
 	u32 adapter_type;
 	u32 peer_d_id;
-	u8 res2[12];
+	u8 res1[2];
+	u16 timer_interval;
+	u8 res2[8];
 	u32 s_id;
 	struct fsf_nport_serv_param nport_serv_param;
 	u8 reserved_nport_serv_param[16];
@@ -436,7 +455,8 @@ struct fsf_qtcb_bottom_config {
 	u32 hardware_version;
 	u8 serial_number[32];
 	struct fsf_nport_serv_param plogi_payload;
-	u8 res4[160];
+	struct fsf_statistics_info stat_info;
+	u8 res4[112];
 } __attribute__ ((packed));
 
 struct fsf_qtcb_bottom_port {
@@ -469,7 +489,10 @@ struct fsf_qtcb_bottom_port {
 	u64 control_requests;
 	u64 input_mb;		/* where 1 MByte == 1.000.000 Bytes */
 	u64 output_mb;		/* where 1 MByte == 1.000.000 Bytes */
-	u8 res2[256];
+	u8 cp_util;
+	u8 cb_util;
+	u8 a_util;
+	u8 res2[253];
 } __attribute__ ((packed));
 
 union fsf_qtcb_bottom {
Index: HEAD/drivers/s390/scsi/zfcp_qdio.c
===================================================================
--- HEAD.orig/drivers/s390/scsi/zfcp_qdio.c
+++ HEAD/drivers/s390/scsi/zfcp_qdio.c
@@ -177,7 +177,7 @@ zfcp_qdio_handler_error_check(struct zfc
                 * which is set again in case we have missed by a mile.
                 */
                zfcp_erp_adapter_reopen(
-                       adapter, 
+                       adapter,
                        ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
                        ZFCP_STATUS_COMMON_ERP_FAILED);
 	}
@@ -241,6 +241,8 @@ static void zfcp_qdio_reqid_check(struct
 {
 	struct zfcp_fsf_req *fsf_req;
 	unsigned long flags;
+	struct fsf_qual_latency_info *lat_inf;
+	struct zfcp_unit *unit;
 
 	debug_long_event(adapter->erp_dbf, 4, req_id);
 
@@ -255,6 +257,36 @@ static void zfcp_qdio_reqid_check(struct
 		panic("error: unknown request id (%ld) on adapter %s.\n",
 		      req_id, zfcp_get_busid_by_adapter(adapter));
 
+	if ((fsf_req->fsf_command == FSF_QTCB_FCP_CMND) &&
+	    (fsf_req->qtcb->prefix.prot_status &
+	    (FSF_PROT_GOOD | FSF_PROT_FSF_STATUS_PRESENTED))) {
+		lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info;
+		unit = fsf_req->unit;
+		switch(fsf_req->qtcb->bottom.io.data_direction) {
+			case FSF_DATADIR_READ:
+				unit->latencies.read.channel +=
+					lat_inf->channel_lat;
+				unit->latencies.read.fabric +=
+					lat_inf->fabric_lat;
+				unit->latencies.read.counter++;
+				break;
+			case FSF_DATADIR_WRITE:
+				unit->latencies.write.channel +=
+					lat_inf->channel_lat;
+				unit->latencies.write.fabric +=
+					lat_inf->fabric_lat;
+				unit->latencies.write.counter++;
+				break;
+			case FSF_DATADIR_CMND:
+				unit->latencies.cmd.channel +=
+					lat_inf->channel_lat;
+				unit->latencies.cmd.fabric +=
+					lat_inf->fabric_lat;
+				unit->latencies.cmd.counter++;
+				break;
+		}
+	}
+
 	zfcp_reqlist_remove(adapter, fsf_req);
 	atomic_dec(&adapter->reqs_active);
 	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
Index: HEAD/drivers/s390/scsi/zfcp_sysfs_unit.c
===================================================================
--- HEAD.orig/drivers/s390/scsi/zfcp_sysfs_unit.c
+++ HEAD/drivers/s390/scsi/zfcp_sysfs_unit.c
@@ -125,6 +125,66 @@ zfcp_sysfs_unit_failed_show(struct devic
 static DEVICE_ATTR(failed, S_IWUSR | S_IRUGO, zfcp_sysfs_unit_failed_show,
 		   zfcp_sysfs_unit_failed_store);
 
+static ssize_t
+zfcp_sysfs_unit_read_latency_show(struct device *dev,
+				  struct device_attribute *attr, char *buf) {
+	struct zfcp_unit *unit;
+	struct zfcp_latencies *lat;
+	struct zfcp_adapter *adapter;
+
+	unit = dev_get_drvdata(dev);
+	lat = &unit->latencies;
+	adapter = unit->port->adapter;
+
+	return sprintf(buf, "%u %u %u\n",
+			lat->read.fabric * adapter->timer_ticks / 1000,
+			lat->read.channel * adapter->timer_ticks / 1000,
+			lat->read.counter);
+}
+
+static DEVICE_ATTR(read_latency, S_IRUGO, zfcp_sysfs_unit_read_latency_show,
+		   NULL);
+
+static ssize_t
+zfcp_sysfs_unit_write_latency_show(struct device *dev,
+				   struct device_attribute *attr, char *buf) {
+	struct zfcp_unit *unit;
+	struct zfcp_latencies *lat;
+	struct zfcp_adapter *adapter;
+
+	unit = dev_get_drvdata(dev);
+	lat = &unit->latencies;
+	adapter = unit->port->adapter;
+
+	return sprintf(buf, "%u %u %u\n",
+		       lat->write.fabric * adapter->timer_ticks / 1000,
+		       lat->write.channel * adapter->timer_ticks / 1000,
+		       lat->write.counter);
+}
+
+static DEVICE_ATTR(write_latency, S_IRUGO, zfcp_sysfs_unit_write_latency_show,
+		   NULL);
+
+static ssize_t
+zfcp_sysfs_unit_cmd_latency_show(struct device *dev,
+				 struct device_attribute *attr, char *buf) {
+	struct zfcp_unit *unit;
+	struct zfcp_latencies *lat;
+	struct zfcp_adapter *adapter;
+
+	unit = dev_get_drvdata(dev);
+	lat = &unit->latencies;
+	adapter = unit->port->adapter;
+
+	return sprintf(buf, "%u %u %u\n",
+		       lat->cmd.fabric * adapter->timer_ticks / 1000,
+		       lat->cmd.channel * adapter->timer_ticks / 1000,
+		       lat->cmd.counter);
+}
+
+static DEVICE_ATTR(cmd_latency, S_IRUGO, zfcp_sysfs_unit_cmd_latency_show,
+		   NULL);
+
 static struct attribute *zfcp_unit_attrs[] = {
 	&dev_attr_failed.attr,
 	&dev_attr_in_recovery.attr,
@@ -132,6 +192,9 @@ static struct attribute *zfcp_unit_attrs
 	&dev_attr_access_denied.attr,
 	&dev_attr_access_shared.attr,
 	&dev_attr_access_readonly.attr,
+	&dev_attr_read_latency.attr,
+	&dev_attr_write_latency.attr,
+	&dev_attr_cmd_latency.attr,
 	NULL
 };
 
Index: HEAD/drivers/s390/scsi/zfcp_ext.h
===================================================================
--- HEAD.orig/drivers/s390/scsi/zfcp_ext.h
+++ HEAD/drivers/s390/scsi/zfcp_ext.h
@@ -1,22 +1,22 @@
-/* 
+/*
  * This file is part of the zfcp device driver for
  * FCP adapters for IBM System z9 and zSeries.
  *
  * (C) Copyright IBM Corp. 2002, 2006
- * 
- * This program is free software; you can redistribute it and/or modify 
- * it under the terms of the GNU General Public License as published by 
- * the Free Software Foundation; either version 2, or (at your option) 
- * any later version. 
- * 
- * This program is distributed in the hope that it will be useful, 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
- * GNU General Public License for more details. 
- * 
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef ZFCP_EXT_H
@@ -37,6 +37,8 @@ extern int  zfcp_sysfs_unit_create_files
 extern void zfcp_sysfs_unit_remove_files(struct device *);
 extern void zfcp_sysfs_port_release(struct device *);
 extern void zfcp_sysfs_unit_release(struct device *);
+extern int  zfcp_sysfs_statistic_services_create_files(struct device *);
+extern void zfcp_sysfs_statistic_services_remove_files(struct device *);
 
 /**************************** CONFIGURATION  *********************************/
 extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, fcp_lun_t);
Index: HEAD/drivers/s390/scsi/zfcp_aux.c
===================================================================
--- HEAD.orig/drivers/s390/scsi/zfcp_aux.c
+++ HEAD/drivers/s390/scsi/zfcp_aux.c
@@ -887,7 +887,7 @@ zfcp_unit_dequeue(struct zfcp_unit *unit
 /*
  * Allocates a combined QTCB/fsf_req buffer for erp actions and fcp/SCSI
  * commands.
- * It also genrates fcp-nameserver request/response buffer and unsolicited 
+ * It also genrates fcp-nameserver request/response buffer and unsolicited
  * status read fsf_req buffers.
  *
  * locks:       must only be called with zfcp_data.config_sema taken
@@ -978,7 +978,7 @@ zfcp_adapter_enqueue(struct ccw_device *
 	struct zfcp_adapter *adapter;
 
 	/*
-	 * Note: It is safe to release the list_lock, as any list changes 
+	 * Note: It is safe to release the list_lock, as any list changes
 	 * are protected by the config_sema, which must be held to get here
 	 */
 
@@ -1059,13 +1059,33 @@ zfcp_adapter_enqueue(struct ccw_device *
 	if (zfcp_sysfs_adapter_create_files(&ccw_device->dev))
 		goto sysfs_failed;
 
+	adapter->stat_services.parent = &adapter->ccw_device->dev;
+	adapter->stat_services.release = zfcp_dummy_release;
+	snprintf(adapter->stat_services.bus_id, BUS_ID_SIZE,
+		 "statistic_services");
+	dev_set_drvdata(&adapter->stat_services, adapter);
+
+	if (device_register(&adapter->stat_services)) {
+		ZFCP_LOG_NORMAL("SSS:stat_reg failed.\n");
+		goto services_failed;
+	}
+	ZFCP_LOG_NORMAL("SSS:stat_reg succeeded.\n");
+
+	if (zfcp_sysfs_statistic_services_create_files(&adapter->stat_services))
+	{
+		ZFCP_LOG_NORMAL("SSS: create files failed.\n");
+		goto sysfs_failed;
+	}
+
+	ZFCP_LOG_NORMAL("SSS:create files succeeded.\n");
+
 	adapter->generic_services.parent = &adapter->ccw_device->dev;
 	adapter->generic_services.release = zfcp_dummy_release;
 	snprintf(adapter->generic_services.bus_id, BUS_ID_SIZE,
 		 "generic_services");
 
 	if (device_register(&adapter->generic_services))
-		goto generic_services_failed;
+		goto services_failed;
 
 	/* put allocated adapter at list tail */
 	write_lock_irq(&zfcp_data.config_lock);
@@ -1077,7 +1097,7 @@ zfcp_adapter_enqueue(struct ccw_device *
 
 	goto out;
 
- generic_services_failed:
+ services_failed:
 	zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
  sysfs_failed:
 	dev_set_drvdata(&ccw_device->dev, NULL);
@@ -1110,6 +1130,8 @@ zfcp_adapter_dequeue(struct zfcp_adapter
 
 	zfcp_adapter_scsi_unregister(adapter);
 	device_unregister(&adapter->generic_services);
+	zfcp_sysfs_statistic_services_remove_files(&adapter->stat_services);
+	device_unregister(&adapter->stat_services);
 	zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
 	dev_set_drvdata(&adapter->ccw_device->dev, NULL);
 	/* sanity check: no pending FSF requests */
Index: HEAD/drivers/s390/scsi/Makefile
===================================================================
--- HEAD.orig/drivers/s390/scsi/Makefile
+++ HEAD/drivers/s390/scsi/Makefile
@@ -4,6 +4,6 @@
 
 zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \
 	     zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \
-	     zfcp_sysfs_unit.o zfcp_sysfs_driver.o
+	     zfcp_sysfs_unit.o zfcp_sysfs_driver.o zfcp_sysfs_statistics.o
 
 obj-$(CONFIG_ZFCP) += zfcp.o
Index: HEAD/drivers/s390/scsi/zfcp_sysfs_statistics.c
===================================================================
--- /dev/null
+++ HEAD/drivers/s390/scsi/zfcp_sysfs_statistics.c
@@ -0,0 +1,191 @@
+/*
+ * This file is part of the zfcp device driver for
+ * FCP adapters for IBM System z9 and zSeries.
+ *
+ * (C) Copyright IBM Corp. 2002, 2006
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "zfcp_ext.h"
+
+#define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_CONFIG
+
+
+static ssize_t
+zfcp_sysfs_adapter_utilization_show(struct device *dev,
+				    struct device_attribute *attr, char *buf) {
+	struct zfcp_adapter *adapter;
+	struct fsf_qtcb_bottom_port *qtcb_port;
+	int retval;
+
+	adapter = dev_get_drvdata(dev);
+
+	qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL);
+	if (!qtcb_port) {
+		ZFCP_LOG_NORMAL("error: cannot allocate memory for exchange "
+				"port data request (adapter %s).\n",
+				zfcp_get_busid_by_adapter(adapter));
+		return (ssize_t) 0;
+	}
+
+	retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port);
+	if (retval) {
+		ZFCP_LOG_NORMAL("error: exchange port data request failed for "
+				"adapter %s.\n",
+				zfcp_get_busid_by_adapter(adapter));
+		kfree(qtcb_port);
+		return (ssize_t) 0;
+	}
+
+	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_utilization_show,
+		   NULL);
+
+static ssize_t
+zfcp_sysfs_adapter_request_show(struct device *dev,
+				struct device_attribute *attr, char *buf) {
+	struct zfcp_adapter *adapter;
+	struct fsf_qtcb_bottom_config *qtcb_config;
+	int retval;
+
+	adapter = dev_get_drvdata(dev);
+
+	qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
+			      GFP_KERNEL);
+	if (!qtcb_config) {
+		ZFCP_LOG_NORMAL("error: cannot allocate memory for exchange "
+				"configuration data request (adapter %s).\n",
+				zfcp_get_busid_by_adapter(adapter));
+		return (ssize_t) 0;
+	}
+
+	retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
+	if (retval)
+		ZFCP_LOG_NORMAL("error: exchange configuration data request "
+				"failed for adapter %s.\n",
+				zfcp_get_busid_by_adapter(adapter));
+	else
+		retval = sprintf(buf, "%lu %lu %lu\n",
+				 qtcb_config->stat_info.input_req,
+				 qtcb_config->stat_info.output_req,
+				 qtcb_config->stat_info.control_req);
+
+	kfree(qtcb_config);
+	return (retval > 0) ? retval : (ssize_t) 0;
+}
+
+static DEVICE_ATTR(requests, S_IRUGO, zfcp_sysfs_adapter_request_show, NULL);
+
+static ssize_t
+zfcp_sysfs_adapter_mb_show(struct device *dev,
+			   struct device_attribute *attr, char *buf) {
+	struct zfcp_adapter *adapter;
+	struct fsf_qtcb_bottom_config *qtcb_config;
+	int retval;
+
+	adapter = dev_get_drvdata(dev);
+
+	qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
+			      GFP_KERNEL);
+
+	if (!qtcb_config) {
+		ZFCP_LOG_NORMAL("error: cannot allocate memory for exchange "
+				"configuration data request (adapter %s).\n",
+				zfcp_get_busid_by_adapter(adapter));
+		return (ssize_t) 0;
+	}
+
+	retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
+	if (retval)
+		ZFCP_LOG_NORMAL("error: exchnage configuration data request "
+				"failed for adapter %s.\n",
+				zfcp_get_busid_by_adapter(adapter));
+	else
+		retval = sprintf(buf, "%lu %lu\n",
+				 qtcb_config->stat_info.input_mb,
+			 	 qtcb_config->stat_info.output_mb);
+
+	kfree(qtcb_config);
+	return (retval > 0) ? retval : (ssize_t) 0;
+}
+
+static DEVICE_ATTR(megabytes, S_IRUGO, zfcp_sysfs_adapter_mb_show, NULL);
+
+static ssize_t
+zfcp_sysfs_adapter_seconds_active_show(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf) {
+	struct zfcp_adapter *adapter;
+	struct fsf_qtcb_bottom_config *qtcb_config;
+	int retval;
+
+	adapter = dev_get_drvdata(dev);
+
+	qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
+			      GFP_KERNEL);
+
+	if (!qtcb_config) {
+		ZFCP_LOG_NORMAL("error: cannot allocate memory for exchange "
+				"configuration data request (adapter %s).\n",
+				zfcp_get_busid_by_adapter(adapter));
+		return (ssize_t) 0;
+	}
+
+	retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
+	if (retval)
+		ZFCP_LOG_NORMAL("error: exchange configuration data request "
+				"failed for adapter %s.\n",
+				zfcp_get_busid_by_adapter(adapter));
+	else
+		retval = sprintf(buf, "%lu\n",
+				 qtcb_config->stat_info.seconds_act);
+
+	kfree(qtcb_config);
+	return (retval > 0) ? retval: (ssize_t) 0;
+}
+
+static DEVICE_ATTR(seconds_active, S_IRUGO,
+		   zfcp_sysfs_adapter_seconds_active_show, NULL);
+
+static struct attribute *zfcp_statistic_services_attrs[] = {
+	&dev_attr_utilization.attr,
+	&dev_attr_requests.attr,
+	&dev_attr_megabytes.attr,
+	&dev_attr_seconds_active.attr,
+	NULL
+};
+
+static struct attribute_group zfcp_statistic_services_attr_group = {
+	.attrs = zfcp_statistic_services_attrs,
+};
+
+int
+zfcp_sysfs_statistic_services_create_files(struct device *dev){
+	return sysfs_create_group(&dev->kobj,
+				  &zfcp_statistic_services_attr_group);
+}
+
+void
+zfcp_sysfs_statistic_services_remove_files(struct device *dev) {
+	sysfs_remove_group(&dev->kobj, &zfcp_statistic_services_attr_group);
+}
+
+#undef ZFCP_LOG_AREA
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux