.params = dev_attrs,
};
+static int __devlock = 0;
+
+void device_lock(void)
+{
+ __devlock++;
+}
+
+void device_unlock(void)
+{
+ __devlock--;
+ if (!__devlock)
+ device_free_unused(NULL);
+}
+
static struct device *
simple_device_create(const char *name, struct blob_attr *attr)
{
{
struct alias_device *alias;
+ device_lock();
+
alias = avl_find_element(&aliases, name, alias, avl);
if (!alias)
return;
alias->cleanup = !dev;
if (dev) {
if (dev != alias->dep.dev) {
- if (alias->dep.dev)
- device_remove_user(&alias->dep);
+ device_remove_user(&alias->dep);
strcpy(alias->dev.ifname, dev->ifname);
device_add_user(&alias->dep, dev);
}
if (!dev && alias->dep.dev && !alias->dep.dev->active)
device_remove_user(&alias->dep);
+
+ device_unlock();
}
static int set_device_state(struct device *dev, bool state)
static void
__device_free_unused(struct device *dev)
{
- if (!list_empty(&dev->users) || dev->current_config || config_init)
+ if (!list_empty(&dev->users) || dev->current_config || __devlock)
return;
device_free(dev);
{
struct device *dev = dep->dev;
+ if (!dep->dev)
+ return;
+
+ dep->hotplug = false;
if (dep->claimed)
device_release(dep);
}
}
-enum dev_change_type
+static enum dev_change_type
device_reload_config(struct device *dev, struct blob_attr *attr)
{
struct blob_attr *tb[__DEV_ATTR_MAX];
if (cfg == &device_attr_list) {
memset(tb, 0, sizeof(tb));
- if (dev->config)
+ if (attr)
blobmsg_parse(dev_attrs, __DEV_ATTR_MAX, tb,
blob_data(attr), blob_len(attr));
return DEV_CONFIG_RECREATE;
}
-static enum dev_change_type
-device_check_config(struct device *dev, const struct device_type *type,
- struct blob_attr *attr)
+enum dev_change_type
+device_set_config(struct device *dev, const struct device_type *type,
+ struct blob_attr *attr)
{
if (type != dev->type)
return DEV_CONFIG_RECREATE;
odev = device_get(name, false);
if (odev) {
odev->current_config = true;
- change = device_check_config(odev, type, config);
+ change = device_set_config(odev, type, config);
switch (change) {
case DEV_CONFIG_APPLIED:
D(DEVICE, "Device '%s': config applied\n", odev->ifname);