diff options
author | Tejun Heo <tj@kernel.org> | 2008-11-03 06:03:17 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-12-28 22:43:20 -0500 |
commit | 1eca4365be25c540650693e941bc06a66cf38f94 (patch) | |
tree | e3ed82850da00308180bf166118f9f9e69d92898 /include | |
parent | 3c92ec8ae91ecf59d88c798301833d7cf83f2179 (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')
-rw-r--r-- | include/linux/libata.h | 76 |
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 | ||
1288 | extern 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) \ | 1300 | enum 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 | |
1308 | enum ata_dev_iter_mode { | ||
1309 | ATA_DITER_ENABLED, | ||
1310 | ATA_DITER_ENABLED_REVERSE, | ||
1311 | ATA_DITER_ALL, | ||
1312 | ATA_DITER_ALL_REVERSE, | ||
1313 | }; | ||
1314 | |||
1315 | extern struct ata_link *ata_link_next(struct ata_link *link, | ||
1316 | struct ata_port *ap, | ||
1317 | enum ata_link_iter_mode mode); | ||
1318 | |||
1319 | extern 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 |