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

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sun Jan 26 23:47:24 2014 +0100

cobalt/rtdm: base named devices on nucleus registry

---

 include/cobalt/kernel/rtdm/driver.h |    6 +-
 kernel/cobalt/rtdm/device.c         |  115 +++++++++++------------------------
 kernel/cobalt/rtdm/internal.h       |    2 +-
 kernel/cobalt/rtdm/proc.c           |   94 ++++++++--------------------
 4 files changed, 66 insertions(+), 151 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 881f517..1fe74e6 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -445,7 +445,10 @@ rtdm_private_to_context(void *dev_private)
 
 struct rtdm_dev_reserved {
        union {
-               struct list_head entry;
+               struct {
+                       struct list_head entry;
+                       xnhandle_t handle;
+               };
                struct xnid id;
        };
        atomic_t refcount;
@@ -460,6 +463,7 @@ struct rtdm_dev_reserved {
  * not reside in write-protected memory.
  */
 struct rtdm_device {
+       unsigned magic;
        /** Revision number of this structure, see
         *  @ref drv_versioning "Driver Versioning" defines */
        int struct_version;
diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c
index 38353ee..aca34f7 100644
--- a/kernel/cobalt/rtdm/device.c
+++ b/kernel/cobalt/rtdm/device.c
@@ -31,6 +31,8 @@
 #include <cobalt/kernel/apc.h>
 #include "rtdm/internal.h"
 
+#define RTDM_DEVICE_MAGIC      0x82846877
+
 #define SET_DEFAULT_OP(device, operation)                              \
        (device).operation##_rt  = (void *)rtdm_no_support;             \
        (device).operation##_nrt = (void *)rtdm_no_support
@@ -44,13 +46,7 @@
 #define ANY_HANDLER(device, operation)                                 \
        ((device).operation##_rt || (device).operation##_nrt)
 
-unsigned int devname_hashtab_size = DEF_DEVNAME_HASHTAB_SIZE;
-module_param(devname_hashtab_size, uint, 0400);
-MODULE_PARM_DESC(devname_hashtab_size,
-                "Size of hash table for named devices (must be power of 2)");
-
-struct list_head *rtdm_named_devices;  /* hash table */
-static int name_hashkey_mask;
+struct list_head rtdm_named_devices;   /* hash table */
 struct rb_root rtdm_protocol_devices;
 
 int rtdm_apc;
@@ -74,18 +70,6 @@ int rtdm_select_bind_no_support(struct rtdm_dev_context 
*context,
        return -EBADF;
 }
 
-static inline int get_name_hash(const char *str, int limit, int hashkey_mask)
-{
-       int hash = 0;
-
-       while (*str != 0) {
-               hash += *str++;
-               if (--limit == 0)
-                       break;
-       }
-       return hash & hashkey_mask;
-}
-
 static inline unsigned long long get_proto_id(int pf, int type)
 {
        unsigned long long llpf = (unsigned)pf;
@@ -99,30 +83,28 @@ static inline void rtdm_reference_device(struct rtdm_device 
*device)
 
 struct rtdm_device *get_named_device(const char *name)
 {
-       struct list_head *entry;
        struct rtdm_device *device;
-       int hashkey;
+       xnhandle_t handle;
+       int err;
        spl_t s;
 
-       hashkey = get_name_hash(name, RTDM_MAX_DEVNAME_LEN, name_hashkey_mask);
+       err = xnregistry_bind(name, XN_NONBLOCK, XN_RELATIVE, &handle);
+       if (err == -EWOULDBLOCK)
+               return NULL;
 
        xnlock_get_irqsave(&rt_dev_lock, s);
 
-       list_for_each(entry, &rtdm_named_devices[hashkey]) {
-               device = list_entry(entry, struct rtdm_device, reserved.entry);
-
-               if (strcmp(name, device->device_name) == 0) {
+       device = xnregistry_fetch(handle);
+       if (device) {
+               if (device->magic != RTDM_DEVICE_MAGIC)
+                       device = NULL;
+               else
                        rtdm_reference_device(device);
-
-                       xnlock_put_irqrestore(&rt_dev_lock, s);
-
-                       return device;
-               }
        }
 
        xnlock_put_irqrestore(&rt_dev_lock, s);
 
-       return NULL;
+       return device;
 }
 
 struct rtdm_device *get_protocol_device(int protocol_family, int socket_type)
@@ -184,10 +166,7 @@ struct rtdm_device *get_protocol_device(int 
protocol_family, int socket_type)
 int rtdm_dev_register(struct rtdm_device *device)
 {
        unsigned long long id;
-       int hashkey;
        spl_t s;
-       struct list_head *entry;
-       struct rtdm_device *existing_dev;
        int ret;
 
        /* Catch unsuccessful initialisation */
@@ -281,6 +260,8 @@ int rtdm_dev_register(struct rtdm_device *device)
 
        down(&nrt_dev_lock);
 
+       device->magic = RTDM_DEVICE_MAGIC;
+
        if ((device->device_flags & RTDM_DEVICE_TYPE_MASK) == 
RTDM_NAMED_DEVICE) {
                trace_mark(xn_rtdm, nameddev_register, "device %p name %s "
                           "flags %d class %d sub_class %d profile_version %d "
@@ -288,29 +269,19 @@ int rtdm_dev_register(struct rtdm_device *device)
                           device->device_flags, device->device_class,
                           device->device_sub_class, device->profile_version,
                           device->driver_version);
-
-               hashkey =
-                   get_name_hash(device->device_name, RTDM_MAX_DEVNAME_LEN,
-                                 name_hashkey_mask);
-
-               list_for_each(entry, &rtdm_named_devices[hashkey]) {
-                       existing_dev =
-                           list_entry(entry, struct rtdm_device,
-                                      reserved.entry);
-                       if (strcmp(device->device_name,
-                                  existing_dev->device_name) == 0) {
-                               ret = -EEXIST;
-                               goto err;
-                       }
-               }
-
                ret = rtdm_proc_register_device(device);
                if (ret)
                        goto err;
 
+               ret = xnregistry_enter(device->device_name, device, 
+                               &device->reserved.handle, NULL);
+               if (ret) {
+                       rtdm_proc_unregister_device(device);
+                       goto err;
+               }
+
                xnlock_get_irqsave(&rt_dev_lock, s);
-               list_add_tail(&device->reserved.entry,
-                             &rtdm_named_devices[hashkey]);
+               list_add_tail(&device->reserved.entry, &rtdm_named_devices);
                xnlock_put_irqrestore(&rt_dev_lock, s);
 
                up(&nrt_dev_lock);
@@ -381,9 +352,10 @@ EXPORT_SYMBOL_GPL(rtdm_dev_register);
  */
 int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay)
 {
-       spl_t s;
        struct rtdm_device *reg_dev;
        unsigned long warned = 0;
+       xnhandle_t handle = 0;
+       spl_t s;
 
        if (!rtdm_initialised)
                return -ENOSYS;
@@ -422,15 +394,20 @@ int rtdm_dev_unregister(struct rtdm_device *device, 
unsigned int poll_delay)
                xnlock_get_irqsave(&rt_dev_lock, s);
        }
 
-       if ((device->device_flags & RTDM_DEVICE_TYPE_MASK) == RTDM_NAMED_DEVICE)
+       if ((device->device_flags & RTDM_DEVICE_TYPE_MASK) == 
+               RTDM_NAMED_DEVICE) {
+               handle = reg_dev->reserved.handle;
                list_del(&reg_dev->reserved.entry);
-       else
+       } else
                xnid_remove(&rtdm_protocol_devices, &reg_dev->reserved.id);
 
        xnlock_put_irqrestore(&rt_dev_lock, s);
 
        rtdm_proc_unregister_device(device);
 
+       if (handle)
+               xnregistry_remove(handle);
+
        up(&nrt_dev_lock);
 
        if (reg_dev->reserved.exclusive_context)
@@ -444,8 +421,6 @@ EXPORT_SYMBOL_GPL(rtdm_dev_unregister);
 
 int __init rtdm_dev_init(void)
 {
-       int err, i;
-
        sema_init(&nrt_dev_lock, 1);
 
        rtdm_apc = xnapc_alloc("deferred RTDM close", rtdm_apc_handler,
@@ -453,31 +428,10 @@ int __init rtdm_dev_init(void)
        if (rtdm_apc < 0)
                return rtdm_apc;
 
-       name_hashkey_mask = devname_hashtab_size - 1;
-       if (((devname_hashtab_size & name_hashkey_mask) != 0)) {
-               err = -EINVAL;
-               goto err_out1;
-       }
-
-       rtdm_named_devices = (struct list_head *)
-           kmalloc(devname_hashtab_size * sizeof(struct list_head),
-                   GFP_KERNEL);
-       if (!rtdm_named_devices) {
-               err = -ENOMEM;
-               goto err_out1;
-       }
-
-       for (i = 0; i < devname_hashtab_size; i++)
-               INIT_LIST_HEAD(&rtdm_named_devices[i]);
-       
+       INIT_LIST_HEAD(&rtdm_named_devices);
        xntree_init(&rtdm_protocol_devices);
 
        return 0;
-
-err_out1:
-       xnapc_free(rtdm_apc);
-
-       return err;
 }
 
 void rtdm_dev_cleanup(void)
@@ -487,7 +441,6 @@ void rtdm_dev_cleanup(void)
         * to deregister as long as there are references.
         */
        xnapc_free(rtdm_apc);
-       kfree(rtdm_named_devices);
 }
 
 /*@}*/
diff --git a/kernel/cobalt/rtdm/internal.h b/kernel/cobalt/rtdm/internal.h
index 0bebe8b..3288068 100644
--- a/kernel/cobalt/rtdm/internal.h
+++ b/kernel/cobalt/rtdm/internal.h
@@ -50,7 +50,7 @@ extern struct rtdm_fildes fildes_table[];
 extern int open_fildes;
 extern struct semaphore nrt_dev_lock;
 extern unsigned int devname_hashtab_size;
-extern struct list_head *rtdm_named_devices;
+extern struct list_head rtdm_named_devices;
 extern struct rb_root rtdm_protocol_devices;
 extern struct xnpersonality rtdm_personality;
 
diff --git a/kernel/cobalt/rtdm/proc.c b/kernel/cobalt/rtdm/proc.c
index 218bf8b..28ec6ab 100644
--- a/kernel/cobalt/rtdm/proc.c
+++ b/kernel/cobalt/rtdm/proc.c
@@ -23,10 +23,7 @@
 struct xnvfile_directory rtdm_vfroot;  /* /proc/xenomai/rtdm */
 
 struct vfile_device_data {
-       int h;
-       int hmax;
-       struct list_head *devmap;
-       struct list_head *curr;
+       struct rtdm_device *curr;
 };
 
 static int get_nrt_lock(struct xnvfile *vfile)
@@ -44,95 +41,59 @@ static struct xnvfile_lock_ops lockops = {
        .put = put_nrt_lock,
 };
 
-static struct list_head *next_devlist(struct vfile_device_data *priv)
-{
-       struct list_head *head;
-
-       while (priv->h < priv->hmax) {
-               head = priv->devmap + priv->h;
-               if (!list_empty(head))
-                       return head;
-               priv->h++;
-       }
-
-       return NULL;
-}
-
-static void *next_dev(struct xnvfile_regular_iterator *it)
+static void *named_next(struct xnvfile_regular_iterator *it)
 {
        struct vfile_device_data *priv = xnvfile_iterator_priv(it);
+       struct rtdm_device *device = priv->curr;
        struct list_head *next;
 
-       next = priv->curr->next;
-seek:
-       if (next == priv->devmap + priv->h) {
-               /* Done with the current hash slot, let's progress. */
-               if (priv->h >= priv->hmax) {
-                       next = NULL; /* all done. */
-                       goto out;
-               }
-
-               priv->h++;
-               next = next_devlist(priv);
-               if (next) {
-                       next = next->next; /* skip head. */
-                       goto seek;
-               }
+       next = device->reserved.entry.next;
+       if (next == &rtdm_named_devices) {
+               priv->curr = NULL; /* all done. */
+               goto out;
        }
-out:
-       priv->curr = next;
 
-       return next;
+       priv->curr = list_entry(next, struct rtdm_device, reserved.entry);
+
+  out:
+       return priv->curr;
 }
 
 static void *named_begin(struct xnvfile_regular_iterator *it)
 {
        struct vfile_device_data *priv = xnvfile_iterator_priv(it);
-       struct list_head *devlist;
+       struct rtdm_device *device;
        loff_t pos = 0;
 
-       priv->devmap = rtdm_named_devices;
-       priv->hmax = devname_hashtab_size;
-       priv->h = 0;
-
-       devlist = next_devlist(priv);
-       if (devlist == NULL)
-               return NULL;    /* All devlists empty. */
+       list_for_each_entry(device, &rtdm_named_devices, reserved.entry)
+               if (pos++ >= it->pos)
+                       break;
 
-       priv->curr = devlist->next;     /* Skip head. */
+       if (&device->reserved.entry == &rtdm_named_devices)
+               return NULL;    /* End of list. */
 
-       /*
-        * priv->curr now points to the first device; advance to the requested
-        * position from there.
-        */
-       while (priv->curr && pos++ < it->pos)
-               priv->curr = next_dev(it);
+       priv->curr = device;    /* Skip head. */
 
        if (pos == 1)
                /* Output the header once, only if some device follows. */
-               xnvfile_puts(it, "Hash\tName\t\t\t\tDriver\t\t/proc\n");
+               xnvfile_puts(it, "Name\t\t\t\tDriver\t\t/proc\n");
 
        return priv->curr;
 }
 
 static int named_show(struct xnvfile_regular_iterator *it, void *data)
 {
-       struct vfile_device_data *priv = xnvfile_iterator_priv(it);
-       struct list_head *curr = data;
-       struct rtdm_device *device;
+       struct rtdm_device *device = data;
 
-       device = list_entry(curr, struct rtdm_device, reserved.entry);
-       xnvfile_printf(it, "%02X\t%-31s\t%-15s\t%s\n",
-                      priv->h, device->device_name,
-                      device->driver_name,
-                      device->proc_name);
+       xnvfile_printf(it, "%-31s\t%-15s\t%s\n", device->device_name, 
+               device->driver_name, device->proc_name);
 
        return 0;
 }
 
 static struct xnvfile_regular_ops named_vfile_ops = {
        .begin = named_begin,
-       .next = next_dev,
+       .next = named_next,
        .show = named_show,
 };
 
@@ -306,7 +267,6 @@ static struct xnvfile_regular allfd_vfile = {
 static int devinfo_vfile_show(struct xnvfile_regular_iterator *it, void *data)
 {
        struct rtdm_device *device;
-       int i;
 
        if (down_interruptible(&nrt_dev_lock))
                return -ERESTARTSYS;
@@ -315,11 +275,9 @@ static int devinfo_vfile_show(struct 
xnvfile_regular_iterator *it, void *data)
         * As the device may have disappeared while the handler was called,
         * first match the pointer against registered devices.
         */
-       for (i = 0; i < devname_hashtab_size; i++)
-               list_for_each_entry(device, &rtdm_named_devices[i],
-                                   reserved.entry)
-                       if (device == xnvfile_priv(it->vfile))
-                               goto found;
+       list_for_each_entry(device, &rtdm_named_devices, reserved.entry)
+               if (device == xnvfile_priv(it->vfile))
+                       goto found;
 
        xntree_for_each_entry(device, &rtdm_protocol_devices, reserved.id)
                if (device == xnvfile_priv(it->vfile))


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

Reply via email to