Commit f20a4c46 authored by Russell King's avatar Russell King Committed by David S. Miller

sfp: ensure we clean up properly on bus registration failure

We fail to correctly clean up after a bus registration failure, which
can lead to an incorrect assumption about the registration state of
the upstream or sfp cage.
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0026129c
...@@ -436,6 +436,13 @@ void sfp_upstream_stop(struct sfp_bus *bus) ...@@ -436,6 +436,13 @@ void sfp_upstream_stop(struct sfp_bus *bus)
} }
EXPORT_SYMBOL_GPL(sfp_upstream_stop); EXPORT_SYMBOL_GPL(sfp_upstream_stop);
static void sfp_upstream_clear(struct sfp_bus *bus)
{
bus->upstream_ops = NULL;
bus->upstream = NULL;
bus->netdev = NULL;
}
/** /**
* sfp_register_upstream() - Register the neighbouring device * sfp_register_upstream() - Register the neighbouring device
* @fwnode: firmware node for the SFP bus * @fwnode: firmware node for the SFP bus
...@@ -462,8 +469,11 @@ struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode, ...@@ -462,8 +469,11 @@ struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
bus->upstream = upstream; bus->upstream = upstream;
bus->netdev = ndev; bus->netdev = ndev;
if (bus->sfp) if (bus->sfp) {
ret = sfp_register_bus(bus); ret = sfp_register_bus(bus);
if (ret)
sfp_upstream_clear(bus);
}
rtnl_unlock(); rtnl_unlock();
} }
...@@ -488,8 +498,7 @@ void sfp_unregister_upstream(struct sfp_bus *bus) ...@@ -488,8 +498,7 @@ void sfp_unregister_upstream(struct sfp_bus *bus)
rtnl_lock(); rtnl_lock();
if (bus->sfp) if (bus->sfp)
sfp_unregister_bus(bus); sfp_unregister_bus(bus);
bus->upstream = NULL; sfp_upstream_clear(bus);
bus->netdev = NULL;
rtnl_unlock(); rtnl_unlock();
sfp_bus_put(bus); sfp_bus_put(bus);
...@@ -561,6 +570,13 @@ void sfp_module_remove(struct sfp_bus *bus) ...@@ -561,6 +570,13 @@ void sfp_module_remove(struct sfp_bus *bus)
} }
EXPORT_SYMBOL_GPL(sfp_module_remove); EXPORT_SYMBOL_GPL(sfp_module_remove);
static void sfp_socket_clear(struct sfp_bus *bus)
{
bus->sfp_dev = NULL;
bus->sfp = NULL;
bus->socket_ops = NULL;
}
struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp, struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp,
const struct sfp_socket_ops *ops) const struct sfp_socket_ops *ops)
{ {
...@@ -573,8 +589,11 @@ struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp, ...@@ -573,8 +589,11 @@ struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp,
bus->sfp = sfp; bus->sfp = sfp;
bus->socket_ops = ops; bus->socket_ops = ops;
if (bus->netdev) if (bus->netdev) {
ret = sfp_register_bus(bus); ret = sfp_register_bus(bus);
if (ret)
sfp_socket_clear(bus);
}
rtnl_unlock(); rtnl_unlock();
} }
...@@ -592,9 +611,7 @@ void sfp_unregister_socket(struct sfp_bus *bus) ...@@ -592,9 +611,7 @@ void sfp_unregister_socket(struct sfp_bus *bus)
rtnl_lock(); rtnl_lock();
if (bus->netdev) if (bus->netdev)
sfp_unregister_bus(bus); sfp_unregister_bus(bus);
bus->sfp_dev = NULL; sfp_socket_clear(bus);
bus->sfp = NULL;
bus->socket_ops = NULL;
rtnl_unlock(); rtnl_unlock();
sfp_bus_put(bus); sfp_bus_put(bus);
......
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