diff options
author | Joe Hershberger | 2015-03-22 17:09:16 -0500 |
---|---|---|
committer | Simon Glass | 2015-04-18 11:11:13 -0600 |
commit | e58780dcb7b8656ebc2dd6ba6d0da728bc65bf40 (patch) | |
tree | 68b6448131caeaa7d02a88cfbb1116e56f3b679b /net/eth.c | |
parent | bfacad7da11711231ca59717c0a8bc7317c5bb28 (diff) |
dm: eth: Add support for aliases
Allow network devices to be referred to as "eth0" instead of
"eth@12345678" when specified in ethact.
Add tests to verify this behavior.
Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'net/eth.c')
-rw-r--r-- | net/eth.c | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/net/eth.c b/net/eth.c index 058c55a0e6e..a2e6f34535e 100644 --- a/net/eth.c +++ b/net/eth.c @@ -135,6 +135,39 @@ static void eth_set_dev(struct udevice *dev) eth_get_uclass_priv()->current = dev; } +/* + * Find the udevice that either has the name passed in as devname or has an + * alias named devname. + */ +struct udevice *eth_get_dev_by_name(const char *devname) +{ + int seq = -1; + char *endp = NULL; + const char *startp = NULL; + struct udevice *it; + struct uclass *uc; + + /* Must be longer than 3 to be an alias */ + if (strlen(devname) > strlen("eth")) { + startp = devname + strlen("eth"); + seq = simple_strtoul(startp, &endp, 10); + } + + uclass_get(UCLASS_ETH, &uc); + uclass_foreach_dev(it, uc) { + /* We need the seq to be valid, so make sure it's probed */ + device_probe(it); + /* + * Check for the name or the sequence number to match + */ + if (strcmp(it->name, devname) == 0 || + (endp > startp && it->seq == seq)) + return it; + } + + return NULL; +} + unsigned char *eth_get_ethaddr(void) { struct eth_pdata *pdata; @@ -421,6 +454,7 @@ UCLASS_DRIVER(eth) = { .pre_remove = eth_pre_remove, .priv_auto_alloc_size = sizeof(struct eth_uclass_priv), .per_device_auto_alloc_size = sizeof(struct eth_device_priv), + .flags = DM_UC_FLAG_SEQ_ALIAS, }; #endif @@ -453,6 +487,11 @@ static void eth_set_current_to_next(void) eth_current = eth_current->next; } +static void eth_set_dev(struct eth_device *dev) +{ + eth_current = dev; +} + struct eth_device *eth_get_dev_by_name(const char *devname) { struct eth_device *dev, *target_dev; @@ -869,7 +908,6 @@ void eth_set_current(void) { static char *act; static int env_changed_id; - void *old_current; int env_id; env_id = get_env_id(); @@ -877,14 +915,8 @@ void eth_set_current(void) act = getenv("ethact"); env_changed_id = env_id; } - if (act != NULL) { - old_current = eth_get_dev(); - do { - if (strcmp(eth_get_name(), act) == 0) - return; - eth_set_current_to_next(); - } while (old_current != eth_get_dev()); - } + if (act != NULL) + eth_set_dev(eth_get_dev_by_name(act)); eth_current_changed(); } |