projects
/
project
/
netifd.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fix the exit status for the proto-shell task, use WEXITSTATUS
[project/netifd.git]
/
device.c
diff --git
a/device.c
b/device.c
index
ccba9d3
..
428d001
100644
(file)
--- a/
device.c
+++ b/
device.c
@@
-41,6
+41,20
@@
const struct config_param_list device_attr_list = {
.params = dev_attrs,
};
.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)
{
static struct device *
simple_device_create(const char *name, struct blob_attr *attr)
{
@@
-172,6
+186,8
@@
alias_notify_device(const char *name, struct device *dev)
{
struct alias_device *alias;
{
struct alias_device *alias;
+ device_lock();
+
alias = avl_find_element(&aliases, name, alias, avl);
if (!alias)
return;
alias = avl_find_element(&aliases, name, alias, avl);
if (!alias)
return;
@@
-179,8
+195,7
@@
alias_notify_device(const char *name, struct device *dev)
alias->cleanup = !dev;
if (dev) {
if (dev != alias->dep.dev) {
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);
}
strcpy(alias->dev.ifname, dev->ifname);
device_add_user(&alias->dep, dev);
}
@@
-190,6
+205,8
@@
alias_notify_device(const char *name, struct device *dev)
if (!dev && alias->dep.dev && !alias->dep.dev->active)
device_remove_user(&alias->dep);
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 int set_device_state(struct device *dev, bool state)
@@
-291,12
+308,13
@@
int device_init(struct device *dev, const struct device_type *type, const char *
}
static struct device *
}
static struct device *
-device_create_default(const char *name)
+device_create_default(const char *name
, bool external
)
{
struct device *dev;
D(DEVICE, "Create simple device '%s'\n", name);
dev = calloc(1, sizeof(*dev));
{
struct device *dev;
D(DEVICE, "Create simple device '%s'\n", name);
dev = calloc(1, sizeof(*dev));
+ dev->external = external;
device_init(dev, &simple_device_type, name);
dev->default_config = true;
return dev;
device_init(dev, &simple_device_type, name);
dev->default_config = true;
return dev;
@@
-315,7
+333,7
@@
device_alias_get(const char *name)
}
struct device *
}
struct device *
-device_get(const char *name,
bool
create)
+device_get(const char *name,
int
create)
{
struct device *dev;
{
struct device *dev;
@@
-332,7
+350,7
@@
device_get(const char *name, bool create)
if (!create)
return NULL;
if (!create)
return NULL;
- return device_create_default(name);
+ return device_create_default(name
, create > 1
);
}
static void
}
static void
@@
-386,7
+404,7
@@
void device_add_user(struct device_user *dep, struct device *dev)
static void
__device_free_unused(struct device *dev)
{
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);
return;
device_free(dev);
@@
-396,6
+414,10
@@
void device_remove_user(struct device_user *dep)
{
struct device *dev = dep->dev;
{
struct device *dev = dep->dev;
+ if (!dep->dev)
+ return;
+
+ dep->hotplug = false;
if (dep->claimed)
device_release(dep);
if (dep->claimed)
device_release(dep);
@@
-430,7
+452,7
@@
device_init_pending(void)
}
}
}
}
-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];
device_reload_config(struct device *dev, struct blob_attr *attr)
{
struct blob_attr *tb[__DEV_ATTR_MAX];
@@
-442,7
+464,7
@@
device_reload_config(struct device *dev, struct blob_attr *attr)
if (cfg == &device_attr_list) {
memset(tb, 0, sizeof(tb));
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));
blobmsg_parse(dev_attrs, __DEV_ATTR_MAX, tb,
blob_data(attr), blob_len(attr));
@@
-452,9
+474,9
@@
device_reload_config(struct device *dev, struct blob_attr *attr)
return DEV_CONFIG_RECREATE;
}
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;
{
if (type != dev->type)
return DEV_CONFIG_RECREATE;
@@
-506,7
+528,7
@@
device_reset_old(void)
if (dev->type != &simple_device_type)
continue;
if (dev->type != &simple_device_type)
continue;
- ndev = device_create_default(dev->ifname);
+ ndev = device_create_default(dev->ifname
, dev->external
);
device_replace(ndev, dev);
}
}
device_replace(ndev, dev);
}
}
@@
-525,7
+547,7
@@
device_create(const char *name, const struct device_type *type,
odev = device_get(name, false);
if (odev) {
odev->current_config = true;
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);
switch (change) {
case DEV_CONFIG_APPLIED:
D(DEVICE, "Device '%s': config applied\n", odev->ifname);