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

Commit e8e008e7 authored by Tejun Heo's avatar Tejun Heo
Browse files

[PATCH] sata_sil24: update sil24_hardreset()



Use phy debouncing instead of unconditional wait after DEV_RST and
make sil24_hardreset() to request followup SRST as that's the only way
to wait for !BSY.  Note that the original implementation never worked
- if the cached status was !BSY, ata_busy_sleep() finished
immediately; otherwise, it timed out regardless of the actual device
status.

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
parent 135da345
Loading
Loading
Loading
Loading
+14 −12
Original line number Original line Diff line number Diff line
@@ -591,7 +591,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
{
{
	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
	const char *reason;
	const char *reason;
	int tout_msec;
	int tout_msec, rc;
	u32 tmp;
	u32 tmp;


	/* sil24 does the right thing(tm) without any protection */
	/* sil24 does the right thing(tm) without any protection */
@@ -605,10 +605,14 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
	tmp = ata_wait_register(port + PORT_CTRL_STAT,
	tmp = ata_wait_register(port + PORT_CTRL_STAT,
				PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec);
				PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec);


	/* SStatus oscillates between zero and valid status for short
	/* SStatus oscillates between zero and valid status after
	 * duration after DEV_RST, give it time to settle.
	 * DEV_RST, debounce it.
	 */
	 */
	msleep(100);
	rc = sata_phy_debounce(ap, sata_deb_timing_before_fsrst);
	if (rc) {
		reason = "PHY debouncing failed";
		goto err;
	}


	if (tmp & PORT_CS_DEV_RST) {
	if (tmp & PORT_CS_DEV_RST) {
		if (ata_port_offline(ap))
		if (ata_port_offline(ap))
@@ -617,15 +621,13 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
		goto err;
		goto err;
	}
	}


	if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
	/* Sil24 doesn't store signature FIS after hardreset, so we
		reason = "device not ready";
	 * can't wait for BSY to clear.  Some devices take a long time
		goto err;
	 * to get ready and those devices will choke if we don't wait
	}
	 * for BSY clearance here.  Tell libata to perform follow-up

	 * softreset.
	/* sil24 doesn't report device class code after hardreset,
	 * leave *class alone.
	 */
	 */
	return 0;
	return -EAGAIN;


 err:
 err:
	ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason);
	ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason);