Module: xenomai-gch
Branch: for-forge
Commit: d529c7725773543f5902dc9d7026b1663ff1009a
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=d529c7725773543f5902dc9d7026b1663ff1009a

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Fri Oct 16 19:29:56 2015 +0200

rtdm/devices: do not use minor 0 for all protocols

Since the device is indexed by its major and minor, device_destroy()
does not destroy the right device if there is more than one.

---

 kernel/cobalt/rtdm/device.c |   27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c
index 4943be4..bcc2ab5 100644
--- a/kernel/cobalt/rtdm/device.c
+++ b/kernel/cobalt/rtdm/device.c
@@ -52,6 +52,7 @@
 static struct rb_root protocol_devices;
 
 static DEFINE_MUTEX(register_lock);
+static DECLARE_BITMAP(protocol_devices_minor_map, RTDM_MAX_MINOR);
 
 static struct class *rtdm_class;
 
@@ -424,14 +425,29 @@ int rtdm_dev_register(struct rtdm_device *dev)
                }
                __set_bit(minor, drv->minor_map);
        } else {
-               dev->minor = -1;
+               if (drv->device_flags & RTDM_FIXED_MINOR) {
+                       minor = dev->minor;
+                       if (minor < 0 || minor >= RTDM_MAX_MINOR) {
+                               ret = -ENXIO;
+                               goto fail;
+                       }
+               } else {
+                       minor = find_first_zero_bit(protocol_devices_minor_map,
+                                               RTDM_MAX_MINOR);
+                       if (minor >= RTDM_MAX_MINOR) {
+                               ret = -ENXIO;
+                               goto fail;
+                       }
+                       dev->minor = minor;
+               }
+
                dev->name = kstrdup(dev->label, GFP_KERNEL);
                if (dev->name == NULL) {
                        ret = -ENOMEM;
                        goto fail;
                }
 
-               rdev = MKDEV(0, 0);
+               rdev = MKDEV(0, minor);
                kdev = device_create(rtdm_class, NULL, rdev,
                                     dev, dev->name);
                if (IS_ERR(kdev)) {
@@ -443,6 +459,7 @@ int rtdm_dev_register(struct rtdm_device *dev)
                ret = xnid_enter(&protocol_devices, &dev->proto.id, id);
                if (ret < 0)
                        goto fail;
+               __set_bit(minor, protocol_devices_minor_map);
        }
 
        dev->rdev = rdev;
@@ -500,8 +517,10 @@ void rtdm_dev_unregister(struct rtdm_device *dev)
        if (drv->device_flags & RTDM_NAMED_DEVICE) {
                xnregistry_remove(dev->named.handle);
                __clear_bit(dev->minor, drv->minor_map);
-       } else
+       } else {
                xnid_remove(&protocol_devices, &dev->proto.id);
+               __clear_bit(dev->minor, protocol_devices_minor_map);
+       }
 
        device_destroy(rtdm_class, dev->rdev);
 
@@ -527,6 +546,8 @@ int __init rtdm_init(void)
        rtdm_class->dev_groups = rtdm_groups;
        rtdm_class->devnode = rtdm_devnode;
 
+       bitmap_zero(protocol_devices_minor_map, RTDM_MAX_MINOR);
+
        return 0;
 }
 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to