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

Commit 9256a2d0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  ahci: add workaround for on-board 5723s on some gigabyte boards
  ahci: Soften up the dmesg on SB600 PMP softreset failure recovery
  Documentation/kernel-parameters.txt: document libata's ignore_hpa option
  sata_nv: MSI support, disabled by default
  libata: OCZ Vertex can't do HPA
  pata_atiixp: fix second channel support
  pata_at91: fix resource release
parents 1ae88b2e 5594639a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1116,6 +1116,10 @@ and is between 256 and 4096 characters. It is defined in the file
			Combinations also work, so libata.dma=3 enables DMA
			for disks and CDROMs, but not CFs.
	
	libata.ignore_hpa=	[LIBATA] Ignore HPA limit
			libata.ignore_hpa=0	  keep BIOS limits (default)
			libata.ignore_hpa=1	  ignore limits, using full disk

	libata.noacpi	[LIBATA] Disables use of ACPI in libata suspend/resume
			when set.
			Format: <int>
+74 −5
Original line number Diff line number Diff line
@@ -219,6 +219,8 @@ enum {
	AHCI_HFLAG_SECT255		= (1 << 8), /* max 255 sectors */
	AHCI_HFLAG_YES_NCQ		= (1 << 9), /* force NCQ cap on */
	AHCI_HFLAG_NO_SUSPEND		= (1 << 10), /* don't suspend */
	AHCI_HFLAG_SRST_TOUT_IS_OFFLINE	= (1 << 11), /* treat SRST timeout as
							link offline */

	/* ap->flags bits */

@@ -1663,6 +1665,7 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
			     int (*check_ready)(struct ata_link *link))
{
	struct ata_port *ap = link->ap;
	struct ahci_host_priv *hpriv = ap->host->private_data;
	const char *reason = NULL;
	unsigned long now, msecs;
	struct ata_taskfile tf;
@@ -1701,11 +1704,20 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,

	/* wait for link to become ready */
	rc = ata_wait_after_reset(link, deadline, check_ready);
	if (rc == -EBUSY && hpriv->flags & AHCI_HFLAG_SRST_TOUT_IS_OFFLINE) {
		/*
		 * Workaround for cases where link online status can't
		 * be trusted.  Treat device readiness timeout as link
		 * offline.
		 */
		ata_link_printk(link, KERN_INFO,
				"device not ready, treating as offline\n");
		*class = ATA_DEV_NONE;
	} else if (rc) {
		/* link occupied, -ENODEV too is an error */
	if (rc) {
		reason = "device not ready";
		goto fail;
	}
	} else
		*class = ahci_dev_classify(ap);

	DPRINTK("EXIT, class=%u\n", *class);
@@ -1773,7 +1785,8 @@ static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class,
		irq_sts = readl(port_mmio + PORT_IRQ_STAT);
		if (irq_sts & PORT_IRQ_BAD_PMP) {
			ata_link_printk(link, KERN_WARNING,
					"failed due to HW bug, retry pmp=0\n");
					"applying SB600 PMP SRST workaround "
					"and retrying\n");
			rc = ahci_do_softreset(link, class, 0, deadline,
					       ahci_check_ready);
		}
@@ -2726,6 +2739,56 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
	return !ver || strcmp(ver, dmi->driver_data) < 0;
}

static bool ahci_broken_online(struct pci_dev *pdev)
{
#define ENCODE_BUSDEVFN(bus, slot, func)			\
	(void *)(unsigned long)(((bus) << 8) | PCI_DEVFN((slot), (func)))
	static const struct dmi_system_id sysids[] = {
		/*
		 * There are several gigabyte boards which use
		 * SIMG5723s configured as hardware RAID.  Certain
		 * 5723 firmware revisions shipped there keep the link
		 * online but fail to answer properly to SRST or
		 * IDENTIFY when no device is attached downstream
		 * causing libata to retry quite a few times leading
		 * to excessive detection delay.
		 *
		 * As these firmwares respond to the second reset try
		 * with invalid device signature, considering unknown
		 * sig as offline works around the problem acceptably.
		 */
		{
			.ident = "EP45-DQ6",
			.matches = {
				DMI_MATCH(DMI_BOARD_VENDOR,
					  "Gigabyte Technology Co., Ltd."),
				DMI_MATCH(DMI_BOARD_NAME, "EP45-DQ6"),
			},
			.driver_data = ENCODE_BUSDEVFN(0x0a, 0x00, 0),
		},
		{
			.ident = "EP45-DS5",
			.matches = {
				DMI_MATCH(DMI_BOARD_VENDOR,
					  "Gigabyte Technology Co., Ltd."),
				DMI_MATCH(DMI_BOARD_NAME, "EP45-DS5"),
			},
			.driver_data = ENCODE_BUSDEVFN(0x03, 0x00, 0),
		},
		{ }	/* terminate list */
	};
#undef ENCODE_BUSDEVFN
	const struct dmi_system_id *dmi = dmi_first_match(sysids);
	unsigned int val;

	if (!dmi)
		return false;

	val = (unsigned long)dmi->driver_data;

	return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
}

