Commit 5a3b583f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ata fixes from Niklas Cassel:

 - Force PIO for ATAPI devices on VT6415/VT6330 as the controller locks
   up on ATAPI DMA (Tasos)

 - Fix ACPI PATA cable type detection such that the controller is not
   forced down to a slow transfer mode (Tasos)

 - Fix build error on 32-bit UML (Johannes)

 - Fix a PCI region leak in the pata_macio driver so that the driver no
   longer fails to load after rmmod (Philipp)

 - Use correct DMI BIOS build date for ThinkPad W541 quirk (me)

 - Disallow LPM for ASUSPRO-D840SA motherboard as this board
   interestingly enough gets graphical corruptions on the iGPU when LPM
   is enabled (me)

 - Disallow LPM for Asus B550-F motherboard as this board will get
   command timeouts on ports 5 and 6, yet LPM with the same drive works
   fine on all other ports (Mikko)

* tag 'ata-6.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux:
  ata: ahci: Disallow LPM for Asus B550-F motherboard
  ata: ahci: Disallow LPM for ASUSPRO-D840SA motherboard
  ata: ahci: Use correct BIOS build date for ThinkPad W541 quirk
  ata: pata_macio: Fix PCI region leak
  ata: pata_cs5536: fix build on 32-bit UML
  ata: libata-acpi: Do not assume 40 wire cable if no devices are enabled
  ata: pata_via: Force PIO for ATAPI devices on VT6415/VT6330
parents 52da431b a7b3b77f
Loading
Loading
Loading
Loading
+33 −6
Original line number Diff line number Diff line
@@ -1410,8 +1410,15 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)

static bool ahci_broken_lpm(struct pci_dev *pdev)
{
	/*
	 * Platforms with LPM problems.
	 * If driver_data is NULL, there is no existing BIOS version with
	 * functioning LPM.
	 * If driver_data is non-NULL, then driver_data contains the DMI BIOS
	 * build date of the first BIOS version with functioning LPM (i.e. older
	 * BIOS versions have broken LPM).
	 */
	static const struct dmi_system_id sysids[] = {
		/* Various Lenovo 50 series have LPM issues with older BIOSen */
		{
			.matches = {
				DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
@@ -1438,13 +1445,30 @@ static bool ahci_broken_lpm(struct pci_dev *pdev)
				DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
				DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W541"),
			},
			.driver_data = "20180409", /* 2.35 */
		},
		{
			.matches = {
				DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
				DMI_MATCH(DMI_PRODUCT_VERSION, "ASUSPRO D840MB_M840SA"),
			},
			/* 320 is broken, there is no known good version. */
		},
		{
			/*
			 * Note date based on release notes, 2.35 has been
			 * reported to be good, but I've been unable to get
			 * a hold of the reporter to get the DMI BIOS date.
			 * TODO: fix this.
			 * AMD 500 Series Chipset SATA Controller [1022:43eb]
			 * on this motherboard timeouts on ports 5 and 6 when
			 * LPM is enabled, at least with WDC WD20EFAX-68FB5N0
			 * hard drives. LPM with the same drive works fine on
			 * all other ports on the same controller.
			 */
			.driver_data = "20180310", /* 2.35 */
			.matches = {
				DMI_MATCH(DMI_BOARD_VENDOR,
					  "ASUSTeK COMPUTER INC."),
				DMI_MATCH(DMI_BOARD_NAME,
					  "ROG STRIX B550-F GAMING (WI-FI)"),
			},
			/* 3621 is broken, there is no known good version. */
		},
		{ }	/* terminate list */
	};
@@ -1455,6 +1479,9 @@ static bool ahci_broken_lpm(struct pci_dev *pdev)
	if (!dmi)
		return false;

	if (!dmi->driver_data)
		return true;

	dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
	snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);

+16 −8
Original line number Diff line number Diff line
@@ -514,15 +514,19 @@ unsigned int ata_acpi_gtm_xfermask(struct ata_device *dev,
EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask);

/**
 * ata_acpi_cbl_80wire		-	Check for 80 wire cable
 * ata_acpi_cbl_pata_type - Return PATA cable type
 * @ap: Port to check
 * @gtm: GTM data to use
 *
 * Return 1 if the @gtm indicates the BIOS selected an 80wire mode.
 * Return ATA_CBL_PATA* according to the transfer mode selected by BIOS
 */
int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm)
int ata_acpi_cbl_pata_type(struct ata_port *ap)
{
	struct ata_device *dev;
	int ret = ATA_CBL_PATA_UNK;
	const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);

	if (!gtm)
		return ATA_CBL_PATA40;

	ata_for_each_dev(dev, &ap->link, ENABLED) {
		unsigned int xfer_mask, udma_mask;
@@ -530,13 +534,17 @@ 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 = ATA_CBL_PATA40;

		if (udma_mask & ~ATA_UDMA_MASK_40C) {
			ret = ATA_CBL_PATA80;
			break;
		}
	}

	return 0;
	return ret;
}
EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
EXPORT_SYMBOL_GPL(ata_acpi_cbl_pata_type);

static void ata_acpi_gtf_to_tf(struct ata_device *dev,
			       const struct ata_acpi_gtf *gtf,
+1 −1
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@
#include <scsi/scsi_host.h>
#include <linux/dmi.h>

#ifdef CONFIG_X86_32
#if defined(CONFIG_X86) && defined(CONFIG_X86_32)
#include <asm/msr.h>
static int use_msr;
module_param_named(msr, use_msr, int, 0644);
+1 −1
Original line number Diff line number Diff line
@@ -1298,7 +1298,7 @@ static int pata_macio_pci_attach(struct pci_dev *pdev,
	priv->dev = &pdev->dev;

	/* Get MMIO regions */
	if (pci_request_regions(pdev, "pata-macio")) {
	if (pcim_request_all_regions(pdev, "pata-macio")) {
		dev_err(&pdev->dev,
			"Cannot obtain PCI resources\n");
		return -EBUSY;
+4 −5
Original line number Diff line number Diff line
@@ -201,11 +201,9 @@ static int via_cable_detect(struct ata_port *ap) {
	   two drives */
	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;
	return ATA_CBL_PATA40;
	return ata_acpi_cbl_pata_type(ap);
}

static int via_pre_reset(struct ata_link *link, unsigned long deadline)
@@ -368,7 +366,8 @@ static unsigned int via_mode_filter(struct ata_device *dev, unsigned int mask)
	}

	if (dev->class == ATA_DEV_ATAPI &&
	    dmi_check_system(no_atapi_dma_dmi_table)) {
	    (dmi_check_system(no_atapi_dma_dmi_table) ||
	     config->id == PCI_DEVICE_ID_VIA_6415)) {
		ata_dev_warn(dev, "controller locks up on ATAPI DMA, forcing PIO\n");
		mask &= ATA_MASK_PIO;
	}
Loading