diff options
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.h | 18 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 114 |
2 files changed, 130 insertions, 2 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 8cce5cc11d50..099970b27001 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h | |||
@@ -213,6 +213,7 @@ | |||
213 | #define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010 | 213 | #define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010 |
214 | #define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020 | 214 | #define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020 |
215 | #define FSF_FEATURE_UPDATE_ALERT 0x00000100 | 215 | #define FSF_FEATURE_UPDATE_ALERT 0x00000100 |
216 | #define FSF_FEATURE_MEASUREMENT_DATA 0x00000200 | ||
216 | 217 | ||
217 | /* host connection features */ | 218 | /* host connection features */ |
218 | #define FSF_FEATURE_NPIV_MODE 0x00000001 | 219 | #define FSF_FEATURE_NPIV_MODE 0x00000001 |
@@ -340,6 +341,15 @@ struct fsf_qtcb_prefix { | |||
340 | u8 res1[20]; | 341 | u8 res1[20]; |
341 | } __attribute__ ((packed)); | 342 | } __attribute__ ((packed)); |
342 | 343 | ||
344 | struct fsf_statistics_info { | ||
345 | u64 input_req; | ||
346 | u64 output_req; | ||
347 | u64 control_req; | ||
348 | u64 input_mb; | ||
349 | u64 output_mb; | ||
350 | u64 seconds_act; | ||
351 | } __attribute__ ((packed)); | ||
352 | |||
343 | union fsf_status_qual { | 353 | union fsf_status_qual { |
344 | u8 byte[FSF_STATUS_QUALIFIER_SIZE]; | 354 | u8 byte[FSF_STATUS_QUALIFIER_SIZE]; |
345 | u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)]; | 355 | u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)]; |
@@ -436,7 +446,8 @@ struct fsf_qtcb_bottom_config { | |||
436 | u32 hardware_version; | 446 | u32 hardware_version; |
437 | u8 serial_number[32]; | 447 | u8 serial_number[32]; |
438 | struct fsf_nport_serv_param plogi_payload; | 448 | struct fsf_nport_serv_param plogi_payload; |
439 | u8 res4[160]; | 449 | struct fsf_statistics_info stat_info; |
450 | u8 res4[112]; | ||
440 | } __attribute__ ((packed)); | 451 | } __attribute__ ((packed)); |
441 | 452 | ||
442 | struct fsf_qtcb_bottom_port { | 453 | struct fsf_qtcb_bottom_port { |
@@ -469,7 +480,10 @@ struct fsf_qtcb_bottom_port { | |||
469 | u64 control_requests; | 480 | u64 control_requests; |
470 | u64 input_mb; /* where 1 MByte == 1.000.000 Bytes */ | 481 | u64 input_mb; /* where 1 MByte == 1.000.000 Bytes */ |
471 | u64 output_mb; /* where 1 MByte == 1.000.000 Bytes */ | 482 | u64 output_mb; /* where 1 MByte == 1.000.000 Bytes */ |
472 | u8 res2[256]; | 483 | u8 cp_util; |
484 | u8 cb_util; | ||
485 | u8 a_util; | ||
486 | u8 res2[253]; | ||
473 | } __attribute__ ((packed)); | 487 | } __attribute__ ((packed)); |
474 | 488 | ||
475 | union fsf_qtcb_bottom { | 489 | union fsf_qtcb_bottom { |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index f81850624eed..01687559dc06 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -40,6 +40,7 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, | |||
40 | unsigned int, unsigned int); | 40 | unsigned int, unsigned int); |
41 | 41 | ||
42 | static struct device_attribute *zfcp_sysfs_sdev_attrs[]; | 42 | static struct device_attribute *zfcp_sysfs_sdev_attrs[]; |
43 | static struct device_attribute *zfcp_a_stats_attrs[]; | ||
43 | 44 | ||
44 | struct zfcp_data zfcp_data = { | 45 | struct zfcp_data zfcp_data = { |
45 | .scsi_host_template = { | 46 | .scsi_host_template = { |
@@ -61,6 +62,7 @@ struct zfcp_data zfcp_data = { | |||
61 | .use_clustering = 1, | 62 | .use_clustering = 1, |
62 | .sdev_attrs = zfcp_sysfs_sdev_attrs, | 63 | .sdev_attrs = zfcp_sysfs_sdev_attrs, |
63 | .max_sectors = ZFCP_MAX_SECTORS, | 64 | .max_sectors = ZFCP_MAX_SECTORS, |
65 | .shost_attrs = zfcp_a_stats_attrs, | ||
64 | }, | 66 | }, |
65 | .driver_version = ZFCP_VERSION, | 67 | .driver_version = ZFCP_VERSION, |
66 | }; | 68 | }; |
@@ -809,4 +811,116 @@ static struct device_attribute *zfcp_sysfs_sdev_attrs[] = { | |||
809 | NULL | 811 | NULL |
810 | }; | 812 | }; |
811 | 813 | ||
814 | static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev, | ||
815 | struct device_attribute *attr, | ||
816 | char *buf) | ||
817 | { | ||
818 | struct Scsi_Host *scsi_host = dev_to_shost(dev); | ||
819 | struct fsf_qtcb_bottom_port *qtcb_port; | ||
820 | int retval; | ||
821 | struct zfcp_adapter *adapter; | ||
822 | |||
823 | adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; | ||
824 | if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) | ||
825 | return -EOPNOTSUPP; | ||
826 | |||
827 | qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL); | ||
828 | if (!qtcb_port) | ||
829 | return -ENOMEM; | ||
830 | |||
831 | retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port); | ||
832 | if (!retval) | ||
833 | retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util, | ||
834 | qtcb_port->cb_util, qtcb_port->a_util); | ||
835 | kfree(qtcb_port); | ||
836 | return retval; | ||
837 | } | ||
838 | |||
839 | static int zfcp_sysfs_adapter_ex_config(struct device *dev, | ||
840 | struct fsf_statistics_info *stat_inf) | ||
841 | { | ||
842 | int retval; | ||
843 | struct fsf_qtcb_bottom_config *qtcb_config; | ||
844 | struct Scsi_Host *scsi_host = dev_to_shost(dev); | ||
845 | struct zfcp_adapter *adapter; | ||
846 | |||
847 | adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; | ||
848 | if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) | ||
849 | return -EOPNOTSUPP; | ||
850 | |||
851 | qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config), | ||
852 | GFP_KERNEL); | ||
853 | if (!qtcb_config) | ||
854 | return -ENOMEM; | ||
855 | |||
856 | retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config); | ||
857 | if (!retval) | ||
858 | *stat_inf = qtcb_config->stat_info; | ||
859 | |||
860 | kfree(qtcb_config); | ||
861 | return retval; | ||
862 | } | ||
863 | |||
864 | static ssize_t zfcp_sysfs_adapter_request_show(struct device *dev, | ||
865 | struct device_attribute *attr, | ||
866 | char *buf) | ||
867 | { | ||
868 | struct fsf_statistics_info stat_info; | ||
869 | int retval; | ||
870 | |||
871 | retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); | ||
872 | if (retval) | ||
873 | return retval; | ||
874 | |||
875 | return sprintf(buf, "%llu %llu %llu\n", | ||
876 | (unsigned long long) stat_info.input_req, | ||
877 | (unsigned long long) stat_info.output_req, | ||
878 | (unsigned long long) stat_info.control_req); | ||
879 | } | ||
880 | |||
881 | static ssize_t zfcp_sysfs_adapter_mb_show(struct device *dev, | ||
882 | struct device_attribute *attr, | ||
883 | char *buf) | ||
884 | { | ||
885 | struct fsf_statistics_info stat_info; | ||
886 | int retval; | ||
887 | |||
888 | retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); | ||
889 | if (retval) | ||
890 | return retval; | ||
891 | |||
892 | return sprintf(buf, "%llu %llu\n", | ||
893 | (unsigned long long) stat_info.input_mb, | ||
894 | (unsigned long long) stat_info.output_mb); | ||
895 | } | ||
896 | |||
897 | static ssize_t zfcp_sysfs_adapter_sec_active_show(struct device *dev, | ||
898 | struct device_attribute *attr, | ||
899 | char *buf) | ||
900 | { | ||
901 | struct fsf_statistics_info stat_info; | ||
902 | int retval; | ||
903 | |||
904 | retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); | ||
905 | if (retval) | ||
906 | return retval; | ||
907 | |||
908 | return sprintf(buf, "%llu\n", | ||
909 | (unsigned long long) stat_info.seconds_act); | ||
910 | } | ||
911 | |||
912 | static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL); | ||
913 | static DEVICE_ATTR(requests, S_IRUGO, zfcp_sysfs_adapter_request_show, NULL); | ||
914 | static DEVICE_ATTR(megabytes, S_IRUGO, zfcp_sysfs_adapter_mb_show, NULL); | ||
915 | static DEVICE_ATTR(seconds_active, S_IRUGO, | ||
916 | zfcp_sysfs_adapter_sec_active_show, NULL); | ||
917 | |||
918 | static struct device_attribute *zfcp_a_stats_attrs[] = { | ||
919 | &dev_attr_utilization, | ||
920 | &dev_attr_requests, | ||
921 | &dev_attr_megabytes, | ||
922 | &dev_attr_seconds_active, | ||
923 | NULL | ||
924 | }; | ||
925 | |||
812 | #undef ZFCP_LOG_AREA | 926 | #undef ZFCP_LOG_AREA |