From 217962615662f1ab7a60978a194444023039f0a4 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 23 Jan 2019 07:30:38 +0100 Subject: net: phy: warn if phy_start is called from invalid state phy_start() should be called from states PHY_READY or PHY_HALTED only. Check for this to detect misbehaving drivers. Also the state machine should be started only when being called from one of the valid states. Some more background: For all invalid states phy_start() basically was a no-op. All it did was triggering a state machine run, but for all "running" states the poll loop was active anyway. And if called from PHY_DOWN, the state machine does nothing. v3: - extended commit message Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/net/phy/phy.c') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index a7fca15888b6..dedd57b86c80 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -856,9 +856,16 @@ void phy_start(struct phy_device *phydev) mutex_lock(&phydev->lock); + if (phydev->state != PHY_READY && phydev->state != PHY_HALTED) { + WARN(1, "called from state %s\n", + phy_state_to_str(phydev->state)); + goto out; + } + switch (phydev->state) { case PHY_READY: phydev->state = PHY_UP; + phy_start_machine(phydev); break; case PHY_HALTED: /* if phy was suspended, bring the physical link up again */ @@ -872,13 +879,13 @@ void phy_start(struct phy_device *phydev) } phydev->state = PHY_RESUMING; + phy_start_machine(phydev); break; default: break; } +out: mutex_unlock(&phydev->lock); - - phy_start_machine(phydev); } EXPORT_SYMBOL(phy_start); -- cgit v1.2.3-59-g8ed1b