linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3 #upstream] ahci: kill AHCI_FLAG_RESET_NEEDS_CLO
@ 2006-11-01  8:58 Tejun Heo
  2006-11-01  8:59 ` [PATCH 2/3 #upstream] libata: separate out and export sata_port_hardreset() Tejun Heo
  2006-11-01  9:22 ` [PATCH 1/3 #upstream] ahci: kill AHCI_FLAG_RESET_NEEDS_CLO Jeff Garzik
  0 siblings, 2 replies; 4+ messages in thread
From: Tejun Heo @ 2006-11-01  8:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide

Now that ahci_softreset() is fixed to automatically perform CLO if
BSY/DRQ is set on entry, AHCI_FLAG_RESET_NEEDS_CLO is redundant.  Kill
it.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---

Jeff, this is respin of the following patch series.

    http://thread.gmane.org/gmane.linux.ide/13471/focus=13471

fix-status-check-in-ahci_softreset patch is separated and submitted
for #upstream-fixes inclusion.

This patch series is against.

   upstream (ee0fd6c1b95105832d463f7318b874ad448e476a)
   + fix-status-check-in-ahci_softreset
     (http://article.gmane.org/gmane.linux.ide/13815)

Thanks.

 drivers/ata/ahci.c |   19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

Index: work/drivers/ata/ahci.c
===================================================================
--- work.orig/drivers/ata/ahci.c
+++ work/drivers/ata/ahci.c
@@ -166,8 +166,7 @@ enum {
 	AHCI_FLAG_MSI		= (1 << 0),
 
 	/* ap->flags bits */
-	AHCI_FLAG_RESET_NEEDS_CLO	= (1 << 24),
-	AHCI_FLAG_NO_NCQ		= (1 << 25),
+	AHCI_FLAG_NO_NCQ		= (1 << 24),
 };
 
 struct ahci_cmd_hdr {
@@ -289,8 +288,7 @@ static const struct ata_port_info ahci_p
 		.sht		= &ahci_sht,
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-				  ATA_FLAG_SKIP_D2H_BSY |
-				  AHCI_FLAG_RESET_NEEDS_CLO | AHCI_FLAG_NO_NCQ,
+				  ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_NO_NCQ,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
 		.port_ops	= &ahci_ops,
@@ -697,17 +695,6 @@ static int ahci_clo(struct ata_port *ap)
 	return 0;
 }
 
-static int ahci_prereset(struct ata_port *ap)
-{
-	if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) &&
-	    (ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) {
-		/* ATA_BUSY hasn't cleared, so send a CLO */
-		ahci_clo(ap);
-	}
-
-	return ata_std_prereset(ap);
-}
-
 static int ahci_softreset(struct ata_port *ap, unsigned int *class)
 {
 	struct ahci_port_priv *pp = ap->private_data;
@@ -1160,7 +1147,7 @@ static void ahci_error_handler(struct at
 	}
 
 	/* perform recovery */
-	ata_do_eh(ap, ahci_prereset, ahci_softreset, ahci_hardreset,
+	ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_hardreset,
 		  ahci_postreset);
 }
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3 #upstream] libata: separate out and export sata_port_hardreset()
  2006-11-01  8:58 [PATCH 1/3 #upstream] ahci: kill AHCI_FLAG_RESET_NEEDS_CLO Tejun Heo
@ 2006-11-01  8:59 ` Tejun Heo
  2006-11-01  9:00   ` [PATCH 3/3 #upstream] ahci: update ahci-vt8251 reset sequence Tejun Heo
  2006-11-01  9:22 ` [PATCH 1/3 #upstream] ahci: kill AHCI_FLAG_RESET_NEEDS_CLO Jeff Garzik
  1 sibling, 1 reply; 4+ messages in thread
From: Tejun Heo @ 2006-11-01  8:59 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide

Separate out sata_port_hardreset() from sata_std_hardreset().  This
will be used by LLD hardreset implementation and later by PMP.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
 drivers/ata/libata-core.c |   52 +++++++++++++++++++++++++++++++++++++---------
 include/linux/libata.h    |    2 +
 2 files changed, 44 insertions(+), 10 deletions(-)

Index: work/drivers/ata/libata-core.c
===================================================================
--- work.orig/drivers/ata/libata-core.c
+++ work/drivers/ata/libata-core.c
@@ -2786,9 +2786,9 @@ int ata_std_softreset(struct ata_port *a
 }
 
 /**
- *	sata_std_hardreset - reset host port via SATA phy reset
+ *	sata_port_hardreset - reset port via SATA phy reset
  *	@ap: port to reset
- *	@class: resulting class of attached device
+ *	@timing: timing parameters { interval, duratinon, timeout } in msec
  *
  *	SATA phy-reset host port using DET bits of SControl register.
  *
@@ -2798,10 +2798,8 @@ int ata_std_softreset(struct ata_port *a
  *	RETURNS:
  *	0 on success, -errno otherwise.
  */
-int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
+int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
 {
-	struct ata_eh_context *ehc = &ap->eh_context;
-	const unsigned long *timing = sata_ehc_deb_timing(ehc);
 	u32 scontrol;
 	int rc;
 
@@ -2814,24 +2812,24 @@ int sata_std_hardreset(struct ata_port *
 		 * and Sil3124.
 		 */
 		if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
-			return rc;
+			goto out;
 
 		scontrol = (scontrol & 0x0f0) | 0x304;
 
 		if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
-			return rc;
+			goto out;
 
 		sata_set_spd(ap);
 	}
 
 	/* issue phy wake/reset */
 	if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
-		return rc;
+		goto out;
 
 	scontrol = (scontrol & 0x0f0) | 0x301;
 
 	if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol)))
-		return rc;
+		goto out;
 
 	/* Couldn't find anything in SATA I/II specs, but AHCI-1.1
 	 * 10.4.2 says at least 1 ms.
@@ -2839,7 +2837,40 @@ int sata_std_hardreset(struct ata_port *
 	msleep(1);
 
 	/* bring phy back */
-	sata_phy_resume(ap, timing);
+	rc = sata_phy_resume(ap, timing);
+ out:
+	DPRINTK("EXIT, rc=%d\n", rc);
+	return rc;
+}
+
+/**
+ *	sata_std_hardreset - reset host port via SATA phy reset
+ *	@ap: port to reset
+ *	@class: resulting class of attached device
+ *
+ *	SATA phy-reset host port using DET bits of SControl register,
+ *	wait for !BSY and classify the attached device.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	0 on success, -errno otherwise.
+ */
+int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
+{
+	const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
+	int rc;
+
+	DPRINTK("ENTER\n");
+
+	/* do hardreset */
+	rc = sata_port_hardreset(ap, timing);
+	if (rc) {
+		ata_port_printk(ap, KERN_ERR,
+				"COMRESET failed (errno=%d)\n", rc);
+		return rc;
+	}
 
 	/* TODO: phy layer with polling, timeouts, etc. */
 	if (ata_port_offline(ap)) {
@@ -6159,6 +6190,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_std_hardreset);
 EXPORT_SYMBOL_GPL(ata_std_postreset);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
Index: work/include/linux/libata.h
===================================================================
--- work.orig/include/linux/libata.h
+++ work/include/linux/libata.h
@@ -702,6 +702,8 @@ extern int sata_phy_debounce(struct ata_
 extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param);
 extern int ata_std_prereset(struct ata_port *ap);
 extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
+extern int sata_port_hardreset(struct ata_port *ap,
+			       const unsigned long *timing);
 extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
 extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
 extern void ata_port_disable(struct ata_port *);

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3 #upstream] ahci: update ahci-vt8251 reset sequence
  2006-11-01  8:59 ` [PATCH 2/3 #upstream] libata: separate out and export sata_port_hardreset() Tejun Heo
@ 2006-11-01  9:00   ` Tejun Heo
  0 siblings, 0 replies; 4+ messages in thread
From: Tejun Heo @ 2006-11-01  9:00 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide

ahci-vt8251

* requires hardreset after PHY status change

* doesn't clear BSY on signature FIS after hardreset

* needs SError cleared for the port to operate after hardreset

This patch implements ahci_vt8251_hardreset() and sets
ATA_FLAG_HRST_TO_RESUME to handle the above behaviors.  This fixes EH
including hotplug on vt8251.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
 drivers/ata/ahci.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 76 insertions(+), 2 deletions(-)

Index: work/drivers/ata/ahci.c
===================================================================
--- work.orig/drivers/ata/ahci.c
+++ work/drivers/ata/ahci.c
@@ -213,6 +213,7 @@ static u8 ahci_check_status(struct ata_p
 static void ahci_freeze(struct ata_port *ap);
 static void ahci_thaw(struct ata_port *ap);
 static void ahci_error_handler(struct ata_port *ap);
+static void ahci_vt8251_error_handler(struct ata_port *ap);
 static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
 static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
 static int ahci_port_resume(struct ata_port *ap);
@@ -272,6 +273,37 @@ static const struct ata_port_operations 
 	.port_stop		= ahci_port_stop,
 };
 
+static const struct ata_port_operations ahci_vt8251_ops = {
+	.port_disable		= ata_port_disable,
+
+	.check_status		= ahci_check_status,
+	.check_altstatus	= ahci_check_status,
+	.dev_select		= ata_noop_dev_select,
+
+	.tf_read		= ahci_tf_read,
+
+	.qc_prep		= ahci_qc_prep,
+	.qc_issue		= ahci_qc_issue,
+
+	.irq_handler		= ahci_interrupt,
+	.irq_clear		= ahci_irq_clear,
+
+	.scr_read		= ahci_scr_read,
+	.scr_write		= ahci_scr_write,
+
+	.freeze			= ahci_freeze,
+	.thaw			= ahci_thaw,
+
+	.error_handler		= ahci_vt8251_error_handler,
+	.post_internal_cmd	= ahci_post_internal_cmd,
+
+	.port_suspend		= ahci_port_suspend,
+	.port_resume		= ahci_port_resume,
+
+	.port_start		= ahci_port_start,
+	.port_stop		= ahci_port_stop,
+};
+
 static const struct ata_port_info ahci_port_info[] = {
 	/* board_ahci */
 	{
@@ -288,10 +320,11 @@ static const struct ata_port_info ahci_p
 		.sht		= &ahci_sht,
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-				  ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_NO_NCQ,
+				  ATA_FLAG_SKIP_D2H_BSY |
+				  ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
-		.port_ops	= &ahci_ops,
+		.port_ops	= &ahci_vt8251_ops,
 	},
 };
 
@@ -832,6 +865,31 @@ static int ahci_hardreset(struct ata_por
 	return rc;
 }
 
+static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
+{
+	void __iomem *mmio = ap->host->mmio_base;
+	void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+	int rc;
+
+	DPRINTK("ENTER\n");
+
+	ahci_stop_engine(port_mmio);
+
+	rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
+
+	/* vt8251 needs SError cleared for the port to operate */
+	ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
+
+	ahci_start_engine(port_mmio);
+
+	DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
+
+	/* vt8251 doesn't clear BSY on signature FIS reception,
+	 * request follow-up softreset.
+	 */
+	return rc ?: -EAGAIN;
+}
+
 static void ahci_postreset(struct ata_port *ap, unsigned int *class)
 {
 	void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
@@ -1151,6 +1209,22 @@ static void ahci_error_handler(struct at
 		  ahci_postreset);
 }
 
+static void ahci_vt8251_error_handler(struct ata_port *ap)
+{
+	void __iomem *mmio = ap->host->mmio_base;
+	void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+
+	if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
+		/* restart engine */
+		ahci_stop_engine(port_mmio);
+		ahci_start_engine(port_mmio);
+	}
+
+	/* perform recovery */
+	ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_vt8251_hardreset,
+		  ahci_postreset);
+}
+
 static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/3 #upstream] ahci: kill AHCI_FLAG_RESET_NEEDS_CLO
  2006-11-01  8:58 [PATCH 1/3 #upstream] ahci: kill AHCI_FLAG_RESET_NEEDS_CLO Tejun Heo
  2006-11-01  8:59 ` [PATCH 2/3 #upstream] libata: separate out and export sata_port_hardreset() Tejun Heo
@ 2006-11-01  9:22 ` Jeff Garzik
  1 sibling, 0 replies; 4+ messages in thread
From: Jeff Garzik @ 2006-11-01  9:22 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide

Tejun Heo wrote:
> Now that ahci_softreset() is fixed to automatically perform CLO if
> BSY/DRQ is set on entry, AHCI_FLAG_RESET_NEEDS_CLO is redundant.  Kill
> it.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>

applied 1-3



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-11-01  9:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-01  8:58 [PATCH 1/3 #upstream] ahci: kill AHCI_FLAG_RESET_NEEDS_CLO Tejun Heo
2006-11-01  8:59 ` [PATCH 2/3 #upstream] libata: separate out and export sata_port_hardreset() Tejun Heo
2006-11-01  9:00   ` [PATCH 3/3 #upstream] ahci: update ahci-vt8251 reset sequence Tejun Heo
2006-11-01  9:22 ` [PATCH 1/3 #upstream] ahci: kill AHCI_FLAG_RESET_NEEDS_CLO Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).