aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-11-03 06:03:17 -0500
committerJeff Garzik <jgarzik@redhat.com>2008-12-28 22:43:20 -0500
commit1eca4365be25c540650693e941bc06a66cf38f94 (patch)
treee3ed82850da00308180bf166118f9f9e69d92898 /include/linux
parent3c92ec8ae91ecf59d88c798301833d7cf83f2179 (diff)
libata: beef up iterators
There currently are the following looping constructs. * __ata_port_for_each_link() for all available links * ata_port_for_each_link() for edge links * ata_link_for_each_dev() for all devices * ata_link_for_each_dev_reverse() for all devices in reverse order Now there's a need for looping construct which is similar to __ata_port_for_each_link() but iterates over PMP links before the host link. Instead of adding another one with long name, do the following cleanup. * Implement and export ata_link_next() and ata_dev_next() which take @mode parameter and can be used to build custom loop. * Implement ata_for_each_link() and ata_for_each_dev() which take looping mode explicitly. The following iteration modes are implemented. * ATA_LITER_EDGE : loop over edge links * ATA_LITER_HOST_FIRST : loop over all links, host link first * ATA_LITER_PMP_FIRST : loop over all links, PMP links first * ATA_DITER_ENABLED : loop over enabled devices * ATA_DITER_ENABLED_REVERSE : loop over enabled devices in reverse order * ATA_DITER_ALL : loop over all devices * ATA_DITER_ALL_REVERSE : loop over all devices in reverse order This change removes exlicit device enabledness checks from many loops and makes it clear which ones are iterated over in which direction. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/libata.h76
1 files changed, 56 insertions, 20 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ed3f26eb5df1..3b2a0c6444ee 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1285,26 +1285,62 @@ static inline int ata_link_active(struct ata_link *link)
1285 return ata_tag_valid(link->active_tag) || link->sactive; 1285 return ata_tag_valid(link->active_tag) || link->sactive;
1286} 1286}
1287 1287
1288extern struct ata_link *__ata_port_next_link(struct ata_port *ap, 1288/*
1289 struct ata_link *link, 1289 * Iterators
1290 bool dev_only); 1290 *
1291 1291 * ATA_LITER_* constants are used to select link iteration mode and
1292#define __ata_port_for_each_link(link, ap) \ 1292 * ATA_DITER_* device iteration mode.
1293 for ((link) = __ata_port_next_link((ap), NULL, false); (link); \ 1293 *
1294 (link) = __ata_port_next_link((ap), (link), false)) 1294 * For a custom iteration directly using ata_{link|dev}_next(), if
1295 1295 * @link or @dev, respectively, is NULL, the first element is
1296#define ata_port_for_each_link(link, ap) \ 1296 * returned. @dev and @link can be any valid device or link and the
1297 for ((link) = __ata_port_next_link((ap), NULL, true); (link); \ 1297 * next element according to the iteration mode will be returned.
1298 (link) = __ata_port_next_link((ap), (link), true)) 1298 * After the last element, NULL is returned.
1299 1299 */
1300#define ata_link_for_each_dev(dev, link) \ 1300enum ata_link_iter_mode {
1301 for ((dev) = (link)->device; \ 1301 ATA_LITER_EDGE, /* if present, PMP links only; otherwise,
1302 (dev) < (link)->device + ata_link_max_devices(link) || ((dev) = NULL); \ 1302 * host link. no slave link */
1303 (dev)++) 1303 ATA_LITER_HOST_FIRST, /* host link followed by PMP or slave links */
1304 1304 ATA_LITER_PMP_FIRST, /* PMP links followed by host link,
1305#define ata_link_for_each_dev_reverse(dev, link) \ 1305 * slave link still comes after host link */
1306 for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \ 1306};
1307 (dev) >= (link)->device || ((dev) = NULL); (dev)--) 1307
1308enum ata_dev_iter_mode {
1309 ATA_DITER_ENABLED,
1310 ATA_DITER_ENABLED_REVERSE,
1311 ATA_DITER_ALL,
1312 ATA_DITER_ALL_REVERSE,
1313};
1314
1315extern struct ata_link *ata_link_next(struct ata_link *link,
1316 struct ata_port *ap,
1317 enum ata_link_iter_mode mode);
1318
1319extern struct ata_device *ata_dev_next(struct ata_device *dev,
1320 struct ata_link *link,
1321 enum ata_dev_iter_mode mode);
1322
1323/*
1324 * Shortcut notation for iterations
1325 *
1326 * ata_for_each_link() iterates over each link of @ap according to
1327 * @mode. @link points to the current link in the loop. @link is
1328 * NULL after loop termination. ata_for_each_dev() works the same way
1329 * except that it iterates over each device of @link.
1330 *
1331 * Note that the mode prefixes ATA_{L|D}ITER_ shouldn't need to be
1332 * specified when using the following shorthand notations. Only the
1333 * mode itself (EDGE, HOST_FIRST, ENABLED, etc...) should be
1334 * specified. This not only increases brevity but also makes it
1335 * impossible to use ATA_LITER_* for device iteration or vice-versa.
1336 */
1337#define ata_for_each_link(link, ap, mode) \
1338 for ((link) = ata_link_next(NULL, (ap), ATA_LITER_##mode); (link); \
1339 (link) = ata_link_next((link), (ap), ATA_LITER_##mode))
1340
1341#define ata_for_each_dev(dev, link, mode) \
1342 for ((dev) = ata_dev_next(NULL, (link), ATA_DITER_##mode); (dev); \
1343 (dev) = ata_dev_next((dev), (link), ATA_DITER_##mode))
1308 1344
1309/** 1345/**
1310 * ata_ncq_enabled - Test whether NCQ is enabled 1346 * ata_ncq_enabled - Test whether NCQ is enabled