aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-01-29 06:31:33 -0500
committerJeff Garzik <jgarzik@redhat.com>2009-02-02 23:03:22 -0500
commita07d499b4759881db1359dd8812eecd00b0e0a28 (patch)
treeaaa5a5c95b64ab121ca89a71899abfe8837890f6 /drivers/ata/libata-core.c
parent99cf610aa4840d822cdc67d194b23b55010ca9bd (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.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 564c03c4ebb3..3c5965d56c47 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 */
2887int sata_down_spd_limit(struct ata_link *link) 2893int 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",