aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-07 09:47:19 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:23 -0400
commit57c9efdfb3cee5d4564fcb5f70555e2edb1bc52a (patch)
treec2289500f093736853a94d2d9577036658676498 /drivers/ata
parent9dadd45b24145d6aee2fabb28d7aef972301892b (diff)
libata: implement and use sata_std_hardreset()
Implement sata_std_hardreset(), which simply wraps around sata_link_hardreset(). sata_std_hardreset() becomes new standard hardreset method for sata_port_ops and sata_sff_hardreset() moves from ata_base_port_ops to ata_sff_port_ops, which is where it really belongs. ata_is_builtin_hardreset() is added so that both ata_std_error_handler() and ata_sff_error_handler() skip both builtin hardresets if SCR isn't accessible. piix_sidpr_hardreset() in ata_piix.c is identical to sata_std_hardreset() in functionality and got replaced with the standard function. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ata_piix.c27
-rw-r--r--drivers/ata/libata-core.c30
-rw-r--r--drivers/ata/libata-eh.c7
-rw-r--r--drivers/ata/libata-sff.c9
-rw-r--r--drivers/ata/libata.h9
5 files changed, 45 insertions, 37 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index f59a55bfade4..b7c38eeb498f 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -165,8 +165,6 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
165static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); 165static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev);
166static int ich_pata_cable_detect(struct ata_port *ap); 166static int ich_pata_cable_detect(struct ata_port *ap);
167static u8 piix_vmw_bmdma_status(struct ata_port *ap); 167static u8 piix_vmw_bmdma_status(struct ata_port *ap);
168static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
169 unsigned long deadline);
170static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val); 168static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val);
171static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val); 169static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val);
172#ifdef CONFIG_PM 170#ifdef CONFIG_PM
@@ -319,7 +317,7 @@ static struct ata_port_operations piix_sata_ops = {
319 317
320static struct ata_port_operations piix_sidpr_sata_ops = { 318static struct ata_port_operations piix_sidpr_sata_ops = {
321 .inherits = &piix_sata_ops, 319 .inherits = &piix_sata_ops,
322 .hardreset = piix_sidpr_hardreset, 320 .hardreset = sata_std_hardreset,
323 .scr_read = piix_sidpr_scr_read, 321 .scr_read = piix_sidpr_scr_read,
324 .scr_write = piix_sidpr_scr_write, 322 .scr_write = piix_sidpr_scr_write,
325}; 323};
@@ -1015,29 +1013,6 @@ static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val)
1015 return 0; 1013 return 0;
1016} 1014}
1017 1015
1018static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
1019 unsigned long deadline)
1020{
1021 const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
1022 int rc;
1023
1024 /* do hardreset */
1025 rc = sata_link_hardreset(link, timing, deadline, NULL, NULL);
1026 if (rc) {
1027 ata_link_printk(link, KERN_ERR,
1028 "COMRESET failed (errno=%d)\n", rc);
1029 return rc;
1030 }
1031
1032 /* TODO: phy layer with polling, timeouts, etc. */
1033 if (ata_link_offline(link)) {
1034 *class = ATA_DEV_NONE;
1035 return 0;
1036 }
1037
1038 return -EAGAIN;
1039}
1040
1041#ifdef CONFIG_PM 1016#ifdef CONFIG_PM
1042static int piix_broken_suspend(void) 1017static int piix_broken_suspend(void)
1043{ 1018{
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b607292b6480..c4fd4afbf349 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -75,7 +75,6 @@ const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 };
75 75
76const struct ata_port_operations ata_base_port_ops = { 76const struct ata_port_operations ata_base_port_ops = {
77 .prereset = ata_std_prereset, 77 .prereset = ata_std_prereset,
78 .hardreset = sata_sff_hardreset,
79 .postreset = ata_std_postreset, 78 .postreset = ata_std_postreset,
80 .error_handler = ata_std_error_handler, 79 .error_handler = ata_std_error_handler,
81}; 80};
@@ -84,6 +83,7 @@ const struct ata_port_operations sata_port_ops = {
84 .inherits = &ata_base_port_ops, 83 .inherits = &ata_base_port_ops,
85 84
86 .qc_defer = ata_std_qc_defer, 85 .qc_defer = ata_std_qc_defer,
86 .hardreset = sata_std_hardreset,
87 .sff_dev_select = ata_noop_dev_select, 87 .sff_dev_select = ata_noop_dev_select,
88}; 88};
89 89
@@ -3661,6 +3661,33 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
3661} 3661}
3662 3662
3663/** 3663/**
3664 * sata_std_hardreset - COMRESET w/o waiting or classification
3665 * @link: link to reset
3666 * @class: resulting class of attached device
3667 * @deadline: deadline jiffies for the operation
3668 *
3669 * Standard SATA COMRESET w/o waiting or classification.
3670 *
3671 * LOCKING:
3672 * Kernel thread context (may sleep)
3673 *
3674 * RETURNS:
3675 * 0 if link offline, -EAGAIN if link online, -errno on errors.
3676 */
3677int sata_std_hardreset(struct ata_link *link, unsigned int *class,
3678 unsigned long deadline)
3679{
3680 const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
3681 bool online;
3682 int rc;
3683
3684 /* do hardreset */
3685 rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
3686 *class = ATA_DEV_NONE;
3687 return online ? -EAGAIN : rc;
3688}
3689
3690/**
3664 * ata_std_postreset - standard postreset callback 3691 * ata_std_postreset - standard postreset callback
3665 * @link: the target ata_link 3692 * @link: the target ata_link
3666 * @classes: classes of attached devices 3693 * @classes: classes of attached devices
@@ -6225,6 +6252,7 @@ EXPORT_SYMBOL_GPL(sata_link_debounce);
6225EXPORT_SYMBOL_GPL(sata_link_resume); 6252EXPORT_SYMBOL_GPL(sata_link_resume);
6226EXPORT_SYMBOL_GPL(ata_std_prereset); 6253EXPORT_SYMBOL_GPL(ata_std_prereset);
6227EXPORT_SYMBOL_GPL(sata_link_hardreset); 6254EXPORT_SYMBOL_GPL(sata_link_hardreset);
6255EXPORT_SYMBOL_GPL(sata_std_hardreset);
6228EXPORT_SYMBOL_GPL(ata_std_postreset); 6256EXPORT_SYMBOL_GPL(ata_std_postreset);
6229EXPORT_SYMBOL_GPL(ata_dev_classify); 6257EXPORT_SYMBOL_GPL(ata_dev_classify);
6230EXPORT_SYMBOL_GPL(ata_dev_pair); 6258EXPORT_SYMBOL_GPL(ata_dev_pair);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index f4f9c2783821..21687bbd9a70 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2857,11 +2857,8 @@ void ata_std_error_handler(struct ata_port *ap)
2857 struct ata_port_operations *ops = ap->ops; 2857 struct ata_port_operations *ops = ap->ops;
2858 ata_reset_fn_t hardreset = ops->hardreset; 2858 ata_reset_fn_t hardreset = ops->hardreset;
2859 2859
2860 /* sata_std_hardreset is inherited to all drivers from 2860 /* ignore built-in hardreset if SCR access is not available */
2861 * ata_base_port_ops. Ignore it if SCR access is not 2861 if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
2862 * available.
2863 */
2864 if (hardreset == sata_sff_hardreset && !sata_scr_valid(&ap->link))
2865 hardreset = NULL; 2862 hardreset = NULL;
2866 2863
2867 ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); 2864 ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 0b97e84d3af6..f464ca1fa261 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -49,6 +49,7 @@ const struct ata_port_operations ata_sff_port_ops = {
49 .thaw = ata_sff_thaw, 49 .thaw = ata_sff_thaw,
50 .prereset = ata_sff_prereset, 50 .prereset = ata_sff_prereset,
51 .softreset = ata_sff_softreset, 51 .softreset = ata_sff_softreset,
52 .hardreset = sata_sff_hardreset,
52 .postreset = ata_sff_postreset, 53 .postreset = ata_sff_postreset,
53 .error_handler = ata_sff_error_handler, 54 .error_handler = ata_sff_error_handler,
54 .post_internal_cmd = ata_sff_post_internal_cmd, 55 .post_internal_cmd = ata_sff_post_internal_cmd,
@@ -2031,14 +2032,12 @@ void ata_sff_error_handler(struct ata_port *ap)
2031 2032
2032 /* PIO and DMA engines have been stopped, perform recovery */ 2033 /* PIO and DMA engines have been stopped, perform recovery */
2033 2034
2034 /* ata_sff_softreset and sata_sff_hardreset are inherited to 2035 /* Ignore ata_sff_softreset if ctl isn't accessible and
2035 * all SFF drivers from ata_sff_port_ops. Ignore softreset if 2036 * built-in hardresets if SCR access isn't available.
2036 * ctl isn't accessible. Ignore hardreset if SCR access isn't
2037 * available.
2038 */ 2037 */
2039 if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr) 2038 if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
2040 softreset = NULL; 2039 softreset = NULL;
2041 if (hardreset == sata_sff_hardreset && !sata_scr_valid(&ap->link)) 2040 if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
2042 hardreset = NULL; 2041 hardreset = NULL;
2043 2042
2044 ata_do_eh(ap, ap->ops->prereset, softreset, hardreset, 2043 ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 08af43e2c081..87f54a1db3b0 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -38,6 +38,15 @@ struct ata_scsi_args {
38 void (*done)(struct scsi_cmnd *); 38 void (*done)(struct scsi_cmnd *);
39}; 39};
40 40
41static inline int ata_is_builtin_hardreset(ata_reset_fn_t reset)
42{
43 if (reset == sata_std_hardreset)
44 return 1;
45 if (reset == sata_sff_hardreset)
46 return 1;
47 return 0;
48}
49
41/* libata-core.c */ 50/* libata-core.c */
42enum { 51enum {
43 /* flags for ata_dev_read_id() */ 52 /* flags for ata_dev_read_id() */