On at least an ASRock 990FX Extreme 4 with a VIA VT6330, the devices have not yet been enabled by the first time ata_acpi_cbl_80wire() is called. This means that the ata_for_each_dev loop is never entered, and a 40 wire cable is assumed. The VIA controller on this board does not report the cable in the PCI config space, thus having to fall back to ACPI even though no SATA bridge is present. The _GTM values are correctly reported by the firmware through ACPI, which has already set up faster transfer modes, but due to the above the controller is forced down to a maximum of UDMA/33. Resolve this by returning EAGAIN in ata_acpi_cbl_80wire() if no devices have been detected and modify pata_via to handle this scenario. First, an unknown cable is assumed which preserves the mode set by the firmware, and then on subsequent calls when the devices have been enabled, an 80 wire cable is correctly detected. Signed-off-by: Tasos Sahanidis <tasos@xxxxxxxxxxxx> --- drivers/ata/libata-acpi.c | 11 ++++++++--- drivers/ata/pata_via.c | 13 ++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index b7f0bf795521..c508a19c2495 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -523,6 +523,7 @@ EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask); int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm) { struct ata_device *dev; + int ret = -EAGAIN; ata_for_each_dev(dev, &ap->link, ENABLED) { unsigned int xfer_mask, udma_mask; @@ -530,11 +531,15 @@ int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm) xfer_mask = ata_acpi_gtm_xfermask(dev, gtm); ata_unpack_xfermask(xfer_mask, NULL, NULL, &udma_mask); - if (udma_mask & ~ATA_UDMA_MASK_40C) - return 1; + ret = 0; + + if (udma_mask & ~ATA_UDMA_MASK_40C) { + ret = 1; + break; + } } - return 0; + return ret; } EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 696b99720dcb..4d03b4a1ea4d 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -182,6 +182,7 @@ static int via_cable_detect(struct ata_port *ap) { const struct via_isa_bridge *config = ap->host->private_data; struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 ata66; + const struct ata_acpi_gtm *gtm; if (via_cable_override(pdev)) return ATA_CBL_PATA40_SHORT; @@ -202,9 +203,15 @@ static int via_cable_detect(struct ata_port *ap) { if (ata66 & (0x10100000 >> (16 * ap->port_no))) return ATA_CBL_PATA80; /* Check with ACPI so we can spot BIOS reported SATA bridges */ - if (ata_acpi_init_gtm(ap) && - ata_acpi_cbl_80wire(ap, ata_acpi_init_gtm(ap))) - return ATA_CBL_PATA80; + gtm = ata_acpi_init_gtm(ap); + if (gtm) { + int cbl = ata_acpi_cbl_80wire(ap, gtm); + + if (cbl < 0) + return ATA_CBL_PATA_UNK; + else if (cbl == 1) + return ATA_CBL_PATA80; + } return ATA_CBL_PATA40; } -- 2.43.0