From aadffb682cc5572f48cc24883681db65530bd284 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 31 Jul 2008 17:02:41 +0900 Subject: [PATCH] libata: reimplement link iterator References: bnc#441420 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 Signed-off-by: Jeff Garzik Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 30 ++++++++++++++++++++++++++++++ include/linux/libata.h | 35 +++++++++-------------------------- 2 files changed, 39 insertions(+), 26 deletions(-) --- 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 @@ -6333,6 +6362,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); --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1266,34 +1266,17 @@ static inline int ata_link_active(struct 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; -} - -#define __ata_port_for_each_link(lk, ap) \ - for ((lk) = &(ap)->link; (lk); (lk) = ata_port_next_link(lk)) +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(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; \