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

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

libata-link: linkify reset



Make reset methods and related functions deal with ata_link instead of
ata_port.

* ata_do_reset()
* ata_eh_reset()
* all prereset/reset/postreset methods and related functions

This patch introduces no behavior change.

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 955e57df
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -1042,9 +1042,10 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
	return 0;
}

static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
			     int pmp, unsigned long deadline)
{
	struct ata_port *ap = link->ap;
	const char *reason = NULL;
	unsigned long now, msecs;
	struct ata_taskfile tf;
@@ -1052,7 +1053,7 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,

	DPRINTK("ENTER\n");

	if (ata_link_offline(&ap->link)) {
	if (ata_link_offline(link)) {
		DPRINTK("PHY reports no device\n");
		*class = ATA_DEV_NONE;
		return 0;
@@ -1061,10 +1062,10 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
	/* prepare for SRST (AHCI-1.1 10.4.1) */
	rc = ahci_kick_engine(ap, 1);
	if (rc)
		ata_port_printk(ap, KERN_WARNING,
		ata_link_printk(link, KERN_WARNING,
				"failed to reset engine (errno=%d)", rc);

	ata_tf_init(ap->link.device, &tf);
	ata_tf_init(link->device, &tf);

	/* issue the first D2H Register FIS */
	msecs = 0;
@@ -1109,19 +1110,20 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
	return 0;

 fail:
	ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
	ata_link_printk(link, KERN_ERR, "softreset failed (%s)\n", reason);
	return rc;
}

static int ahci_softreset(struct ata_port *ap, unsigned int *class,
static int ahci_softreset(struct ata_link *link, unsigned int *class,
			  unsigned long deadline)
{
	return ahci_do_softreset(ap, class, 0, deadline);
	return ahci_do_softreset(link, class, 0, deadline);
}

static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
static int ahci_hardreset(struct ata_link *link, unsigned int *class,
			  unsigned long deadline)
{
	struct ata_port *ap = link->ap;
	struct ahci_port_priv *pp = ap->private_data;
	u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
	struct ata_taskfile tf;
@@ -1132,15 +1134,15 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
	ahci_stop_engine(ap);

	/* clear D2H reception area to properly wait for D2H FIS */
	ata_tf_init(ap->link.device, &tf);
	ata_tf_init(link->device, &tf);
	tf.command = 0x80;
	ata_tf_to_fis(&tf, 0, 0, d2h_fis);

	rc = sata_std_hardreset(ap, class, deadline);
	rc = sata_std_hardreset(link, class, deadline);

	ahci_start_engine(ap);

	if (rc == 0 && ata_link_online(&ap->link))
	if (rc == 0 && ata_link_online(link))
		*class = ahci_dev_classify(ap);
	if (*class == ATA_DEV_UNKNOWN)
		*class = ATA_DEV_NONE;
@@ -1149,9 +1151,10 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
	return rc;
}

static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
				 unsigned long deadline)
{
	struct ata_port *ap = link->ap;
	u32 serror;
	int rc;

@@ -1159,7 +1162,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,

	ahci_stop_engine(ap);

	rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->link.eh_context),
	rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
				 deadline);

	/* vt8251 needs SError cleared for the port to operate */
@@ -1176,12 +1179,13 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
	return rc ?: -EAGAIN;
}

static void ahci_postreset(struct ata_port *ap, unsigned int *class)
static void ahci_postreset(struct ata_link *link, unsigned int *class)
{
	struct ata_port *ap = link->ap;
	void __iomem *port_mmio = ahci_port_base(ap);
	u32 new_tmp, tmp;

	ata_std_postreset(ap, class);
	ata_std_postreset(link, class);

	/* Make sure port's ATAPI bit is set appropriately */
	new_tmp = tmp = readl(port_mmio + PORT_CMD);
+4 −3
Original line number Diff line number Diff line
@@ -657,19 +657,20 @@ static int ich_pata_cable_detect(struct ata_port *ap)

/**
 *	piix_pata_prereset - prereset for PATA host controller
 *	@ap: Target port
 *	@link: Target link
 *	@deadline: deadline jiffies for the operation
 *
 *	LOCKING:
 *	None (inherited from caller).
 */
static int piix_pata_prereset(struct ata_port *ap, unsigned long deadline)
static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
{
	struct ata_port *ap = link->ap;
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);

	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
		return -ENOENT;
	return ata_std_prereset(ap, deadline);
	return ata_std_prereset(link, deadline);
}

static void piix_pata_error_handler(struct ata_port *ap)
+24 −25
Original line number Diff line number Diff line
@@ -3306,10 +3306,10 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,

/**
 *	ata_std_prereset - prepare for reset
 *	@ap: ATA port to be reset
 *	@link: ATA link to be reset
 *	@deadline: deadline jiffies for the operation
 *
 *	@ap is about to be reset.  Initialize it.  Failure from
 *	@link is about to be reset.  Initialize it.  Failure from
 *	prereset makes libata abort whole reset sequence and give up
 *	that port, so prereset should be best-effort.  It does its
 *	best to prepare for reset sequence but if things go wrong, it
@@ -3321,9 +3321,9 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
 *	RETURNS:
 *	0 on success, -errno otherwise.
 */
int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
int ata_std_prereset(struct ata_link *link, unsigned long deadline)
{
	struct ata_link *link = &ap->link;
	struct ata_port *ap = link->ap;
	struct ata_eh_context *ehc = &link->eh_context;
	const unsigned long *timing = sata_ehc_deb_timing(ehc);
	int rc;
@@ -3342,7 +3342,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
		rc = sata_link_resume(link, timing, deadline);
		/* whine about phy resume failure but proceed */
		if (rc && rc != -EOPNOTSUPP)
			ata_port_printk(ap, KERN_WARNING, "failed to resume "
			ata_link_printk(link, KERN_WARNING, "failed to resume "
					"link for reset (errno=%d)\n", rc);
	}

@@ -3352,7 +3352,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
	if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_link_offline(link)) {
		rc = ata_wait_ready(ap, deadline);
		if (rc && rc != -ENODEV) {
			ata_port_printk(ap, KERN_WARNING, "device not ready "
			ata_link_printk(link, KERN_WARNING, "device not ready "
					"(errno=%d), forcing hardreset\n", rc);
			ehc->i.action |= ATA_EH_HARDRESET;
		}
@@ -3363,7 +3363,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)

/**
 *	ata_std_softreset - reset host port via ATA SRST
 *	@ap: port to reset
 *	@link: ATA link to reset
 *	@classes: resulting classes of attached devices
 *	@deadline: deadline jiffies for the operation
 *
@@ -3375,10 +3375,10 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
 *	RETURNS:
 *	0 on success, -errno otherwise.
 */
int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
int ata_std_softreset(struct ata_link *link, unsigned int *classes,
		      unsigned long deadline)
{
	struct ata_link *link = &ap->link;
	struct ata_port *ap = link->ap;
	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
	unsigned int devmask = 0;
	int rc;
@@ -3405,7 +3405,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
	rc = ata_bus_softreset(ap, devmask, deadline);
	/* if link is occupied, -ENODEV too is an error */
	if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
		ata_port_printk(ap, KERN_ERR, "SRST failed (errno=%d)\n", rc);
		ata_link_printk(link, KERN_ERR, "SRST failed (errno=%d)\n", rc);
		return rc;
	}

@@ -3420,12 +3420,12 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
}

/**
 *	sata_port_hardreset - reset port via SATA phy reset
 *	@ap: port to reset
 *	sata_link_hardreset - reset link via SATA phy reset
 *	@link: link to reset
 *	@timing: timing parameters { interval, duratinon, timeout } in msec
 *	@deadline: deadline jiffies for the operation
 *
 *	SATA phy-reset host port using DET bits of SControl register.
 *	SATA phy-reset @link using DET bits of SControl register.
 *
 *	LOCKING:
 *	Kernel thread context (may sleep)
@@ -3433,10 +3433,9 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
 *	RETURNS:
 *	0 on success, -errno otherwise.
 */
int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing,
int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
			unsigned long deadline)
{
	struct ata_link *link = &ap->link;
	u32 scontrol;
	int rc;

@@ -3482,7 +3481,7 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing,

/**
 *	sata_std_hardreset - reset host port via SATA phy reset
 *	@ap: port to reset
 *	@link: link to reset
 *	@class: resulting class of attached device
 *	@deadline: deadline jiffies for the operation
 *
@@ -3495,19 +3494,19 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing,
 *	RETURNS:
 *	0 on success, -errno otherwise.
 */
int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
int sata_std_hardreset(struct ata_link *link, unsigned int *class,
		       unsigned long deadline)
{
	struct ata_link *link = &ap->link;
	struct ata_port *ap = link->ap;
	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
	int rc;

	DPRINTK("ENTER\n");

	/* do hardreset */
	rc = sata_port_hardreset(ap, timing, deadline);
	rc = sata_link_hardreset(link, timing, deadline);
	if (rc) {
		ata_port_printk(ap, KERN_ERR,
		ata_link_printk(link, KERN_ERR,
				"COMRESET failed (errno=%d)\n", rc);
		return rc;
	}
@@ -3525,7 +3524,7 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
	rc = ata_wait_ready(ap, deadline);
	/* link occupied, -ENODEV too is an error */
	if (rc) {
		ata_port_printk(ap, KERN_ERR,
		ata_link_printk(link, KERN_ERR,
				"COMRESET failed (errno=%d)\n", rc);
		return rc;
	}
@@ -3540,7 +3539,7 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class,

/**
 *	ata_std_postreset - standard postreset callback
 *	@ap: the target ata_port
 *	@link: the target ata_link
 *	@classes: classes of attached devices
 *
 *	This function is invoked after a successful reset.  Note that
@@ -3550,9 +3549,9 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
 *	LOCKING:
 *	Kernel thread context (may sleep)
 */
void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
void ata_std_postreset(struct ata_link *link, unsigned int *classes)
{
	struct ata_link *link = &ap->link;
	struct ata_port *ap = link->ap;
	u32 serror;

	DPRINTK("ENTER\n");
@@ -6946,7 +6945,7 @@ EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_std_prereset);
EXPORT_SYMBOL_GPL(ata_std_softreset);
EXPORT_SYMBOL_GPL(sata_port_hardreset);
EXPORT_SYMBOL_GPL(sata_link_hardreset);
EXPORT_SYMBOL_GPL(sata_std_hardreset);
EXPORT_SYMBOL_GPL(ata_std_postreset);
EXPORT_SYMBOL_GPL(ata_dev_classify);
+17 −18
Original line number Diff line number Diff line
@@ -1737,16 +1737,16 @@ static void ata_eh_report(struct ata_port *ap)
	}
}

static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
			unsigned int *classes, unsigned long deadline)
{
	struct ata_device *dev;
	int rc;

	ata_link_for_each_dev(dev, &ap->link)
	ata_link_for_each_dev(dev, link)
		classes[dev->devno] = ATA_DEV_UNKNOWN;

	rc = reset(ap, classes, deadline);
	rc = reset(link, classes, deadline);
	if (rc)
		return rc;

@@ -1754,12 +1754,12 @@ static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
	 * is complete and convert all ATA_DEV_UNKNOWN to
	 * ATA_DEV_NONE.
	 */
	ata_link_for_each_dev(dev, &ap->link)
	ata_link_for_each_dev(dev, link)
		if (classes[dev->devno] != ATA_DEV_UNKNOWN)
			break;

	if (dev) {
		ata_link_for_each_dev(dev, &ap->link) {
		ata_link_for_each_dev(dev, link) {
			if (classes[dev->devno] == ATA_DEV_UNKNOWN)
				classes[dev->devno] = ATA_DEV_NONE;
		}
@@ -1780,11 +1780,10 @@ static int ata_eh_followup_srst_needed(int rc, int classify,
	return 0;
}

static int ata_eh_reset(struct ata_port *ap, int classify,
static int ata_eh_reset(struct ata_link *link, int classify,
			ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
			ata_reset_fn_t hardreset, ata_postreset_fn_t postreset)
{
	struct ata_link *link = &ap->link;
	struct ata_eh_context *ehc = &link->eh_context;
	unsigned int *classes = ehc->classes;
	int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
@@ -1810,10 +1809,10 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
		ehc->i.action |= ATA_EH_HARDRESET;

	if (prereset) {
		rc = prereset(ap, jiffies + ATA_EH_PRERESET_TIMEOUT);
		rc = prereset(link, jiffies + ATA_EH_PRERESET_TIMEOUT);
		if (rc) {
			if (rc == -ENOENT) {
				ata_port_printk(ap, KERN_DEBUG,
				ata_link_printk(link, KERN_DEBUG,
						"port disabled. ignoring.\n");
				ehc->i.action &= ~ATA_EH_RESET_MASK;

@@ -1822,7 +1821,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,

				rc = 0;
			} else
				ata_port_printk(ap, KERN_ERR,
				ata_link_printk(link, KERN_ERR,
					"prereset failed (errno=%d)\n", rc);
			goto out;
		}
@@ -1854,7 +1853,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,

	/* shut up during boot probing */
	if (verbose)
		ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
		ata_link_printk(link, KERN_INFO, "%s resetting link\n",
				reset == softreset ? "soft" : "hard");

	/* mark that this EH session started with reset */
@@ -1863,7 +1862,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
	else
		ehc->i.flags |= ATA_EHI_DID_SOFTRESET;

	rc = ata_do_reset(ap, reset, classes, deadline);
	rc = ata_do_reset(link, reset, classes, deadline);

	if (reset == hardreset &&
	    ata_eh_followup_srst_needed(rc, classify, classes)) {
@@ -1871,7 +1870,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
		reset = softreset;

		if (!reset) {
			ata_port_printk(ap, KERN_ERR,
			ata_link_printk(link, KERN_ERR,
					"follow-up softreset required "
					"but no softreset avaliable\n");
			rc = -EINVAL;
@@ -1879,11 +1878,11 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
		}

		ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK);
		rc = ata_do_reset(ap, reset, classes, deadline);
		rc = ata_do_reset(link, reset, classes, deadline);

		if (rc == 0 && classify &&
		    classes[0] == ATA_DEV_UNKNOWN) {
			ata_port_printk(ap, KERN_ERR,
			ata_link_printk(link, KERN_ERR,
					"classification failed\n");
			rc = -EINVAL;
			goto out;
@@ -1896,7 +1895,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
		if (time_before(now, deadline)) {
			unsigned long delta = deadline - jiffies;

			ata_port_printk(ap, KERN_WARNING, "reset failed "
			ata_link_printk(link, KERN_WARNING, "reset failed "
				"(errno=%d), retrying in %u secs\n",
				rc, (jiffies_to_msecs(delta) + 999) / 1000);

@@ -1925,7 +1924,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
			link->sata_spd = (sstatus >> 4) & 0xf;

		if (postreset)
			postreset(ap, classes);
			postreset(link, classes);

		/* reset successful, schedule revalidation */
		ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK);
@@ -2202,7 +2201,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
	if (ehc->i.action & ATA_EH_RESET_MASK) {
		ata_eh_freeze_port(ap);

		rc = ata_eh_reset(ap, ata_port_nr_vacant(ap), prereset,
		rc = ata_eh_reset(&ap->link, ata_port_nr_vacant(ap), prereset,
				  softreset, hardreset, postreset);
		if (rc) {
			ata_port_printk(ap, KERN_ERR,
+9 −7
Original line number Diff line number Diff line
@@ -119,27 +119,28 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
}

/**
 *	amd_probe_init		-	perform reset handling
 *	@ap: ATA port
 *	amd_pre_reset		-	perform reset handling
 *	@link: ATA link
 *	@deadline: deadline jiffies for the operation
 *
 *	Reset sequence checking enable bits to see which ports are
 *	active.
 */

static int amd_pre_reset(struct ata_port *ap, unsigned long deadline)
static int amd_pre_reset(struct ata_link *link, unsigned long deadline)
{
	static const struct pci_bits amd_enable_bits[] = {
		{ 0x40, 1, 0x02, 0x02 },
		{ 0x40, 1, 0x01, 0x01 }
	};

	struct ata_port *ap = link->ap;
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);

	if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
		return -ENOENT;

	return ata_std_prereset(ap, deadline);
	return ata_std_prereset(link, deadline);
}

static void amd_error_handler(struct ata_port *ap)
@@ -221,25 +222,26 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)

/**
 *	nv_probe_init	-	cable detection
 *	@ap: ATA port
 *	@lin: ATA link
 *
 *	Perform cable detection. The BIOS stores this in PCI config
 *	space for us.
 */

static int nv_pre_reset(struct ata_port *ap, unsigned long deadline)
static int nv_pre_reset(struct ata_link *link, unsigned long deadline)
{
	static const struct pci_bits nv_enable_bits[] = {
		{ 0x50, 1, 0x02, 0x02 },
		{ 0x50, 1, 0x01, 0x01 }
	};

	struct ata_port *ap = link->ap;
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);

	if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
		return -ENOENT;

	return ata_std_prereset(ap, deadline);
	return ata_std_prereset(link, deadline);
}

static void nv_error_handler(struct ata_port *ap)
Loading