aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorBin Meng2015-10-07 21:45:44 -0700
committerJoe Hershberger2015-10-29 14:05:52 -0500
commitac1d31380618f3f68bf7f05b73b6ab0cdeab0e9f (patch)
tree727411073a7ad684eaaa844ee492b9dec4a176af /net
parent6d9764c2a87cc5a1ce4f3919add6360ec36f81c7 (diff)
net: eth: Check return value in various places
eth_get_dev() can return NULL which means device_probe() fails for that ethernet device. Add return value check in various places or U-Boot will crash due to NULL pointer access. With this commit, 'dm_test_eth_act' test case passes. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'net')
-rw-r--r--net/eth.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/net/eth.c b/net/eth.c
index c661775d1ca..c542f4aa3b3 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -179,8 +179,12 @@ struct udevice *eth_get_dev(void)
*/
static void eth_set_dev(struct udevice *dev)
{
- if (dev && !device_active(dev))
+ if (dev && !device_active(dev)) {
eth_errno = device_probe(dev);
+ if (eth_errno)
+ dev = NULL;
+ }
+
eth_get_uclass_priv()->current = dev;
}
@@ -213,10 +217,9 @@ struct udevice *eth_get_dev_by_name(const char *devname)
* match an alias or it will match a literal name and we'll pick
* up the error when we try to probe again in eth_set_dev().
*/
- device_probe(it);
- /*
- * Check for the name or the sequence number to match
- */
+ if (device_probe(it))
+ continue;
+ /* Check for the name or the sequence number to match */
if (strcmp(it->name, devname) == 0 ||
(endp > startp && it->seq == seq))
return it;
@@ -346,23 +349,27 @@ int eth_init(void)
old_current = current;
do {
- debug("Trying %s\n", current->name);
-
- if (device_active(current)) {
- ret = eth_get_ops(current)->start(current);
- if (ret >= 0) {
- struct eth_device_priv *priv =
- current->uclass_priv;
-
- priv->state = ETH_STATE_ACTIVE;
- return 0;
+ if (current) {
+ debug("Trying %s\n", current->name);
+
+ if (device_active(current)) {
+ ret = eth_get_ops(current)->start(current);
+ if (ret >= 0) {
+ struct eth_device_priv *priv =
+ current->uclass_priv;
+
+ priv->state = ETH_STATE_ACTIVE;
+ return 0;
+ }
+ } else {
+ ret = eth_errno;
}
+
+ debug("FAIL\n");
} else {
- ret = eth_errno;
+ debug("PROBE FAIL\n");
}
- debug("FAIL\n");
-
/*
* If ethrotate is enabled, this will change "current",
* otherwise we will drop out of this while loop immediately