diff options
author | Tejun Heo <htejun@gmail.com> | 2008-04-07 09:47:19 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-17 15:44:23 -0400 |
commit | 57c9efdfb3cee5d4564fcb5f70555e2edb1bc52a (patch) | |
tree | c2289500f093736853a94d2d9577036658676498 /drivers/ata | |
parent | 9dadd45b24145d6aee2fabb28d7aef972301892b (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.c | 27 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 30 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 7 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 9 | ||||
-rw-r--r-- | drivers/ata/libata.h | 9 |
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); | |||
165 | static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); | 165 | static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); |
166 | static int ich_pata_cable_detect(struct ata_port *ap); | 166 | static int ich_pata_cable_detect(struct ata_port *ap); |
167 | static u8 piix_vmw_bmdma_status(struct ata_port *ap); | 167 | static u8 piix_vmw_bmdma_status(struct ata_port *ap); |
168 | static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class, | ||
169 | unsigned long deadline); | ||
170 | static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val); | 168 | static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val); |
171 | static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val); | 169 | static 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 | ||
320 | static struct ata_port_operations piix_sidpr_sata_ops = { | 318 | static 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 | ||
1018 | static 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 |
1042 | static int piix_broken_suspend(void) | 1017 | static 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 | ||
76 | const struct ata_port_operations ata_base_port_ops = { | 76 | const 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 | */ | ||
3677 | int 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); | |||
6225 | EXPORT_SYMBOL_GPL(sata_link_resume); | 6252 | EXPORT_SYMBOL_GPL(sata_link_resume); |
6226 | EXPORT_SYMBOL_GPL(ata_std_prereset); | 6253 | EXPORT_SYMBOL_GPL(ata_std_prereset); |
6227 | EXPORT_SYMBOL_GPL(sata_link_hardreset); | 6254 | EXPORT_SYMBOL_GPL(sata_link_hardreset); |
6255 | EXPORT_SYMBOL_GPL(sata_std_hardreset); | ||
6228 | EXPORT_SYMBOL_GPL(ata_std_postreset); | 6256 | EXPORT_SYMBOL_GPL(ata_std_postreset); |
6229 | EXPORT_SYMBOL_GPL(ata_dev_classify); | 6257 | EXPORT_SYMBOL_GPL(ata_dev_classify); |
6230 | EXPORT_SYMBOL_GPL(ata_dev_pair); | 6258 | EXPORT_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 | ||
41 | static 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 */ |
42 | enum { | 51 | enum { |
43 | /* flags for ata_dev_read_id() */ | 52 | /* flags for ata_dev_read_id() */ |