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

Commit 05944bdf authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

libata: implement no[hs]rst force params



Implement force params nohrst, nosrst and norst.  This is to work
around reset related problems and ease debugging.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 6a55617e
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.

+30 −16
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);
		}
	}
}

@@ -5200,7 +5211,7 @@ int sata_link_init_spd(struct ata_link *link)
	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;

@@ -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;
+4 −0
Original line number Diff line number Diff line
@@ -2210,6 +2210,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);
+1 −0
Original line number Diff line number Diff line
@@ -163,6 +163,7 @@ enum {
	ATA_DEV_NONE		= 9,	/* no device */

	/* struct ata_link flags */
	ATA_LFLAG_NO_HRST	= (1 << 1), /* avoid hardreset */
	ATA_LFLAG_NO_SRST	= (1 << 2), /* avoid softreset */
	ATA_LFLAG_ASSUME_ATA	= (1 << 3), /* assume ATA class */
	ATA_LFLAG_ASSUME_SEMB	= (1 << 4), /* assume SEMB class */