diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2008-03-28 17:33:46 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-17 15:44:19 -0400 |
commit | 15a5551c847c8787d6cd75b8cf7682cd6d642e1b (patch) | |
tree | 8a48f734a41b4856448d4c715d572fb6057b68cc /drivers/ata | |
parent | d21279f4125893c63ec285962e1f2164b4d71117 (diff) |
libata: isolate and rework cable logic
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 54f85508bc6e..9121cc443be8 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -3886,6 +3886,49 @@ static int ata_is_40wire(struct ata_device *dev) | |||
3886 | } | 3886 | } |
3887 | 3887 | ||
3888 | /** | 3888 | /** |
3889 | * cable_is_40wire - 40/80/SATA decider | ||
3890 | * @ap: port to consider | ||
3891 | * | ||
3892 | * This function encapsulates the policy for speed management | ||
3893 | * in one place. At the moment we don't cache the result but | ||
3894 | * there is a good case for setting ap->cbl to the result when | ||
3895 | * we are called with unknown cables (and figuring out if it | ||
3896 | * impacts hotplug at all). | ||
3897 | * | ||
3898 | * Return 1 if the cable appears to be 40 wire. | ||
3899 | */ | ||
3900 | |||
3901 | static int cable_is_40wire(struct ata_port *ap) | ||
3902 | { | ||
3903 | struct ata_link *link; | ||
3904 | struct ata_device *dev; | ||
3905 | |||
3906 | /* If the controller thinks we are 40 wire, we are */ | ||
3907 | if (ap->cbl == ATA_CBL_PATA40) | ||
3908 | return 1; | ||
3909 | /* If the controller thinks we are 80 wire, we are */ | ||
3910 | if (ap->cbl == ATA_CBL_PATA80 || ap->cbl == ATA_CBL_SATA) | ||
3911 | return 0; | ||
3912 | /* If the controller doesn't know we scan | ||
3913 | |||
3914 | - Note: We look for all 40 wire detects at this point. | ||
3915 | Any 80 wire detect is taken to be 80 wire cable | ||
3916 | because | ||
3917 | - In many setups only the one drive (slave if present) | ||
3918 | will give a valid detect | ||
3919 | - If you have a non detect capable drive you don't | ||
3920 | want it to colour the choice | ||
3921 | */ | ||
3922 | ata_port_for_each_link(link, ap) { | ||
3923 | ata_link_for_each_dev(dev, link) { | ||
3924 | if (!ata_is_40wire(dev)) | ||
3925 | return 0; | ||
3926 | } | ||
3927 | } | ||
3928 | return 1; | ||
3929 | } | ||
3930 | |||
3931 | /** | ||
3889 | * ata_dev_xfermask - Compute supported xfermask of the given device | 3932 | * ata_dev_xfermask - Compute supported xfermask of the given device |
3890 | * @dev: Device to compute xfermask for | 3933 | * @dev: Device to compute xfermask for |
3891 | * | 3934 | * |
@@ -3953,10 +3996,7 @@ static void ata_dev_xfermask(struct ata_device *dev) | |||
3953 | */ | 3996 | */ |
3954 | if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) | 3997 | if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) |
3955 | /* UDMA/44 or higher would be available */ | 3998 | /* UDMA/44 or higher would be available */ |
3956 | if ((ap->cbl == ATA_CBL_PATA40) || | 3999 | if (cable_is_40wire(ap)) { |
3957 | (ata_is_40wire(dev) && | ||
3958 | (ap->cbl == ATA_CBL_PATA_UNK || | ||
3959 | ap->cbl == ATA_CBL_PATA80))) { | ||
3960 | ata_dev_printk(dev, KERN_WARNING, | 4000 | ata_dev_printk(dev, KERN_WARNING, |
3961 | "limited to UDMA/33 due to 40-wire cable\n"); | 4001 | "limited to UDMA/33 due to 40-wire cable\n"); |
3962 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); | 4002 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); |