|
@@ -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);
|