diff options
author | Krzysztof Halasa <khc@pm.waw.pl> | 2008-12-26 00:50:41 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-26 00:50:41 (GMT) |
commit | 161c8d2f50109b44b664eaf23831ea1587979a61 (patch) | |
tree | 1d9b2b4aaa72296f98c449e6f955ade61e84ed02 /drivers/net/phy/mdio_bus.c | |
parent | f7d1b9f5aafa371d7f51f644aa3c38bc914e9205 (diff) | |
download | linux-161c8d2f50109b44b664eaf23831ea1587979a61.tar.xz |
net: PHYLIB mdio fixes #2
The PHYLIB mdio code has more problems in error paths:
- mdiobus_release can be called before bus->state is set to
MDIOBUS_REGISTERED
- mdiobus_scan allocates resources which need to be freed
- the comment is wrong, the resistors used are actually pull-ups.
Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/mdio_bus.c')
-rw-r--r-- | drivers/net/phy/mdio_bus.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 7a33360..11adf6e 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -63,7 +63,9 @@ EXPORT_SYMBOL(mdiobus_alloc); static void mdiobus_release(struct device *d) { struct mii_bus *bus = to_mii_bus(d); - BUG_ON(bus->state != MDIOBUS_RELEASED); + BUG_ON(bus->state != MDIOBUS_RELEASED && + /* for compatibility with error handling in drivers */ + bus->state != MDIOBUS_ALLOCATED); kfree(bus); } @@ -83,8 +85,7 @@ static struct class mdio_bus_class = { */ int mdiobus_register(struct mii_bus *bus) { - int i; - int err = 0; + int i, err; if (NULL == bus || NULL == bus->name || NULL == bus->read || @@ -116,16 +117,23 @@ int mdiobus_register(struct mii_bus *bus) struct phy_device *phydev; phydev = mdiobus_scan(bus, i); - if (IS_ERR(phydev)) + if (IS_ERR(phydev)) { err = PTR_ERR(phydev); + goto error; + } } } - if (!err) - bus->state = MDIOBUS_REGISTERED; - + bus->state = MDIOBUS_REGISTERED; pr_info("%s: probed\n", bus->name); + return 0; +error: + while (--i >= 0) { + if (bus->phy_map[i]) + device_unregister(&bus->phy_map[i]->dev); + } + device_del(&bus->dev); return err; } EXPORT_SYMBOL(mdiobus_register); |