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

Commit fdd324aa authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull libata fixes from Tejun Heo:
 "Dan updated tag allocation to accomodate devices which choke when tags
  jump back and forth.  Quite a few ahci MSI related fixes.  A couple
  config dependency fixes and other misc fixes"

* 'for-3.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
  libata/ahci: accommodate tag ordered controllers
  ahci: Do not receive interrupts sent by dummy ports
  ahci: Use pci_enable_msi_exact() instead of pci_enable_msi_range()
  ahci: Ensure "MSI Revert to Single Message" mode is not enforced
  ahci: do not request irq for dummy port
  pata_samsung_cf: fix ata_host_activate() failure handling
  pata_arasan_cf: fix ata_host_activate() failure handling
  ata: fix i.MX AHCI driver dependencies
  pata_at91: fix ata_host_activate() failure handling
  libata: Update queued trim blacklist for M5x0 drives
  libata: make AHCI_XGENE depend on PHY_XGENE
parents db725c88 8a4aeec8
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ config AHCI_ST

config AHCI_IMX
	tristate "Freescale i.MX AHCI SATA support"
	depends on MFD_SYSCON
	depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST)
	help
	  This option enables support for the Freescale i.MX SoC's
	  onboard AHCI SATA.
@@ -134,8 +134,7 @@ config AHCI_SUNXI

config AHCI_XGENE
	tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support"
	depends on ARM64 || COMPILE_TEST
	select PHY_XGENE
	depends on PHY_XGENE
	help
	 This option enables support for APM X-Gene SoC SATA host controller.

+21 −14
Original line number Diff line number Diff line
@@ -1166,7 +1166,7 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host)
static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
				struct ahci_host_priv *hpriv)
{
	int nvec;
	int rc, nvec;

	if (hpriv->flags & AHCI_HFLAG_NO_MSI)
		goto intx;
@@ -1183,12 +1183,19 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
	if (nvec < n_ports)
		goto single_msi;

	nvec = pci_enable_msi_range(pdev, nvec, nvec);
	if (nvec == -ENOSPC)
	rc = pci_enable_msi_exact(pdev, nvec);
	if (rc == -ENOSPC)
		goto single_msi;
	else if (nvec < 0)
	else if (rc < 0)
		goto intx;

	/* fallback to single MSI mode if the controller enforced MRSM mode */
	if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) {
		pci_disable_msi(pdev);
		printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n");
		goto single_msi;
	}

	return nvec;

single_msi:
@@ -1232,18 +1239,18 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis)
		return rc;

	for (i = 0; i < host->n_ports; i++) {
		const char* desc;
		struct ahci_port_priv *pp = host->ports[i]->private_data;

		/* pp is NULL for dummy ports */
		if (pp)
			desc = pp->irq_desc;
		else
			desc = dev_driver_string(host->dev);
		/* Do not receive interrupts sent by dummy ports */
		if (!pp) {
			disable_irq(irq + i);
			continue;
		}

		rc = devm_request_threaded_irq(host->dev,
			irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED,
			desc, host->ports[i]);
		rc = devm_request_threaded_irq(host->dev, irq + i,
					       ahci_hw_interrupt,
					       ahci_thread_fn, IRQF_SHARED,
					       pp->irq_desc, host->ports[i]);
		if (rc)
			goto out_free_irqs;
	}
+1 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ enum {
	/* HOST_CTL bits */
	HOST_RESET		= (1 << 0),  /* reset controller; self-clear */
	HOST_IRQ_EN		= (1 << 1),  /* global IRQ enable */
	HOST_MRSM		= (1 << 2),  /* MSI Revert to Single Message */
	HOST_AHCI_EN		= (1 << 31), /* AHCI enabled */

	/* HOST_CAP bits */
+17 −10
Original line number Diff line number Diff line
@@ -4224,8 +4224,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
	{ "PIONEER DVD-RW  DVR-216D",	NULL,	ATA_HORKAGE_NOSETXFER },

	/* devices that don't properly handle queued TRIM commands */
	{ "Micron_M500*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM, },
	{ "Crucial_CT???M500SSD*",	NULL,	ATA_HORKAGE_NO_NCQ_TRIM, },
	{ "Micron_M500*",		"MU0[1-4]*",	ATA_HORKAGE_NO_NCQ_TRIM, },
	{ "Crucial_CT???M500SSD*",	"MU0[1-4]*",	ATA_HORKAGE_NO_NCQ_TRIM, },
	{ "Micron_M550*",		NULL,		ATA_HORKAGE_NO_NCQ_TRIM, },
	{ "Crucial_CT???M550SSD*",	NULL,		ATA_HORKAGE_NO_NCQ_TRIM, },

	/*
	 * Some WD SATA-I drives spin up and down erratically when the link
@@ -4792,21 +4794,26 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
{
	struct ata_queued_cmd *qc = NULL;
	unsigned int i;
	unsigned int i, tag;

	/* no command while frozen */
	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
		return NULL;

	for (i = 0; i < ATA_MAX_QUEUE; i++) {
		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;

		/* the last tag is reserved for internal command. */
	for (i = 0; i < ATA_MAX_QUEUE - 1; i++)
		if (!test_and_set_bit(i, &ap->qc_allocated)) {
			qc = __ata_qc_from_tag(ap, i);
		if (tag == ATA_TAG_INTERNAL)
			continue;

		if (!test_and_set_bit(tag, &ap->qc_allocated)) {
			qc = __ata_qc_from_tag(ap, tag);
			qc->tag = tag;
			ap->last_tag = tag;
			break;
		}

	if (qc)
		qc->tag = i;
	}

	return qc;
}
+5 −2
Original line number Diff line number Diff line
@@ -898,9 +898,12 @@ static int arasan_cf_probe(struct platform_device *pdev)

	cf_card_detect(acdev, 0);

	return ata_host_activate(host, acdev->irq, irq_handler, 0,
	ret = ata_host_activate(host, acdev->irq, irq_handler, 0,
				&arasan_cf_sht);
	if (!ret)
		return 0;

	cf_exit(acdev);
free_clk:
	clk_put(acdev->clk);
	return ret;
Loading