#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
        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)];
        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 {
        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 {
 
                                          unsigned int, unsigned int);
 
 static struct device_attribute *zfcp_sysfs_sdev_attrs[];
+static struct device_attribute *zfcp_a_stats_attrs[];
 
 struct zfcp_data zfcp_data = {
        .scsi_host_template = {
                .use_clustering         = 1,
                .sdev_attrs             = zfcp_sysfs_sdev_attrs,
                .max_sectors            = ZFCP_MAX_SECTORS,
+               .shost_attrs            = zfcp_a_stats_attrs,
        },
        .driver_version = ZFCP_VERSION,
 };
        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;
+       int retval;
+       struct zfcp_adapter *adapter;
+
+       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;
+
+       retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port);
+       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 int zfcp_sysfs_adapter_ex_config(struct device *dev,
+                                       struct fsf_statistics_info *stat_inf)
+{
+       int retval;
+       struct fsf_qtcb_bottom_config *qtcb_config;
+       struct Scsi_Host *scsi_host = dev_to_shost(dev);
+       struct zfcp_adapter *adapter;
+
+       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;
+
+       retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
+       if (!retval)
+               *stat_inf = qtcb_config->stat_info;
+
+       kfree(qtcb_config);
+       return retval;
+}
+
+static ssize_t zfcp_sysfs_adapter_request_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, "%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);
+}
+
+static ssize_t zfcp_sysfs_adapter_mb_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, "%llu %llu\n",
+                      (unsigned long long) stat_info.input_mb,
+                      (unsigned long long) stat_info.output_mb);
+}
+
+static ssize_t zfcp_sysfs_adapter_sec_active_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, "%llu\n",
+                      (unsigned long long) stat_info.seconds_act);
+}
+
+static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL);
+static DEVICE_ATTR(requests, S_IRUGO, zfcp_sysfs_adapter_request_show, NULL);
+static DEVICE_ATTR(megabytes, S_IRUGO, zfcp_sysfs_adapter_mb_show, NULL);
+static DEVICE_ATTR(seconds_active, S_IRUGO,
+                  zfcp_sysfs_adapter_sec_active_show, NULL);
+
+static struct device_attribute *zfcp_a_stats_attrs[] = {
+       &dev_attr_utilization,
+       &dev_attr_requests,
+       &dev_attr_megabytes,
+       &dev_attr_seconds_active,
+       NULL
+};
+
 #undef ZFCP_LOG_AREA