diff options
-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 54f85508bc6..9121cc443be 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) } /** + * 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 * @dev: Device to compute xfermask for * @@ -3953,10 +3996,7 @@ static void ata_dev_xfermask(struct ata_device *dev) */ if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) /* UDMA/44 or higher would be available */ - if ((ap->cbl == ATA_CBL_PATA40) || - (ata_is_40wire(dev) && - (ap->cbl == ATA_CBL_PATA_UNK || - ap->cbl == ATA_CBL_PATA80))) { + if (cable_is_40wire(ap)) { ata_dev_printk(dev, KERN_WARNING, "limited to UDMA/33 due to 40-wire cable\n"); xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); |