diff options
author | Tejun Heo <tj@kernel.org> | 2009-01-29 06:31:33 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-02-02 23:03:22 -0500 |
commit | a07d499b4759881db1359dd8812eecd00b0e0a28 (patch) | |
tree | aaa5a5c95b64ab121ca89a71899abfe8837890f6 /drivers/ata/libata-core.c | |
parent | 99cf610aa4840d822cdc67d194b23b55010ca9bd (diff) |
libata: add @spd_limit to sata_down_spd_limit()
Add @spd_limit to sata_down_spd_limit() so that the caller can specify
the SPD limit it wants. This parameter doesn't get in the way even
when it's too low. The closest possible limit is applied.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 564c03c4ebb..3c5965d56c4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2777,7 +2777,7 @@ int ata_bus_probe(struct ata_port *ap) | |||
2777 | /* This is the last chance, better to slow | 2777 | /* This is the last chance, better to slow |
2778 | * down than lose it. | 2778 | * down than lose it. |
2779 | */ | 2779 | */ |
2780 | sata_down_spd_limit(&ap->link); | 2780 | sata_down_spd_limit(&ap->link, 0); |
2781 | ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); | 2781 | ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); |
2782 | } | 2782 | } |
2783 | } | 2783 | } |
@@ -2873,21 +2873,27 @@ void ata_port_disable(struct ata_port *ap) | |||
2873 | /** | 2873 | /** |
2874 | * sata_down_spd_limit - adjust SATA spd limit downward | 2874 | * sata_down_spd_limit - adjust SATA spd limit downward |
2875 | * @link: Link to adjust SATA spd limit for | 2875 | * @link: Link to adjust SATA spd limit for |
2876 | * @spd_limit: Additional limit | ||
2876 | * | 2877 | * |
2877 | * Adjust SATA spd limit of @link downward. Note that this | 2878 | * Adjust SATA spd limit of @link downward. Note that this |
2878 | * function only adjusts the limit. The change must be applied | 2879 | * function only adjusts the limit. The change must be applied |
2879 | * using sata_set_spd(). | 2880 | * using sata_set_spd(). |
2880 | * | 2881 | * |
2882 | * If @spd_limit is non-zero, the speed is limited to equal to or | ||
2883 | * lower than @spd_limit if such speed is supported. If | ||
2884 | * @spd_limit is slower than any supported speed, only the lowest | ||
2885 | * supported speed is allowed. | ||
2886 | * | ||
2881 | * LOCKING: | 2887 | * LOCKING: |
2882 | * Inherited from caller. | 2888 | * Inherited from caller. |
2883 | * | 2889 | * |
2884 | * RETURNS: | 2890 | * RETURNS: |
2885 | * 0 on success, negative errno on failure | 2891 | * 0 on success, negative errno on failure |
2886 | */ | 2892 | */ |
2887 | int sata_down_spd_limit(struct ata_link *link) | 2893 | int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) |
2888 | { | 2894 | { |
2889 | u32 sstatus, spd, mask; | 2895 | u32 sstatus, spd, mask; |
2890 | int rc, highbit; | 2896 | int rc, bit; |
2891 | 2897 | ||
2892 | if (!sata_scr_valid(link)) | 2898 | if (!sata_scr_valid(link)) |
2893 | return -EOPNOTSUPP; | 2899 | return -EOPNOTSUPP; |
@@ -2906,8 +2912,8 @@ int sata_down_spd_limit(struct ata_link *link) | |||
2906 | return -EINVAL; | 2912 | return -EINVAL; |
2907 | 2913 | ||
2908 | /* unconditionally mask off the highest bit */ | 2914 | /* unconditionally mask off the highest bit */ |
2909 | highbit = fls(mask) - 1; | 2915 | bit = fls(mask) - 1; |
2910 | mask &= ~(1 << highbit); | 2916 | mask &= ~(1 << bit); |
2911 | 2917 | ||
2912 | /* Mask off all speeds higher than or equal to the current | 2918 | /* Mask off all speeds higher than or equal to the current |
2913 | * one. Force 1.5Gbps if current SPD is not available. | 2919 | * one. Force 1.5Gbps if current SPD is not available. |
@@ -2921,6 +2927,15 @@ int sata_down_spd_limit(struct ata_link *link) | |||
2921 | if (!mask) | 2927 | if (!mask) |
2922 | return -EINVAL; | 2928 | return -EINVAL; |
2923 | 2929 | ||
2930 | if (spd_limit) { | ||
2931 | if (mask & ((1 << spd_limit) - 1)) | ||
2932 | mask &= (1 << spd_limit) - 1; | ||
2933 | else { | ||
2934 | bit = ffs(mask) - 1; | ||
2935 | mask = 1 << bit; | ||
2936 | } | ||
2937 | } | ||
2938 | |||
2924 | link->sata_spd_limit = mask; | 2939 | link->sata_spd_limit = mask; |
2925 | 2940 | ||
2926 | ata_link_printk(link, KERN_WARNING, "limiting SATA link speed to %s\n", | 2941 | ata_link_printk(link, KERN_WARNING, "limiting SATA link speed to %s\n", |