From 3675617531443a503f674e71e70248b9c5a205cd Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 28 Apr 2019 19:37:20 +0200 Subject: dsa: Make use of the list of tag drivers Implement the _get and _put functions to make use of the list of tag drivers. Also, trigger the loading of the module, based on the alias information. The _get function takes a reference on the tag driver, so it cannot be unloaded, and the _put function releases the reference. Signed-off-by: Andrew Lunn Reviewed-by: Florian Fainelli v2: Make tag_driver_register void Signed-off-by: David S. Miller --- net/dsa/dsa.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'net/dsa') diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 54e89c97ce11..67d21647c500 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -125,20 +125,49 @@ const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops) const struct dsa_device_ops *dsa_tag_driver_get(int tag_protocol) { + struct dsa_tag_driver *dsa_tag_driver; const struct dsa_device_ops *ops; + char module_name[128]; + bool found = false; - if (tag_protocol >= DSA_TAG_LAST) - return ERR_PTR(-EINVAL); - ops = dsa_device_ops[tag_protocol]; + snprintf(module_name, 127, "%s%d", DSA_TAG_DRIVER_ALIAS, + tag_protocol); - if (!ops) - return ERR_PTR(-ENOPROTOOPT); + request_module(module_name); + + mutex_lock(&dsa_tag_drivers_lock); + list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) { + ops = dsa_tag_driver->ops; + if (ops->proto == tag_protocol) { + found = true; + break; + } + } + + if (found) { + if (!try_module_get(dsa_tag_driver->owner)) + ops = ERR_PTR(-ENOPROTOOPT); + } else { + ops = ERR_PTR(-ENOPROTOOPT); + } + + mutex_unlock(&dsa_tag_drivers_lock); return ops; } void dsa_tag_driver_put(const struct dsa_device_ops *ops) { + struct dsa_tag_driver *dsa_tag_driver; + + mutex_lock(&dsa_tag_drivers_lock); + list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) { + if (dsa_tag_driver->ops == ops) { + module_put(dsa_tag_driver->owner); + break; + } + } + mutex_unlock(&dsa_tag_drivers_lock); } static int dev_is_class(struct device *dev, void *class) -- cgit v1.2.3-59-g8ed1b