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

Commit a7b354e8 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:
  [libata] pata_it821x: fix warning
  libata: Fix a large collection of DMA mode mismatches
  ahci: sis controllers actually can do PMP
  pata_via: clean up recent tf_load changes
  libata: restore SControl on detach
  libata: use ata_link_printk() when printing SError
  libata: always do follow-up SRST if hardreset returned -EAGAIN
  libata: fix EH action overwriting in ata_eh_reset()
  sata_mv: add the Gen IIE flag to the SoC devices.
  ata_piix: IDE Mode SATA patch for Intel Ibex Peak DeviceIDs
  ahci: RAID mode SATA patch for Intel Ibex Peak DeviceIDs
  sata_mv: don't issue two DMA commands concurrently
  libata: implement no[hs]rst force params
parents f7edd5fb 4ef28185
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1074,6 +1074,9 @@ and is between 256 and 4096 characters. It is defined in the file

			* [no]ncq: Turn on or off NCQ.

			* nohrst, nosrst, norst: suppress hard, soft
                          and both resets.

			If there are multiple matching configurations changing
			the same attribute, the last one is used.

+5 −3
Original line number Diff line number Diff line
@@ -486,6 +486,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
	{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
	{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
	{ PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
	{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */

	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -575,9 +577,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
	{ PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci },		/* MCP7B */

	/* SiS */
	{ PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp },		/* SiS 966 */
	{ PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp },		/* SiS 968 */
	{ PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp },		/* SiS 968 */
	{ PCI_VDEVICE(SI, 0x1184), board_ahci },		/* SiS 966 */
	{ PCI_VDEVICE(SI, 0x1185), board_ahci },		/* SiS 968 */
	{ PCI_VDEVICE(SI, 0x0186), board_ahci },		/* SiS 968 */

	/* Marvell */
	{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },	/* 6145 */
+8 −0
Original line number Diff line number Diff line
@@ -275,6 +275,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
	{ 0x8086, 0x3a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
	/* SATA Controller IDE (ICH10) */
	{ 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
	/* SATA Controller IDE (PCH) */
	{ 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
	/* SATA Controller IDE (PCH) */
	{ 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
	/* SATA Controller IDE (PCH) */
	{ 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
	/* SATA Controller IDE (PCH) */
	{ 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },

	{ }	/* terminate list */
};
+37 −23
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ struct ata_force_param {
	unsigned long	xfer_mask;
	unsigned int	horkage_on;
	unsigned int	horkage_off;
	unsigned int	lflags;
};

struct ata_force_ent {
@@ -196,22 +197,23 @@ void ata_force_cbl(struct ata_port *ap)
}

/**
 *	ata_force_spd_limit - force SATA spd limit according to libata.force
 *	ata_force_link_limits - force link limits according to libata.force
 *	@link: ATA link of interest
 *
 *	Force SATA spd limit according to libata.force and whine about
 *	it.  When only the port part is specified (e.g. 1:), the limit
 *	applies to all links connected to both the host link and all
 *	fan-out ports connected via PMP.  If the device part is
 *	specified as 0 (e.g. 1.00:), it specifies the first fan-out
 *	link not the host link.  Device number 15 always points to the
 *	host link whether PMP is attached or not.
 *	Force link flags and SATA spd limit according to libata.force
 *	and whine about it.  When only the port part is specified
 *	(e.g. 1:), the limit applies to all links connected to both
 *	the host link and all fan-out ports connected via PMP.  If the
 *	device part is specified as 0 (e.g. 1.00:), it specifies the
 *	first fan-out link not the host link.  Device number 15 always
 *	points to the host link whether PMP is attached or not.
 *
 *	LOCKING:
 *	EH context.
 */
static void ata_force_spd_limit(struct ata_link *link)
static void ata_force_link_limits(struct ata_link *link)
{
	bool did_spd = false;
	int linkno, i;

	if (ata_is_host_link(link))
@@ -228,13 +230,22 @@ static void ata_force_spd_limit(struct ata_link *link)
		if (fe->device != -1 && fe->device != linkno)
			continue;

		if (!fe->param.spd_limit)
			continue;

		/* only honor the first spd limit */
		if (!did_spd && fe->param.spd_limit) {
			link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
			ata_link_printk(link, KERN_NOTICE,
			"FORCE: PHY spd limit set to %s\n", fe->param.name);
		return;
					"FORCE: PHY spd limit set to %s\n",
					fe->param.name);
			did_spd = true;
		}

		/* let lflags stack */
		if (fe->param.lflags) {
			link->flags |= fe->param.lflags;
			ata_link_printk(link, KERN_NOTICE,
					"FORCE: link flag 0x%x forced -> 0x%x\n",
					fe->param.lflags, link->flags);
		}
	}
}

@@ -3277,7 +3288,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
		dev->dma_mode = ata_xfer_mask2mode(dma_mask);

		found = 1;
		if (dev->dma_mode != 0xff)
		if (ata_dma_enabled(dev))
			used_dma = 1;
	}
	if (!found)
@@ -3302,7 +3313,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)

	/* step 3: set host DMA timings */
	ata_link_for_each_dev(dev, link) {
		if (!ata_dev_enabled(dev) || dev->dma_mode == 0xff)
		if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev))
			continue;

		dev->xfer_mode = dev->dma_mode;
@@ -5188,19 +5199,18 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
 */
int sata_link_init_spd(struct ata_link *link)
{
	u32 scontrol;
	u8 spd;
	int rc;

	rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
	rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol);
	if (rc)
		return rc;

	spd = (scontrol >> 4) & 0xf;
	spd = (link->saved_scontrol >> 4) & 0xf;
	if (spd)
		link->hw_sata_spd_limit &= (1 << spd) - 1;

	ata_force_spd_limit(link);
	ata_force_link_limits(link);

	link->sata_spd_limit = link->hw_sata_spd_limit;

@@ -5783,9 +5793,10 @@ static void ata_port_detach(struct ata_port *ap)
	ata_port_wait_eh(ap);

	/* EH is now guaranteed to see UNLOADING - EH context belongs
	 * to us.  Disable all existing devices.
	 * to us.  Restore SControl and disable all existing devices.
	 */
	ata_port_for_each_link(link, ap) {
	__ata_port_for_each_link(link, ap) {
		sata_scr_write(link, SCR_CONTROL, link->saved_scontrol);
		ata_link_for_each_dev(dev, link)
			ata_dev_disable(dev);
	}
@@ -5991,6 +6002,9 @@ static int __init ata_parse_force_one(char **cur,
		{ "udma133",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 6) },
		{ "udma/133",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 6) },
		{ "udma7",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 7) },
		{ "nohrst",	.lflags		= ATA_LFLAG_NO_HRST },
		{ "nosrst",	.lflags		= ATA_LFLAG_NO_SRST },
		{ "norst",	.lflags		= ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
	};
	char *start = *cur, *p = *cur;
	char *id, *val, *endp;
+13 −17
Original line number Diff line number Diff line
@@ -2040,7 +2040,7 @@ static void ata_eh_link_report(struct ata_link *link)
	}

	if (ehc->i.serror)
		ata_port_printk(ap, KERN_ERR,
		ata_link_printk(link, KERN_ERR,
		  "SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",
		  ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
		  ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
@@ -2171,18 +2171,12 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
}

static int ata_eh_followup_srst_needed(struct ata_link *link,
				       int rc, int classify,
				       const unsigned int *classes)
				       int rc, const unsigned int *classes)
{
	if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
		return 0;
	if (rc == -EAGAIN) {
		if (classify)
	if (rc == -EAGAIN)
		return 1;
		rc = 0;
	}
	if (rc != 0)
		return 0;
	if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
		return 1;
	return 0;
@@ -2210,6 +2204,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
	 */
	while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
		max_tries++;
	if (link->flags & ATA_LFLAG_NO_HRST)
		hardreset = NULL;
	if (link->flags & ATA_LFLAG_NO_SRST)
		softreset = NULL;

	now = jiffies;
	deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
@@ -2247,10 +2245,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
	ehc->i.action &= ~ATA_EH_RESET;
	if (hardreset) {
		reset = hardreset;
		ehc->i.action = ATA_EH_HARDRESET;
		ehc->i.action |= ATA_EH_HARDRESET;
	} else if (softreset) {
		reset = softreset;
		ehc->i.action = ATA_EH_SOFTRESET;
		ehc->i.action |= ATA_EH_SOFTRESET;
	}

	if (prereset) {
@@ -2305,9 +2303,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
			ehc->i.flags |= ATA_EHI_DID_SOFTRESET;

		rc = ata_do_reset(link, reset, classes, deadline);
		if (rc && rc != -EAGAIN)
			goto fail;

		if (reset == hardreset &&
		    ata_eh_followup_srst_needed(link, rc, classify, classes)) {
		    ata_eh_followup_srst_needed(link, rc, classes)) {
			/* okay, let's do follow-up softreset */
			reset = softreset;

@@ -2322,10 +2322,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
			ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
			rc = ata_do_reset(link, reset, classes, deadline);
		}

		/* -EAGAIN can happen if we skipped followup SRST */
		if (rc && rc != -EAGAIN)
			goto fail;
	} else {
		if (verbose)
			ata_link_printk(link, KERN_INFO, "no reset method "
Loading