diff options
author | Tejun Heo <htejun@gmail.com> | 2008-04-07 09:47:18 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-17 15:44:22 -0400 |
commit | 0aa1113d544226bc2c4a20d6ac1d71170512a361 (patch) | |
tree | 503b33b0805424d312abddd3535c941bb85c03bc | |
parent | 288623a06c652239d2f57d271af12bb024cf7218 (diff) |
libata: separate out ata_std_prereset() from ata_sff_prereset()
Separate out generic ATA portion from ata_sff_prereset() into
ata_std_prereset() and implement ata_sff_prereset() using the std
version. Waiting for device readiness is the only SFF specific part.
ata_base_port_ops now has ata_std_prereset() for its prereset and
ata_sff_port_ops overrides it to ata_sff_prereset(). This change can
affect pdc_adma, ahci, sata_fsl and sata_sil24. pdc_adma implements
its own prereset using ata_sff_prereset() and the rest has hardreset
and thus are unaffected by this change.
This change reflects real world situation. There is no generic way to
wait for device readiness for non-SFF controllers and some of them
don't have any mechanism for that. Non-sff drivers which don't have
hardreset should wrap ata_std_prereset() and wait for device readiness
itself but there's no such driver now and isn't likely to be popular
in the future either.
Signed-off-by: Tejun Heo <htejun@gmail.com>
-rw-r--r-- | drivers/ata/libata-core.c | 17 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 43 | ||||
-rw-r--r-- | include/linux/libata.h | 1 |
3 files changed, 48 insertions, 13 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fd912ccb90f8..5f771bb44332 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -74,7 +74,7 @@ const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; | |||
74 | const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; | 74 | 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_sff_prereset, | 77 | .prereset = ata_std_prereset, |
78 | .hardreset = sata_sff_hardreset, | 78 | .hardreset = sata_sff_hardreset, |
79 | .postreset = ata_sff_postreset, | 79 | .postreset = ata_sff_postreset, |
80 | .error_handler = ata_std_error_handler, | 80 | .error_handler = ata_std_error_handler, |
@@ -3416,7 +3416,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, | |||
3416 | } | 3416 | } |
3417 | 3417 | ||
3418 | /** | 3418 | /** |
3419 | * ata_sff_prereset - prepare for reset | 3419 | * ata_std_prereset - prepare for reset |
3420 | * @link: ATA link to be reset | 3420 | * @link: ATA link to be reset |
3421 | * @deadline: deadline jiffies for the operation | 3421 | * @deadline: deadline jiffies for the operation |
3422 | * | 3422 | * |
@@ -3432,7 +3432,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, | |||
3432 | * RETURNS: | 3432 | * RETURNS: |
3433 | * 0 on success, -errno otherwise. | 3433 | * 0 on success, -errno otherwise. |
3434 | */ | 3434 | */ |
3435 | int ata_sff_prereset(struct ata_link *link, unsigned long deadline) | 3435 | int ata_std_prereset(struct ata_link *link, unsigned long deadline) |
3436 | { | 3436 | { |
3437 | struct ata_port *ap = link->ap; | 3437 | struct ata_port *ap = link->ap; |
3438 | struct ata_eh_context *ehc = &link->eh_context; | 3438 | struct ata_eh_context *ehc = &link->eh_context; |
@@ -3452,16 +3452,6 @@ int ata_sff_prereset(struct ata_link *link, unsigned long deadline) | |||
3452 | "link for reset (errno=%d)\n", rc); | 3452 | "link for reset (errno=%d)\n", rc); |
3453 | } | 3453 | } |
3454 | 3454 | ||
3455 | /* wait for !BSY if we don't know that no device is attached */ | ||
3456 | if (!ata_link_offline(link)) { | ||
3457 | rc = ata_sff_wait_ready(ap, deadline); | ||
3458 | if (rc && rc != -ENODEV) { | ||
3459 | ata_link_printk(link, KERN_WARNING, "device not ready " | ||
3460 | "(errno=%d), forcing hardreset\n", rc); | ||
3461 | ehc->i.action |= ATA_EH_HARDRESET; | ||
3462 | } | ||
3463 | } | ||
3464 | |||
3465 | return 0; | 3455 | return 0; |
3466 | } | 3456 | } |
3467 | 3457 | ||
@@ -6104,6 +6094,7 @@ EXPORT_SYMBOL_GPL(ata_dev_disable); | |||
6104 | EXPORT_SYMBOL_GPL(sata_set_spd); | 6094 | EXPORT_SYMBOL_GPL(sata_set_spd); |
6105 | EXPORT_SYMBOL_GPL(sata_link_debounce); | 6095 | EXPORT_SYMBOL_GPL(sata_link_debounce); |
6106 | EXPORT_SYMBOL_GPL(sata_link_resume); | 6096 | EXPORT_SYMBOL_GPL(sata_link_resume); |
6097 | EXPORT_SYMBOL_GPL(ata_std_prereset); | ||
6107 | EXPORT_SYMBOL_GPL(sata_link_hardreset); | 6098 | EXPORT_SYMBOL_GPL(sata_link_hardreset); |
6108 | EXPORT_SYMBOL_GPL(ata_dev_classify); | 6099 | EXPORT_SYMBOL_GPL(ata_dev_classify); |
6109 | EXPORT_SYMBOL_GPL(ata_dev_pair); | 6100 | EXPORT_SYMBOL_GPL(ata_dev_pair); |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c11601617134..9234bc047956 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -47,6 +47,7 @@ const struct ata_port_operations ata_sff_port_ops = { | |||
47 | 47 | ||
48 | .freeze = ata_sff_freeze, | 48 | .freeze = ata_sff_freeze, |
49 | .thaw = ata_sff_thaw, | 49 | .thaw = ata_sff_thaw, |
50 | .prereset = ata_sff_prereset, | ||
50 | .softreset = ata_sff_softreset, | 51 | .softreset = ata_sff_softreset, |
51 | .error_handler = ata_sff_error_handler, | 52 | .error_handler = ata_sff_error_handler, |
52 | .post_internal_cmd = ata_sff_post_internal_cmd, | 53 | .post_internal_cmd = ata_sff_post_internal_cmd, |
@@ -1607,6 +1608,48 @@ void ata_sff_thaw(struct ata_port *ap) | |||
1607 | } | 1608 | } |
1608 | 1609 | ||
1609 | /** | 1610 | /** |
1611 | * ata_sff_prereset - prepare SFF link for reset | ||
1612 | * @link: SFF link to be reset | ||
1613 | * @deadline: deadline jiffies for the operation | ||
1614 | * | ||
1615 | * SFF link @link is about to be reset. Initialize it. It first | ||
1616 | * calls ata_std_prereset() and wait for !BSY if the port is | ||
1617 | * being softreset. | ||
1618 | * | ||
1619 | * LOCKING: | ||
1620 | * Kernel thread context (may sleep) | ||
1621 | * | ||
1622 | * RETURNS: | ||
1623 | * 0 on success, -errno otherwise. | ||
1624 | */ | ||
1625 | int ata_sff_prereset(struct ata_link *link, unsigned long deadline) | ||
1626 | { | ||
1627 | struct ata_port *ap = link->ap; | ||
1628 | struct ata_eh_context *ehc = &link->eh_context; | ||
1629 | int rc; | ||
1630 | |||
1631 | rc = ata_std_prereset(link, deadline); | ||
1632 | if (rc) | ||
1633 | return rc; | ||
1634 | |||
1635 | /* if we're about to do hardreset, nothing more to do */ | ||
1636 | if (ehc->i.action & ATA_EH_HARDRESET) | ||
1637 | return 0; | ||
1638 | |||
1639 | /* wait for !BSY if we don't know that no device is attached */ | ||
1640 | if (!ata_link_offline(link)) { | ||
1641 | rc = ata_sff_wait_ready(ap, deadline); | ||
1642 | if (rc && rc != -ENODEV) { | ||
1643 | ata_link_printk(link, KERN_WARNING, "device not ready " | ||
1644 | "(errno=%d), forcing hardreset\n", rc); | ||
1645 | ehc->i.action |= ATA_EH_HARDRESET; | ||
1646 | } | ||
1647 | } | ||
1648 | |||
1649 | return 0; | ||
1650 | } | ||
1651 | |||
1652 | /** | ||
1610 | * ata_devchk - PATA device presence detection | 1653 | * ata_devchk - PATA device presence detection |
1611 | * @ap: ATA channel to examine | 1654 | * @ap: ATA channel to examine |
1612 | * @device: Device to examine (starting at zero) | 1655 | * @device: Device to examine (starting at zero) |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 603712b59cf3..595ede55fe4c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -824,6 +824,7 @@ static inline int ata_port_is_dummy(struct ata_port *ap) | |||
824 | extern void sata_print_link_status(struct ata_link *link); | 824 | extern void sata_print_link_status(struct ata_link *link); |
825 | extern void ata_port_probe(struct ata_port *); | 825 | extern void ata_port_probe(struct ata_port *); |
826 | extern int sata_set_spd(struct ata_link *link); | 826 | extern int sata_set_spd(struct ata_link *link); |
827 | extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); | ||
827 | extern int sata_link_debounce(struct ata_link *link, | 828 | extern int sata_link_debounce(struct ata_link *link, |
828 | const unsigned long *params, unsigned long deadline); | 829 | const unsigned long *params, unsigned long deadline); |
829 | extern int sata_link_resume(struct ata_link *link, const unsigned long *params, | 830 | extern int sata_link_resume(struct ata_link *link, const unsigned long *params, |