linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHSET] libata: various fixes related to EH, take #4
@ 2006-02-10 14:58 Tejun Heo
  2006-02-10 14:58 ` [PATCH 7/9] ata_piix: convert sata to new reset mechanism Tejun Heo
                   ` (9 more replies)
  0 siblings, 10 replies; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: htejun


Hello, Jeff.

< %nn denotes patch nn from the last iteration, #nn in this iteration >

This is the fourth take of new reset mechanism.  4 (%01-%04) out of 11
patches made into upstream in the last iteration [1].  The rest are
acked but haven't been applied because standard reset operations need
more changes before being used.

This patchset is composed of 9 patches.

#01-02	: modify std reset operations such that they act almost
	  identically with ->phy_reset register-wise.
#03-09	: These seven patches are %05-%09 with minor changes.

After #01, the only meaningful difference of the new reset mechanism
from ->phy_reset is that SError is cleared after SATA hardreset.  This
difference is removed by #02.  #02 is separated to make the change
optional.  If #02 gets into upstream, I'll have to submit another
patch to resurrect it later for EH.  Jeff, it's your call.

After #01 and #02, the following differences remain.

1. SStatus access for sata_print_link_status() in ata_std_postreset()
   is at different postion register-wise compared to ->phy_reset.

2. ->phy_reset doesn't proceed with softreset if ata_busy_sleep()
   fails after PHY is waken, but new reset mechanism proceeds anyway.
   Note that the original code is not very consistent regarding this.
   Some drivers (e.g. ata_piix), uses ata_bus_reset() instead of
   sata_phy_reset() and thus doesn't perform ata_busy_sleep() before
   SRST in the first place.

If a low level driver uses ata_std_probeinit() but doesn't implement
softreset, it will end up performing extra phy_resume and
ata_busy_sleep before the actual hardreset sequence compared to
->phy_reset.  This is noted int the comment above ata_std_probeinit().

#08 has been modified not to use ata_std_probeinit() because it only
implements hardreset, but #09 implements softreset and adds
ata_std_probeinit() back; thus, the end result is unchanged.

Thanks.

--
tejun

[1] http://article.gmane.org/gmane.linux.ide/7804


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

* [PATCH 2/9] libata: kill SError clearing in sata_std_hardreset().
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
  2006-02-10 14:58 ` [PATCH 7/9] ata_piix: convert sata to new reset mechanism Tejun Heo
  2006-02-10 14:58 ` [PATCH 4/9] sata_sil24: convert " Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-10 14:58 ` [PATCH 6/9] ata_piix: convert pata to new reset mechanism Tejun Heo
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

Don't clear SError in sata_std_hardreset().  This makes hardreset act
identically to ->phy_reset register-wise.

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

---

 drivers/scsi/libata-core.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

