Commit d005a09e authored by Marc Kleine-Budde's avatar Marc Kleine-Budde Committed by David S. Miller

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: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ff9a57a6
...@@ -442,11 +442,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, ...@@ -442,11 +442,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
u32 flags, phy_interface_t interface) u32 flags, phy_interface_t interface)
{ {
struct device *d = &phydev->dev; struct device *d = &phydev->dev;
int err;
/* Assume that if there is no driver, that it doesn't /* Assume that if there is no driver, that it doesn't
* exist, and we should use the genphy driver. */ * exist, and we should use the genphy driver. */
if (NULL == d->driver) { if (NULL == d->driver) {
int err;
d->driver = &genphy_driver.driver; d->driver = &genphy_driver.driver;
err = d->driver->probe(d); err = d->driver->probe(d);
...@@ -474,7 +474,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, ...@@ -474,7 +474,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
/* Do initial configuration here, now that /* Do initial configuration here, now that
* we have certain key parameters * we have certain key parameters
* (dev_flags and interface) */ * (dev_flags and interface) */
return phy_init_hw(phydev); err = phy_init_hw(phydev);
if (err)
phy_detach(phydev);
return err;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment