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>
This commit is contained in:
Alan Cox 2008-03-28 14:33:46 -07:00 committed by Jeff Garzik
parent d21279f412
commit 15a5551c84

View File

@ -3885,6 +3885,49 @@ static int ata_is_40wire(struct ata_device *dev)
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
* @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);