Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -436,6 +436,13 @@ void sfp_upstream_stop(struct sfp_bus *bus)
}
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
 * @fwnode: firmware node for the SFP bus
@@ -462,8 +469,11 @@ struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
		bus->upstream = upstream;
		bus->netdev = ndev;

		if (bus->sfp)
		if (bus->sfp) {
			ret = sfp_register_bus(bus);
			if (ret)
				sfp_upstream_clear(bus);
		}
		rtnl_unlock();
	}

@@ -488,8 +498,7 @@ void sfp_unregister_upstream(struct sfp_bus *bus)
	rtnl_lock();
	if (bus->sfp)
		sfp_unregister_bus(bus);
	bus->upstream = NULL;
	bus->netdev = NULL;
	sfp_upstream_clear(bus);
	rtnl_unlock();

	sfp_bus_put(bus);
@@ -561,6 +570,13 @@ void sfp_module_remove(struct sfp_bus *bus)
}
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,
				    const struct sfp_socket_ops *ops)
{
@@ -573,8 +589,11 @@ struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp,
		bus->sfp = sfp;
		bus->socket_ops = ops;

		if (bus->netdev)
		if (bus->netdev) {
			ret = sfp_register_bus(bus);
			if (ret)
				sfp_socket_clear(bus);
		}
		rtnl_unlock();
	}

@@ -592,9 +611,7 @@ void sfp_unregister_socket(struct sfp_bus *bus)
	rtnl_lock();
	if (bus->netdev)
		sfp_unregister_bus(bus);
	bus->sfp_dev = NULL;
	bus->sfp = NULL;
	bus->socket_ops = NULL;
	sfp_socket_clear(bus);
	rtnl_unlock();

	sfp_bus_put(bus);