Commit 15a5551c authored by Alan Cox's avatar Alan Cox Committed by Jeff Garzik

libata: isolate and rework cable logic

Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent d21279f4
...@@ -3885,6 +3885,49 @@ static int ata_is_40wire(struct ata_device *dev) ...@@ -3885,6 +3885,49 @@ static int ata_is_40wire(struct ata_device *dev)
return ata_drive_40wire(dev->id); return ata_drive_40wire(dev->id);
} }
/**
* cable_is_40wire - 40/80/SATA decider
* @ap: port to consider
*
* This function encapsulates the policy for speed management
* in one place. At the moment we don't cache the result but
* there is a good case for setting ap->cbl to the result when
* we are called with unknown cables (and figuring out if it
* impacts hotplug at all).
*
* Return 1 if the cable appears to be 40 wire.
*/
static int cable_is_40wire(struct ata_port *ap)
{
struct ata_link *link;
struct ata_device *dev;
/* If the controller thinks we are 40 wire, we are */
if (ap->cbl == ATA_CBL_PATA40)
return 1;
/* If the controller thinks we are 80 wire, we are */
if (ap->cbl == ATA_CBL_PATA80 || ap->cbl == ATA_CBL_SATA)
return 0;
/* If the controller doesn't know we scan
- Note: We look for all 40 wire detects at this point.
Any 80 wire detect is taken to be 80 wire cable
because
- In many setups only the one drive (slave if present)
will give a valid detect
- If you have a non detect capable drive you don't
want it to colour the choice
*/
ata_port_for_each_link(link, ap) {
ata_link_for_each_dev(dev, link) {
if (!ata_is_40wire(dev))
return 0;
}
}
return 1;
}
/** /**
* ata_dev_xfermask - Compute supported xfermask of the given device * ata_dev_xfermask - Compute supported xfermask of the given device
* @dev: Device to compute xfermask for * @dev: Device to compute xfermask for
...@@ -3953,10 +3996,7 @@ static void ata_dev_xfermask(struct ata_device *dev) ...@@ -3953,10 +3996,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
*/ */
if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
/* UDMA/44 or higher would be available */ /* UDMA/44 or higher would be available */
if ((ap->cbl == ATA_CBL_PATA40) || if (cable_is_40wire(ap)) {
(ata_is_40wire(dev) &&
(ap->cbl == ATA_CBL_PATA_UNK ||
ap->cbl == ATA_CBL_PATA80))) {
ata_dev_printk(dev, KERN_WARNING, ata_dev_printk(dev, KERN_WARNING,
"limited to UDMA/33 due to 40-wire cable\n"); "limited to UDMA/33 due to 40-wire cable\n");
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment