Start separating SATA specific code from libata-scsi.c: * un-static ata_scsi_find_dev() * move following code to libata-sata.c: - SATA only sysfs device attributes handling - __ata_change_queue_depth() - ata_scsi_change_queue_depth() * cover with CONFIG_SATA_HOST ifdef SATA only sysfs device attributes handling code and ATA_SHT_NCQ() macro in <linux/libata.h> Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 20702 105 576 21383 5387 drivers/ata/libata-scsi.o after: 19137 23 576 19736 4d18 drivers/ata/libata-scsi.o
Unified · Split
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #include <linux/kernel.h> |
| 10 | 10 | #include <linux/module.h> |
| 11 | +#include <scsi/scsi_device.h> | |
| 11 | 12 | #include <linux/libata.h> |
| 12 | 13 | |
| 13 | 14 | #include "libata.h" |
| @@ -764,3 +765,300 @@ bool sata_lpm_ignore_phy_events(struct ata_link *link) · 750 unmodified lines | ||
| 764 | 765 | return false; |
| 765 | 766 | } |
| 766 | 767 | EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); |
| 768 | + | |
| 769 | +static const char *ata_lpm_policy_names[] = { | |
| 770 | + [ATA_LPM_UNKNOWN] = "max_performance", | |
| 771 | + [ATA_LPM_MAX_POWER] = "max_performance", | |
| 772 | + [ATA_LPM_MED_POWER] = "medium_power", | |
| 773 | + [ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm", | |
| 774 | + [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial", | |
| 775 | + [ATA_LPM_MIN_POWER] = "min_power", | |
| 776 | +}; | |
| 777 | + | |
| 778 | +static ssize_t ata_scsi_lpm_store(struct device *device, | |
| 779 | + struct device_attribute *attr, | |
| 780 | + const char *buf, size_t count) | |
| 781 | +{ | |
| 782 | + struct Scsi_Host *shost = class_to_shost(device); | |
| 783 | + struct ata_port *ap = ata_shost_to_port(shost); | |
| 784 | + struct ata_link *link; | |
| 785 | + struct ata_device *dev; | |
| 786 | + enum ata_lpm_policy policy; | |
| 787 | + unsigned long flags; | |
| 788 | + | |
| 789 | + /* UNKNOWN is internal state, iterate from MAX_POWER */ | |
| 790 | + for (policy = ATA_LPM_MAX_POWER; | |
| 791 | + policy < ARRAY_SIZE(ata_lpm_policy_names); policy++) { | |
| 792 | + const char *name = ata_lpm_policy_names[policy]; | |
| 793 | + | |
| 794 | + if (strncmp(name, buf, strlen(name)) == 0) | |
| 795 | + break; | |
| 796 | + } | |
| 797 | + if (policy == ARRAY_SIZE(ata_lpm_policy_names)) | |
| 798 | + return -EINVAL; | |
| 799 | + | |
| 800 | + spin_lock_irqsave(ap->lock, flags); | |
| 801 | + | |
| 802 | + ata_for_each_link(link, ap, EDGE) { | |
| 803 | + ata_for_each_dev(dev, &ap->link, ENABLED) { | |
| 804 | + if (dev->horkage & ATA_HORKAGE_NOLPM) { | |
| 805 | + count = -EOPNOTSUPP; | |
| 806 | + goto out_unlock; | |
| 807 | + } | |
| 808 | + } | |
| 809 | + } | |
| 810 | + | |
| 811 | + ap->target_lpm_policy = policy; | |
| 812 | + ata_port_schedule_eh(ap); | |
| 813 | +out_unlock: | |
| 814 | + spin_unlock_irqrestore(ap->lock, flags); | |
| 815 | + return count; | |
| 816 | +} | |
| 817 | + | |
| 818 | +static ssize_t ata_scsi_lpm_show(struct device *dev, | |
| 819 | + struct device_attribute *attr, char *buf) | |
| 820 | +{ | |
| 821 | + struct Scsi_Host *shost = class_to_shost(dev); | |
| 822 | + struct ata_port *ap = ata_shost_to_port(shost); | |
| 823 | + | |
| 824 | + if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) | |
| 825 | + return -EINVAL; | |
| 826 | + | |
| 827 | + return snprintf(buf, PAGE_SIZE, "%s\n", | |
| 828 | + ata_lpm_policy_names[ap->target_lpm_policy]); | |
| 829 | +} | |
| 830 | +DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, | |
| 831 | + ata_scsi_lpm_show, ata_scsi_lpm_store); | |
| 832 | +EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); | |
| 833 | + | |
| 834 | +static ssize_t ata_ncq_prio_enable_show(struct device *device, | |
| 835 | + struct device_attribute *attr, | |
| 836 | + char *buf) | |
| 837 | +{ | |
| 838 | + struct scsi_device *sdev = to_scsi_device(device); | |
| 839 | + struct ata_port *ap; | |
| 840 | + struct ata_device *dev; | |
| 841 | + bool ncq_prio_enable; | |
| 842 | + int rc = 0; | |
| 843 | + | |
| 844 | + ap = ata_shost_to_port(sdev->host); | |
| 845 | + | |
| 846 | + spin_lock_irq(ap->lock); | |
| 847 | + dev = ata_scsi_find_dev(ap, sdev); | |
| 848 | + if (!dev) { | |
| 849 | + rc = -ENODEV; | |
| 850 | + goto unlock; | |
| 851 | + } | |
| 852 | + | |
| 853 | + ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE; | |
| 854 | + | |
| 855 | +unlock: | |
| 856 | + spin_unlock_irq(ap->lock); | |
| 857 | + | |
| 858 | + return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable); | |
| 859 | +} | |
| 860 | + | |
| 861 | +static ssize_t ata_ncq_prio_enable_store(struct device *device, | |
| 862 | + struct device_attribute *attr, | |
| 863 | + const char *buf, size_t len) | |
| 864 | +{ | |
| 865 | + struct scsi_device *sdev = to_scsi_device(device); | |
| 866 | + struct ata_port *ap; | |
| 867 | + struct ata_device *dev; | |
| 868 | + long int input; | |
| 869 | + int rc; | |
| 870 | + | |
| 871 | + rc = kstrtol(buf, 10, &input); | |
| 872 | + if (rc) | |
| 873 | + return rc; | |
| 874 | + if ((input < 0) || (input > 1)) | |
| 875 | + return -EINVAL; | |
| 876 | + | |
| 877 | + ap = ata_shost_to_port(sdev->host); | |
| 878 | + dev = ata_scsi_find_dev(ap, sdev); | |
| 879 | + if (unlikely(!dev)) | |
| 880 | + return -ENODEV; | |
| 881 | + | |
| 882 | + spin_lock_irq(ap->lock); | |
| 883 | + if (input) | |
| 884 | + dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE; | |
| 885 | + else | |
| 886 | + dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; | |
| 887 | + | |
| 888 | + dev->link->eh_info.action |= ATA_EH_REVALIDATE; | |
| 889 | + dev->link->eh_info.flags |= ATA_EHI_QUIET; | |
| 890 | + ata_port_schedule_eh(ap); | |
| 891 | + spin_unlock_irq(ap->lock); | |
| 892 | + | |
| 893 | + ata_port_wait_eh(ap); | |
| 894 | + | |
| 895 | + if (input) { | |
| 896 | + spin_lock_irq(ap->lock); | |
| 897 | + if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) { | |
| 898 | + dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; | |
| 899 | + rc = -EIO; | |
| 900 | + } | |
| 901 | + spin_unlock_irq(ap->lock); | |
| 902 | + } | |
| 903 | + | |
| 904 | + return rc ? rc : len; | |
| 905 | +} | |
| 906 | + | |
| 907 | +DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, | |
| 908 | + ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); | |
| 909 | +EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); | |
| 910 | + | |
| 911 | +struct device_attribute *ata_ncq_sdev_attrs[] = { | |
| 912 | + &dev_attr_unload_heads, | |
| 913 | + &dev_attr_ncq_prio_enable, | |
| 914 | + NULL | |
| 915 | +}; | |
| 916 | +EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); | |
| 917 | + | |
| 918 | +static ssize_t | |
| 919 | +ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, | |
| 920 | + const char *buf, size_t count) | |
| 921 | +{ | |
| 922 | + struct Scsi_Host *shost = class_to_shost(dev); | |
| 923 | + struct ata_port *ap = ata_shost_to_port(shost); | |
| 924 | + if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) | |
| 925 | + return ap->ops->em_store(ap, buf, count); | |
| 926 | + return -EINVAL; | |
| 927 | +} | |
| 928 | + | |
| 929 | +static ssize_t | |
| 930 | +ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, | |
| 931 | + char *buf) | |
| 932 | +{ | |
| 933 | + struct Scsi_Host *shost = class_to_shost(dev); | |
| 934 | + struct ata_port *ap = ata_shost_to_port(shost); | |
| 935 | + | |
| 936 | + if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) | |
| 937 | + return ap->ops->em_show(ap, buf); | |
| 938 | + return -EINVAL; | |
| 939 | +} | |
| 940 | +DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR, | |
| 941 | + ata_scsi_em_message_show, ata_scsi_em_message_store); | |
| 942 | +EXPORT_SYMBOL_GPL(dev_attr_em_message); | |
| 943 | + | |
| 944 | +static ssize_t | |
| 945 | +ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, | |
| 946 | + char *buf) | |
| 947 | +{ | |
| 948 | + struct Scsi_Host *shost = class_to_shost(dev); | |
| 949 | + struct ata_port *ap = ata_shost_to_port(shost); | |
| 950 | + | |
| 951 | + return snprintf(buf, 23, "%d\n", ap->em_message_type); | |
| 952 | +} | |
| 953 | +DEVICE_ATTR(em_message_type, S_IRUGO, | |
| 954 | + ata_scsi_em_message_type_show, NULL); | |
| 955 | +EXPORT_SYMBOL_GPL(dev_attr_em_message_type); | |
| 956 | + | |
| 957 | +static ssize_t | |
| 958 | +ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, | |
| 959 | + char *buf) | |
| 960 | +{ | |
| 961 | + struct scsi_device *sdev = to_scsi_device(dev); | |
| 962 | + struct ata_port *ap = ata_shost_to_port(sdev->host); | |
| 963 | + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); | |
| 964 | + | |
| 965 | + if (atadev && ap->ops->sw_activity_show && | |
| 966 | + (ap->flags & ATA_FLAG_SW_ACTIVITY)) | |
| 967 | + return ap->ops->sw_activity_show(atadev, buf); | |
| 968 | + return -EINVAL; | |
| 969 | +} | |
| 970 | + | |
| 971 | +static ssize_t | |
| 972 | +ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, | |
| 973 | + const char *buf, size_t count) | |
| 974 | +{ | |
| 975 | + struct scsi_device *sdev = to_scsi_device(dev); | |
| 976 | + struct ata_port *ap = ata_shost_to_port(sdev->host); | |
| 977 | + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); | |
| 978 | + enum sw_activity val; | |
| 979 | + int rc; | |
| 980 | + | |
| 981 | + if (atadev && ap->ops->sw_activity_store && | |
| 982 | + (ap->flags & ATA_FLAG_SW_ACTIVITY)) { | |
| 983 | + val = simple_strtoul(buf, NULL, 0); | |
| 984 | + switch (val) { | |
| 985 | + case OFF: case BLINK_ON: case BLINK_OFF: | |
| 986 | + rc = ap->ops->sw_activity_store(atadev, val); | |
| 987 | + if (!rc) | |
| 988 | + return count; | |
| 989 | + else | |
| 990 | + return rc; | |
| 991 | + } | |
| 992 | + } | |
| 993 | + return -EINVAL; | |
| 994 | +} | |
| 995 | +DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show, | |
| 996 | + ata_scsi_activity_store); | |
| 997 | +EXPORT_SYMBOL_GPL(dev_attr_sw_activity); | |
| 998 | + | |
| 999 | +/** | |
| 1000 | + * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth | |
| 1001 | + * @ap: ATA port to which the device change the queue depth | |
| 1002 | + * @sdev: SCSI device to configure queue depth for | |
| 1003 | + * @queue_depth: new queue depth | |
| 1004 | + * | |
| 1005 | + * libsas and libata have different approaches for associating a sdev to | |
| 1006 | + * its ata_port. | |
| 1007 | + * | |
| 1008 | + */ | |
| 1009 | +int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, | |
| 1010 | + int queue_depth) | |
| 1011 | +{ | |
| 1012 | + struct ata_device *dev; | |
| 1013 | + unsigned long flags; | |
| 1014 | + | |
| 1015 | + if (queue_depth < 1 || queue_depth == sdev->queue_depth) | |
| 1016 | + return sdev->queue_depth; | |
| 1017 | + | |
| 1018 | + dev = ata_scsi_find_dev(ap, sdev); | |
| 1019 | + if (!dev || !ata_dev_enabled(dev)) | |
| 1020 | + return sdev->queue_depth; | |
| 1021 | + | |
| 1022 | + /* NCQ enabled? */ | |
| 1023 | + spin_lock_irqsave(ap->lock, flags); | |
| 1024 | + dev->flags &= ~ATA_DFLAG_NCQ_OFF; | |
| 1025 | + if (queue_depth == 1 || !ata_ncq_enabled(dev)) { | |
| 1026 | + dev->flags |= ATA_DFLAG_NCQ_OFF; | |
| 1027 | + queue_depth = 1; | |
| 1028 | + } | |
| 1029 | + spin_unlock_irqrestore(ap->lock, flags); | |
| 1030 | + | |
| 1031 | + /* limit and apply queue depth */ | |
| 1032 | + queue_depth = min(queue_depth, sdev->host->can_queue); | |
| 1033 | + queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); | |
| 1034 | + queue_depth = min(queue_depth, ATA_MAX_QUEUE); | |
| 1035 | + | |
| 1036 | + if (sdev->queue_depth == queue_depth) | |
| 1037 | + return -EINVAL; | |
| 1038 | + | |
| 1039 | + return scsi_change_queue_depth(sdev, queue_depth); | |
| 1040 | +} | |
| 1041 | +EXPORT_SYMBOL_GPL(__ata_change_queue_depth); | |
| 1042 | + | |
| 1043 | +/** | |
| 1044 | + * ata_scsi_change_queue_depth - SCSI callback for queue depth config | |
| 1045 | + * @sdev: SCSI device to configure queue depth for | |
| 1046 | + * @queue_depth: new queue depth | |
| 1047 | + * | |
| 1048 | + * This is libata standard hostt->change_queue_depth callback. | |
| 1049 | + * SCSI will call into this callback when user tries to set queue | |
| 1050 | + * depth via sysfs. | |
| 1051 | + * | |
| 1052 | + * LOCKING: | |
| 1053 | + * SCSI layer (we don't care) | |
| 1054 | + * | |
| 1055 | + * RETURNS: | |
| 1056 | + * Newly configured queue depth. | |
| 1057 | + */ | |
| 1058 | +int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) | |
| 1059 | +{ | |
| 1060 | + struct ata_port *ap = ata_shost_to_port(sdev->host); | |
| 1061 | + | |
| 1062 | + return __ata_change_queue_depth(ap, sdev, queue_depth); | |
| 1063 | +} | |
| 1064 | +EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); | |
| @@ -46,8 +46,6 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, |
| 48 | 48 | const struct scsi_device *scsidev); |
| 49 | −static struct ata_device *ata_scsi_find_dev(struct ata_port *ap, | |
| 50 | − const struct scsi_device *scsidev); | |
| 51 | 49 | |
| 52 | 50 | #define RW_RECOVERY_MPAGE 0x1 |
| 53 | 51 | #define RW_RECOVERY_MPAGE_LEN 12 |
| @@ -87,71 +85,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { · 33 unmodified lines | ||
| 87 | 85 | 0, 30 /* extended self test time, see 05-359r1 */ |
| 88 | 86 | }; |
| 89 | 87 | |
| 90 | −static const char *ata_lpm_policy_names[] = { | |
| 91 | − [ATA_LPM_UNKNOWN] = "max_performance", | |
| 92 | − [ATA_LPM_MAX_POWER] = "max_performance", | |
| 93 | − [ATA_LPM_MED_POWER] = "medium_power", | |
| 94 | − [ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm", | |
| 95 | − [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial", | |
| 96 | − [ATA_LPM_MIN_POWER] = "min_power", | |
| 97 | −}; | |
| 98 | − | |
| 99 | −static ssize_t ata_scsi_lpm_store(struct device *device, | |
| 100 | − struct device_attribute *attr, | |
| 101 | − const char *buf, size_t count) | |
| 102 | −{ | |
| 103 | − struct Scsi_Host *shost = class_to_shost(device); | |
| 104 | − struct ata_port *ap = ata_shost_to_port(shost); | |
| 105 | − struct ata_link *link; | |
| 106 | − struct ata_device *dev; | |
| 107 | − enum ata_lpm_policy policy; | |
| 108 | − unsigned long flags; | |
| 109 | − | |
| 110 | − /* UNKNOWN is internal state, iterate from MAX_POWER */ | |
| 111 | − for (policy = ATA_LPM_MAX_POWER; | |
| 112 | − policy < ARRAY_SIZE(ata_lpm_policy_names); policy++) { | |
| 113 | − const char *name = ata_lpm_policy_names[policy]; | |
| 114 | − | |
| 115 | − if (strncmp(name, buf, strlen(name)) == 0) | |
| 116 | − break; | |
| 117 | − } | |
| 118 | − if (policy == ARRAY_SIZE(ata_lpm_policy_names)) | |
| 119 | − return -EINVAL; | |
| 120 | − | |
| 121 | − spin_lock_irqsave(ap->lock, flags); | |
| 122 | − | |
| 123 | − ata_for_each_link(link, ap, EDGE) { | |
| 124 | − ata_for_each_dev(dev, &ap->link, ENABLED) { | |
| 125 | − if (dev->horkage & ATA_HORKAGE_NOLPM) { | |
| 126 | − count = -EOPNOTSUPP; | |
| 127 | − goto out_unlock; | |
| 128 | − } | |
| 129 | − } | |
| 130 | − } | |
| 131 | − | |
| 132 | − ap->target_lpm_policy = policy; | |
| 133 | − ata_port_schedule_eh(ap); | |
| 134 | −out_unlock: | |
| 135 | − spin_unlock_irqrestore(ap->lock, flags); | |
| 136 | − return count; | |
| 137 | −} | |
| 138 | − | |
| 139 | −static ssize_t ata_scsi_lpm_show(struct device *dev, | |
| 140 | − struct device_attribute *attr, char *buf) | |
| 141 | −{ | |
| 142 | − struct Scsi_Host *shost = class_to_shost(dev); | |
| 143 | − struct ata_port *ap = ata_shost_to_port(shost); | |
| 144 | − | |
| 145 | − if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) | |
| 146 | − return -EINVAL; | |
| 147 | − | |
| 148 | − return snprintf(buf, PAGE_SIZE, "%s\n", | |
| 149 | − ata_lpm_policy_names[ap->target_lpm_policy]); | |
| 150 | −} | |
| 151 | −DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, | |
| 152 | − ata_scsi_lpm_show, ata_scsi_lpm_store); | |
| 153 | −EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); | |
| 154 | − | |
| 155 | 88 | static ssize_t ata_scsi_park_show(struct device *device, |
| 156 | 89 | struct device_attribute *attr, char *buf) |
| 157 | 90 | { |
| @@ -255,83 +188,6 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR, · 97 unmodified lines | ||
| 255 | 188 | ata_scsi_park_show, ata_scsi_park_store); |
| 256 | 189 | EXPORT_SYMBOL_GPL(dev_attr_unload_heads); |
| 257 | 190 | |
| 258 | −static ssize_t ata_ncq_prio_enable_show(struct device *device, | |
| 259 | − struct device_attribute *attr, | |
| 260 | − char *buf) | |
| 261 | −{ | |
| 262 | − struct scsi_device *sdev = to_scsi_device(device); | |
| 263 | − struct ata_port *ap; | |
| 264 | − struct ata_device *dev; | |
| 265 | − bool ncq_prio_enable; | |
| 266 | − int rc = 0; | |
| 267 | − | |
| 268 | − ap = ata_shost_to_port(sdev->host); | |
| 269 | − | |
| 270 | − spin_lock_irq(ap->lock); | |
| 271 | − dev = ata_scsi_find_dev(ap, sdev); | |
| 272 | − if (!dev) { | |
| 273 | − rc = -ENODEV; | |
| 274 | − goto unlock; | |
| 275 | − } | |
| 276 | − | |
| 277 | − ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE; | |
| 278 | − | |
| 279 | −unlock: | |
| 280 | − spin_unlock_irq(ap->lock); | |
| 281 | − | |
| 282 | − return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable); | |
| 283 | −} | |
| 284 | − | |
| 285 | −static ssize_t ata_ncq_prio_enable_store(struct device *device, | |
| 286 | − struct device_attribute *attr, | |
| 287 | − const char *buf, size_t len) | |
| 288 | −{ | |
| 289 | − struct scsi_device *sdev = to_scsi_device(device); | |
| 290 | − struct ata_port *ap; | |
| 291 | − struct ata_device *dev; | |
| 292 | − long int input; | |
| 293 | − int rc; | |
| 294 | − | |
| 295 | − rc = kstrtol(buf, 10, &input); | |
| 296 | − if (rc) | |
| 297 | − return rc; | |
| 298 | − if ((input < 0) || (input > 1)) | |
| 299 | − return -EINVAL; | |
| 300 | − | |
| 301 | − ap = ata_shost_to_port(sdev->host); | |
| 302 | − dev = ata_scsi_find_dev(ap, sdev); | |
| 303 | − if (unlikely(!dev)) | |
| 304 | − return -ENODEV; | |
| 305 | − | |
| 306 | − spin_lock_irq(ap->lock); | |
| 307 | − if (input) | |
| 308 | − dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE; | |
| 309 | − else | |
| 310 | − dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; | |
| 311 | − | |
| 312 | − dev->link->eh_info.action |= ATA_EH_REVALIDATE; | |
| 313 | − dev->link->eh_info.flags |= ATA_EHI_QUIET; | |
| 314 | − ata_port_schedule_eh(ap); | |
| 315 | − spin_unlock_irq(ap->lock); | |
| 316 | − | |
| 317 | − ata_port_wait_eh(ap); | |
| 318 | − | |
| 319 | − if (input) { | |
| 320 | − spin_lock_irq(ap->lock); | |
| 321 | − if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) { | |
| 322 | − dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; | |
| 323 | − rc = -EIO; | |
| 324 | − } | |
| 325 | − spin_unlock_irq(ap->lock); | |
| 326 | − } | |
| 327 | − | |
| 328 | − return rc ? rc : len; | |
| 329 | −} | |
| 330 | − | |
| 331 | −DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, | |
| 332 | − ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); | |
| 333 | −EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); | |
| 334 | − | |
| 335 | 191 | void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd, |
| 336 | 192 | u8 sk, u8 asc, u8 ascq) |
| 337 | 193 | { |
| @@ -380,100 +236,12 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev, · 42 unmodified lines | ||
| 380 | 236 | field, 0xff, 0); |
| 381 | 237 | } |
| 382 | 238 | |
| 383 | −static ssize_t | |
| 384 | −ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, | |
| 385 | − const char *buf, size_t count) | |
| 386 | −{ | |
| 387 | − struct Scsi_Host *shost = class_to_shost(dev); | |
| 388 | − struct ata_port *ap = ata_shost_to_port(shost); | |
| 389 | − if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) | |
| 390 | − return ap->ops->em_store(ap, buf, count); | |
| 391 | − return -EINVAL; | |
| 392 | −} | |
| 393 | − | |
| 394 | −static ssize_t | |
| 395 | −ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, | |
| 396 | − char *buf) | |
| 397 | −{ | |
| 398 | − struct Scsi_Host *shost = class_to_shost(dev); | |
| 399 | − struct ata_port *ap = ata_shost_to_port(shost); | |
| 400 | − | |
| 401 | − if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) | |
| 402 | − return ap->ops->em_show(ap, buf); | |
| 403 | − return -EINVAL; | |
| 404 | −} | |
| 405 | −DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR, | |
| 406 | − ata_scsi_em_message_show, ata_scsi_em_message_store); | |
| 407 | −EXPORT_SYMBOL_GPL(dev_attr_em_message); | |
| 408 | − | |
| 409 | −static ssize_t | |
| 410 | −ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, | |
| 411 | − char *buf) | |
| 412 | −{ | |
| 413 | − struct Scsi_Host *shost = class_to_shost(dev); | |
| 414 | − struct ata_port *ap = ata_shost_to_port(shost); | |
| 415 | − | |
| 416 | − return snprintf(buf, 23, "%d\n", ap->em_message_type); | |
| 417 | −} | |
| 418 | −DEVICE_ATTR(em_message_type, S_IRUGO, | |
| 419 | − ata_scsi_em_message_type_show, NULL); | |
| 420 | −EXPORT_SYMBOL_GPL(dev_attr_em_message_type); | |
| 421 | − | |
| 422 | −static ssize_t | |
| 423 | −ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, | |
| 424 | − char *buf) | |
| 425 | −{ | |
| 426 | − struct scsi_device *sdev = to_scsi_device(dev); | |
| 427 | − struct ata_port *ap = ata_shost_to_port(sdev->host); | |
| 428 | − struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); | |
| 429 | − | |
| 430 | − if (atadev && ap->ops->sw_activity_show && | |
| 431 | − (ap->flags & ATA_FLAG_SW_ACTIVITY)) | |
| 432 | − return ap->ops->sw_activity_show(atadev, buf); | |
| 433 | − return -EINVAL; | |
| 434 | −} | |
| 435 | − | |
| 436 | −static ssize_t | |
| 437 | −ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, | |
| 438 | − const char *buf, size_t count) | |
| 439 | −{ | |
| 440 | − struct scsi_device *sdev = to_scsi_device(dev); | |
| 441 | − struct ata_port *ap = ata_shost_to_port(sdev->host); | |
| 442 | − struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); | |
| 443 | − enum sw_activity val; | |
| 444 | − int rc; | |
| 445 | − | |
| 446 | − if (atadev && ap->ops->sw_activity_store && | |
| 447 | − (ap->flags & ATA_FLAG_SW_ACTIVITY)) { | |
| 448 | − val = simple_strtoul(buf, NULL, 0); | |
| 449 | − switch (val) { | |
| 450 | − case OFF: case BLINK_ON: case BLINK_OFF: | |
| 451 | − rc = ap->ops->sw_activity_store(atadev, val); | |
| 452 | − if (!rc) | |
| 453 | − return count; | |
| 454 | − else | |
| 455 | − return rc; | |
| 456 | − } | |
| 457 | − } | |
| 458 | − return -EINVAL; | |
| 459 | −} | |
| 460 | −DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show, | |
| 461 | − ata_scsi_activity_store); | |
| 462 | −EXPORT_SYMBOL_GPL(dev_attr_sw_activity); | |
| 463 | − | |
| 464 | 239 | struct device_attribute *ata_common_sdev_attrs[] = { |
| 465 | 240 | &dev_attr_unload_heads, |
| 466 | 241 | NULL |
| 467 | 242 | }; |
| 468 | 243 | EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); |
| 469 | 244 | |
| 470 | −struct device_attribute *ata_ncq_sdev_attrs[] = { | |
| 471 | − &dev_attr_unload_heads, | |
| 472 | − &dev_attr_ncq_prio_enable, | |
| 473 | − NULL | |
| 474 | −}; | |
| 475 | −EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); | |
| 476 | − | |
| 477 | 245 | /** |
| 478 | 246 | * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. |
| 479 | 247 | * @sdev: SCSI device for which BIOS geometry is to be determined |
| @@ -1391,73 +1159,6 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) · 911 unmodified lines | ||
| 1391 | 1159 | } |
| 1392 | 1160 | EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); |
| 1393 | 1161 | |
| 1394 | −/** | |
| 1395 | − * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth | |
| 1396 | − * @ap: ATA port to which the device change the queue depth | |
| 1397 | − * @sdev: SCSI device to configure queue depth for | |
| 1398 | − * @queue_depth: new queue depth | |
| 1399 | − * | |
| 1400 | − * libsas and libata have different approaches for associating a sdev to | |
| 1401 | − * its ata_port. | |
| 1402 | − * | |
| 1403 | − */ | |
| 1404 | −int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, | |
| 1405 | − int queue_depth) | |
| 1406 | −{ | |
| 1407 | − struct ata_device *dev; | |
| 1408 | − unsigned long flags; | |
| 1409 | − | |
| 1410 | − if (queue_depth < 1 || queue_depth == sdev->queue_depth) | |
| 1411 | − return sdev->queue_depth; | |
| 1412 | − | |
| 1413 | − dev = ata_scsi_find_dev(ap, sdev); | |
| 1414 | − if (!dev || !ata_dev_enabled(dev)) | |
| 1415 | − return sdev->queue_depth; | |
| 1416 | − | |
| 1417 | − /* NCQ enabled? */ | |
| 1418 | − spin_lock_irqsave(ap->lock, flags); | |
| 1419 | − dev->flags &= ~ATA_DFLAG_NCQ_OFF; | |
| 1420 | − if (queue_depth == 1 || !ata_ncq_enabled(dev)) { | |
| 1421 | − dev->flags |= ATA_DFLAG_NCQ_OFF; | |
| 1422 | − queue_depth = 1; | |
| 1423 | − } | |
| 1424 | − spin_unlock_irqrestore(ap->lock, flags); | |
| 1425 | − | |
| 1426 | − /* limit and apply queue depth */ | |
| 1427 | − queue_depth = min(queue_depth, sdev->host->can_queue); | |
| 1428 | − queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); | |
| 1429 | − queue_depth = min(queue_depth, ATA_MAX_QUEUE); | |
| 1430 | − | |
| 1431 | − if (sdev->queue_depth == queue_depth) | |
| 1432 | − return -EINVAL; | |
| 1433 | − | |
| 1434 | − return scsi_change_queue_depth(sdev, queue_depth); | |
| 1435 | −} | |
| 1436 | −EXPORT_SYMBOL_GPL(__ata_change_queue_depth); | |
| 1437 | − | |
| 1438 | −/** | |
| 1439 | − * ata_scsi_change_queue_depth - SCSI callback for queue depth config | |
| 1440 | − * @sdev: SCSI device to configure queue depth for | |
| 1441 | − * @queue_depth: new queue depth | |
| 1442 | − * | |
| 1443 | − * This is libata standard hostt->change_queue_depth callback. | |
| 1444 | − * SCSI will call into this callback when user tries to set queue | |
| 1445 | − * depth via sysfs. | |
| 1446 | − * | |
| 1447 | − * LOCKING: | |
| 1448 | − * SCSI layer (we don't care) | |
| 1449 | − * | |
| 1450 | − * RETURNS: | |
| 1451 | − * Newly configured queue depth. | |
| 1452 | − */ | |
| 1453 | −int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) | |
| 1454 | −{ | |
| 1455 | − struct ata_port *ap = ata_shost_to_port(sdev->host); | |
| 1456 | − | |
| 1457 | − return __ata_change_queue_depth(ap, sdev, queue_depth); | |
| 1458 | −} | |
| 1459 | −EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); | |
| 1460 | − | |
| 1461 | 1162 | /** |
| 1462 | 1163 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command |
| 1463 | 1164 | * @qc: Storage for translated ATA taskfile |
| @@ -3094,7 +2795,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, · 1630 unmodified lines | ||
| 3094 | 2795 | * RETURNS: |
| 3095 | 2796 | * Associated ATA device, or %NULL if not found. |
| 3096 | 2797 | */ |
| 3097 | −static struct ata_device * | |
| 2798 | +struct ata_device * | |
| 3098 | 2799 | ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) |
| 3099 | 2800 | { |
| 3100 | 2801 | struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev); |
| @@ -112,6 +112,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {} · 111 unmodified lines | ||
| 112 | 112 | #endif |
| 113 | 113 | |
| 114 | 114 | /* libata-scsi.c */ |
| 115 | +extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap, | |
| 116 | + const struct scsi_device *scsidev); | |
| 115 | 117 | extern int ata_scsi_add_hosts(struct ata_host *host, |
| 116 | 118 | struct scsi_host_template *sht); |
| 117 | 119 | extern void ata_scsi_scan_host(struct ata_port *ap, int sync); |
| @@ -530,12 +530,14 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes, · 529 unmodified lines | ||
| 530 | 530 | unsigned long deadline); |
| 531 | 531 | typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes); |
| 532 | 532 | |
| 533 | −extern struct device_attribute dev_attr_link_power_management_policy; | |
| 534 | 533 | extern struct device_attribute dev_attr_unload_heads; |
| 534 | +#ifdef CONFIG_SATA_HOST | |
| 535 | +extern struct device_attribute dev_attr_link_power_management_policy; | |
| 535 | 536 | extern struct device_attribute dev_attr_ncq_prio_enable; |
| 536 | 537 | extern struct device_attribute dev_attr_em_message_type; |
| 537 | 538 | extern struct device_attribute dev_attr_em_message; |
| 538 | 539 | extern struct device_attribute dev_attr_sw_activity; |
| 540 | +#endif | |
| 539 | 541 | |
| 540 | 542 | enum sw_activity { |
| 541 | 543 | OFF, |
| @@ -1371,7 +1373,6 @@ extern int ata_link_nr_enabled(struct ata_link *link); · 829 unmodified lines | ||
| 1371 | 1373 | extern const struct ata_port_operations ata_base_port_ops; |
| 1372 | 1374 | extern const struct ata_port_operations sata_port_ops; |
| 1373 | 1375 | extern struct device_attribute *ata_common_sdev_attrs[]; |
| 1374 | −extern struct device_attribute *ata_ncq_sdev_attrs[]; | |
| 1375 | 1376 | |
| 1376 | 1377 | /* |
| 1377 | 1378 | * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated |
| @@ -1399,10 +1400,14 @@ extern struct device_attribute *ata_ncq_sdev_attrs[]; · 21 unmodified lines | ||
| 1399 | 1400 | __ATA_BASE_SHT(drv_name), \ |
| 1400 | 1401 | .sdev_attrs = ata_common_sdev_attrs |
| 1401 | 1402 | |
| 1403 | +#ifdef CONFIG_SATA_HOST | |
| 1404 | +extern struct device_attribute *ata_ncq_sdev_attrs[]; | |
| 1405 | + | |
| 1402 | 1406 | #define ATA_NCQ_SHT(drv_name) \ |
| 1403 | 1407 | __ATA_BASE_SHT(drv_name), \ |
| 1404 | 1408 | .sdev_attrs = ata_ncq_sdev_attrs, \ |
| 1405 | 1409 | .change_queue_depth = ata_scsi_change_queue_depth |
| 1410 | +#endif | |
| 1406 | 1411 | |
| 1407 | 1412 | /* |
| 1408 | 1413 | * PMP helpers |