summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-07-31 17:02:41 +0900
committerJeff Garzik <jgarzik@redhat.com>2008-09-29 00:22:30 -0400
commitaadffb682cc5572f48cc24883681db65530bd284 (patch)
tree24ab92ec9b0cdd9e6f4c0bf7a8a4c04635be03db
parent82ef04fb4c82542b3eda81cca461f0594ce9cd0b (diff)
downloadlinux-aadffb682cc5572f48cc24883681db65530bd284.tar.gz
linux-aadffb682cc5572f48cc24883681db65530bd284.tar.bz2
linux-aadffb682cc5572f48cc24883681db65530bd284.zip
libata: reimplement link iterator
Implement __ata_port_next_link() and reimplement __ata_port_for_each_link() and ata_port_for_each_link() using it. This removes relatively large inlined code and makes iteration easier to extend. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/libata-core.c30
-rw-r--r--include/linux/libata.h33
2 files changed, 38 insertions, 25 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 825461a33abe..d156616f45f5 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -163,6 +163,35 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+/*
+ * Iterator helpers. Don't use directly.
+ *
+ * LOCKING:
+ * Host lock or EH context.
+ */
+struct ata_link *__ata_port_next_link(struct ata_port *ap,
+ struct ata_link *link, bool dev_only)
+{
+ /* NULL link indicates start of iteration */
+ if (!link) {
+ if (dev_only && sata_pmp_attached(ap))
+ return ap->pmp_link;
+ return &ap->link;
+ }
+
+ /* we just iterated over the host link, what's next? */
+ if (ata_is_host_link(link)) {
+ if (!sata_pmp_attached(ap))
+ return NULL;
+ return ap->pmp_link;
+ }
+
+ /* iterate to the next PMP link */
+ if (++link < ap->pmp_link + ap->nr_pmp_links)
+ return link;
+ return NULL;
+}
+
/**
* ata_force_cbl - force cable type according to libata.force
* @ap: ATA port of interest
@@ -6255,6 +6284,7 @@ EXPORT_SYMBOL_GPL(ata_base_port_ops);
EXPORT_SYMBOL_GPL(sata_port_ops);
EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
EXPORT_SYMBOL_GPL(ata_dummy_port_info);
+EXPORT_SYMBOL_GPL(__ata_port_next_link);
EXPORT_SYMBOL_GPL(ata_std_bios_param);
EXPORT_SYMBOL_GPL(ata_host_init);
EXPORT_SYMBOL_GPL(ata_host_alloc);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ffd622fa319c..3eaca347ce29 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1265,34 +1265,17 @@ static inline int ata_link_active(struct ata_link *link)
return ata_tag_valid(link->active_tag) || link->sactive;
}
-static inline struct ata_link *ata_port_first_link(struct ata_port *ap)
-{
- if (sata_pmp_attached(ap))
- return ap->pmp_link;
- return &ap->link;
-}
-
-static inline struct ata_link *ata_port_next_link(struct ata_link *link)
-{
- struct ata_port *ap = link->ap;
-
- if (ata_is_host_link(link)) {
- if (!sata_pmp_attached(ap))
- return NULL;
- return ap->pmp_link;
- }
-
- if (++link < ap->nr_pmp_links + ap->pmp_link)
- return link;
- return NULL;
-}
+extern struct ata_link *__ata_port_next_link(struct ata_port *ap,
+ struct ata_link *link,
+ bool dev_only);
-#define __ata_port_for_each_link(lk, ap) \
- for ((lk) = &(ap)->link; (lk); (lk) = ata_port_next_link(lk))
+#define __ata_port_for_each_link(link, ap) \
+ for ((link) = __ata_port_next_link((ap), NULL, false); (link); \
+ (link) = __ata_port_next_link((ap), (link), false))
#define ata_port_for_each_link(link, ap) \
- for ((link) = ata_port_first_link(ap); (link); \
- (link) = ata_port_next_link(link))
+ for ((link) = __ata_port_next_link((ap), NULL, true); (link); \
+ (link) = __ata_port_next_link((ap), (link), true))
#define ata_link_for_each_dev(dev, link) \
for ((dev) = (link)->device; \