diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2011-03-28 10:54:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-30 05:31:36 -0400 |
commit | d005a09edf8b12dd1bec651b2cf94caa0e7bb1be (patch) | |
tree | 7be85d432af96505426104e2a4e47d85ceebe73b /drivers/net/phy | |
parent | ff9a57a62afbbe2d0f3a09af321f1fd7645f38a5 (diff) |
phylib: phy_attach_direct: phy_init_hw can fail, add cleanup
The function phy_attach_direct attaches the phy and calls phy_init_hw.
phy_init_hw can fail, but the phy is still marked as attached. Successive
calls to phy_attach_direct will fail because the phy is busy.
[ 1.020000] eth0: Freescale FEC PHY driver [Generic PHY] (mii_bus:phy_addr=1:00, irq=-1)
[ 1.030000] eth1: Freescale FEC PHY driver [Generic PHY] (mii_bus:phy_addr=1:01, irq=-1)
[ 2.050000] Sending DHCP requests .
[ 3.020000] PHY: 1:00 - Link is Up - 100/Full
[ 5.110000] ..... timed out!
[ 87.660000] IP-Config: Reopening network devices...
[ 88.190000] FEC: MDIO read timeout
[ 88.190000] eth0: could not attach to PHY
[ 88.190000] IP-Config: Failed to open eth0
[ 88.210000] FEC: MDIO read timeout
[ 88.210000] eth1: could not attach to PHY
[ 88.210000] IP-Config: Failed to open eth1
[ 88.220000] IP-Config: No network devices available.
[ 88.220000] Freeing init memory: 6968K
[...]
starting network interfaces...
ip: RTNETLINK answers: File exists
[ 94.000000] net eth0: PHY already attached
[ 94.010000] eth0: could not attach to PHY
ip: SIOCSIFFLAGS: Device or resource busy
This patch adds phy_detach to clean up if phy_init_hw fails.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/phy_device.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 993c52c82aeb..e870c0698bbe 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -442,11 +442,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
442 | u32 flags, phy_interface_t interface) | 442 | u32 flags, phy_interface_t interface) |
443 | { | 443 | { |
444 | struct device *d = &phydev->dev; | 444 | struct device *d = &phydev->dev; |
445 | int err; | ||
445 | 446 | ||
446 | /* Assume that if there is no driver, that it doesn't | 447 | /* Assume that if there is no driver, that it doesn't |
447 | * exist, and we should use the genphy driver. */ | 448 | * exist, and we should use the genphy driver. */ |
448 | if (NULL == d->driver) { | 449 | if (NULL == d->driver) { |
449 | int err; | ||
450 | d->driver = &genphy_driver.driver; | 450 | d->driver = &genphy_driver.driver; |
451 | 451 | ||
452 | err = d->driver->probe(d); | 452 | err = d->driver->probe(d); |
@@ -474,7 +474,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
474 | /* Do initial configuration here, now that | 474 | /* Do initial configuration here, now that |
475 | * we have certain key parameters | 475 | * we have certain key parameters |
476 | * (dev_flags and interface) */ | 476 | * (dev_flags and interface) */ |
477 | return phy_init_hw(phydev); | 477 | err = phy_init_hw(phydev); |
478 | if (err) | ||
479 | phy_detach(phydev); | ||
480 | |||
481 | return err; | ||
478 | } | 482 | } |
479 | 483 | ||
480 | /** | 484 | /** |