* [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).