mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
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>
This commit is contained in:
parent
3c92ec8ae9
commit
1eca4365be
15 changed files with 302 additions and 235 deletions
|
@ -1285,26 +1285,62 @@ static inline int ata_link_active(struct ata_link *link)
|
|||
return ata_tag_valid(link->active_tag) || link->sactive;
|
||||
}
|
||||
|
||||
extern struct ata_link *__ata_port_next_link(struct ata_port *ap,
|
||||
struct ata_link *link,
|
||||
bool dev_only);
|
||||
/*
|
||||
* Iterators
|
||||
*
|
||||
* ATA_LITER_* constants are used to select link iteration mode and
|
||||
* ATA_DITER_* device iteration mode.
|
||||
*
|
||||
* For a custom iteration directly using ata_{link|dev}_next(), if
|
||||
* @link or @dev, respectively, is NULL, the first element is
|
||||
* returned. @dev and @link can be any valid device or link and the
|
||||
* next element according to the iteration mode will be returned.
|
||||
* After the last element, NULL is returned.
|
||||
*/
|
||||
enum ata_link_iter_mode {
|
||||
ATA_LITER_EDGE, /* if present, PMP links only; otherwise,
|
||||
* host link. no slave link */
|
||||
ATA_LITER_HOST_FIRST, /* host link followed by PMP or slave links */
|
||||
ATA_LITER_PMP_FIRST, /* PMP links followed by host link,
|
||||
* slave link still comes after host link */
|
||||
};
|
||||
|
||||
#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))
|
||||
enum ata_dev_iter_mode {
|
||||
ATA_DITER_ENABLED,
|
||||
ATA_DITER_ENABLED_REVERSE,
|
||||
ATA_DITER_ALL,
|
||||
ATA_DITER_ALL_REVERSE,
|
||||
};
|
||||
|
||||
#define ata_port_for_each_link(link, ap) \
|
||||
for ((link) = __ata_port_next_link((ap), NULL, true); (link); \
|
||||
(link) = __ata_port_next_link((ap), (link), true))
|
||||
extern struct ata_link *ata_link_next(struct ata_link *link,
|
||||
struct ata_port *ap,
|
||||
enum ata_link_iter_mode mode);
|
||||
|
||||
#define ata_link_for_each_dev(dev, link) \
|
||||
for ((dev) = (link)->device; \
|
||||
(dev) < (link)->device + ata_link_max_devices(link) || ((dev) = NULL); \
|
||||
(dev)++)
|
||||
extern struct ata_device *ata_dev_next(struct ata_device *dev,
|
||||
struct ata_link *link,
|
||||
enum ata_dev_iter_mode mode);
|
||||
|
||||
#define ata_link_for_each_dev_reverse(dev, link) \
|
||||
for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \
|
||||
(dev) >= (link)->device || ((dev) = NULL); (dev)--)
|
||||
/*
|
||||
* Shortcut notation for iterations
|
||||
*
|
||||
* ata_for_each_link() iterates over each link of @ap according to
|
||||
* @mode. @link points to the current link in the loop. @link is
|
||||
* NULL after loop termination. ata_for_each_dev() works the same way
|
||||
* except that it iterates over each device of @link.
|
||||
*
|
||||
* Note that the mode prefixes ATA_{L|D}ITER_ shouldn't need to be
|
||||
* specified when using the following shorthand notations. Only the
|
||||
* mode itself (EDGE, HOST_FIRST, ENABLED, etc...) should be
|
||||
* specified. This not only increases brevity but also makes it
|
||||
* impossible to use ATA_LITER_* for device iteration or vice-versa.
|
||||
*/
|
||||
#define ata_for_each_link(link, ap, mode) \
|
||||
for ((link) = ata_link_next(NULL, (ap), ATA_LITER_##mode); (link); \
|
||||
(link) = ata_link_next((link), (ap), ATA_LITER_##mode))
|
||||
|
||||
#define ata_for_each_dev(dev, link, mode) \
|
||||
for ((dev) = ata_dev_next(NULL, (link), ATA_DITER_##mode); (dev); \
|
||||
(dev) = ata_dev_next((dev), (link), ATA_DITER_##mode))
|
||||
|
||||
/**
|
||||
* ata_ncq_enabled - Test whether NCQ is enabled
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue