Module: xenomai-rpm
Branch: queue/vfile
Commit: c655437a44acd176c0fc44ae96032e342be77438
URL:    
http://git.xenomai.org/?p=xenomai-rpm.git;a=commit;h=c655437a44acd176c0fc44ae96032e342be77438

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Jun 17 12:27:42 2010 +0200

rtdm: convert to vfile

---

 include/rtdm/rtdm_driver.h |    8 +-
 ksrc/skins/rtdm/device.c   |   17 +-
 ksrc/skins/rtdm/internal.h |   24 ++-
 ksrc/skins/rtdm/module.c   |   10 -
 ksrc/skins/rtdm/proc.c     |  523 ++++++++++++++++++++++++++------------------
 5 files changed, 343 insertions(+), 239 deletions(-)

diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h
index fd41690..4b1d054 100644
--- a/include/rtdm/rtdm_driver.h
+++ b/include/rtdm/rtdm_driver.h
@@ -39,6 +39,7 @@
 #include <nucleus/pod.h>
 #include <nucleus/synch.h>
 #include <nucleus/select.h>
+#include <nucleus/vfile.h>
 #include <rtdm/rtdm.h>
 
 /* debug support */
@@ -517,8 +518,11 @@ struct rtdm_device {
 
        /** Name of /proc entry for the device, must not be NULL */
        const char *proc_name;
-       /** Set to device's /proc root entry after registration, do not modify 
*/
-       struct proc_dir_entry *proc_entry;
+#ifdef CONFIG_PROC_FS
+       /** Set to device's vfile data after registration, do not modify */
+       struct xnvfile_directory vfroot;
+       struct xnvfile_regular info_vfile;
+#endif
 
        /** Driver definable device ID */
        int device_id;
diff --git a/ksrc/skins/rtdm/device.c b/ksrc/skins/rtdm/device.c
index 3acc5ee..af097fb 100644
--- a/ksrc/skins/rtdm/device.c
+++ b/ksrc/skins/rtdm/device.c
@@ -213,7 +213,7 @@ int rtdm_dev_register(struct rtdm_device *device)
 
        /* Sanity check: proc_name specified? */
        XENO_ASSERT(RTDM, device->proc_name,
-                   xnlogerr("RTDM: no /proc entry name specified\n");
+                   xnlogerr("RTDM: no vfile (/proc) name specified\n");
                    return -EINVAL;);
 
        switch (device->device_flags & RTDM_DEVICE_TYPE_MASK) {
@@ -310,10 +310,9 @@ int rtdm_dev_register(struct rtdm_device *device)
                        }
                }
 
-#ifdef CONFIG_PROC_FS
-               if ((ret = rtdm_proc_register_device(device)) < 0)
+               ret = rtdm_proc_register_device(device);
+               if (ret)
                        goto err;
-#endif /* CONFIG_PROC_FS */
 
                xnlock_get_irqsave(&rt_dev_lock, s);
                list_add_tail(&device->reserved.entry,
@@ -350,10 +349,9 @@ int rtdm_dev_register(struct rtdm_device *device)
                        }
                }
 
-#ifdef CONFIG_PROC_FS
-               if ((ret = rtdm_proc_register_device(device)) < 0)
+               ret = rtdm_proc_register_device(device);
+               if (ret)
                        goto err;
-#endif /* CONFIG_PROC_FS */
 
                xnlock_get_irqsave(&rt_dev_lock, s);
                list_add_tail(&device->reserved.entry,
@@ -443,10 +441,7 @@ int rtdm_dev_unregister(struct rtdm_device *device, 
unsigned int poll_delay)
 
        xnlock_put_irqrestore(&rt_dev_lock, s);
 
-#ifdef CONFIG_PROC_FS
-       remove_proc_entry("information", device->proc_entry);
-       remove_proc_entry(device->proc_name, rtdm_proc_root);
-#endif /* CONFIG_PROC_FS */
+       rtdm_proc_unregister_device(device);
 
        up(&nrt_dev_lock);
 
diff --git a/ksrc/skins/rtdm/internal.h b/ksrc/skins/rtdm/internal.h
index a05cd7d..74abed2 100644
--- a/ksrc/skins/rtdm/internal.h
+++ b/ksrc/skins/rtdm/internal.h
@@ -61,7 +61,6 @@ extern unsigned int devname_hashtab_size;
 extern unsigned int protocol_hashtab_size;
 extern struct list_head *rtdm_named_devices;
 extern struct list_head *rtdm_protocol_devices;
-extern struct proc_dir_entry *rtdm_proc_root;
 
 #ifdef MODULE
 #define rtdm_initialised 1
@@ -82,9 +81,28 @@ static inline void rtdm_dereference_device(struct 
rtdm_device *device)
 int __init rtdm_dev_init(void);
 void rtdm_dev_cleanup(void);
 
-int rtdm_proc_register_device(struct rtdm_device *device);
-int __init rtdm_proc_init(void);
+#ifdef CONFIG_PROC_FS
+int rtdm_proc_init(void);
 void rtdm_proc_cleanup(void);
+int rtdm_proc_register_device(struct rtdm_device *device);
+void rtdm_proc_unregister_device(struct rtdm_device *device);
+#else
+static inline int rtdm_proc_init(void)
+{
+       return 0;
+}
+void rtdm_proc_cleanup(void)
+{
+}
+static int rtdm_proc_register_device(struct rtdm_device *device)
+{
+       return 0;
+}
+static void rtdm_proc_unregister_device(struct rtdm_device *device)
+{
+}
+#endif
+
 void rtdm_apc_handler(void *cookie);
 
 #endif /* _RTDM_INTERNAL_H */
diff --git a/ksrc/skins/rtdm/module.c b/ksrc/skins/rtdm/module.c
index b5120e4..2ff8d7a 100644
--- a/ksrc/skins/rtdm/module.c
+++ b/ksrc/skins/rtdm/module.c
@@ -48,11 +48,7 @@ MODULE_PARM_DESC(tick_arg, "Fixed clock tick value (us), 0 
for tick-less mode");
 static void __exit rtdm_skin_shutdown(int xtype)
 {
        rtdm_dev_cleanup();
-
-#ifdef CONFIG_PROC_FS
        rtdm_proc_cleanup();
-#endif /* CONFIG_PROC_FS */
-
 #ifdef CONFIG_XENO_OPT_PERVASIVE
        rtdm_syscall_cleanup();
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
@@ -79,11 +75,9 @@ static int __init SKIN_INIT(rtdm)
        if (err)
                goto cleanup_tbase;
 
-#ifdef CONFIG_PROC_FS
        err = rtdm_proc_init();
        if (err)
                goto cleanup_dev;
-#endif /* CONFIG_PROC_FS */
 
 #ifdef CONFIG_XENO_OPT_PERVASIVE
        err = rtdm_syscall_init();
@@ -102,13 +96,9 @@ static int __init SKIN_INIT(rtdm)
 #ifdef CONFIG_XENO_OPT_PERVASIVE
 cleanup_proc:
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
-
-#ifdef CONFIG_PROC_FS
        rtdm_proc_cleanup();
 
 cleanup_dev:
-#endif /* CONFIG_PROC_FS */
-
        rtdm_dev_cleanup();
 
 cleanup_tbase:
diff --git a/ksrc/skins/rtdm/proc.c b/ksrc/skins/rtdm/proc.c
index c797764..6321bb0 100644
--- a/ksrc/skins/rtdm/proc.c
+++ b/ksrc/skins/rtdm/proc.c
@@ -17,293 +17,390 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include <nucleus/vfile.h>
 #include "rtdm/internal.h"
 
-/* Derived from Erwin Rol's rtai_proc_fs.h.
-   Assumes that output fits into the provided buffer. */
+struct xnvfile_directory rtdm_vfroot;  /* /proc/xenomai/rtdm */
 
-#define RTDM_PROC_PRINT_VARS(MAX_BLOCK_LEN)                            \
-       const int max_block_len = MAX_BLOCK_LEN;                        \
-       off_t __limit = count - MAX_BLOCK_LEN;                          \
-       int __len = 0;                                                  \
-                                                                       \
-       *eof = 1;                                                       \
-       if (count < MAX_BLOCK_LEN)                                      \
-               return 0
+struct vfile_device_data {
+       int h;
+       int hmax;
+       struct list_head *devmap;
+       struct list_head *curr;
+};
 
-#define RTDM_PROC_PRINT(fmt, args...)                                  \
-({                                                                     \
-       __len += snprintf(buf + __len, max_block_len, fmt, ##args);     \
-       (__len <= __limit);                                             \
-})
+static int get_nrt_lock(struct xnvfile *vfile)
+{
+       return down_interruptible(&nrt_dev_lock) ? -ERESTARTSYS : 0;
+}
 
-#define RTDM_PROC_PRINT_DONE                                           \
-        return __len
+static void put_nrt_lock(struct xnvfile *vfile)
+{
+       up(&nrt_dev_lock);
+}
 
-struct proc_dir_entry *rtdm_proc_root; /* /proc/xenomai/rtdm */
+static struct xnvfile_lock_ops lockops = {
+       .get = get_nrt_lock,
+       .put = put_nrt_lock,
+};
 
-static int proc_read_named_devs(char *buf, char **start, off_t offset,
-                               int count, int *eof, void *data)
+static struct list_head *next_devlist(struct vfile_device_data *priv)
 {
-       int i;
-       struct list_head *entry;
-       struct rtdm_device *device;
-       RTDM_PROC_PRINT_VARS(80);
+       struct list_head *head;
 
-       if (down_interruptible(&nrt_dev_lock))
-               return -ERESTARTSYS;
+       while (priv->h < priv->hmax) {
+               head = priv->devmap + priv->h;
+               if (!list_empty(head))
+                       return head;
+               priv->h++;
+       }
 
-       if (!RTDM_PROC_PRINT("Hash\tName\t\t\t\tDriver\t\t/proc\n"))
-               goto done;
+       return NULL;
+}
 
-       for (i = 0; i < devname_hashtab_size; i++)
-               list_for_each(entry, &rtdm_named_devices[i]) {
-                       device = list_entry(entry, struct rtdm_device,
-                                           reserved.entry);
+static void *next_dev(struct xnvfile_regular_iterator *it)
+{
+       struct vfile_device_data *priv = xnvfile_iterator_priv(it);
+       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;
+               }
 
-                       if (!RTDM_PROC_PRINT("%02X\t%-31s\t%-15s\t%s\n",
-                                            i, device->device_name,
-                                            device->driver_name,
-                                            device->proc_name))
-                               break;
+               priv->h++;
+               next = next_devlist(priv);
+               if (next) {
+                       next = next->next; /* skip head. */
+                       goto seek;
                }
+       }
+out:
+       priv->curr = next;
 
-      done:
-       up(&nrt_dev_lock);
+       return next;
+}
 
-       RTDM_PROC_PRINT_DONE;
+static void *named_begin(struct xnvfile_regular_iterator *it)
+{
+       struct vfile_device_data *priv = xnvfile_iterator_priv(it);
+       loff_t pos = 0;
+
+       priv->devmap = rtdm_named_devices;
+       priv->hmax = devname_hashtab_size;
+       priv->h = 0;
+
+       priv->curr = next_devlist(priv);
+       if (priv->curr == NULL)
+               return NULL;    /* All devlists empty. */
+
+       /*
+        * priv->curr now points to the first populated device list
+        * attached to a hash slot; advance to the requested position
+        * from there.
+        */
+       do
+               priv->curr = next_dev(it);
+       while (priv->curr && ++pos < it->pos);
+
+       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");
+
+       return priv->curr;
 }
 
-static int proc_read_proto_devs(char *buf, char **start, off_t offset,
-                               int count, int *eof, void *data)
+static int named_show(struct xnvfile_regular_iterator *it, void *data)
 {
-       int i;
-       struct list_head *entry;
+       struct vfile_device_data *priv = xnvfile_iterator_priv(it);
+       struct list_head *curr = data;
        struct rtdm_device *device;
-       char txt[32];
-       RTDM_PROC_PRINT_VARS(80);
-
-       if (down_interruptible(&nrt_dev_lock))
-               return -ERESTARTSYS;
-
-       if (!RTDM_PROC_PRINT("Hash\tProtocolFamily:SocketType\tDriver\t\t"
-                            "/proc\n"))
-               goto done;
-
-       for (i = 0; i < protocol_hashtab_size; i++)
-               list_for_each(entry, &rtdm_protocol_devices[i]) {
-                       device = list_entry(entry, struct rtdm_device,
-                                           reserved.entry);
-
-                       snprintf(txt, sizeof(txt), "%u:%u",
-                                device->protocol_family, device->socket_type);
-                       if (!RTDM_PROC_PRINT("%02X\t%-31s\t%-15s\t%s\n", i,
-                                            txt, device->driver_name,
-                                            device->proc_name))
-                               break;
-               }
 
-      done:
-       up(&nrt_dev_lock);
+       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);
 
-       RTDM_PROC_PRINT_DONE;
+       return 0;
 }
 
-static int proc_read_open_fildes(char *buf, char **start, off_t offset,
-                                int count, int *eof, void *data)
+static struct xnvfile_regular_ops named_vfile_ops = {
+       .begin = named_begin,
+       .next = next_dev,
+       .show = named_show,
+};
+
+static struct xnvfile_regular named_vfile = {
+       .privsz = sizeof(struct vfile_device_data),
+       .ops = &named_vfile_ops,
+       .entry = { .lockops = &lockops }
+};
+
+static void *proto_begin(struct xnvfile_regular_iterator *it)
 {
-       int i;
-       int close_lock_count;
-       struct rtdm_device *device;
-       struct rtdm_process owner;
-       spl_t s;
-       RTDM_PROC_PRINT_VARS(80);
 
-       if (!RTDM_PROC_PRINT("Index\tLocked\tDevice\t\tOwner [PID]\n"))
-               goto done;
+       struct vfile_device_data *priv = xnvfile_iterator_priv(it);
+       loff_t pos = 0;
 
-       if (down_interruptible(&nrt_dev_lock))
-               return -ERESTARTSYS;
+       priv->devmap = rtdm_protocol_devices;
+       priv->hmax = protocol_hashtab_size;
+       priv->h = 0;
 
-       for (i = 0; i < RTDM_FD_MAX; i++) {
-               struct rtdm_dev_context *context;
+       priv->curr = next_devlist(priv);
+       if (priv->curr == NULL)
+               return NULL;    /* All devlists empty. */
 
-               xnlock_get_irqsave(&rt_fildes_lock, s);
+       /*
+        * priv->curr now points to the first populated device list
+        * attached to a hash slot; advance to the requested position
+        * from there.
+        */
+       do
+               priv->curr = next_dev(it);
+       while (priv->curr && ++pos < it->pos);
 
-               context = fildes_table[i].context;
-               if (!context) {
-                       xnlock_put_irqrestore(&rt_fildes_lock, s);
-                       continue;
-               }
+       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");
 
-               close_lock_count = atomic_read(&context->close_lock_count);
-               device = context->device;
+       return priv->curr;
+}
 
-               if (context->reserved.owner)
-                       memcpy(&owner, context->reserved.owner, sizeof(owner));
-               else {
-                       strcpy(owner.name, "<kernel>");
-                       owner.pid = -1;
-               }
+static int proto_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;
+       char pnum[32];
 
-               xnlock_put_irqrestore(&rt_fildes_lock, s);
+       device = list_entry(curr, struct rtdm_device, reserved.entry);
 
-               if (!RTDM_PROC_PRINT("%d\t%d\t%-15s %s [%d]\n", i,
-                                    close_lock_count,
-                                    (device->device_flags&RTDM_NAMED_DEVICE) ?
-                                    device->device_name : device->proc_name,
-                                    owner.name, owner.pid))
-                       break;
-       }
+       snprintf(pnum, sizeof(pnum), "%u:%u",
+                device->protocol_family, device->socket_type);
 
-       up(&nrt_dev_lock);
+       xnvfile_printf(it, "%02X\t%-31s\t%-15s\t%s\n",
+                      priv->h,
+                      pnum, device->driver_name,
+                      device->proc_name);
+       return 0;
+}
+
+static struct xnvfile_regular_ops proto_vfile_ops = {
+       .begin = proto_begin,
+       .next = next_dev,
+       .show = proto_show,
+};
+
+static struct xnvfile_regular proto_vfile = {
+       .privsz = sizeof(struct vfile_device_data),
+       .ops = &proto_vfile_ops,
+       .entry = { .lockops = &lockops }
+};
 
-      done:
-       RTDM_PROC_PRINT_DONE;
+static void *openfd_begin(struct xnvfile_regular_iterator *it)
+{
+       if (it->pos == 0)
+               xnvfile_puts(it, "Index\tLocked\tDevice\t\tOwner [PID]\n");
+
+       return it;      /* Whatever non-NULL pointer will do. */
 }
 
-static int proc_kill_open_fildes(struct file *file, const char __user *buffer,
-                                unsigned long count, void *data)
+static void *openfd_next(struct xnvfile_regular_iterator *it)
 {
-       char krnl_buf[32];
-       int fd;
-       int res;
+       if (it->pos >= RTDM_FD_MAX)
+               return NULL;
 
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
+       return it;
+}
 
-       if (count >= sizeof(krnl_buf))
-               return -EINVAL;
+static int openfd_show(struct xnvfile_regular_iterator *it, void *data)
+{
+       struct rtdm_dev_context *context;
+       struct rtdm_device *device;
+       struct rtdm_process owner;
+       int close_lock_count;
+       spl_t s;
 
-       if (copy_from_user(krnl_buf, buffer, count))
-               return -EFAULT;
-       krnl_buf[count] = '\0';
+       xnlock_get_irqsave(&rt_fildes_lock, s);
 
-       if (!sscanf(krnl_buf, "%d", &fd))
-               return -EINVAL;
+       context = fildes_table[it->pos].context;
+       if (context == NULL) {
+               xnlock_put_irqrestore(&rt_fildes_lock, s);
+               return VFILE_SEQ_SKIP;
+       }
+
+       close_lock_count = atomic_read(&context->close_lock_count);
+       device = context->device;
+       if (context->reserved.owner)
+               memcpy(&owner, context->reserved.owner, sizeof(owner));
+       else {
+               strcpy(owner.name, "<kernel>");
+               owner.pid = -1;
+       }
 
-       res = __rt_dev_close(current, fd);
-       if (res < 0)
-               return res;
+       xnlock_put_irqrestore(&rt_fildes_lock, s);
 
-       return count;
+       xnvfile_printf(it, "%d\t%d\t%-15s %s [%d]\n", (int)it->pos,
+                      close_lock_count,
+                      (device->device_flags & RTDM_NAMED_DEVICE) ?
+                      device->device_name : device->proc_name,
+                      owner.name, owner.pid);
+       return 0;
 }
 
-static int proc_read_fildes(char *buf, char **start, off_t offset,
-                           int count, int *eof, void *data)
+static ssize_t openfd_store(struct xnvfile_input *input)
 {
-       RTDM_PROC_PRINT_VARS(80);
+       ssize_t ret, cret;
+       long val;
+
+       ret = xnvfile_get_integer(input, &val);
+       if (ret < 0)
+               return ret;
+
+       cret = __rt_dev_close(current, (int)val);
+       if (cret < 0)
+               return cret;
+
+       return ret;
+}
 
-       RTDM_PROC_PRINT("total=%d:open=%d:free=%d\n", RTDM_FD_MAX,
-                       open_fildes, RTDM_FD_MAX - open_fildes);
+static struct xnvfile_regular_ops openfd_vfile_ops = {
+       .begin = openfd_begin,
+       .next = openfd_next,
+       .show = openfd_show,
+       .store = openfd_store,
+};
 
-       RTDM_PROC_PRINT_DONE;
+static struct xnvfile_regular openfd_vfile = {
+       .ops = &openfd_vfile_ops,
+       .entry = { .lockops = &lockops }
+};
+
+static int allfd_vfile_show(struct xnvfile_regular_iterator *it, void *data)
+{
+       xnvfile_printf(it, "total=%d:open=%d:free=%d\n", RTDM_FD_MAX,
+                      open_fildes, RTDM_FD_MAX - open_fildes);
+       return 0;
 }
 
-static int proc_read_dev_info(char *buf, char **start, off_t offset,
-                             int count, int *eof, void *data)
+static struct xnvfile_regular_ops allfd_vfile_ops = {
+       .show = allfd_vfile_show,
+};
+
+static struct xnvfile_regular allfd_vfile = {
+       .ops = &allfd_vfile_ops,
+};
+
+static int devinfo_vfile_show(struct xnvfile_regular_iterator *it, void *data)
 {
-       /* accessing the device during unregister (remove_proc_entry) might be
-          racy, but no official workaround is known yet */
-       struct rtdm_device *device = data;
-       RTDM_PROC_PRINT_VARS(256);
-
-       if (!RTDM_PROC_PRINT("driver:\t\t%s\nversion:\t%d.%d.%d\n",
-                            device->driver_name,
-                            RTDM_DRIVER_MAJOR_VER(device->driver_version),
-                            RTDM_DRIVER_MINOR_VER(device->driver_version),
-                            RTDM_DRIVER_PATCH_VER(device->driver_version)))
-               goto done;
-       if (!RTDM_PROC_PRINT("peripheral:\t%s\nprovider:\t%s\n",
-                            device->peripheral_name, device->provider_name))
-               goto done;
-       if (!RTDM_PROC_PRINT("class:\t\t%d\nsub-class:\t%d\n",
-                            device->device_class, device->device_sub_class))
-               goto done;
-       if (!RTDM_PROC_PRINT("flags:\t\t%s%s%s\n",
-                            (device->device_flags & RTDM_EXCLUSIVE) ?
-                            "EXCLUSIVE  " : "",
-                            (device->device_flags & RTDM_NAMED_DEVICE) ?
-                            "NAMED_DEVICE  " : "",
-                            (device->device_flags & RTDM_PROTOCOL_DEVICE) ?
-                            "PROTOCOL_DEVICE  " : ""))
-               goto done;
-       RTDM_PROC_PRINT("lock count:\t%d\n",
-                       atomic_read(&device->reserved.refcount));
-
-      done:
-       RTDM_PROC_PRINT_DONE;
+       struct rtdm_device *device = xnvfile_priv(it->vfile);
+
+       /*
+        * Accessing the device during unregister (remove_proc_entry) might be
+        * racy, but no official workaround is known yet.
+        */
+       xnvfile_printf(it, "driver:\t\t%s\nversion:\t%d.%d.%d\n",
+                      device->driver_name,
+                      RTDM_DRIVER_MAJOR_VER(device->driver_version),
+                      RTDM_DRIVER_MINOR_VER(device->driver_version),
+                      RTDM_DRIVER_PATCH_VER(device->driver_version));
+
+       xnvfile_printf(it, "peripheral:\t%s\nprovider:\t%s\n",
+                      device->peripheral_name, device->provider_name);
+
+       xnvfile_printf(it, "class:\t\t%d\nsub-class:\t%d\n",
+                      device->device_class, device->device_sub_class);
+
+       xnvfile_printf(it, "flags:\t\t%s%s%s\n",
+                      (device->device_flags & RTDM_EXCLUSIVE) ?
+                      "EXCLUSIVE  " : "",
+                      (device->device_flags & RTDM_NAMED_DEVICE) ?
+                      "NAMED_DEVICE  " : "",
+                      (device->device_flags & RTDM_PROTOCOL_DEVICE) ?
+                      "PROTOCOL_DEVICE  " : "");
+
+       xnvfile_printf(it, "lock count:\t%d\n",
+                      atomic_read(&device->reserved.refcount));
+
+       return 0;
 }
 
+static struct xnvfile_regular_ops devinfo_vfile_ops = {
+       .show = devinfo_vfile_show,
+};
+
 int rtdm_proc_register_device(struct rtdm_device *device)
 {
-       struct proc_dir_entry *dev_dir;
-       struct proc_dir_entry *proc_entry;
+       int ret;
 
-       dev_dir = create_proc_entry(device->proc_name, S_IFDIR, rtdm_proc_root);
-       if (!dev_dir)
+       ret = xnvfile_init_dir(device->proc_name,
+                              &device->vfroot, &rtdm_vfroot);
+       if (ret)
                goto err_out;
 
-       proc_entry = create_proc_entry("information", S_IFREG | S_IRUGO,
-                                      dev_dir);
-       if (!proc_entry) {
-               remove_proc_entry(device->proc_name, rtdm_proc_root);
+       memset(&device->info_vfile, 0, sizeof(device->info_vfile));
+       device->info_vfile.ops = &devinfo_vfile_ops;
+
+       ret = xnvfile_init_regular("information", &device->info_vfile,
+                                  &device->vfroot);
+       if (ret) {
+               xnvfile_destroy_dir(&device->vfroot);
                goto err_out;
        }
-       proc_entry->data = device;
-       proc_entry->read_proc = proc_read_dev_info;
 
-       device->proc_entry = dev_dir;
+       xnvfile_priv(&device->info_vfile) = device;
 
        return 0;
 
       err_out:
-       xnlogerr("RTDM: error while creating device proc entry\n");
-       return -EAGAIN;
+       xnlogerr("RTDM: error while creating device vfile\n");
+       return ret;
+}
+
+void rtdm_proc_unregister_device(struct rtdm_device *device)
+{
+       xnvfile_destroy_regular(&device->info_vfile);
+       xnvfile_destroy_dir(&device->vfroot);
 }
 
 int __init rtdm_proc_init(void)
 {
-       struct proc_dir_entry *proc_entry;
-
-       /* Initialise /proc entries */
-       rtdm_proc_root = create_proc_entry("xenomai/rtdm", S_IFDIR, NULL);
-       if (!rtdm_proc_root)
-               return -EAGAIN;
-
-       proc_entry = create_proc_entry("named_devices", S_IFREG | S_IRUGO,
-                                      rtdm_proc_root);
-       if (!proc_entry)
-               return -EAGAIN;
-       proc_entry->read_proc = proc_read_named_devs;
-
-       proc_entry = create_proc_entry("protocol_devices", S_IFREG | S_IRUGO,
-                                      rtdm_proc_root);
-       if (!proc_entry)
-               return -EAGAIN;
-       proc_entry->read_proc = proc_read_proto_devs;
-
-       proc_entry =
-           create_proc_entry("open_fildes", S_IFREG | S_IRUGO, rtdm_proc_root);
-       if (!proc_entry)
-               return -EAGAIN;
-       proc_entry->read_proc = proc_read_open_fildes;
-       proc_entry->write_proc = proc_kill_open_fildes;
-
-       proc_entry =
-           create_proc_entry("fildes", S_IFREG | S_IRUGO, rtdm_proc_root);
-       if (!proc_entry)
-               return -EAGAIN;
-       proc_entry->read_proc = proc_read_fildes;
+       int ret;
+
+       /* Initialise vfiles */
+       ret = xnvfile_init_dir("rtdm", &rtdm_vfroot, NULL);
+       if (ret)
+               return ret;
+
+       ret = xnvfile_init_regular("named_devices", &named_vfile, &rtdm_vfroot);
+       if (ret)
+               return ret;
+
+       ret = xnvfile_init_regular("protocol_devices", &proto_vfile, 
&rtdm_vfroot);
+       if (ret)
+               return ret;
+
+       ret = xnvfile_init_regular("open_fildes", &openfd_vfile, &rtdm_vfroot);
+       if (ret)
+               return ret;
+
+       ret = xnvfile_init_regular("fildes", &allfd_vfile, &rtdm_vfroot);
+       if (ret)
+               return ret;
 
        return 0;
 }
 
 void rtdm_proc_cleanup(void)
 {
-       remove_proc_entry("fildes", rtdm_proc_root);
-       remove_proc_entry("open_fildes", rtdm_proc_root);
-       remove_proc_entry("protocol_devices", rtdm_proc_root);
-       remove_proc_entry("named_devices", rtdm_proc_root);
-       remove_proc_entry("xenomai/rtdm", NULL);
+       xnvfile_destroy_regular(&allfd_vfile);
+       xnvfile_destroy_regular(&openfd_vfile);
+       xnvfile_destroy_regular(&proto_vfile);
+       xnvfile_destroy_regular(&named_vfile);
+       xnvfile_destroy_dir(&rtdm_vfroot);
 }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to