Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+44 −4
Original line number Diff line number Diff line
@@ -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);