* [PATCH 01/12] libata: export ata_busy_sleep
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-27 4:18 ` Jeff Garzik
2006-01-24 8:05 ` [PATCH 07/12] sata_sil24: convert to new reset mechanism Tejun Heo
` (10 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +Cc: Tejun Heo
Export ata_busy_sleep(), to be used by low level driver reset functions.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 9 +++------
include/linux/libata.h | 3 +++
2 files changed, 6 insertions(+), 6 deletions(-)
902e47427cf54147ffa1450794b5d953696ea10e
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index a6be973..bc13729 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -61,9 +61,6 @@
#include "libata.h"
-static unsigned int ata_busy_sleep (struct ata_port *ap,
- unsigned long tmout_pat,
- unsigned long tmout);
static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev);
static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
static void ata_set_mode(struct ata_port *ap);
@@ -2007,9 +2004,8 @@ err_out:
*
*/
-static unsigned int ata_busy_sleep (struct ata_port *ap,
- unsigned long tmout_pat,
- unsigned long tmout)
+unsigned int ata_busy_sleep (struct ata_port *ap,
+ unsigned long tmout_pat, unsigned long tmout)
{
unsigned long timer_start, timeout;
u8 status;
@@ -5207,6 +5203,7 @@ EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
+EXPORT_SYMBOL_GPL(ata_busy_sleep);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_error);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 7837ba3..b33f035 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -503,6 +503,9 @@ extern int ata_scsi_device_suspend(struc
extern int ata_device_resume(struct ata_port *, struct ata_device *);
extern int ata_device_suspend(struct ata_port *, struct ata_device *);
extern int ata_ratelimit(void);
+extern unsigned int ata_busy_sleep(struct ata_port *ap,
+ unsigned long timeout_pat,
+ unsigned long timeout);
/*
* Default driver ops implementations
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCHSET] libata: new reset mechanism, take#2
@ 2006-01-24 8:05 Tejun Heo
2006-01-24 8:05 ` [PATCH 01/12] libata: export ata_busy_sleep Tejun Heo
` (11 more replies)
0 siblings, 12 replies; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +Cc: htejun
Hello, all.
This is the second take of new reset mechanism patchset and against
upstream-2.6.17 + eh-misc-updates patchset + three ahci update patches
I've sent yesterday.
The goals of new reset mechanism are.
* Do not allow individual reset methods manipulate libata internal
data structures (e.g. disable port) to give more control to higher
driving logic (e.g. to allow retries).
* Goes hand-in-hand with above. Make low level operations easily
shareable with other uses (probe and EH).
* Minimize code duplications but yet allow flexibility if needed.
Major difference from the first take is that core layer doesn't
directly drive resets anymore. It just calls ->probe_reset and the
rest is upto the low level driver. However, as reset driving logic is
identical for most drivers, helper routines are supplied such that low
level drivers only have to implement supported reset operations.
Jeff, I think the above change hopefully resolves your concern about
fixed driving logic. The other issue was regarding how reset itself
should be performed - resets are event-driven in nature and should be
implemented accordingly as a qc protocol. I still disagree and don't
really see how it can be done. My rationales are in the following two
messages. Can you please share your thoughts in deeper detail?
http://marc.theaimsgroup.com/?l=linux-ide&m=113497224219265&w=2
http://marc.theaimsgroup.com/?l=linux-ide&m=113497644716191&w=2
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 09/12] ata_piix: convert pata to new reset mechanism
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (9 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 12/12] ahci: add softreset Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-24 8:05 ` [PATCH 05/12] libata: implement standard reset component operations and ->probe_reset Tejun Heo
11 siblings, 0 replies; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +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 | 46 ++++++++++++++++++++++++++++++----------------
1 files changed, 30 insertions(+), 16 deletions(-)
3e72273956b2974ad50165c34b278164fd4094d4
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index fc3ca05..657d3f3 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -129,7 +129,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);
@@ -205,7 +205,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,
@@ -256,8 +256,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 */
@@ -282,7 +281,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 */
@@ -363,30 +362,45 @@ 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_softreset, NULL,
+ piix_pata_postreset, classes);
}
/**
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 02/12] libata: modify ata_dev_try_classify
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (3 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 11/12] ahci: convert " Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-27 4:20 ` Jeff Garzik
2006-01-24 8:05 ` [PATCH 04/12] libata: implement ata_drive_probe_reset() Tejun Heo
` (6 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +Cc: Tejun Heo
Make ata_dev_try_classify take @r_err to store tf error register value
on completion and return device class instead of directly manipulating
dev->class. This is preparation for new reset mechanism.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 30 ++++++++++++++++--------------
1 files changed, 16 insertions(+), 14 deletions(-)
0ac93b37ce5955cee51d85fa2810cb40b8909c33
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index bc13729..e10169d 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -830,6 +830,7 @@ unsigned int ata_dev_classify(const stru
* ata_dev_try_classify - Parse returned ATA device signature
* @ap: ATA channel to examine
* @device: Device to examine (starting at zero)
+ * @r_err: Value of error register on completion
*
* After an event -- SRST, E.D.D., or SATA COMRESET -- occurs,
* an ATA/ATAPI-defined set of values is placed in the ATA
@@ -842,11 +843,14 @@ unsigned int ata_dev_classify(const stru
*
* LOCKING:
* caller.
+ *
+ * RETURNS:
+ * Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE.
*/
-static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
+static unsigned int
+ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err)
{
- struct ata_device *dev = &ap->device[device];
struct ata_taskfile tf;
unsigned int class;
u8 err;
@@ -857,8 +861,8 @@ static u8 ata_dev_try_classify(struct at
ap->ops->tf_read(ap, &tf);
err = tf.feature;
-
- dev->class = ATA_DEV_NONE;
+ if (r_err)
+ *r_err = err;
/* see if device passed diags */
if (err == 1)
@@ -866,18 +870,16 @@ static u8 ata_dev_try_classify(struct at
else if ((device == 0) && (err == 0x81))
/* do nothing */ ;
else
- return err;
+ return ATA_DEV_NONE;
- /* determine if device if ATA or ATAPI */
+ /* determine if device is ATA or ATAPI */
class = ata_dev_classify(&tf);
+
if (class == ATA_DEV_UNKNOWN)
- return err;
+ return ATA_DEV_NONE;
if ((class == ATA_DEV_ATA) && (ata_chk_status(ap) == 0))
- return err;
-
- dev->class = class;
-
- return err;
+ return ATA_DEV_NONE;
+ return class;
}
/**
@@ -2224,9 +2226,9 @@ void ata_bus_reset(struct ata_port *ap)
/*
* determine by signature whether we have ATA or ATAPI devices
*/
- err = ata_dev_try_classify(ap, 0);
+ ap->device[0].class = ata_dev_try_classify(ap, 0, &err);
if ((slave_possible) && (err != 0x81))
- ata_dev_try_classify(ap, 1);
+ ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
/* re-enable interrupts */
if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 03/12] libata: new ->probe_reset operation
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (6 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 08/12] sata_sil24: add hardreset Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-24 8:05 ` [PATCH 06/12] sata_sil: convert to new reset mechanism Tejun Heo
` (3 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +Cc: Tejun Heo
Add new ->probe_reset operation to ata_port_operations obsoleting
->phy_reset. The main difference from ->phy_reset is that the new
operation is not allowed to manipulate libata internals directly.
It's not allowed to configure or disable the port or devices. It can
only succeed or fail and classify attached devices into passed
@classes.
This change gives more control to higher level and eases sharing reset
methods with EH.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 19 ++++++++++++++++++-
include/linux/libata.h | 8 +++++---
2 files changed, 23 insertions(+), 4 deletions(-)
65ce0d036067942117a705c7293aa544804e47a1
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index e10169d..c70151a 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1532,7 +1532,24 @@ static int ata_bus_probe(struct ata_port
{
unsigned int i, found = 0;
- ap->ops->phy_reset(ap);
+ if (ap->ops->probe_reset) {
+ unsigned int classes[ATA_MAX_DEVICES];
+ int rc;
+
+ ata_port_probe(ap);
+
+ rc = ap->ops->probe_reset(ap, classes);
+ if (rc == 0) {
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ ap->device[i].class = classes[i];
+ } else {
+ printk(KERN_ERR "ata%u: probe reset failed, "
+ "disabling port\n", ap->id);
+ ata_port_disable(ap);
+ }
+ } else
+ ap->ops->phy_reset(ap);
+
if (ap->flags & ATA_FLAG_PORT_DISABLED)
goto err_out;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index b33f035..6f36d9a 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -148,9 +148,9 @@ enum {
ATA_FLAG_PORT_DISABLED = (1 << 2), /* port is disabled, ignore it */
ATA_FLAG_SATA = (1 << 3),
ATA_FLAG_NO_LEGACY = (1 << 4), /* no legacy mode check */
- ATA_FLAG_SRST = (1 << 5), /* use ATA SRST, not E.D.D. */
+ ATA_FLAG_SRST = (1 << 5), /* (obsolete) use ATA SRST, not E.D.D. */
ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */
- ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */
+ ATA_FLAG_SATA_RESET = (1 << 7), /* (obsolete) use COMRESET */
ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */
ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once
* proper HSM is in place. */
@@ -422,7 +422,9 @@ struct ata_port_operations {
u8 (*check_altstatus)(struct ata_port *ap);
void (*dev_select)(struct ata_port *ap, unsigned int device);
- void (*phy_reset) (struct ata_port *ap);
+ void (*phy_reset) (struct ata_port *ap); /* obsolete */
+ int (*probe_reset) (struct ata_port *ap, unsigned int *classes);
+
void (*post_set_mode) (struct ata_port *ap);
int (*check_atapi_dma) (struct ata_queued_cmd *qc);
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 04/12] libata: implement ata_drive_probe_reset()
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (4 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 02/12] libata: modify ata_dev_try_classify Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-28 1:58 ` Jeff Garzik
2006-01-24 8:05 ` [PATCH 08/12] sata_sil24: add hardreset Tejun Heo
` (5 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +Cc: Tejun Heo
Most low level drivers share supported reset/classify actions and
sequence. This patch implements ata_drive_probe_reset() which helps
constructing ->probe_reset from three component operations -
softreset, hardreset and postreset. This minimizes duplicate code and
yet allows flexibility if needed. The three component operations can
also be shared by EH later.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 89 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/libata.h | 5 ++
2 files changed, 94 insertions(+), 0 deletions(-)
a0161772ae1a16f1a4ffb5f830752ccc3bf44e9f
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index c70151a..48aa57e 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2280,6 +2280,94 @@ err_out:
DPRINTK("EXIT\n");
}
+static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
+ ata_postreset_fn_t postreset,
+ unsigned int *classes)
+{
+ int i, rc;
+
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ classes[i] = ATA_DEV_UNKNOWN;
+
+ rc = reset(ap, 0, classes);
+ if (rc)
+ return rc;
+
+ /* If any class isn't ATA_DEV_UNKNOWN, consider classification
+ * is complete and convert all ATA_DEV_UNKNOWN to
+ * ATA_DEV_NONE.
+ */
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ if (classes[i] != ATA_DEV_UNKNOWN)
+ break;
+
+ if (i < ATA_MAX_DEVICES)
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ if (classes[i] == ATA_DEV_UNKNOWN)
+ classes[i] = ATA_DEV_NONE;
+
+ if (postreset)
+ postreset(ap, classes);
+
+ return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV;
+}
+
+/**
+ * ata_drive_probe_reset - Perform probe reset with given methods
+ * @ap: port to reset
+ * @softreset: softreset method (can be NULL)
+ * @hardreset: hardreset method (can be NULL)
+ * @postreset: postreset method (can be NULL)
+ * @classes: resulting classes of attached devices
+ *
+ * Reset the specified port and classify attached devices using
+ * given methods. This function prefers softreset but tries all
+ * possible reset sequences to reset and classify devices. This
+ * function is intended to be used for constructing ->probe_reset
+ * callback by low level drivers.
+ *
+ * Reset methods should follow the following rules.
+ *
+ * - Return 0 on sucess, -errno on failure.
+ * - If classification is supported, fill classes[] with
+ * recognized class codes.
+ * - If classification is not supported, leave classes[] alone.
+ * - If verbose is non-zero, print error message on failure;
+ * otherwise, shut up.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -EINVAL if no reset method is avaliable, -ENODEV
+ * if classification fails, and any error code from reset
+ * methods.
+ */
+int ata_drive_probe_reset(struct ata_port *ap,
+ ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+ ata_postreset_fn_t postreset, unsigned int *classes)
+{
+ int rc = -EINVAL;
+
+ if (softreset) {
+ rc = do_probe_reset(ap, softreset, postreset, classes);
+ if (rc == 0)
+ return 0;
+ }
+
+ if (!hardreset)
+ return rc;
+
+ rc = do_probe_reset(ap, hardreset, postreset, classes);
+ if (rc == 0 || rc != -ENODEV)
+ return rc;
+
+ if (softreset)
+ rc = do_probe_reset(ap, softreset, postreset, classes);
+
+ return rc;
+}
+
static void ata_pr_blacklisted(const struct ata_port *ap,
const struct ata_device *dev)
{
@@ -5220,6 +5308,7 @@ EXPORT_SYMBOL_GPL(ata_port_probe);
EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
+EXPORT_SYMBOL_GPL(ata_drive_probe_reset);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_busy_sleep);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 6f36d9a..3d7392e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -244,6 +244,8 @@ struct ata_queued_cmd;
/* typedefs */
typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
+typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *);
+typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *);
struct ata_ioports {
unsigned long cmd_addr;
@@ -481,6 +483,9 @@ extern void ata_port_probe(struct ata_po
extern void __sata_phy_reset(struct ata_port *ap);
extern void sata_phy_reset(struct ata_port *ap);
extern void ata_bus_reset(struct ata_port *ap);
+extern int ata_drive_probe_reset(struct ata_port *ap,
+ ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+ ata_postreset_fn_t postreset, unsigned int *classes);
extern void ata_port_disable(struct ata_port *);
extern void ata_std_ports(struct ata_ioports *ioaddr);
#ifdef CONFIG_PCI
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 06/12] sata_sil: convert to new reset mechanism
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (7 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 03/12] libata: new ->probe_reset operation Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-28 18:09 ` Jeff Garzik
2006-01-24 8:05 ` [PATCH 12/12] ahci: add softreset Tejun Heo
` (2 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +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(-)
48aa3f1d130e624f5789307286aacd6880b7ac0e
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index b017f85..6c8becc 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -157,7 +157,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,
@@ -180,7 +180,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 */
@@ -189,8 +189,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 */
@@ -199,7 +198,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.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 07/12] sata_sil24: convert to new reset mechanism
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
2006-01-24 8:05 ` [PATCH 01/12] libata: export ata_busy_sleep Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-24 8:05 ` [PATCH 10/12] ata_piix: convert sata " Tejun Heo
` (9 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +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 | 55 ++++++++++++++++++++++-----------------------
1 files changed, 27 insertions(+), 28 deletions(-)
0e78d1ce36a30c8e8168af303579c248e32467f1
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 1160fda..f884c31 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);
@@ -305,7 +305,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,
@@ -335,8 +335,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 */
@@ -346,8 +346,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 */
@@ -357,8 +357,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 */
@@ -427,7 +427,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;
@@ -436,6 +437,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);
@@ -465,30 +468,26 @@ 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, sil24_softreset, NULL,
+ ata_std_postreset, classes);
}
static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 10/12] ata_piix: convert sata to new reset mechanism
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
2006-01-24 8:05 ` [PATCH 01/12] libata: export ata_busy_sleep Tejun Heo
2006-01-24 8:05 ` [PATCH 07/12] sata_sil24: convert to new reset mechanism Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-24 8:05 ` [PATCH 11/12] ahci: convert " Tejun Heo
` (8 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +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 | 43 +++++++++++++++++++++----------------------
1 files changed, 21 insertions(+), 22 deletions(-)
06160eed7c3ea396b25298f0e7a92d81e15cb3f2
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 657d3f3..f312ea9 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -130,7 +130,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);
@@ -233,7 +233,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,
@@ -270,8 +270,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 */
@@ -295,9 +295,8 @@ static struct ata_port_info piix_port_in
/* ich6_sata */
{
.sht = &piix_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
- PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
- ATA_FLAG_SLAVE_POSS,
+ .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
+ PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
@@ -307,9 +306,9 @@ 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 | PIIX_FLAG_CHECKINTR |
- ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
+ .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
+ PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS |
+ PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
@@ -451,28 +450,28 @@ 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_softreset, NULL,
+ ata_std_postreset, classes);
}
/**
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 08/12] sata_sil24: add hardreset
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (5 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 04/12] libata: implement ata_drive_probe_reset() Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-24 8:05 ` [PATCH 03/12] libata: new ->probe_reset operation Tejun Heo
` (4 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +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(-)
873ad4e86a46fa83982f694d56d2b9e52d0c2b6a
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index f884c31..f2a4e01 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -484,9 +484,18 @@ 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, sil24_softreset, NULL,
+ return ata_drive_probe_reset(ap, sil24_softreset, sil24_hardreset,
ata_std_postreset, classes);
}
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 05/12] libata: implement standard reset component operations and ->probe_reset
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (10 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 09/12] ata_piix: convert pata to new reset mechanism Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-28 1:58 ` Jeff Garzik
11 siblings, 1 reply; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +Cc: Tejun Heo
Implement SRST, COMRESET and standard postreset component operations
for ata_drive_probe_reset(), and use these three functions to
implement ata_std_probe_reset.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 206 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/libata.h | 6 +
2 files changed, 212 insertions(+), 0 deletions(-)
254523d00d03d4948a7452b0cbf04af7cb11f4fe
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 48aa57e..f6511bd 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2280,6 +2280,208 @@ err_out:
DPRINTK("EXIT\n");
}
+/**
+ * ata_std_softreset - reset host port via ATA SRST
+ * @ap: port to reset
+ * @verbose: fail verbosely
+ * @classes: resulting classes of attached devices
+ *
+ * Reset host port using ATA SRST. This function is to be used
+ * as standard callback for ata_drive_*_reset() functions.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
+{
+ unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+ unsigned int devmask = 0, err_mask;
+ u8 err;
+
+ DPRINTK("ENTER\n");
+
+ /* 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);
+
+ /* issue bus reset */
+ DPRINTK("about to softreset, devmask=%x\n", devmask);
+ err_mask = ata_bus_softreset(ap, devmask);
+ if (err_mask) {
+ if (verbose)
+ printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
+ ap->id, err_mask);
+ else
+ DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n",
+ err_mask);
+ return -EIO;
+ }
+
+ /* determine by signature whether we have ATA or ATAPI devices */
+ classes[0] = ata_dev_try_classify(ap, 0, &err);
+ if (slave_possible && err != 0x81)
+ classes[1] = ata_dev_try_classify(ap, 1, &err);
+
+ DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
+ return 0;
+}
+
+/**
+ * sata_std_hardreset - reset host port via SATA phy reset
+ * @ap: port to reset
+ * @verbose: fail verbosely
+ * @class: resulting class of attached device
+ *
+ * SATA phy-reset host port using DET bits of SControl register.
+ * This function is to be used as standard callback for
+ * ata_drive_*_reset().
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+{
+ u32 sstatus, serror;
+ unsigned long timeout = jiffies + (HZ * 5);
+
+ DPRINTK("ENTER\n");
+
+ /* Issue phy wake/reset */
+ scr_write_flush(ap, SCR_CONTROL, 0x301);
+
+ /*
+ * Couldn't find anything in SATA I/II specs, but AHCI-1.1
+ * 10.4.2 says at least 1 ms.
+ */
+ msleep(1);
+
+ scr_write_flush(ap, SCR_CONTROL, 0x300);
+
+ /* Wait for phy to become ready, if necessary. */
+ do {
+ msleep(200);
+ sstatus = scr_read(ap, SCR_STATUS);
+ if ((sstatus & 0xf) != 1)
+ break;
+ } while (time_before(jiffies, timeout));
+
+ /* 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;
+ DPRINTK("EXIT, link offline\n");
+ return 0;
+ }
+
+ if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+ if (verbose)
+ printk(KERN_ERR "ata%u: COMRESET failed "
+ "(device not ready)\n", ap->id);
+ else
+ DPRINTK("EXIT, device not ready\n");
+ return -EIO;
+ }
+
+ *class = ata_dev_try_classify(ap, 0, NULL);
+
+ DPRINTK("EXIT, class=%u\n", *class);
+ return 0;
+}
+
+/**
+ * ata_std_postreset - standard postreset callback
+ * @ap: the target ata_port
+ * @classes: classes of attached devices
+ *
+ * This function is invoked after a successful reset. Note that
+ * the device might have been reset more than once using
+ * different reset methods before postreset is invoked.
+ * postreset is also reponsible for setting cable type.
+ *
+ * This function is to be used as standard callback for
+ * ata_drive_*_reset().
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ */
+void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
+{
+ DPRINTK("ENTER\n");
+
+ /* set cable type */
+ if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA)
+ ap->cbl = ATA_CBL_SATA;
+
+ /* print link status */
+ 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;
+ }
+
+ /* is double-select really necessary? */
+ if (classes[0] != ATA_DEV_NONE)
+ ap->ops->dev_select(ap, 1);
+ 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);
+
+ DPRINTK("EXIT\n");
+}
+
+/**
+ * ata_std_probe_reset - standard probe reset method
+ * @ap: prot to perform probe-reset
+ * @classes: resulting classes of attached devices
+ *
+ * The stock off-the-shelf ->probe_reset method.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
+{
+ ata_reset_fn_t hardreset;
+
+ hardreset = NULL;
+ if (ap->cbl == ATA_CBL_SATA && ap->ops->scr_read)
+ hardreset = sata_std_hardreset;
+
+ return ata_drive_probe_reset(ap, ata_std_softreset, hardreset,
+ ata_std_postreset, classes);
+}
+
static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
ata_postreset_fn_t postreset,
unsigned int *classes)
@@ -5308,6 +5510,10 @@ EXPORT_SYMBOL_GPL(ata_port_probe);
EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
+EXPORT_SYMBOL_GPL(ata_std_softreset);
+EXPORT_SYMBOL_GPL(sata_std_hardreset);
+EXPORT_SYMBOL_GPL(ata_std_postreset);
+EXPORT_SYMBOL_GPL(ata_std_probe_reset);
EXPORT_SYMBOL_GPL(ata_drive_probe_reset);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 3d7392e..f4cd1eb 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -486,6 +486,11 @@ extern void ata_bus_reset(struct ata_por
extern int ata_drive_probe_reset(struct ata_port *ap,
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
ata_postreset_fn_t postreset, unsigned int *classes);
+extern int ata_std_softreset(struct ata_port *ap, int verbose,
+ unsigned int *classes);
+extern int sata_std_hardreset(struct ata_port *ap, int verbose,
+ unsigned int *class);
+extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
extern void ata_port_disable(struct ata_port *);
extern void ata_std_ports(struct ata_ioports *ioaddr);
#ifdef CONFIG_PCI
@@ -526,6 +531,7 @@ extern void ata_std_dev_select (struct a
extern u8 ata_check_status(struct ata_port *ap);
extern u8 ata_altstatus(struct ata_port *ap);
extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
+extern int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes);
extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap);
extern void ata_host_stop (struct ata_host_set *host_set);
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 12/12] ahci: add softreset
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (8 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 06/12] sata_sil: convert to new reset mechanism Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-24 8:05 ` [PATCH 09/12] ata_piix: convert pata to new reset mechanism Tejun Heo
2006-01-24 8:05 ` [PATCH 05/12] libata: implement standard reset component operations and ->probe_reset Tejun Heo
11 siblings, 0 replies; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +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 | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 133 insertions(+), 1 deletions(-)
8796cd07b5183339240083c14714700a46821ae7
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index c5a1ba6..81ba5f5 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -510,6 +510,138 @@ static inline void ahci_fill_cmd_slot(st
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;
@@ -550,7 +682,7 @@ 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, ahci_hardreset,
+ return ata_drive_probe_reset(ap, ahci_softreset, ahci_hardreset,
ahci_postreset, classes);
}
--
1.1.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 11/12] ahci: convert to new reset mechanism
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
` (2 preceding siblings ...)
2006-01-24 8:05 ` [PATCH 10/12] ata_piix: convert sata " Tejun Heo
@ 2006-01-24 8:05 ` Tejun Heo
2006-01-24 8:05 ` [PATCH 02/12] libata: modify ata_dev_try_classify Tejun Heo
` (7 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Tejun Heo @ 2006-01-24 8:05 UTC (permalink / raw)
To: jgarzik, linux-ide, albertcc; +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(-)
73d592b3ebb6520d3f87b1cfcd94c323be2d8889
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 66402ef..c5a1ba6 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);
@@ -229,7 +229,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,
@@ -251,8 +251,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,
@@ -511,28 +510,35 @@ static inline void ahci_fill_cmd_slot(st
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;
@@ -542,6 +548,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, 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.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 01/12] libata: export ata_busy_sleep
2006-01-24 8:05 ` [PATCH 01/12] libata: export ata_busy_sleep Tejun Heo
@ 2006-01-27 4:18 ` Jeff Garzik
0 siblings, 0 replies; 21+ messages in thread
From: Jeff Garzik @ 2006-01-27 4:18 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, albertcc
Tejun Heo wrote:
> Export ata_busy_sleep(), to be used by low level driver reset functions.
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
applied
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 02/12] libata: modify ata_dev_try_classify
2006-01-24 8:05 ` [PATCH 02/12] libata: modify ata_dev_try_classify Tejun Heo
@ 2006-01-27 4:20 ` Jeff Garzik
0 siblings, 0 replies; 21+ messages in thread
From: Jeff Garzik @ 2006-01-27 4:20 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, albertcc
Tejun Heo wrote:
> Make ata_dev_try_classify take @r_err to store tf error register value
> on completion and return device class instead of directly manipulating
> dev->class. This is preparation for new reset mechanism.
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
applied 2-3
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 04/12] libata: implement ata_drive_probe_reset()
2006-01-24 8:05 ` [PATCH 04/12] libata: implement ata_drive_probe_reset() Tejun Heo
@ 2006-01-28 1:58 ` Jeff Garzik
0 siblings, 0 replies; 21+ messages in thread
From: Jeff Garzik @ 2006-01-28 1:58 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, albertcc
Tejun Heo wrote:
> Most low level drivers share supported reset/classify actions and
> sequence. This patch implements ata_drive_probe_reset() which helps
> constructing ->probe_reset from three component operations -
> softreset, hardreset and postreset. This minimizes duplicate code and
> yet allows flexibility if needed. The three component operations can
> also be shared by EH later.
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
applied
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 05/12] libata: implement standard reset component operations and ->probe_reset
2006-01-24 8:05 ` [PATCH 05/12] libata: implement standard reset component operations and ->probe_reset Tejun Heo
@ 2006-01-28 1:58 ` Jeff Garzik
0 siblings, 0 replies; 21+ messages in thread
From: Jeff Garzik @ 2006-01-28 1:58 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, albertcc
Tejun Heo wrote:
> Implement SRST, COMRESET and standard postreset component operations
> for ata_drive_probe_reset(), and use these three functions to
> implement ata_std_probe_reset.
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
applied
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 06/12] sata_sil: convert to new reset mechanism
2006-01-24 8:05 ` [PATCH 06/12] sata_sil: convert to new reset mechanism Tejun Heo
@ 2006-01-28 18:09 ` Jeff Garzik
2006-01-28 18:27 ` Jeff Garzik
2006-01-28 23:17 ` Tejun
0 siblings, 2 replies; 21+ messages in thread
From: Jeff Garzik @ 2006-01-28 18:09 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, albertcc
Tejun Heo wrote:
> 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>
Major NAK.
The placement of every hardware register read/write has been very
carefully laid out, and your reset hardware re-orders a lot of that.
Code re-ordering is fine. Changing the order of I/O operations is not.
With this patch, sata_sil fails to wake up and initialize the SATA phy!
Proper code transformation is art. You're doing really well, but this
was a bit of a hiccup. You should have presented a series of patches
which changed over to your new ata_drive_probe_reset() stuff, while -not
changing the hardware operations at all-. Like a mathematical solution,
your code is then provably correct. If there is a regression, then you
know it is a driver bug, and not a problem with hardware acting weird.
If the driver can access the SATA PHY registers, the very first thing it
should usually do is the code in sata_std_hardreset()... everything
except the 0x301 value write. Or in other words, follow the code in
__sata_phy_reset() PRECISELY (presuming that ATA_FLAG_SATA_RESET is not
set).
sata_sil hardware initialization order and behavior should not change at
all [though certainly you will change it sometime in the future].
So... I will drop all other patches from you, let you resync with the
latest stuff in libata-dev.git#upstream (NOTE: renamed from
upstream-2.6.17 to upstream), and wait for your next barrage of patches ;-)
Jeff
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 06/12] sata_sil: convert to new reset mechanism
2006-01-28 18:09 ` Jeff Garzik
@ 2006-01-28 18:27 ` Jeff Garzik
2006-01-28 23:17 ` Tejun
1 sibling, 0 replies; 21+ messages in thread
From: Jeff Garzik @ 2006-01-28 18:27 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, albertcc
Jeff Garzik wrote:
> If the driver can access the SATA PHY registers, the very first thing it
> should usually do is the code in sata_std_hardreset()... everything
> except the 0x301 value write.
...and possibly the device classification. Probably want to do a soft
reset, then get the signature. Read the port multiplier spec PM
initialization sequence... that is a highly relevant description.
Jeff
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 06/12] sata_sil: convert to new reset mechanism
2006-01-28 18:09 ` Jeff Garzik
2006-01-28 18:27 ` Jeff Garzik
@ 2006-01-28 23:17 ` Tejun
2006-01-29 2:41 ` Jeff Garzik
1 sibling, 1 reply; 21+ messages in thread
From: Tejun @ 2006-01-28 23:17 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-ide, albertcc
Jeff Garzik wrote:
> Tejun Heo wrote:
>
>> 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>
>
>
> Major NAK.
>
> The placement of every hardware register read/write has been very
> carefully laid out, and your reset hardware re-orders a lot of that.
> Code re-ordering is fine. Changing the order of I/O operations is not.
> With this patch, sata_sil fails to wake up and initialize the SATA phy!
>
> Proper code transformation is art. You're doing really well, but this
> was a bit of a hiccup. You should have presented a series of patches
> which changed over to your new ata_drive_probe_reset() stuff, while -not
> changing the hardware operations at all-. Like a mathematical solution,
> your code is then provably correct. If there is a regression, then you
> know it is a driver bug, and not a problem with hardware acting weird.
>
> If the driver can access the SATA PHY registers, the very first thing it
> should usually do is the code in sata_std_hardreset()... everything
> except the 0x301 value write. Or in other words, follow the code in
> __sata_phy_reset() PRECISELY (presuming that ATA_FLAG_SATA_RESET is not
> set).
>
> sata_sil hardware initialization order and behavior should not change at
> all [though certainly you will change it sometime in the future].
Okay, I see. I'll rewrite those parts such that it acts in the same way
as the original reset.
> So... I will drop all other patches from you, let you resync with the
> latest stuff in libata-dev.git#upstream (NOTE: renamed from
> upstream-2.6.17 to upstream), and wait for your next barrage of patches ;-)
It's lunar new year here and I am away from office until 1st Feb, so it
will take me some time.
Thanks a lot for all your help and guidance. It's been a great year.
Happy (lunar) new year, guys. :-)
--
tejun
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 06/12] sata_sil: convert to new reset mechanism
2006-01-28 23:17 ` Tejun
@ 2006-01-29 2:41 ` Jeff Garzik
0 siblings, 0 replies; 21+ messages in thread
From: Jeff Garzik @ 2006-01-29 2:41 UTC (permalink / raw)
To: Tejun; +Cc: linux-ide, albertcc
Tejun wrote:
> Thanks a lot for all your help and guidance. It's been a great year.
>
> Happy (lunar) new year, guys. :-)
Definitely! Once we get EH/reset stuff taken care of, hotplug, NCQ and
other fun will be a lot easier to implement.
Thanks,
Jeff
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2006-01-29 2:41 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-24 8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
2006-01-24 8:05 ` [PATCH 01/12] libata: export ata_busy_sleep Tejun Heo
2006-01-27 4:18 ` Jeff Garzik
2006-01-24 8:05 ` [PATCH 07/12] sata_sil24: convert to new reset mechanism Tejun Heo
2006-01-24 8:05 ` [PATCH 10/12] ata_piix: convert sata " Tejun Heo
2006-01-24 8:05 ` [PATCH 11/12] ahci: convert " Tejun Heo
2006-01-24 8:05 ` [PATCH 02/12] libata: modify ata_dev_try_classify Tejun Heo
2006-01-27 4:20 ` Jeff Garzik
2006-01-24 8:05 ` [PATCH 04/12] libata: implement ata_drive_probe_reset() Tejun Heo
2006-01-28 1:58 ` Jeff Garzik
2006-01-24 8:05 ` [PATCH 08/12] sata_sil24: add hardreset Tejun Heo
2006-01-24 8:05 ` [PATCH 03/12] libata: new ->probe_reset operation Tejun Heo
2006-01-24 8:05 ` [PATCH 06/12] sata_sil: convert to new reset mechanism Tejun Heo
2006-01-28 18:09 ` Jeff Garzik
2006-01-28 18:27 ` Jeff Garzik
2006-01-28 23:17 ` Tejun
2006-01-29 2:41 ` Jeff Garzik
2006-01-24 8:05 ` [PATCH 12/12] ahci: add softreset Tejun Heo
2006-01-24 8:05 ` [PATCH 09/12] ata_piix: convert pata to new reset mechanism Tejun Heo
2006-01-24 8:05 ` [PATCH 05/12] libata: implement standard reset component operations and ->probe_reset Tejun Heo
2006-01-28 1:58 ` 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).