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

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

libata: implement and use sata_std_hardreset()



Implement sata_std_hardreset(), which simply wraps around
sata_link_hardreset().  sata_std_hardreset() becomes new standard
hardreset method for sata_port_ops and sata_sff_hardreset() moves from
ata_base_port_ops to ata_sff_port_ops, which is where it really
belongs.

ata_is_builtin_hardreset() is added so that both
ata_std_error_handler() and ata_sff_error_handler() skip both builtin
hardresets if SCR isn't accessible.

piix_sidpr_hardreset() in ata_piix.c is identical to
sata_std_hardreset() in functionality and got replaced with the
standard function.

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
parent 9dadd45b
Loading
Loading
Loading
Loading
+1 −26
Original line number Diff line number Diff line
@@ -165,8 +165,6 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev);
static int ich_pata_cable_detect(struct ata_port *ap);
static u8 piix_vmw_bmdma_status(struct ata_port *ap);
static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
				unsigned long deadline);
static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val);
static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val);
#ifdef CONFIG_PM
@@ -319,7 +317,7 @@ static struct ata_port_operations piix_sata_ops = {

static struct ata_port_operations piix_sidpr_sata_ops = {
	.inherits		= &piix_sata_ops,
	.hardreset		= piix_sidpr_hardreset,
	.hardreset		= sata_std_hardreset,
	.scr_read		= piix_sidpr_scr_read,
	.scr_write		= piix_sidpr_scr_write,
};
@@ -1015,29 +1013,6 @@ static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val)
	return 0;
}

static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
				unsigned long deadline)
{
	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
	int rc;

	/* do hardreset */
	rc = sata_link_hardreset(link, timing, deadline, NULL, NULL);
	if (rc) {
		ata_link_printk(link, KERN_ERR,
				"COMRESET failed (errno=%d)\n", rc);
		return rc;
	}

	/* TODO: phy layer with polling, timeouts, etc. */
	if (ata_link_offline(link)) {
		*class = ATA_DEV_NONE;
		return 0;
	}

	return -EAGAIN;
}

#ifdef CONFIG_PM
static int piix_broken_suspend(void)
{
+29 −1
Original line number Diff line number Diff line
@@ -75,7 +75,6 @@ const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 };

const struct ata_port_operations ata_base_port_ops = {
	.prereset		= ata_std_prereset,
	.hardreset		= sata_sff_hardreset,
	.postreset		= ata_std_postreset,
	.error_handler		= ata_std_error_handler,
};
@@ -84,6 +83,7 @@ const struct ata_port_operations sata_port_ops = {
	.inherits		= &ata_base_port_ops,

	.qc_defer		= ata_std_qc_defer,
	.hardreset		= sata_std_hardreset,
	.sff_dev_select		= ata_noop_dev_select,
};

@@ -3660,6 +3660,33 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
	return rc;
}

/**
 *	sata_std_hardreset - COMRESET w/o waiting or classification
 *	@link: link to reset
 *	@class: resulting class of attached device
 *	@deadline: deadline jiffies for the operation
 *
 *	Standard SATA COMRESET w/o waiting or classification.
 *
 *	LOCKING:
 *	Kernel thread context (may sleep)
 *
 *	RETURNS:
 *	0 if link offline, -EAGAIN if link online, -errno on errors.
 */
int sata_std_hardreset(struct ata_link *link, unsigned int *class,
		       unsigned long deadline)
{
	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
	bool online;
	int rc;

	/* do hardreset */
	rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
	*class = ATA_DEV_NONE;
	return online ? -EAGAIN : rc;
}

/**
 *	ata_std_postreset - standard postreset callback
 *	@link: the target ata_link
@@ -6225,6 +6252,7 @@ EXPORT_SYMBOL_GPL(sata_link_debounce);
EXPORT_SYMBOL_GPL(sata_link_resume);
EXPORT_SYMBOL_GPL(ata_std_prereset);
EXPORT_SYMBOL_GPL(sata_link_hardreset);
EXPORT_SYMBOL_GPL(sata_std_hardreset);
EXPORT_SYMBOL_GPL(ata_std_postreset);
EXPORT_SYMBOL_GPL(ata_dev_classify);
EXPORT_SYMBOL_GPL(ata_dev_pair);
+2 −5
Original line number Diff line number Diff line
@@ -2857,11 +2857,8 @@ void ata_std_error_handler(struct ata_port *ap)
	struct ata_port_operations *ops = ap->ops;
	ata_reset_fn_t hardreset = ops->hardreset;

	/* sata_std_hardreset is inherited to all drivers from
	 * ata_base_port_ops.  Ignore it if SCR access is not
	 * available.
	 */
	if (hardreset == sata_sff_hardreset && !sata_scr_valid(&ap->link))
	/* ignore built-in hardreset if SCR access is not available */
	if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
		hardreset = NULL;

	ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
+4 −5
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ const struct ata_port_operations ata_sff_port_ops = {
	.thaw			= ata_sff_thaw,
	.prereset		= ata_sff_prereset,
	.softreset		= ata_sff_softreset,
	.hardreset		= sata_sff_hardreset,
	.postreset		= ata_sff_postreset,
	.error_handler		= ata_sff_error_handler,
	.post_internal_cmd	= ata_sff_post_internal_cmd,
@@ -2031,14 +2032,12 @@ void ata_sff_error_handler(struct ata_port *ap)

	/* PIO and DMA engines have been stopped, perform recovery */

	/* ata_sff_softreset and sata_sff_hardreset are inherited to
	 * all SFF drivers from ata_sff_port_ops.  Ignore softreset if
	 * ctl isn't accessible.  Ignore hardreset if SCR access isn't
	 * available.
	/* Ignore ata_sff_softreset if ctl isn't accessible and
	 * built-in hardresets if SCR access isn't available.
	 */
	if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
		softreset = NULL;
	if (hardreset == sata_sff_hardreset && !sata_scr_valid(&ap->link))
	if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
		hardreset = NULL;

	ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
+9 −0
Original line number Diff line number Diff line
@@ -38,6 +38,15 @@ struct ata_scsi_args {
	void			(*done)(struct scsi_cmnd *);
};

static inline int ata_is_builtin_hardreset(ata_reset_fn_t reset)
{
	if (reset == sata_std_hardreset)
		return 1;
	if (reset == sata_sff_hardreset)
		return 1;
	return 0;
}

/* libata-core.c */
enum {
	/* flags for ata_dev_read_id() */
Loading