aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-07 09:47:18 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:22 -0400
commit0aa1113d544226bc2c4a20d6ac1d71170512a361 (patch)
tree503b33b0805424d312abddd3535c941bb85c03bc
parent288623a06c652239d2f57d271af12bb024cf7218 (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.c17
-rw-r--r--drivers/ata/libata-sff.c43
-rw-r--r--include/linux/libata.h1
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 };
74const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; 74const 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_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 */
3435int ata_sff_prereset(struct ata_link *link, unsigned long deadline) 3435int 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);
6104EXPORT_SYMBOL_GPL(sata_set_spd); 6094EXPORT_SYMBOL_GPL(sata_set_spd);
6105EXPORT_SYMBOL_GPL(sata_link_debounce); 6095EXPORT_SYMBOL_GPL(sata_link_debounce);
6106EXPORT_SYMBOL_GPL(sata_link_resume); 6096EXPORT_SYMBOL_GPL(sata_link_resume);
6097EXPORT_SYMBOL_GPL(ata_std_prereset);
6107EXPORT_SYMBOL_GPL(sata_link_hardreset); 6098EXPORT_SYMBOL_GPL(sata_link_hardreset);
6108EXPORT_SYMBOL_GPL(ata_dev_classify); 6099EXPORT_SYMBOL_GPL(ata_dev_classify);
6109EXPORT_SYMBOL_GPL(ata_dev_pair); 6100EXPORT_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 */
1625int 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)
824extern void sata_print_link_status(struct ata_link *link); 824extern void sata_print_link_status(struct ata_link *link);
825extern void ata_port_probe(struct ata_port *); 825extern void ata_port_probe(struct ata_port *);
826extern int sata_set_spd(struct ata_link *link); 826extern int sata_set_spd(struct ata_link *link);
827extern int ata_std_prereset(struct ata_link *link, unsigned long deadline);
827extern int sata_link_debounce(struct ata_link *link, 828extern int sata_link_debounce(struct ata_link *link,
828 const unsigned long *params, unsigned long deadline); 829 const unsigned long *params, unsigned long deadline);
829extern int sata_link_resume(struct ata_link *link, const unsigned long *params, 830extern int sata_link_resume(struct ata_link *link, const unsigned long *params,