static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	static int printed_version;
@@ -2841,6 +2904,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
			   "BIOS update required for suspend/resume\n");
	}

	if (ahci_broken_online(pdev)) {
		hpriv->flags |= AHCI_HFLAG_SRST_TOUT_IS_OFFLINE;
		dev_info(&pdev->dev,
			 "online status unreliable, applying workaround\n");
	}

	/* CAP.NP sometimes indicate the index of the last enabled
	 * port, at other times, that of the last possible port, so
	 * determining the maximum port number requires looking at
+3 −0
Original line number Diff line number Diff line
@@ -4302,6 +4302,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
	{ "WDC WD2500JD-00HBB0", "WD-WMAL71490727", ATA_HORKAGE_BROKEN_HPA },
	{ "MAXTOR 6L080L4",	"A93.0500",	ATA_HORKAGE_BROKEN_HPA },

	/* this one allows HPA unlocking but fails IOs on the area */
	{ "OCZ-VERTEX",		    "1.30",	ATA_HORKAGE_BROKEN_HPA },

	/* Devices which report 1 sector over size HPA */
	{ "ST340823A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
	{ "ST320413A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
+4 −13
Original line number Diff line number Diff line
@@ -250,7 +250,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
		ata_port_desc(ap, "no IRQ, using PIO polling");
	}

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);

	if (!info) {
		dev_err(dev, "failed to allocate memory for private data\n");
@@ -275,7 +275,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
	if (!info->ide_addr) {
		dev_err(dev, "failed to map IO base\n");
		ret = -ENOMEM;
		goto err_ide_ioremap;
		goto err_put;
	}

	info->alt_addr = devm_ioremap(dev,
@@ -284,7 +284,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
	if (!info->alt_addr) {
		dev_err(dev, "failed to map CTL base\n");
		ret = -ENOMEM;
		goto err_alt_ioremap;
		goto err_put;
	}

	ap->ioaddr.cmd_addr = info->ide_addr;
@@ -303,13 +303,8 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
			irq ? ata_sff_interrupt : NULL,
			irq_flags, &pata_at91_sht);

err_alt_ioremap:
	devm_iounmap(dev, info->ide_addr);

err_ide_ioremap:
err_put:
	clk_put(info->mck);
	kfree(info);

	return ret;
}

@@ -317,7 +312,6 @@ static int __devexit pata_at91_remove(struct platform_device *pdev)
{
	struct ata_host *host = dev_get_drvdata(&pdev->dev);
	struct at91_ide_info *info;
	struct device *dev = &pdev->dev;

	if (!host)
		return 0;
@@ -328,11 +322,8 @@ static int __devexit pata_at91_remove(struct platform_device *pdev)
	if (!info)
		return 0;

	devm_iounmap(dev, info->ide_addr);
	devm_iounmap(dev, info->alt_addr);
	clk_put(info->mck);

	kfree(info);
	return 0;
}

+10 −9
Original line number Diff line number Diff line
/*
 * pata_atiixp.c 	- ATI PATA for new ATA layer
 *			  (C) 2005 Red Hat Inc
 *			  (C) 2009 Bartlomiej Zolnierkiewicz
 *
 * Based on
 *
@@ -61,20 +62,19 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev,

	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	int dn = 2 * ap->port_no + adev->devno;

	/* Check this is correct - the order is odd in both drivers */
	int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
	u16 pio_mode_data, pio_timing_data;
	u32 pio_timing_data;
	u16 pio_mode_data;

	pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
	pio_mode_data &= ~(0x7 << (4 * dn));
	pio_mode_data |= pio << (4 * dn);
	pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data);

	pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
	pci_read_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
	pio_timing_data &= ~(0xFF << timing_shift);
	pio_timing_data |= (pio_timings[pio] << timing_shift);
	pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
	pci_write_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
}

/**
@@ -119,16 +119,17 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
		udma_mode_data |= dma << (4 * dn);
		pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data);
	} else {
		u16 mwdma_timing_data;
		/* Check this is correct - the order is odd in both drivers */
		int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
		u32 mwdma_timing_data;

		dma -= XFER_MW_DMA_0;

		pci_read_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, &mwdma_timing_data);
		pci_read_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
				      &mwdma_timing_data);
		mwdma_timing_data &= ~(0xFF << timing_shift);
		mwdma_timing_data |= (mwdma_timings[dma] << timing_shift);
		pci_write_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, mwdma_timing_data);
		pci_write_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
				       mwdma_timing_data);
	}
	/*
	 *	We must now look at the PIO mode situation. We may need to
Loading