aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/ata/libata-core.c25
-rw-r--r--drivers/ata/libata-eh.c10
-rw-r--r--drivers/ata/libata-pmp.c2
-rw-r--r--drivers/ata/libata.h2
4 files changed, 27 insertions, 12 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",
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 90092c1aae53..685509bc7ff0 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1875,7 +1875,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
1875 /* speed down? */ 1875 /* speed down? */
1876 if (verdict & ATA_EH_SPDN_SPEED_DOWN) { 1876 if (verdict & ATA_EH_SPDN_SPEED_DOWN) {
1877 /* speed down SATA link speed if possible */ 1877 /* speed down SATA link speed if possible */
1878 if (sata_down_spd_limit(link) == 0) { 1878 if (sata_down_spd_limit(link, 0) == 0) {
1879 action |= ATA_EH_RESET; 1879 action |= ATA_EH_RESET;
1880 goto done; 1880 goto done;
1881 } 1881 }
@@ -2627,11 +2627,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
2627 } 2627 }
2628 2628
2629 if (try == max_tries - 1) { 2629 if (try == max_tries - 1) {
2630 sata_down_spd_limit(link); 2630 sata_down_spd_limit(link, 0);
2631 if (slave) 2631 if (slave)
2632 sata_down_spd_limit(slave); 2632 sata_down_spd_limit(slave, 0);
2633 } else if (rc == -EPIPE) 2633 } else if (rc == -EPIPE)
2634 sata_down_spd_limit(failed_link); 2634 sata_down_spd_limit(failed_link, 0);
2635 2635
2636 if (hardreset) 2636 if (hardreset)
2637 reset = hardreset; 2637 reset = hardreset;
@@ -3011,7 +3011,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
3011 /* This is the last chance, better to slow 3011 /* This is the last chance, better to slow
3012 * down than lose it. 3012 * down than lose it.
3013 */ 3013 */
3014 sata_down_spd_limit(ata_dev_phys_link(dev)); 3014 sata_down_spd_limit(ata_dev_phys_link(dev), 0);
3015 if (dev->pio_mode > XFER_PIO_0) 3015 if (dev->pio_mode > XFER_PIO_0)
3016 ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); 3016 ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
3017 } 3017 }
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 98ca07a2db87..619f2c33950e 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -729,7 +729,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
729 if (tries) { 729 if (tries) {
730 /* consecutive revalidation failures? speed down */ 730 /* consecutive revalidation failures? speed down */
731 if (reval_failed) 731 if (reval_failed)
732 sata_down_spd_limit(link); 732 sata_down_spd_limit(link, 0);
733 else 733 else
734 reval_failed = 1; 734 reval_failed = 1;
735 735
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 0a6f5be15112..cea8014cd87e 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -99,7 +99,7 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
99extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, 99extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
100 unsigned int readid_flags); 100 unsigned int readid_flags);
101extern int ata_dev_configure(struct ata_device *dev); 101extern int ata_dev_configure(struct ata_device *dev);
102extern int sata_down_spd_limit(struct ata_link *link); 102extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
103extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); 103extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
104extern void ata_sg_clean(struct ata_queued_cmd *qc); 104extern void ata_sg_clean(struct ata_queued_cmd *qc);
105extern void ata_qc_free(struct ata_queued_cmd *qc); 105extern void ata_qc_free(struct ata_queued_cmd *qc);