Module: xenomai-3 Branch: arm64 Commit: fec4f73dab365b9e3328e88c5b230610cd0f6316 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=fec4f73dab365b9e3328e88c5b230610cd0f6316
Author: Philippe Gerum <r...@xenomai.org> Date: Sat Oct 3 19:04:30 2015 +0200 cobalt/rtdm: fix default minor assignation Devices may come and go, so using the device reference count maintained in the driver descriptor is not a particularly bright idea from /me. Replace this by a bitmap, allowing for proper dynamic minor registration/deregistration. --- include/cobalt/kernel/rtdm/driver.h | 4 ++++ kernel/cobalt/rtdm/device.c | 33 +++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 541fb04..b0a37c4 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -93,6 +93,9 @@ enum rtdm_selecttype; #define RTDM_SECURE_DEVICE 0x80000000 /** @} Device Flags */ +/** Maximum number of named devices per driver. */ +#define RTDM_MAX_MINOR 256 + /** @} rtdm_device_register */ /*! @@ -279,6 +282,7 @@ struct rtdm_driver { }; atomic_t refcount; struct notifier_block nb_statechange; + DECLARE_BITMAP(minor_map, RTDM_MAX_MINOR); }; }; diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c index 9af2221..4943be4 100644 --- a/kernel/cobalt/rtdm/device.c +++ b/kernel/cobalt/rtdm/device.c @@ -303,6 +303,7 @@ static int register_driver(struct rtdm_driver *drv) drv->named.major = MAJOR(rdev); atomic_set(&drv->refcount, 1); + bitmap_zero(drv->minor_map, RTDM_MAX_MINOR); done: drv->nb_statechange.notifier_call = state_change_notifier; @@ -354,9 +355,9 @@ static void unregister_driver(struct rtdm_driver *drv) */ int rtdm_dev_register(struct rtdm_device *dev) { - int ret, pos, major, minor; struct device *kdev = NULL; struct rtdm_driver *drv; + int ret, major, minor; xnkey_t id; dev_t rdev; @@ -369,7 +370,6 @@ int rtdm_dev_register(struct rtdm_device *dev) dev->name = NULL; drv = dev->driver; - pos = atomic_read(&drv->refcount); ret = register_driver(drv); if (ret) { mutex_unlock(®ister_lock); @@ -386,16 +386,22 @@ int rtdm_dev_register(struct rtdm_device *dev) dev->ops.close = __rtdm_dev_close; /* Interpose on driver's handler. */ atomic_set(&dev->refcount, 0); - if (drv->device_flags & RTDM_FIXED_MINOR) { - minor = dev->minor; - if (minor < 0 || minor >= drv->device_count) { - ret = -EINVAL; - goto fail; + if (drv->device_flags & RTDM_NAMED_DEVICE) { + if (drv->device_flags & RTDM_FIXED_MINOR) { + minor = dev->minor; + if (minor < 0 || minor >= drv->device_count) { + ret = -ENXIO; + goto fail; + } + } else { + minor = find_first_zero_bit(drv->minor_map, RTDM_MAX_MINOR); + if (minor >= RTDM_MAX_MINOR) { + ret = -ENXIO; + goto fail; + } + dev->minor = minor; } - } else - dev->minor = minor = pos; - if (drv->device_flags & RTDM_NAMED_DEVICE) { major = drv->named.major; dev->name = kasformat(dev->label, minor); if (dev->name == NULL) { @@ -416,7 +422,9 @@ int rtdm_dev_register(struct rtdm_device *dev) ret = PTR_ERR(kdev); goto fail; } + __set_bit(minor, drv->minor_map); } else { + dev->minor = -1; dev->name = kstrdup(dev->label, GFP_KERNEL); if (dev->name == NULL) { ret = -ENOMEM; @@ -489,9 +497,10 @@ void rtdm_dev_unregister(struct rtdm_device *dev) mutex_lock(®ister_lock); - if (drv->device_flags & RTDM_NAMED_DEVICE) + if (drv->device_flags & RTDM_NAMED_DEVICE) { xnregistry_remove(dev->named.handle); - else + __clear_bit(dev->minor, drv->minor_map); + } else xnid_remove(&protocol_devices, &dev->proto.id); device_destroy(rtdm_class, dev->rdev); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git