24bff807a5f2bed38aadb4b8aa25bc40791bf2aa
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 8424bd9..38e72c1 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2018,8 +2018,6 @@ int ata_std_softreset(struct ata_port *a
  */
 int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
 {
-	u32 serror;
-
 	DPRINTK("ENTER\n");
 
 	/* Issue phy wake/reset */
@@ -2034,10 +2032,6 @@ int sata_std_hardreset(struct ata_port *
 	/* Bring phy back */
 	sata_phy_resume(ap);
 
-	/* Clear SError */
-	serror = scr_read(ap, SCR_ERROR);
-	scr_write(ap, SCR_ERROR, serror);
-
 	/* TODO: phy layer with polling, timeouts, etc. */
 	if (!sata_dev_present(ap)) {
 		*class = ATA_DEV_NONE;
-- 
1.1.5



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

* [PATCH 6/9] ata_piix: convert pata to new reset mechanism
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
                   ` (2 preceding siblings ...)
  2006-02-10 14:58 ` [PATCH 2/9] libata: kill SError clearing in sata_std_hardreset() Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-11 23:29   ` Jeff Garzik
  2006-02-10 14:58 ` [PATCH 5/9] sata_sil24: add hardreset Tejun Heo
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

Convert ata_piix pata ->phy_reset to new reset mechanism.

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

---

 drivers/scsi/ata_piix.c |   47 +++++++++++++++++++++++++++++++----------------
 1 files changed, 31 insertions(+), 16 deletions(-)

aa17cffcebd940a844e0a8a5a99d2192699c9b4e
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 4933ba2..650c687 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -131,7 +131,7 @@ enum {
 static int piix_init_one (struct pci_dev *pdev,
 				    const struct pci_device_id *ent);
 
-static void piix_pata_phy_reset(struct ata_port *ap);
+static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes);
 static void piix_sata_phy_reset(struct ata_port *ap);
 static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
 static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
@@ -208,7 +208,7 @@ static const struct ata_port_operations 
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
 
-	.phy_reset		= piix_pata_phy_reset,
+	.probe_reset		= piix_pata_probe_reset,
 
 	.bmdma_setup		= ata_bmdma_setup,
 	.bmdma_start		= ata_bmdma_start,
@@ -259,8 +259,7 @@ static struct ata_port_info piix_port_in
 	/* ich5_pata */
 	{
 		.sht		= &piix_sht,
-		.host_flags	= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
-				  PIIX_FLAG_CHECKINTR,
+		.host_flags	= ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 #if 0
 		.mwdma_mask	= 0x06, /* mwdma1-2 */
@@ -285,7 +284,7 @@ static struct ata_port_info piix_port_in
 	/* piix4_pata */
 	{
 		.sht		= &piix_sht,
-		.host_flags	= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+		.host_flags	= ATA_FLAG_SLAVE_POSS,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 #if 0
 		.mwdma_mask	= 0x06, /* mwdma1-2 */
@@ -367,30 +366,46 @@ cbl40:
 }
 
 /**
- *	piix_pata_phy_reset - Probe specified port on PATA host controller
- *	@ap: Port to probe
+ *	piix_pata_postreset - Postreset stuff on PATA host controller
+ *	@ap: Target port
+ *	@classes: Classes of attached devices
  *
- *	Probe PATA phy.
+ *	Postreset processing including cable detection.
  *
  *	LOCKING:
  *	None (inherited from caller).
  */
+static void piix_pata_postreset(struct ata_port *ap, unsigned int *classes)
+{
+	piix_pata_cbl_detect(ap);
+	ata_std_postreset(ap, classes);
+}
 
-static void piix_pata_phy_reset(struct ata_port *ap)
+/**
+ *	piix_pata_probe_reset - Perform reset on PATA port and classify
+ *	@ap: Port to reset
+ *	@classes: Resulting classes of attached devices
+ *
+ *	Reset PATA phy and classify attached devices.
+ *
+ *	LOCKING:
+ *	None (inherited from caller).
+ */
+static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+	int i;
 
 	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) {
-		ata_port_disable(ap);
+		for (i = 0; i < ATA_MAX_DEVICES; i++)
+			classes[i] = ATA_DEV_NONE;
 		printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
-		return;
+		return 0;
 	}
 
-	piix_pata_cbl_detect(ap);
-
-	ata_port_probe(ap);
-
-	ata_bus_reset(ap);
+	return ata_drive_probe_reset(ap, ata_std_probeinit,
+				     ata_std_softreset, NULL,
+				     piix_pata_postreset, classes);
 }
 
 /**
-- 
1.1.5



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

* [PATCH 4/9] sata_sil24: convert to new reset mechanism
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
  2006-02-10 14:58 ` [PATCH 7/9] ata_piix: convert sata to new reset mechanism Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-10 14:58 ` [PATCH 2/9] libata: kill SError clearing in sata_std_hardreset() Tejun Heo
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

Convert sata_sil24 ->phy_reset to new reset mechanism.

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

---

 drivers/scsi/sata_sil24.c |   56 +++++++++++++++++++++++----------------------
 1 files changed, 28 insertions(+), 28 deletions(-)

e616f994715634d1feb81f6e0ac24e34896a4bb1
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 962396b..ccac05a 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -249,7 +249,7 @@ static u8 sil24_check_status(struct ata_
 static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
 static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
 static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-static void sil24_phy_reset(struct ata_port *ap);
+static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes);
 static void sil24_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
 static void sil24_irq_clear(struct ata_port *ap);
@@ -306,7 +306,7 @@ static const struct ata_port_operations 
 
 	.tf_read		= sil24_tf_read,
 
-	.phy_reset		= sil24_phy_reset,
+	.probe_reset		= sil24_probe_reset,
 
 	.qc_prep		= sil24_qc_prep,
 	.qc_issue		= sil24_qc_issue,
@@ -336,8 +336,8 @@ static struct ata_port_info sil24_port_i
 	{
 		.sht		= &sil24_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO |
-				  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
+				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+				  SIL24_NPORTS2FLAG(4),
 		.pio_mask	= 0x1f,			/* pio0-4 */
 		.mwdma_mask	= 0x07,			/* mwdma0-2 */
 		.udma_mask	= 0x3f,			/* udma0-5 */
@@ -347,8 +347,8 @@ static struct ata_port_info sil24_port_i
 	{
 		.sht		= &sil24_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO |
-				  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
+				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+				  SIL24_NPORTS2FLAG(2),
 		.pio_mask	= 0x1f,			/* pio0-4 */
 		.mwdma_mask	= 0x07,			/* mwdma0-2 */
 		.udma_mask	= 0x3f,			/* udma0-5 */
@@ -358,8 +358,8 @@ static struct ata_port_info sil24_port_i
 	{
 		.sht		= &sil24_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO |
-				  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
+				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+				  SIL24_NPORTS2FLAG(1),
 		.pio_mask	= 0x1f,			/* pio0-4 */
 		.mwdma_mask	= 0x07,			/* mwdma0-2 */
 		.udma_mask	= 0x3f,			/* udma0-5 */
@@ -428,7 +428,8 @@ static void sil24_tf_read(struct ata_por
 	*tf = pp->tf;
 }
 
-static int sil24_issue_SRST(struct ata_port *ap)
+static int sil24_softreset(struct ata_port *ap, int verbose,
+			   unsigned int *class)
 {
 	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
 	struct sil24_port_priv *pp = ap->private_data;
@@ -437,6 +438,8 @@ static int sil24_issue_SRST(struct ata_p
 	u32 irq_enable, irq_stat;
 	int cnt;
 
+	DPRINTK("ENTER\n");
+
 	/* temporarily turn off IRQs during SRST */
 	irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
 	writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
@@ -466,30 +469,27 @@ static int sil24_issue_SRST(struct ata_p
 	/* restore IRQs */
 	writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
 
-	if (!(irq_stat & PORT_IRQ_COMPLETE))
-		return -1;
+	if (sata_dev_present(ap)) {
+		if (!(irq_stat & PORT_IRQ_COMPLETE)) {
+			DPRINTK("EXIT, srst failed\n");
+			return -EIO;
+		}
 
-	/* update TF */
-	sil24_update_tf(ap);
+		sil24_update_tf(ap);
+		*class = ata_dev_classify(&pp->tf);
+	}
+	if (*class == ATA_DEV_UNKNOWN)
+		*class = ATA_DEV_NONE;
+
+	DPRINTK("EXIT, class=%u\n", *class);
 	return 0;
 }
 
-static void sil24_phy_reset(struct ata_port *ap)
+static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes)
 {
-	struct sil24_port_priv *pp = ap->private_data;
-
-	__sata_phy_reset(ap);
-	if (ap->flags & ATA_FLAG_PORT_DISABLED)
-		return;
-
-	if (sil24_issue_SRST(ap) < 0) {
-		printk(KERN_ERR DRV_NAME
-		       " ata%u: SRST failed, disabling port\n", ap->id);
-		ap->ops->port_disable(ap);
-		return;
-	}
-
-	ap->device->class = ata_dev_classify(&pp->tf);
+	return ata_drive_probe_reset(ap, ata_std_probeinit,
+				     sil24_softreset, NULL,
+				     ata_std_postreset, classes);
 }
 
 static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
-- 
1.1.5



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

* [PATCH 7/9] ata_piix: convert sata to new reset mechanism
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-11 23:30   ` Jeff Garzik
  2006-02-10 14:58 ` [PATCH 4/9] sata_sil24: convert " Tejun Heo
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

Convert ata_piix sata ->phy_reset to new reset mechanism.

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

---

 drivers/scsi/ata_piix.c |   39 +++++++++++++++++++--------------------
 1 files changed, 19 insertions(+), 20 deletions(-)

9314defd1d310a822bf491b60cddbf9d652ab6e0
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 650c687..0da8076 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -132,7 +132,7 @@ static int piix_init_one (struct pci_dev
 				    const struct pci_device_id *ent);
 
 static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes);
-static void piix_sata_phy_reset(struct ata_port *ap);
+static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes);
 static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
 static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
 
@@ -236,7 +236,7 @@ static const struct ata_port_operations 
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
 
-	.phy_reset		= piix_sata_phy_reset,
+	.probe_reset		= piix_sata_probe_reset,
 
 	.bmdma_setup		= ata_bmdma_setup,
 	.bmdma_start		= ata_bmdma_start,
@@ -273,8 +273,8 @@ static struct ata_port_info piix_port_in
 	/* ich5_sata */
 	{
 		.sht		= &piix_sht,
-		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
-				  PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR,
+		.host_flags	= ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
+				  PIIX_FLAG_CHECKINTR,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
 		.udma_mask	= 0x7f,	/* udma0-6 */
@@ -298,8 +298,7 @@ static struct ata_port_info piix_port_in
 	/* ich6_sata */
 	{
 		.sht		= &piix_sht,
-		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
-				  PIIX_FLAG_COMBINED_ICH6 |
+		.host_flags	= ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
 				  PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
@@ -310,8 +309,7 @@ static struct ata_port_info piix_port_in
 	/* ich6_sata_ahci */
 	{
 		.sht		= &piix_sht,
-		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
-				  PIIX_FLAG_COMBINED_ICH6 |
+		.host_flags	= ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
 				  PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS |
 				  PIIX_FLAG_AHCI,
 		.pio_mask	= 0x1f,	/* pio0-4 */
@@ -456,28 +454,29 @@ static int piix_sata_probe (struct ata_p
 }
 
 /**
- *	piix_sata_phy_reset - Probe specified port on SATA host controller
- *	@ap: Port to probe
+ *	piix_sata_probe_reset - Perform reset on SATA port and classify
+ *	@ap: Port to reset
+ *	@classes: Resulting classes of attached devices
  *
- *	Probe SATA phy.
+ *	Reset SATA phy and classify attached devices.
  *
  *	LOCKING:
  *	None (inherited from caller).
  */
-
-static void piix_sata_phy_reset(struct ata_port *ap)
+static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes)
 {
+	int i;
+
 	if (!piix_sata_probe(ap)) {
-		ata_port_disable(ap);
+		for (i = 0; i < ATA_MAX_DEVICES; i++)
+			classes[i] = ATA_DEV_NONE;
 		printk(KERN_INFO "ata%u: SATA port has no device.\n", ap->id);
-		return;
+		return 0;
 	}
 
-	ap->cbl = ATA_CBL_SATA;
-
-	ata_port_probe(ap);
-
-	ata_bus_reset(ap);
+	return ata_drive_probe_reset(ap, ata_std_probeinit,
+				     ata_std_softreset, NULL,
+				     ata_std_postreset, classes);
 }
 
 /**
-- 
1.1.5



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

* [PATCH 1/9] libata: make new reset act identical to ->phy_reset register-wise
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
                   ` (5 preceding siblings ...)
  2006-02-10 14:58 ` [PATCH 3/9] sata_sil: convert to new reset mechanism Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-10 15:30   ` Jeff Garzik
  2006-02-10 14:58 ` [PATCH 8/9] ahci: convert to new reset mechanism Tejun Heo
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

This patch makes std component operations act identical to ->phy_reset
register-wise except for SError clearing on sata_std_hardreset.

Note that if a driver only implements/uses hardreset, it should not
use ata_std_probeinit() to avoid extra sata_phy_resume() and
ata_busy_sleep() compared to ->phy_reset.

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

---

 drivers/scsi/libata-core.c |   51 +++++++++++++++++++++++++++++---------------
 1 files changed, 34 insertions(+), 17 deletions(-)

132ad18278df23894fe8b0768ef0be8087ce790d
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index b938c7a..8424bd9 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1924,11 +1924,20 @@ static int sata_phy_resume(struct ata_po
  *
  *	@ap is about to be probed.  Initialize it.  This function is
  *	to be used as standard callback for ata_drive_probe_reset().
+ *
+ *	NOTE!!! Do not use this function as probeinit if a low level
+ *	driver implements only hardreset.  Just pass NULL as probeinit
+ *	in that case.  Using this function is probably okay but doing
+ *	so makes reset sequence different from the original
+ *	->phy_reset implementation and Jeff nervous.  :-P
  */
 extern void ata_std_probeinit(struct ata_port *ap)
 {
-	if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read)
+	if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) {
 		sata_phy_resume(ap);
+		if (sata_dev_present(ap))
+			ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+	}
 }
 
 /**
@@ -1954,20 +1963,17 @@ int ata_std_softreset(struct ata_port *a
 
 	DPRINTK("ENTER\n");
 
+	if (ap->ops->scr_read && !sata_dev_present(ap)) {
+		classes[0] = ATA_DEV_NONE;
+		goto out;
+	}
+
 	/* determine if device 0/1 are present */
 	if (ata_devchk(ap, 0))
 		devmask |= (1 << 0);
 	if (slave_possible && ata_devchk(ap, 1))
 		devmask |= (1 << 1);
 
-	/* devchk reports device presence without actual device on
-	 * most SATA controllers.  Check SStatus and turn devmask off
-	 * if link is offline.  Note that we should continue resetting
-	 * even when it seems like there's no device.
-	 */
-	if (ap->ops->scr_read && !sata_dev_present(ap))
-		devmask = 0;
-
 	/* select device 0 again */
 	ap->ops->dev_select(ap, 0);
 
@@ -1989,6 +1995,7 @@ int ata_std_softreset(struct ata_port *a
 	if (slave_possible && err != 0x81)
 		classes[1] = ata_dev_try_classify(ap, 1, &err);
 
+ out:
 	DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
 	return 0;
 }
@@ -2047,6 +2054,8 @@ int sata_std_hardreset(struct ata_port *
 		return -EIO;
 	}
 
+	ap->ops->dev_select(ap, 0);	/* probably unnecessary */
+
 	*class = ata_dev_try_classify(ap, 0, NULL);
 
 	DPRINTK("EXIT, class=%u\n", *class);
@@ -2081,11 +2090,9 @@ void ata_std_postreset(struct ata_port *
 	if (ap->cbl == ATA_CBL_SATA)
 		sata_print_link_status(ap);
 
-	/* bail out if no device is present */
-	if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
-		DPRINTK("EXIT, no device\n");
-		return;
-	}
+	/* re-enable interrupts */
+	if (ap->ioaddr.ctl_addr)	/* FIXME: hack. create a hook instead */
+		ata_irq_on(ap);
 
 	/* is double-select really necessary? */
 	if (classes[0] != ATA_DEV_NONE)
@@ -2093,9 +2100,19 @@ void ata_std_postreset(struct ata_port *
 	if (classes[1] != ATA_DEV_NONE)
 		ap->ops->dev_select(ap, 0);
 
-	/* re-enable interrupts & set up device control */
-	if (ap->ioaddr.ctl_addr)	/* FIXME: hack. create a hook instead */
-		ata_irq_on(ap);
+	/* bail out if no device is present */
+	if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
+		DPRINTK("EXIT, no device\n");
+		return;
+	}
+
+	/* set up device control */
+	if (ap->ioaddr.ctl_addr) {
+		if (ap->flags & ATA_FLAG_MMIO)
+			writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
+		else
+			outb(ap->ctl, ap->ioaddr.ctl_addr);
+	}
 
 	DPRINTK("EXIT\n");
 }
-- 
1.1.5



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

* [PATCH 3/9] sata_sil: convert to new reset mechanism
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
                   ` (4 preceding siblings ...)
  2006-02-10 14:58 ` [PATCH 5/9] sata_sil24: add hardreset Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-10 14:58 ` [PATCH 1/9] libata: make new reset act identical to ->phy_reset register-wise Tejun Heo
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

Convert sata_sil to use new reset mechanism.  sata_sil is fairly
generic and can directly use std routine.

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

---

 drivers/scsi/sata_sil.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

0ae93718b02a7763abfacd0a900b51ba27c6212d
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index f40f25e..bd28877 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -158,7 +158,7 @@ static const struct ata_port_operations 
 	.check_status		= ata_check_status,
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
-	.phy_reset		= sata_phy_reset,
+	.probe_reset		= ata_std_probe_reset,
 	.post_set_mode		= sil_post_set_mode,
 	.bmdma_setup            = ata_bmdma_setup,
 	.bmdma_start            = ata_bmdma_start,
@@ -181,7 +181,7 @@ static const struct ata_port_info sil_po
 	{
 		.sht		= &sil_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+				  ATA_FLAG_MMIO,
 		.pio_mask	= 0x1f,			/* pio0-4 */
 		.mwdma_mask	= 0x07,			/* mwdma0-2 */
 		.udma_mask	= 0x3f,			/* udma0-5 */
@@ -190,8 +190,7 @@ static const struct ata_port_info sil_po
 	{
 		.sht		= &sil_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO |
-				  SIL_FLAG_MOD15WRITE,
+				  ATA_FLAG_MMIO | SIL_FLAG_MOD15WRITE,
 		.pio_mask	= 0x1f,			/* pio0-4 */
 		.mwdma_mask	= 0x07,			/* mwdma0-2 */
 		.udma_mask	= 0x3f,			/* udma0-5 */
@@ -200,7 +199,7 @@ static const struct ata_port_info sil_po
 	{
 		.sht		= &sil_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+				  ATA_FLAG_MMIO,
 		.pio_mask	= 0x1f,			/* pio0-4 */
 		.mwdma_mask	= 0x07,			/* mwdma0-2 */
 		.udma_mask	= 0x3f,			/* udma0-5 */
-- 
1.1.5



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

* [PATCH 5/9] sata_sil24: add hardreset
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
                   ` (3 preceding siblings ...)
  2006-02-10 14:58 ` [PATCH 6/9] ata_piix: convert pata to new reset mechanism Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-10 14:58 ` [PATCH 3/9] sata_sil: convert to new reset mechanism Tejun Heo
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

Now that libata is smart enough to handle both soft and hard resets,
add hardreset method.  Note that sil24 hardreset doesn't supply
signature; still, the new reset mechanism can make good use of it.

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

---

 drivers/scsi/sata_sil24.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

1e7c4c83847442f2e881e04e6a3b8f257dcc241e
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index ccac05a..228a7fa 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -485,10 +485,19 @@ static int sil24_softreset(struct ata_po
 	return 0;
 }
 
+static int sil24_hardreset(struct ata_port *ap, int verbose,
+			   unsigned int *class)
+{
+	unsigned int dummy_class;
+
+	/* sil24 doesn't report device signature after hard reset */
+	return sata_std_hardreset(ap, verbose, &dummy_class);
+}
+
 static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes)
 {
 	return ata_drive_probe_reset(ap, ata_std_probeinit,
-				     sil24_softreset, NULL,
+				     sil24_softreset, sil24_hardreset,
 				     ata_std_postreset, classes);
 }
 
-- 
1.1.5



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

* [PATCH 9/9] ahci: add softreset
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
                   ` (7 preceding siblings ...)
  2006-02-10 14:58 ` [PATCH 8/9] ahci: convert to new reset mechanism Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-10 15:01 ` Sorry, wrong PATCHSET name, it should be [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
  9 siblings, 0 replies; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

Now that libata is smart enought to handle both soft and hard resets,
add softreset method.

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

---

 drivers/scsi/ahci.c |  135 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 134 insertions(+), 1 deletions(-)

264f1acba3f46c66575e135e521d83000c7ccf01
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 9fb97ff..2789274 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -515,6 +515,138 @@ static void ahci_fill_cmd_slot(struct at
 	pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
 }
 
+static int ahci_wait_for_bit(void __iomem *reg, u32 mask, u32 val,
+			     unsigned long interval_msec,
+			     unsigned long timeout_msec)
+{
+	unsigned long timeout;
+	u32 tmp;
+
+	timeout = jiffies + (timeout_msec * HZ) / 1000;
+	do {
+		tmp = readl(reg);
+		if ((tmp & mask) != val)
+			return 0;
+		msleep(interval_msec);
+	} while (time_before(jiffies, timeout));
+
+	return -1;
+}
+
+static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
+{
+	struct ahci_host_priv *hpriv = ap->host_set->private_data;
+	struct ahci_port_priv *pp = ap->private_data;
+	void __iomem *mmio = ap->host_set->mmio_base;
+	void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+	const u32 cmd_fis_len = 5; /* five dwords */
+	const char *reason = NULL;
+	struct ata_taskfile tf;
+	u8 *fis;
+	int rc;
+
+	DPRINTK("ENTER\n");
+
+	/* prepare for SRST (AHCI-1.1 10.4.1) */
+	rc = ahci_stop_engine(ap);
+	if (rc) {
+		reason = "failed to stop engine";
+		goto fail_restart;
+	}
+
+	/* check BUSY/DRQ, perform Command List Override if necessary */
+	ahci_tf_read(ap, &tf);
+	if (tf.command & (ATA_BUSY | ATA_DRQ)) {
+		u32 tmp;
+
+		if (!(hpriv->cap & HOST_CAP_CLO)) {
+			rc = -EIO;
+			reason = "port busy but no CLO";
+			goto fail_restart;
+		}
+
+		tmp = readl(port_mmio + PORT_CMD);
+		tmp |= PORT_CMD_CLO;
+		writel(tmp, port_mmio + PORT_CMD);
+		readl(port_mmio + PORT_CMD); /* flush */
+
+		if (ahci_wait_for_bit(port_mmio + PORT_CMD,
+				      PORT_CMD_CLO, PORT_CMD_CLO, 1, 500)) {
+			rc = -EIO;
+			reason = "CLO failed";
+			goto fail_restart;
+		}
+	}
+
+	/* restart engine */
+	ahci_start_engine(ap);
+
+	ata_tf_init(ap, &tf, 0);
+	fis = pp->cmd_tbl;
+
+	/* issue the first D2H Register FIS */
+	ahci_fill_cmd_slot(ap, cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY);
+
+	tf.ctl |= ATA_SRST;
+	ata_tf_to_fis(&tf, fis, 0);
+	fis[1] &= ~(1 << 7);	/* turn off Command FIS bit */
+
+	writel(1, port_mmio + PORT_CMD_ISSUE);
+	readl(port_mmio + PORT_CMD_ISSUE);	/* flush */
+
+	if (ahci_wait_for_bit(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500)) {
+		rc = -EIO;
+		reason = "1st FIS failed";
+		goto fail;
+	}
+
+	/* spec says at least 5us, but be generous and sleep for 1ms */
+	msleep(1);
+
+	/* issue the second D2H Register FIS */
+	ahci_fill_cmd_slot(ap, cmd_fis_len);
+
+	tf.ctl &= ~ATA_SRST;
+	ata_tf_to_fis(&tf, fis, 0);
+	fis[1] &= ~(1 << 7);	/* turn off Command FIS bit */
+
+	writel(1, port_mmio + PORT_CMD_ISSUE);
+	readl(port_mmio + PORT_CMD_ISSUE);	/* flush */
+
+	/* spec mandates ">= 2ms" before checking status.
+	 * We wait 150ms, because that was the magic delay used for
+	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
+	 * between when the ATA command register is written, and then
+	 * status is checked.  Because waiting for "a while" before
+	 * checking status is fine, post SRST, we perform this magic
+	 * delay here as well.
+	 */
+	msleep(150);
+
+	*class = ATA_DEV_NONE;
+	if (sata_dev_present(ap)) {
+		if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+			rc = -EIO;
+			reason = "device not ready";
+			goto fail;
+		}
+		*class = ahci_dev_classify(ap);
+	}
+
+	DPRINTK("EXIT, class=%u\n", *class);
+	return 0;
+
+ fail_restart:
+	ahci_start_engine(ap);
+ fail:
+	if (verbose)
+		printk(KERN_ERR "ata%u: softreset failed (%s)\n",
+		       ap->id, reason);
+	else
+		DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason);
+	return rc;
+}
+
 static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
 {
 	int rc;
@@ -555,7 +687,8 @@ static void ahci_postreset(struct ata_po
 
 static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes)
 {
-	return ata_drive_probe_reset(ap, NULL, NULL, ahci_hardreset,
+	return ata_drive_probe_reset(ap, ata_std_probeinit,
+				     ahci_softreset, ahci_hardreset,
 				     ahci_postreset, classes);
 }
 
-- 
1.1.5



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

* [PATCH 8/9] ahci: convert to new reset mechanism
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
                   ` (6 preceding siblings ...)
  2006-02-10 14:58 ` [PATCH 1/9] libata: make new reset act identical to ->phy_reset register-wise Tejun Heo
@ 2006-02-10 14:58 ` Tejun Heo
  2006-02-10 14:58 ` [PATCH 9/9] ahci: add softreset Tejun Heo
  2006-02-10 15:01 ` Sorry, wrong PATCHSET name, it should be [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
  9 siblings, 0 replies; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 14:58 UTC (permalink / raw)
  To: jgarzik, albertcc, linux-ide; +Cc: Tejun Heo

Convert ahci ->phy_reset to new reset mechanism.

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

---

 drivers/scsi/ahci.c |   46 +++++++++++++++++++++++++++++-----------------
 1 files changed, 29 insertions(+), 17 deletions(-)

f91eac3e9ceb5fdd5e52a3b6c4e2d53d616b3cc4
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 98ce6bb..9fb97ff 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -190,7 +190,7 @@ static void ahci_scr_write (struct ata_p
 static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
 static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
-static void ahci_phy_reset(struct ata_port *ap);
+static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes);
 static void ahci_irq_clear(struct ata_port *ap);
 static void ahci_eng_timeout(struct ata_port *ap);
 static int ahci_port_start(struct ata_port *ap);
@@ -230,7 +230,7 @@ static const struct ata_port_operations 
 
 	.tf_read		= ahci_tf_read,
 
-	.phy_reset		= ahci_phy_reset,
+	.probe_reset		= ahci_probe_reset,
 
 	.qc_prep		= ahci_qc_prep,
 	.qc_issue		= ahci_qc_issue,
@@ -252,8 +252,7 @@ static const struct ata_port_info ahci_p
 	{
 		.sht		= &ahci_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
-				  ATA_FLAG_PIO_DMA,
+				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
 		.port_ops	= &ahci_ops,
@@ -516,28 +515,35 @@ static void ahci_fill_cmd_slot(struct at
 	pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
 }
 
-static void ahci_phy_reset(struct ata_port *ap)
+static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
 {
-	void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
-	struct ata_device *dev = &ap->device[0];
-	u32 new_tmp, tmp;
+	int rc;
+
+	DPRINTK("ENTER\n");
 
 	ahci_stop_engine(ap);
-	__sata_phy_reset(ap);
+	rc = sata_std_hardreset(ap, verbose, class);
 	ahci_start_engine(ap);
 
-	if (ap->flags & ATA_FLAG_PORT_DISABLED)
-		return;
+	if (rc == 0)
+		*class = ahci_dev_classify(ap);
+	if (*class == ATA_DEV_UNKNOWN)
+		*class = ATA_DEV_NONE;
 
-	dev->class = ahci_dev_classify(ap);
-	if (!ata_dev_present(dev)) {
-		ata_port_disable(ap);
-		return;
-	}
+	DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
+	return rc;
+}
+
+static void ahci_postreset(struct ata_port *ap, unsigned int *class)
+{
+	void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+	u32 new_tmp, tmp;
+
+	ata_std_postreset(ap, class);
 
 	/* Make sure port's ATAPI bit is set appropriately */
 	new_tmp = tmp = readl(port_mmio + PORT_CMD);
-	if (dev->class == ATA_DEV_ATAPI)
+	if (*class == ATA_DEV_ATAPI)
 		new_tmp |= PORT_CMD_ATAPI;
 	else
 		new_tmp &= ~PORT_CMD_ATAPI;
@@ -547,6 +553,12 @@ static void ahci_phy_reset(struct ata_po
 	}
 }
 
+static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes)
+{
+	return ata_drive_probe_reset(ap, NULL, NULL, ahci_hardreset,
+				     ahci_postreset, classes);
+}
+
 static u8 ahci_check_status(struct ata_port *ap)
 {
 	void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
-- 
1.1.5



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

* Re: Sorry, wrong PATCHSET name, it should be [PATCHSET] libata: various fixes related to EH, take #4
  2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
                   ` (8 preceding siblings ...)
  2006-02-10 14:58 ` [PATCH 9/9] ahci: add softreset Tejun Heo
@ 2006-02-10 15:01 ` Tejun Heo
  2006-02-10 15:04   ` Gee, wrong again. libata: [PATCHSET] libata: new reset mechanism, take#4 Tejun Heo
  9 siblings, 1 reply; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 15:01 UTC (permalink / raw)
  To: Tejun Heo; +Cc: jgarzik, albertcc, linux-ide

Tejun Heo wrote:
> Hello, Jeff.
> 
> < %nn denotes patch nn from the last iteration, #nn in this iteration >
> 
> This is the fourth take of new reset mechanism.  4 (%01-%04) out of 11
> patches made into upstream in the last iteration [1].  The rest are
> acked but haven't been applied because standard reset operations need
> more changes before being used.
> 
> This patchset is composed of 9 patches.
> 
> #01-02	: modify std reset operations such that they act almost
> 	  identically with ->phy_reset register-wise.
> #03-09	: These seven patches are %05-%09 with minor changes.
> 
> After #01, the only meaningful difference of the new reset mechanism
> from ->phy_reset is that SError is cleared after SATA hardreset.  This
> difference is removed by #02.  #02 is separated to make the change
> optional.  If #02 gets into upstream, I'll have to submit another
> patch to resurrect it later for EH.  Jeff, it's your call.
> 
> After #01 and #02, the following differences remain.
> 
> 1. SStatus access for sata_print_link_status() in ata_std_postreset()
>    is at different postion register-wise compared to ->phy_reset.
> 
> 2. ->phy_reset doesn't proceed with softreset if ata_busy_sleep()
>    fails after PHY is waken, but new reset mechanism proceeds anyway.
>    Note that the original code is not very consistent regarding this.
>    Some drivers (e.g. ata_piix), uses ata_bus_reset() instead of
>    sata_phy_reset() and thus doesn't perform ata_busy_sleep() before
>    SRST in the first place.
> 
> If a low level driver uses ata_std_probeinit() but doesn't implement
> softreset, it will end up performing extra phy_resume and
> ata_busy_sleep before the actual hardreset sequence compared to
> ->phy_reset.  This is noted int the comment above ata_std_probeinit().
> 
> #08 has been modified not to use ata_std_probeinit() because it only
> implements hardreset, but #09 implements softreset and adds
> ata_std_probeinit() back; thus, the end result is unchanged.
> 
> Thanks.
> 
> --
> tejun
> 
> [1] http://article.gmane.org/gmane.linux.ide/7804
> 


-- 
tejun

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

* Re: Gee, wrong again. libata: [PATCHSET] libata: new reset mechanism, take#4
  2006-02-10 15:01 ` Sorry, wrong PATCHSET name, it should be [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
@ 2006-02-10 15:04   ` Tejun Heo
  0 siblings, 0 replies; 15+ messages in thread
From: Tejun Heo @ 2006-02-10 15:04 UTC (permalink / raw)
  To: Tejun Heo; +Cc: jgarzik, albertcc, linux-ide

And I'm not even smoking something good.  Sorry people.

--
tejun

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

* Re: [PATCH 1/9] libata: make new reset act identical to ->phy_reset register-wise
  2006-02-10 14:58 ` [PATCH 1/9] libata: make new reset act identical to ->phy_reset register-wise Tejun Heo
@ 2006-02-10 15:30   ` Jeff Garzik
  0 siblings, 0 replies; 15+ messages in thread
From: Jeff Garzik @ 2006-02-10 15:30 UTC (permalink / raw)
  To: Tejun Heo; +Cc: albertcc, linux-ide

Tejun Heo wrote:
> This patch makes std component operations act identical to ->phy_reset
> register-wise except for SError clearing on sata_std_hardreset.
> 
> Note that if a driver only implements/uses hardreset, it should not
> use ata_std_probeinit() to avoid extra sata_phy_resume() and
> ata_busy_sleep() compared to ->phy_reset.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>

applied 1-5 to 'upstream'



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

* Re: [PATCH 6/9] ata_piix: convert pata to new reset mechanism
  2006-02-10 14:58 ` [PATCH 6/9] ata_piix: convert pata to new reset mechanism Tejun Heo
@ 2006-02-11 23:29   ` Jeff Garzik
  0 siblings, 0 replies; 15+ messages in thread
From: Jeff Garzik @ 2006-02-11 23:29 UTC (permalink / raw)
  To: Tejun Heo; +Cc: albertcc, linux-ide

Tejun Heo wrote:
> Convert ata_piix pata ->phy_reset to new reset mechanism.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>
> 
> ---
> 
>  drivers/scsi/ata_piix.c |   47 +++++++++++++++++++++++++++++++----------------
>  1 files changed, 31 insertions(+), 16 deletions(-)
> 
> aa17cffcebd940a844e0a8a5a99d2192699c9b4e
> diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
> index 4933ba2..650c687 100644
> --- a/drivers/scsi/ata_piix.c
> +++ b/drivers/scsi/ata_piix.c
> @@ -131,7 +131,7 @@ enum {
>  static int piix_init_one (struct pci_dev *pdev,
>  				    const struct pci_device_id *ent);
>  
> -static void piix_pata_phy_reset(struct ata_port *ap);
> +static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes);
>  static void piix_sata_phy_reset(struct ata_port *ap);
>  static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
>  static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
> @@ -208,7 +208,7 @@ static const struct ata_port_operations 
>  	.exec_command		= ata_exec_command,
>  	.dev_select		= ata_std_dev_select,
>  
> -	.phy_reset		= piix_pata_phy_reset,
> +	.probe_reset		= piix_pata_probe_reset,
>  
>  	.bmdma_setup		= ata_bmdma_setup,
>  	.bmdma_start		= ata_bmdma_start,
> @@ -259,8 +259,7 @@ static struct ata_port_info piix_port_in
>  	/* ich5_pata */
>  	{
>  		.sht		= &piix_sht,
> -		.host_flags	= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
> -				  PIIX_FLAG_CHECKINTR,
> +		.host_flags	= ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR,
>  		.pio_mask	= 0x1f,	/* pio0-4 */
>  #if 0
>  		.mwdma_mask	= 0x06, /* mwdma1-2 */
> @@ -285,7 +284,7 @@ static struct ata_port_info piix_port_in
>  	/* piix4_pata */
>  	{
>  		.sht		= &piix_sht,
> -		.host_flags	= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
> +		.host_flags	= ATA_FLAG_SLAVE_POSS,
>  		.pio_mask	= 0x1f,	/* pio0-4 */
>  #if 0
>  		.mwdma_mask	= 0x06, /* mwdma1-2 */
> @@ -367,30 +366,46 @@ cbl40:
>  }
>  
>  /**
> - *	piix_pata_phy_reset - Probe specified port on PATA host controller
> - *	@ap: Port to probe
> + *	piix_pata_postreset - Postreset stuff on PATA host controller
> + *	@ap: Target port
> + *	@classes: Classes of attached devices
>   *
> - *	Probe PATA phy.
> + *	Postreset processing including cable detection.
>   *
>   *	LOCKING:
>   *	None (inherited from caller).
>   */
> +static void piix_pata_postreset(struct ata_port *ap, unsigned int *classes)
> +{
> +	piix_pata_cbl_detect(ap);
> +	ata_std_postreset(ap, classes);
> +}
>  
> -static void piix_pata_phy_reset(struct ata_port *ap)
> +/**
> + *	piix_pata_probe_reset - Perform reset on PATA port and classify
> + *	@ap: Port to reset
> + *	@classes: Resulting classes of attached devices
> + *
> + *	Reset PATA phy and classify attached devices.
> + *
> + *	LOCKING:
> + *	None (inherited from caller).
> + */
> +static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes)
>  {
>  	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
> +	int i;
>  
>  	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) {
> -		ata_port_disable(ap);
> +		for (i = 0; i < ATA_MAX_DEVICES; i++)
> +			classes[i] = ATA_DEV_NONE;

ACK except for the above loop.  The above is really a regression, since 
its hand-coding something in a driver that libata should really be 
responsible for.

Whether you can ata_port_disable() or create a new function, the driver 
should be making a function call not hand-coding the loop.

Think about it conceptually:  the driver is really requesting that 
libata mark all devices on this port non-existent.  If you ever need to 
change the definition of non-existent (as this patch does, in fact), 
then its much easier to modify a function in libata once, rather than 
touch each driver as necessary.

	Jeff




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

* Re: [PATCH 7/9] ata_piix: convert sata to new reset mechanism
  2006-02-10 14:58 ` [PATCH 7/9] ata_piix: convert sata to new reset mechanism Tejun Heo
@ 2006-02-11 23:30   ` Jeff Garzik
  0 siblings, 0 replies; 15+ messages in thread
From: Jeff Garzik @ 2006-02-11 23:30 UTC (permalink / raw)
  To: Tejun Heo; +Cc: albertcc, linux-ide

Tejun Heo wrote:
> Convert ata_piix sata ->phy_reset to new reset mechanism.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>
> 
> ---
> 
>  drivers/scsi/ata_piix.c |   39 +++++++++++++++++++--------------------
>  1 files changed, 19 insertions(+), 20 deletions(-)
> 
> 9314defd1d310a822bf491b60cddbf9d652ab6e0
> diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
> index 650c687..0da8076 100644
> --- a/drivers/scsi/ata_piix.c
> +++ b/drivers/scsi/ata_piix.c
> @@ -132,7 +132,7 @@ static int piix_init_one (struct pci_dev
>  				    const struct pci_device_id *ent);
>  
>  static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes);
> -static void piix_sata_phy_reset(struct ata_port *ap);
> +static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes);
>  static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
>  static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
>  
> @@ -236,7 +236,7 @@ static const struct ata_port_operations 
>  	.exec_command		= ata_exec_command,
>  	.dev_select		= ata_std_dev_select,
>  
> -	.phy_reset		= piix_sata_phy_reset,
> +	.probe_reset		= piix_sata_probe_reset,
>  
>  	.bmdma_setup		= ata_bmdma_setup,
>  	.bmdma_start		= ata_bmdma_start,
> @@ -273,8 +273,8 @@ static struct ata_port_info piix_port_in
>  	/* ich5_sata */
>  	{
>  		.sht		= &piix_sht,
> -		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
> -				  PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR,
> +		.host_flags	= ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
> +				  PIIX_FLAG_CHECKINTR,
>  		.pio_mask	= 0x1f,	/* pio0-4 */
>  		.mwdma_mask	= 0x07, /* mwdma0-2 */
>  		.udma_mask	= 0x7f,	/* udma0-6 */
> @@ -298,8 +298,7 @@ static struct ata_port_info piix_port_in
>  	/* ich6_sata */
>  	{
>  		.sht		= &piix_sht,
> -		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
> -				  PIIX_FLAG_COMBINED_ICH6 |
> +		.host_flags	= ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
>  				  PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS,
>  		.pio_mask	= 0x1f,	/* pio0-4 */
>  		.mwdma_mask	= 0x07, /* mwdma0-2 */
> @@ -310,8 +309,7 @@ static struct ata_port_info piix_port_in
>  	/* ich6_sata_ahci */
>  	{
>  		.sht		= &piix_sht,
> -		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
> -				  PIIX_FLAG_COMBINED_ICH6 |
> +		.host_flags	= ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
>  				  PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS |
>  				  PIIX_FLAG_AHCI,
>  		.pio_mask	= 0x1f,	/* pio0-4 */
> @@ -456,28 +454,29 @@ static int piix_sata_probe (struct ata_p
>  }
>  
>  /**
> - *	piix_sata_phy_reset - Probe specified port on SATA host controller
> - *	@ap: Port to probe
> + *	piix_sata_probe_reset - Perform reset on SATA port and classify
> + *	@ap: Port to reset
> + *	@classes: Resulting classes of attached devices
>   *
> - *	Probe SATA phy.
> + *	Reset SATA phy and classify attached devices.
>   *
>   *	LOCKING:
>   *	None (inherited from caller).
>   */
> -
> -static void piix_sata_phy_reset(struct ata_port *ap)
> +static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes)
>  {
> +	int i;
> +
>  	if (!piix_sata_probe(ap)) {
> -		ata_port_disable(ap);
> +		for (i = 0; i < ATA_MAX_DEVICES; i++)
> +			classes[i] = ATA_DEV_NONE;

Same comment as previous patch.

	Jeff




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

end of thread, other threads:[~2006-02-11 23:30 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-02-10 14:58 [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
2006-02-10 14:58 ` [PATCH 7/9] ata_piix: convert sata to new reset mechanism Tejun Heo
2006-02-11 23:30   ` Jeff Garzik
2006-02-10 14:58 ` [PATCH 4/9] sata_sil24: convert " Tejun Heo
2006-02-10 14:58 ` [PATCH 2/9] libata: kill SError clearing in sata_std_hardreset() Tejun Heo
2006-02-10 14:58 ` [PATCH 6/9] ata_piix: convert pata to new reset mechanism Tejun Heo
2006-02-11 23:29   ` Jeff Garzik
2006-02-10 14:58 ` [PATCH 5/9] sata_sil24: add hardreset Tejun Heo
2006-02-10 14:58 ` [PATCH 3/9] sata_sil: convert to new reset mechanism Tejun Heo
2006-02-10 14:58 ` [PATCH 1/9] libata: make new reset act identical to ->phy_reset register-wise Tejun Heo
2006-02-10 15:30   ` Jeff Garzik
2006-02-10 14:58 ` [PATCH 8/9] ahci: convert to new reset mechanism Tejun Heo
2006-02-10 14:58 ` [PATCH 9/9] ahci: add softreset Tejun Heo
2006-02-10 15:01 ` Sorry, wrong PATCHSET name, it should be [PATCHSET] libata: various fixes related to EH, take #4 Tejun Heo
2006-02-10 15:04   ` Gee, wrong again. libata: [PATCHSET] libata: new reset mechanism, take#4 Tejun Heo

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