diff options
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 01687559dc06..4b0c85acb0f0 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -778,6 +778,68 @@ struct fc_function_template zfcp_transport_functions = { | |||
778 | .disable_target_scan = 1, | 778 | .disable_target_scan = 1, |
779 | }; | 779 | }; |
780 | 780 | ||
781 | #define ZFCP_DEFINE_LATENCY_ATTR(_name) \ | ||
782 | static ssize_t \ | ||
783 | zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \ | ||
784 | struct device_attribute *attr, \ | ||
785 | char *buf) { \ | ||
786 | struct scsi_device *sdev = to_scsi_device(dev); \ | ||
787 | struct zfcp_unit *unit = sdev->hostdata; \ | ||
788 | struct zfcp_latencies *lat = &unit->latencies; \ | ||
789 | struct zfcp_adapter *adapter = unit->port->adapter; \ | ||
790 | unsigned long flags; \ | ||
791 | unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \ | ||
792 | \ | ||
793 | spin_lock_irqsave(&lat->lock, flags); \ | ||
794 | fsum = lat->_name.fabric.sum * adapter->timer_ticks; \ | ||
795 | fmin = lat->_name.fabric.min * adapter->timer_ticks; \ | ||
796 | fmax = lat->_name.fabric.max * adapter->timer_ticks; \ | ||
797 | csum = lat->_name.channel.sum * adapter->timer_ticks; \ | ||
798 | cmin = lat->_name.channel.min * adapter->timer_ticks; \ | ||
799 | cmax = lat->_name.channel.max * adapter->timer_ticks; \ | ||
800 | cc = lat->_name.counter; \ | ||
801 | spin_unlock_irqrestore(&lat->lock, flags); \ | ||
802 | \ | ||
803 | do_div(fsum, 1000); \ | ||
804 | do_div(fmin, 1000); \ | ||
805 | do_div(fmax, 1000); \ | ||
806 | do_div(csum, 1000); \ | ||
807 | do_div(cmin, 1000); \ | ||
808 | do_div(cmax, 1000); \ | ||
809 | \ | ||
810 | return sprintf(buf, "%llu %llu %llu %llu %llu %llu %llu\n", \ | ||
811 | fmin, fmax, fsum, cmin, cmax, csum, cc); \ | ||
812 | } \ | ||
813 | static ssize_t \ | ||
814 | zfcp_sysfs_unit_##_name##_latency_store(struct device *dev, \ | ||
815 | struct device_attribute *attr, \ | ||
816 | const char *buf, size_t count) \ | ||
817 | { \ | ||
818 | struct scsi_device *sdev = to_scsi_device(dev); \ | ||
819 | struct zfcp_unit *unit = sdev->hostdata; \ | ||
820 | struct zfcp_latencies *lat = &unit->latencies; \ | ||
821 | unsigned long flags; \ | ||
822 | \ | ||
823 | spin_lock_irqsave(&lat->lock, flags); \ | ||
824 | lat->_name.fabric.sum = 0; \ | ||
825 | lat->_name.fabric.min = 0xFFFFFFFF; \ | ||
826 | lat->_name.fabric.max = 0; \ | ||
827 | lat->_name.channel.sum = 0; \ | ||
828 | lat->_name.channel.min = 0xFFFFFFFF; \ | ||
829 | lat->_name.channel.max = 0; \ | ||
830 | lat->_name.counter = 0; \ | ||
831 | spin_unlock_irqrestore(&lat->lock, flags); \ | ||
832 | \ | ||
833 | return (ssize_t) count; \ | ||
834 | } \ | ||
835 | static DEVICE_ATTR(_name##_latency, S_IWUSR | S_IRUGO, \ | ||
836 | zfcp_sysfs_unit_##_name##_latency_show, \ | ||
837 | zfcp_sysfs_unit_##_name##_latency_store); | ||
838 | |||
839 | ZFCP_DEFINE_LATENCY_ATTR(read); | ||
840 | ZFCP_DEFINE_LATENCY_ATTR(write); | ||
841 | ZFCP_DEFINE_LATENCY_ATTR(cmd); | ||
842 | |||
781 | /** | 843 | /** |
782 | * ZFCP_DEFINE_SCSI_ATTR | 844 | * ZFCP_DEFINE_SCSI_ATTR |
783 | * @_name: name of show attribute | 845 | * @_name: name of show attribute |
@@ -808,6 +870,9 @@ static struct device_attribute *zfcp_sysfs_sdev_attrs[] = { | |||
808 | &dev_attr_fcp_lun, | 870 | &dev_attr_fcp_lun, |
809 | &dev_attr_wwpn, | 871 | &dev_attr_wwpn, |
810 | &dev_attr_hba_id, | 872 | &dev_attr_hba_id, |
873 | &dev_attr_read_latency, | ||
874 | &dev_attr_write_latency, | ||
875 | &dev_attr_cmd_latency, | ||
811 | NULL | 876 | NULL |
812 | }; | 877 | }; |
813 | 878 | ||