All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai] RTDM rework (2)
@ 2014-03-07 20:19 Gilles Chanteperdrix
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
  2014-04-05 12:14 ` [Xenomai] RTDM rework (2) Gilles Chanteperdrix
  0 siblings, 2 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:19 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai


Hi,

here comes a second attempt at introducing a file descriptor support for
other purposes than RTDM drivers.

This time, the file descriptors are called rtdm_fd and are part of the
RTDM API, but can be used by the POSIX personality. The actual RB-tree
where they are stored is part of the xnsys_ppd structure, as this way it
can be used by one of the RTDM and POSIX personalities, even if the
current process is not bound to the other personality.

I have posted the patches to the timerbench, switchtest, rtdm, xddp,
iddp and bufp drivers to allow seeing the API changes.

Regards.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid
  2014-03-07 20:19 [Xenomai] RTDM rework (2) Gilles Chanteperdrix
@ 2014-03-07 20:20 ` Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 2/9] cobalt/rtdm: base named devices on nucleus registry Gilles Chanteperdrix
                     ` (7 more replies)
  2014-04-05 12:14 ` [Xenomai] RTDM rework (2) Gilles Chanteperdrix
  1 sibling, 8 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

---
 include/cobalt/kernel/rtdm/driver.h |    6 +-
 kernel/cobalt/rtdm/device.c         |  103 ++++++++++++-----------------------
 kernel/cobalt/rtdm/internal.h       |    4 +-
 kernel/cobalt/rtdm/proc.c           |   60 ++++++++++----------
 4 files changed, 71 insertions(+), 102 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h
index 78ce5e4..75d0c0f 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -39,6 +39,7 @@
 #include <cobalt/kernel/apc.h>
 #include <cobalt/kernel/shadow.h>
 #include <cobalt/kernel/init.h>
+#include <cobalt/kernel/tree.h>
 #include <rtdm/rtdm.h>
 
 /* debug support */
@@ -444,7 +445,10 @@ rtdm_private_to_context(void *dev_private)
 }
 
 struct rtdm_dev_reserved {
-	struct list_head entry;
+	union {
+		struct list_head entry;
+		struct xnid id;
+	};
 	atomic_t refcount;
 	struct rtdm_dev_context *exclusive_context;
 };
diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c
index 1aa2542..38353ee 100644
--- a/kernel/cobalt/rtdm/device.c
+++ b/kernel/cobalt/rtdm/device.c
@@ -45,19 +45,13 @@
 	((device).operation##_rt || (device).operation##_nrt)
 
 unsigned int devname_hashtab_size = DEF_DEVNAME_HASHTAB_SIZE;
-unsigned int protocol_hashtab_size = DEF_PROTO_HASHTAB_SIZE;
 module_param(devname_hashtab_size, uint, 0400);
-module_param(protocol_hashtab_size, uint, 0400);
 MODULE_PARM_DESC(devname_hashtab_size,
 		 "Size of hash table for named devices (must be power of 2)");
-MODULE_PARM_DESC(protocol_hashtab_size,
-		 "Size of hash table for protocol devices "
-		 "(must be power of 2)");
 
 struct list_head *rtdm_named_devices;	/* hash table */
-struct list_head *rtdm_protocol_devices;	/* hash table */
 static int name_hashkey_mask;
-static int proto_hashkey_mask;
+struct rb_root rtdm_protocol_devices;
 
 int rtdm_apc;
 EXPORT_SYMBOL_GPL(rtdm_apc);
@@ -92,9 +86,10 @@ static inline int get_name_hash(const char *str, int limit, int hashkey_mask)
 	return hash & hashkey_mask;
 }
 
-static inline int get_proto_hash(int protocol_family, int socket_type)
+static inline unsigned long long get_proto_id(int pf, int type)
 {
-	return protocol_family & proto_hashkey_mask;
+	unsigned long long llpf = (unsigned)pf;
+	return (llpf << 32) | (unsigned)type;
 }
 
 static inline void rtdm_reference_device(struct rtdm_device *device)
@@ -132,31 +127,26 @@ struct rtdm_device *get_named_device(const char *name)
 
 struct rtdm_device *get_protocol_device(int protocol_family, int socket_type)
 {
-	struct list_head *entry;
 	struct rtdm_device *device;
-	int hashkey;
+	unsigned long long id;
+	struct xnid *xnid;
 	spl_t s;
 
-	hashkey = get_proto_hash(protocol_family, socket_type);
+	id = get_proto_id(protocol_family, socket_type);
 
 	xnlock_get_irqsave(&rt_dev_lock, s);
 
-	list_for_each(entry, &rtdm_protocol_devices[hashkey]) {
-		device = list_entry(entry, struct rtdm_device, reserved.entry);
-
-		if ((device->protocol_family == protocol_family) &&
-		    (device->socket_type == socket_type)) {
-			rtdm_reference_device(device);
-
-			xnlock_put_irqrestore(&rt_dev_lock, s);
+	xnid = xnid_fetch(&rtdm_protocol_devices, id);
+	if (xnid) {
+		device = container_of(xnid, struct rtdm_device, reserved.id);
 
-			return device;
-		}
-	}
+		rtdm_reference_device(device);
+	} else
+		device = NULL;
 
 	xnlock_put_irqrestore(&rt_dev_lock, s);
 
-	return NULL;
+	return device;
 }
 
 /*!
@@ -193,6 +183,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;
@@ -333,34 +324,24 @@ int rtdm_dev_register(struct rtdm_device *device)
 			   device->device_sub_class, device->profile_version,
 			   device->driver_version);
 
-		hashkey = get_proto_hash(device->protocol_family,
-					 device->socket_type);
+		id = get_proto_id(device->protocol_family,
+				device->socket_type);
 
-		list_for_each(entry, &rtdm_protocol_devices[hashkey]) {
-			existing_dev =
-			    list_entry(entry, struct rtdm_device,
-				       reserved.entry);
-			if ((device->protocol_family ==
-			     existing_dev->protocol_family)
-			    && (device->socket_type ==
-				existing_dev->socket_type)) {
-				printk(XENO_ERR "protocol %u:%u already "
-				       "registered by RTDM device\n",
-				       device->protocol_family,
-				       device->socket_type);
-				ret = -EEXIST;
-				goto err;
-			}
-		}
+		xnlock_get_irqsave(&rt_dev_lock, s);
+		ret = xnid_enter(&rtdm_protocol_devices, 
+				&device->reserved.id, id);
+		xnlock_put_irqrestore(&rt_dev_lock, s);
+		if (ret < 0)
+			goto err;
 
 		ret = rtdm_proc_register_device(device);
-		if (ret)
+		if (ret) {
+			xnlock_get_irqsave(&rt_dev_lock, s);
+			xnid_remove(&rtdm_protocol_devices, 
+				&device->reserved.id);
+			xnlock_put_irqrestore(&rt_dev_lock, s);
 			goto err;
-
-		xnlock_get_irqsave(&rt_dev_lock, s);
-		list_add_tail(&device->reserved.entry,
-			      &rtdm_protocol_devices[hashkey]);
-		xnlock_put_irqrestore(&rt_dev_lock, s);
+		}
 
 		up(&nrt_dev_lock);
 	}
@@ -441,7 +422,10 @@ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay)
 		xnlock_get_irqsave(&rt_dev_lock, s);
 	}
 
-	list_del(&reg_dev->reserved.entry);
+	if ((device->device_flags & RTDM_DEVICE_TYPE_MASK) == RTDM_NAMED_DEVICE)
+		list_del(&reg_dev->reserved.entry);
+	else
+		xnid_remove(&rtdm_protocol_devices, &reg_dev->reserved.id);
 
 	xnlock_put_irqrestore(&rt_dev_lock, s);
 
@@ -470,9 +454,7 @@ int __init rtdm_dev_init(void)
 		return rtdm_apc;
 
 	name_hashkey_mask = devname_hashtab_size - 1;
-	proto_hashkey_mask = protocol_hashtab_size - 1;
-	if (((devname_hashtab_size & name_hashkey_mask) != 0) ||
-	    ((protocol_hashtab_size & proto_hashkey_mask) != 0)) {
+	if (((devname_hashtab_size & name_hashkey_mask) != 0)) {
 		err = -EINVAL;
 		goto err_out1;
 	}
@@ -487,23 +469,11 @@ int __init rtdm_dev_init(void)
 
 	for (i = 0; i < devname_hashtab_size; i++)
 		INIT_LIST_HEAD(&rtdm_named_devices[i]);
-
-	rtdm_protocol_devices = (struct list_head *)
-	    kmalloc(protocol_hashtab_size * sizeof(struct list_head),
-		    GFP_KERNEL);
-	if (!rtdm_protocol_devices) {
-		err = -ENOMEM;
-		goto err_out2;
-	}
-
-	for (i = 0; i < protocol_hashtab_size; i++)
-		INIT_LIST_HEAD(&rtdm_protocol_devices[i]);
+	
+	xntree_init(&rtdm_protocol_devices);
 
 	return 0;
 
-err_out2:
-	kfree(rtdm_named_devices);
-
 err_out1:
 	xnapc_free(rtdm_apc);
 
@@ -518,7 +488,6 @@ void rtdm_dev_cleanup(void)
 	 */
 	xnapc_free(rtdm_apc);
 	kfree(rtdm_named_devices);
-	kfree(rtdm_protocol_devices);
 }
 
 /*@}*/
diff --git a/kernel/cobalt/rtdm/internal.h b/kernel/cobalt/rtdm/internal.h
index b5184c1..0bebe8b 100644
--- a/kernel/cobalt/rtdm/internal.h
+++ b/kernel/cobalt/rtdm/internal.h
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/sem.h>
 #include <cobalt/kernel/ppd.h>
+#include <cobalt/kernel/tree.h>
 #include <rtdm/driver.h>
 
 #define RTDM_FD_MAX			CONFIG_XENO_OPT_RTDM_FILDES
@@ -49,9 +50,8 @@ extern struct rtdm_fildes fildes_table[];
 extern int open_fildes;
 extern struct semaphore nrt_dev_lock;
 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 rb_root rtdm_protocol_devices;
 extern struct xnpersonality rtdm_personality;
 
 extern int rtdm_initialised;
diff --git a/kernel/cobalt/rtdm/proc.c b/kernel/cobalt/rtdm/proc.c
index ccbbf90..218bf8b 100644
--- a/kernel/cobalt/rtdm/proc.c
+++ b/kernel/cobalt/rtdm/proc.c
@@ -142,51 +142,49 @@ static struct xnvfile_regular named_vfile = {
 	.entry = { .lockops = &lockops }
 };
 
+struct vfile_proto_data {
+	struct rtdm_device *curr;
+};
+
+static void *proto_next(struct xnvfile_regular_iterator *it)
+{
+	struct vfile_proto_data *priv = xnvfile_iterator_priv(it);
+
+	return priv->curr = xnid_next_entry(priv->curr, reserved.id);
+}
+
 static void *proto_begin(struct xnvfile_regular_iterator *it)
 {
 
-	struct vfile_device_data *priv = xnvfile_iterator_priv(it);
-	struct list_head *devlist;
+	struct vfile_proto_data *priv = xnvfile_iterator_priv(it);
+	struct rtdm_device *dev = NULL;
 	loff_t pos = 0;
 
-	priv->devmap = rtdm_protocol_devices;
-	priv->hmax = protocol_hashtab_size;
-	priv->h = 0;
+	xntree_for_each_entry(dev, &rtdm_protocol_devices, reserved.id)
+		if (pos++ >= it->pos)
+			break;
+	
+	if (dev == NULL)
+		return NULL;	/* Empty */
 
-	devlist = next_devlist(priv);
-	if (devlist == NULL)
-		return NULL;	/* All devlists empty. */
-
-	priv->curr = devlist->next;	/* Skip head. */
-
-	/*
-	 * 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 = dev;
 
 	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 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;
+	struct rtdm_device *device = data;
 	char pnum[32];
 
-	device = list_entry(curr, struct rtdm_device, reserved.entry);
-
 	snprintf(pnum, sizeof(pnum), "%u:%u",
 		 device->protocol_family, device->socket_type);
 
-	xnvfile_printf(it, "%02X\t%-31s\t%-15s\t%s\n",
-		       priv->h,
+	xnvfile_printf(it, "%-31s\t%-15s\t%s\n",
 		       pnum, device->driver_name,
 		       device->proc_name);
 	return 0;
@@ -194,12 +192,12 @@ static int proto_show(struct xnvfile_regular_iterator *it, void *data)
 
 static struct xnvfile_regular_ops proto_vfile_ops = {
 	.begin = proto_begin,
-	.next = next_dev,
+	.next = proto_next,
 	.show = proto_show,
 };
 
 static struct xnvfile_regular proto_vfile = {
-	.privsz = sizeof(struct vfile_device_data),
+	.privsz = sizeof(struct vfile_proto_data),
 	.ops = &proto_vfile_ops,
 	.entry = { .lockops = &lockops }
 };
@@ -323,11 +321,9 @@ static int devinfo_vfile_show(struct xnvfile_regular_iterator *it, void *data)
 			if (device == xnvfile_priv(it->vfile))
 				goto found;
 
-	for (i = 0; i < protocol_hashtab_size; i++)
-		list_for_each_entry(device, &rtdm_protocol_devices[i],
-				    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))
+			goto found;
 
 	up(&nrt_dev_lock);
 	return -ENODEV;
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 2/9] cobalt/rtdm: base named devices on nucleus registry
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
@ 2014-03-07 20:20   ` Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 3/9] cobalt/rtdm: extract fd API Gilles Chanteperdrix
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

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

diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h
index 75d0c0f..c76df5d 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -445,8 +445,12 @@ rtdm_private_to_context(void *dev_private)
 }
 
 struct rtdm_dev_reserved {
+	unsigned magic;
 	union {
-		struct list_head entry;
+		struct {
+			struct list_head entry;
+			xnhandle_t handle;
+		};
 		struct xnid id;
 	};
 	atomic_t refcount;
@@ -461,6 +465,9 @@ struct rtdm_dev_reserved {
  * not reside in write-protected memory.
  */
 struct rtdm_device {
+	/** Data stored by RTDM inside a registered device (internal use only) */
+	struct rtdm_dev_reserved reserved;
+
 	/** Revision number of this structure, see
 	 *  @ref drv_versioning "Driver Versioning" defines */
 	int struct_version;
@@ -529,9 +536,6 @@ struct rtdm_device {
 	int device_id;
 	/** Driver definable device data */
 	void *device_data;
-
-	/** Data stored by RTDM inside a registered device (internal use only) */
-	struct rtdm_dev_reserved reserved;
 };
 /** @} devregister */
 
diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c
index 38353ee..299c788 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_lookup(handle, NULL);
+	if (device) {
+		if (device->reserved.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->reserved.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))
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 3/9] cobalt/rtdm: extract fd API
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 2/9] cobalt/rtdm: base named devices on nucleus registry Gilles Chanteperdrix
@ 2014-03-07 20:20   ` Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 4/9] drivers/testing: adapt timerbench after RTDM changes Gilles Chanteperdrix
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

for use by POSIX skin.
---
 include/cobalt/kernel/ppd.h         |    3 +-
 include/cobalt/kernel/rtdm/driver.h |  338 ++++----------------
 include/cobalt/kernel/rtdm/fd.h     |  186 +++++++++++
 include/cobalt/kernel/rtdm/rtdm.h   |   48 +--
 include/cobalt/uapi/rtdm/syscall.h  |   17 +-
 kernel/cobalt/Kconfig               |    8 +-
 kernel/cobalt/init.c                |    3 +
 kernel/cobalt/posix/select.c        |   47 +--
 kernel/cobalt/rtdm/Makefile         |    1 +
 kernel/cobalt/rtdm/core.c           |  578 ++++++-----------------------------
 kernel/cobalt/rtdm/device.c         |   48 +--
 kernel/cobalt/rtdm/drvlib.c         |   36 +--
 kernel/cobalt/rtdm/fd.c             |  541 ++++++++++++++++++++++++++++++++
 kernel/cobalt/rtdm/internal.h       |    6 -
 kernel/cobalt/rtdm/proc.c           |   33 +-
 kernel/cobalt/rtdm/syscall.c        |   72 ++---
 kernel/cobalt/shadow.c              |    3 +
 lib/cobalt/init.c                   |    7 +-
 lib/cobalt/rtdm.c                   |  502 ++++++++++++++----------------
 19 files changed, 1212 insertions(+), 1265 deletions(-)
 create mode 100644 include/cobalt/kernel/rtdm/fd.h
 create mode 100644 kernel/cobalt/rtdm/fd.c

diff --git a/include/cobalt/kernel/ppd.h b/include/cobalt/kernel/ppd.h
index 4ddd045..d2cfd46 100644
--- a/include/cobalt/kernel/ppd.h
+++ b/include/cobalt/kernel/ppd.h
@@ -25,10 +25,10 @@
 #include <cobalt/kernel/shadow.h>
 #include <cobalt/kernel/lock.h>
 #include <cobalt/kernel/heap.h>
+#include <rtdm/fd.h>
 
 #define NR_PERSONALITIES  4
 
-/* Called with nklock locked irqs off. */
 void *xnshadow_private_get(unsigned int muxid);
 
 struct xnsys_ppd {
@@ -36,6 +36,7 @@ struct xnsys_ppd {
 	unsigned long mayday_addr;
 	atomic_t refcnt;
 	char *exe_path;
+	struct rb_root fds;
 };
 
 struct xnshadow_process {
diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h
index c76df5d..078ac1a 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -40,6 +40,7 @@
 #include <cobalt/kernel/shadow.h>
 #include <cobalt/kernel/init.h>
 #include <cobalt/kernel/tree.h>
+#include <rtdm/fd.h>
 #include <rtdm/rtdm.h>
 
 /* debug support */
@@ -78,22 +79,6 @@ enum rtdm_selecttype;
 /** @} Device Flags */
 
 /*!
- * @anchor ctx_flags @name Context Flags
- * Dynamic flags describing the state of an open RTDM device (bit numbers)
- * @{
- */
-/** Set by RTDM if the device instance was created in non-real-time
- *  context. */
-#define RTDM_CREATED_IN_NRT		0
-
-/** Set by RTDM when the device is being closed. */
-#define RTDM_CLOSING			1
-
-/** Lowest bit number the driver developer can use freely */
-#define RTDM_USER_CONTEXT_FLAG		8  /* first user-definable flag */
-/** @} Context Flags */
-
-/*!
  * @anchor drv_versioning @name Driver Versioning
  * Current revisions of RTDM structures, encoding of driver versions. See
  * @ref api_versioning "API Versioning" for the interface revision.
@@ -154,9 +139,7 @@ enum rtdm_selecttype {
 /**
  * Named device open handler
  *
- * @param[in] context Context structure associated with opened device instance
- * @param[in] user_info Opaque pointer to information about user mode caller,
- * NULL if kernel mode call
+ * @param[in] context File descriptor structure associated with opened device instance
  * @param[in] oflag Open flags as passed by the user
  *
  * @return 0 on success. On failure return either -ENOSYS, to request that
@@ -165,15 +148,12 @@ enum rtdm_selecttype {
  *
  * @see @c open() in IEEE Std 1003.1,
  * http://www.opengroup.org/onlinepubs/009695399 */
-typedef int (*rtdm_open_handler_t)(struct rtdm_dev_context *context,
-				   rtdm_user_info_t *user_info, int oflag);
+typedef int (*rtdm_open_handler_t)(struct rtdm_fd *context, int oflag);
 
 /**
  * Socket creation handler for protocol devices
  *
- * @param[in] context Context structure associated with opened device instance
- * @param[in] user_info Opaque pointer to information about user mode caller,
- * NULL if kernel mode call
+ * @param[in] context File descriptor structure associated with opened device instance
  * @param[in] protocol Protocol number as passed by the user
  *
  * @return 0 on success. On failure return either -ENOSYS, to request that
@@ -182,203 +162,15 @@ typedef int (*rtdm_open_handler_t)(struct rtdm_dev_context *context,
  *
  * @see @c socket() in IEEE Std 1003.1,
  * http://www.opengroup.org/onlinepubs/009695399 */
-typedef int (*rtdm_socket_handler_t)(struct rtdm_dev_context *context,
-				     rtdm_user_info_t *user_info, int protocol);
-
-/**
- * Close handler
- *
- * @param[in] context Context structure associated with opened device instance
- * @param[in] user_info Opaque pointer to information about user mode caller,
- * NULL if kernel mode or deferred user mode call
- *
- * @return 0 on success. On failure return either -ENOSYS, to request that
- * this handler be called again from the opposite realtime/non-realtime
- * context, -EAGAIN to request a recall after a grace period, or a valid
- * negative error code according to IEEE Std 1003.1.
- *
- * @note Drivers must be prepared for that case that the close handler is
- * invoked more than once per open context (even if the handler already
- * completed an earlier run successfully). The driver has to avoid releasing
- * resources twice as well as returning false errors on successive close
- * invocations.
- *
- * @see @c close() in IEEE Std 1003.1,
- * http://www.opengroup.org/onlinepubs/009695399 */
-typedef int (*rtdm_close_handler_t)(struct rtdm_dev_context *context,
-				    rtdm_user_info_t *user_info);
-
-/**
- * IOCTL handler
- *
- * @param[in] context Context structure associated with opened device instance
- * @param[in] user_info Opaque pointer to information about user mode caller,
- * NULL if kernel mode call
- * @param[in] request Request number as passed by the user
- * @param[in,out] arg Request argument as passed by the user
- *
- * @return A positive value or 0 on success. On failure return either
- * -ENOSYS, to request that the function be called again from the opposite
- * realtime/non-realtime context, or another negative error code.
- *
- * @see @c ioctl() in IEEE Std 1003.1,
- * http://www.opengroup.org/onlinepubs/009695399 */
-typedef int (*rtdm_ioctl_handler_t)(struct rtdm_dev_context *context,
-				    rtdm_user_info_t *user_info,
-				    unsigned int request, void __user *arg);
-
-/**
- * Select binding handler
- *
- * @param[in] context Context structure associated with opened device instance
- * @param[in,out] selector Object that shall be bound to the given event
- * @param[in] type Event type the selector is interested in
- * @param[in] fd_index Opaque value, to be passed to rtdm_event_select_bind or
- * rtdm_sem_select_bind unmodfied
- *
- * @return 0 on success. On failure return either -ENOSYS, to request that
- * this handler be called again from the opposite realtime/non-realtime
- * context, or another negative error code.
- */
-typedef int (*rtdm_select_bind_handler_t)(struct rtdm_dev_context *context,
-					  rtdm_selector_t *selector,
-					  enum rtdm_selecttype type,
-					  unsigned fd_index);
+typedef int (*rtdm_socket_handler_t)(struct rtdm_fd *context, int protocol);
 
-/**
- * Read handler
- *
- * @param[in] context Context structure associated with opened device instance
- * @param[in] user_info Opaque pointer to information about user mode caller,
- * NULL if kernel mode call
- * @param[out] buf Input buffer as passed by the user
- * @param[in] nbyte Number of bytes the user requests to read
- *
- * @return On success, the number of bytes read. On failure return either
- * -ENOSYS, to request that this handler be called again from the opposite
- * realtime/non-realtime context, or another negative error code.
- *
- * @see @c read() in IEEE Std 1003.1,
- * http://www.opengroup.org/onlinepubs/009695399 */
-typedef ssize_t (*rtdm_read_handler_t)(struct rtdm_dev_context *context,
-				       rtdm_user_info_t *user_info,
-				       void *buf, size_t nbyte);
-
-/**
- * Write handler
- *
- * @param[in] context Context structure associated with opened device instance
- * @param[in] user_info Opaque pointer to information about user mode caller,
- * NULL if kernel mode call
- * @param[in] buf Output buffer as passed by the user
- * @param[in] nbyte Number of bytes the user requests to write
- *
- * @return On success, the number of bytes written. On failure return
- * either -ENOSYS, to request that this handler be called again from the
- * opposite realtime/non-realtime context, or another negative error code.
- *
- * @see @c write() in IEEE Std 1003.1,
- * http://www.opengroup.org/onlinepubs/009695399 */
-typedef ssize_t (*rtdm_write_handler_t)(struct rtdm_dev_context *context,
-					rtdm_user_info_t *user_info,
-					const void *buf, size_t nbyte);
-
-/**
- * Receive message handler
- *
- * @param[in] context Context structure associated with opened device instance
- * @param[in] user_info Opaque pointer to information about user mode caller,
- * NULL if kernel mode call
- * @param[in,out] msg Message descriptor as passed by the user, automatically
- * mirrored to safe kernel memory in case of user mode call
- * @param[in] flags Message flags as passed by the user
- *
- * @return On success, the number of bytes received. On failure return
- * either -ENOSYS, to request that this handler be called again from the
- * opposite realtime/non-realtime context, or another negative error code.
- *
- * @see @c recvmsg() in IEEE Std 1003.1,
- * http://www.opengroup.org/onlinepubs/009695399 */
-typedef ssize_t (*rtdm_recvmsg_handler_t)(struct rtdm_dev_context *context,
-					  rtdm_user_info_t *user_info,
-					  struct msghdr *msg, int flags);
-
-/**
- * Transmit message handler
- *
- * @param[in] context Context structure associated with opened device instance
- * @param[in] user_info Opaque pointer to information about user mode caller,
- * NULL if kernel mode call
- * @param[in] msg Message descriptor as passed by the user, automatically
- * mirrored to safe kernel memory in case of user mode call
- * @param[in] flags Message flags as passed by the user
- *
- * @return On success, the number of bytes transmitted. On failure return
- * either -ENOSYS, to request that this handler be called again from the
- * opposite realtime/non-realtime context, or another negative error code.
- *
- * @see @c sendmsg() in IEEE Std 1003.1,
- * http://www.opengroup.org/onlinepubs/009695399 */
-typedef ssize_t (*rtdm_sendmsg_handler_t)(struct rtdm_dev_context *context,
-					  rtdm_user_info_t *user_info,
-					  const struct msghdr *msg, int flags);
 /** @} Operation Handler Prototypes */
 
-typedef int (*rtdm_rt_handler_t)(struct rtdm_dev_context *context,
-				 rtdm_user_info_t *user_info, void *arg);
-/**
- * Device operations
- */
-struct rtdm_operations {
-	/*! @name Common Operations
-	 * @{ */
-	/** Close handler for real-time contexts (optional, deprecated)
-	 *  @deprecated Only use non-real-time close handler in new drivers. */
-	rtdm_close_handler_t close_rt;
-	/** Close handler for non-real-time contexts (required) */
-	rtdm_close_handler_t close_nrt;
-
-	/** IOCTL from real-time context (optional) */
-	rtdm_ioctl_handler_t ioctl_rt;
-	/** IOCTL from non-real-time context (optional) */
-	rtdm_ioctl_handler_t ioctl_nrt;
-
-	/** Select binding handler for any context (optional) */
-	rtdm_select_bind_handler_t select_bind;
-	/** @} Common Operations */
-
-	/*! @name Stream-Oriented Device Operations
-	 * @{ */
-	/** Read handler for real-time context (optional) */
-	rtdm_read_handler_t read_rt;
-	/** Read handler for non-real-time context (optional) */
-	rtdm_read_handler_t read_nrt;
-
-	/** Write handler for real-time context (optional) */
-	rtdm_write_handler_t write_rt;
-	/** Write handler for non-real-time context (optional) */
-	rtdm_write_handler_t write_nrt;
-	/** @} Stream-Oriented Device Operations */
-
-	/*! @name Message-Oriented Device Operations
-	 * @{ */
-	/** Receive message handler for real-time context (optional) */
-	rtdm_recvmsg_handler_t recvmsg_rt;
-	/** Receive message handler for non-real-time context (optional) */
-	rtdm_recvmsg_handler_t recvmsg_nrt;
-
-	/** Transmit message handler for real-time context (optional) */
-	rtdm_sendmsg_handler_t sendmsg_rt;
-	/** Transmit message handler for non-real-time context (optional) */
-	rtdm_sendmsg_handler_t sendmsg_nrt;
-	/** @} Message-Oriented Device Operations */
-};
-
 struct rtdm_process;
 
 struct rtdm_devctx_reserved {
 	struct rtdm_process *owner;
-	struct list_head cleanup;
+	void (*close)(struct rtdm_fd *fd);
 };
 
 /**
@@ -393,19 +185,9 @@ struct rtdm_devctx_reserved {
  * device registration.
  */
 struct rtdm_dev_context {
-	/** Context flags, see @ref ctx_flags "Context Flags" for details */
-	unsigned long context_flags;
-
-	/** Associated file descriptor */
-	int fd;
-
-	/** Lock counter of context, held while structure is referenced by an
-	 *  operation handler */
-	atomic_t close_lock_count;
+	struct rtdm_fd fd;
 
 	/** Set of active device operation handlers */
-	struct rtdm_operations *ops;
-
 	/** Reference to owning device */
 	struct rtdm_device *device;
 
@@ -416,6 +198,11 @@ struct rtdm_dev_context {
 	char dev_private[0];
 };
 
+static inline struct rtdm_dev_context *rtdm_context(struct rtdm_fd *fd)
+{
+	return container_of(fd, struct rtdm_dev_context, fd);
+}
+
 /**
  * Locate the driver private area associated to a device context structure
  *
@@ -425,9 +212,9 @@ struct rtdm_dev_context {
  * context.
  */
 static inline void *
-rtdm_context_to_private(struct rtdm_dev_context *context)
+rtdm_context_to_private(struct rtdm_fd *context)
 {
-	return (void *)context->dev_private;
+	return (void *)rtdm_context(context)->dev_private;
 }
 
 /**
@@ -438,10 +225,22 @@ rtdm_context_to_private(struct rtdm_dev_context *context)
  * @return The address of the device context structure defining @a
  * dev_private.
  */
-static inline struct rtdm_dev_context *
+static inline struct rtdm_fd *
 rtdm_private_to_context(void *dev_private)
 {
-	return container_of(dev_private, struct rtdm_dev_context, dev_private);
+	struct rtdm_dev_context *ctx;
+	ctx = container_of(dev_private, struct rtdm_dev_context, dev_private);
+	return &ctx->fd;
+}
+
+static inline bool rtdm_context_user_p(struct rtdm_fd *context)
+{
+	return rtdm_fd_owner(context) != &__xnsys_global_ppd;
+}
+
+static inline struct rtdm_device *rtdm_context_device(struct rtdm_fd *context)
+{
+	return rtdm_context(context)->device;
 }
 
 struct rtdm_dev_reserved {
@@ -455,6 +254,7 @@ struct rtdm_dev_reserved {
 	};
 	atomic_t refcount;
 	struct rtdm_dev_context *exclusive_context;
+	void (*close)(struct rtdm_fd *);
 };
 
 /**
@@ -489,23 +289,17 @@ struct rtdm_device {
 	 *  optional (but deprecated) if open_nrt is non-NULL, ignored for
 	 *  protocol devices
 	 *  @deprecated Only use non-real-time open handler in new drivers. */
-	rtdm_open_handler_t open_rt;
-	/** Named device instance creation for non-real-time contexts,
-	 *  optional if open_rt is non-NULL, ignored for protocol devices */
-	rtdm_open_handler_t open_nrt;
+	rtdm_open_handler_t open;
 
 	/** Protocol socket creation for real-time contexts,
 	 *  optional (but deprecated) if socket_nrt is non-NULL, ignored for
 	 *  named devices
 	 *  @deprecated Only use non-real-time socket creation handler in new
 	 *  drivers. */
-	rtdm_socket_handler_t socket_rt;
-	/** Protocol socket creation for non-real-time contexts,
-	 *  optional if socket_rt is non-NULL, ignored for named devices */
-	rtdm_socket_handler_t socket_nrt;
+	rtdm_socket_handler_t socket;
 
 	/** Default operations on newly opened device instance */
-	struct rtdm_operations ops;
+	struct rtdm_fd_ops ops;
 
 	/** Device class ID, see @ref RTDM_CLASS_xxx */
 	int device_class;
@@ -567,36 +361,16 @@ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay);
 #define rtdm_getpeername	rt_dev_getpeername
 #define rtdm_shutdown		rt_dev_shutdown
 
-struct rtdm_dev_context *rtdm_context_get(int fd);
-
 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
 
-#define CONTEXT_IS_LOCKED(context) \
-	(atomic_read(&(context)->close_lock_count) > 1 || \
-	 (test_bit(RTDM_CLOSING, &(context)->context_flags) && \
-	  atomic_read(&(context)->close_lock_count) > 0))
-
-static inline void rtdm_context_lock(struct rtdm_dev_context *context)
-{
-	/* just warn if context was a dangling pointer */
-	XENO_ASSERT(RTDM, CONTEXT_IS_LOCKED(context));
-	atomic_inc(&context->close_lock_count);
-}
-
-extern int rtdm_apc;
-
-static inline void rtdm_context_unlock(struct rtdm_dev_context *context)
+static inline int rtdm_context_lock(struct rtdm_fd *context)
 {
-	/* just warn if context was a dangling pointer */
-	XENO_ASSERT(RTDM, CONTEXT_IS_LOCKED(context));
-	smp_mb__before_atomic_dec();
-	if (unlikely(atomic_dec_and_test(&context->close_lock_count)))
-		xnapc_schedule(rtdm_apc);
+	return rtdm_fd_lock(context);
 }
 
-static inline void rtdm_context_put(struct rtdm_dev_context *context)
+static inline void rtdm_context_unlock(struct rtdm_fd *context)
 {
-	rtdm_context_unlock(context);
+	rtdm_fd_unlock(context);
 }
 
 /* --- clock services --- */
@@ -611,14 +385,6 @@ static inline nanosecs_abs_t rtdm_clock_read_monotonic(void)
 }
 #endif /* !DOXYGEN_CPP */
 
-/*!
- * @addtogroup rtdmsync
- * @{
- */
-
-int rtdm_select_bind(int fd, rtdm_selector_t *selector,
-		     enum rtdm_selecttype type, unsigned fd_index);
-
 /* --- spin lock services --- */
 /*!
  * @name Global Lock across Scheduler Invocation
@@ -1309,38 +1075,38 @@ static inline void rtdm_free(void *ptr)
 	xnfree(ptr);
 }
 
-int rtdm_mmap_to_user(rtdm_user_info_t *user_info,
+int rtdm_mmap_to_user(struct rtdm_fd *context,
 		      void *src_addr, size_t len,
 		      int prot, void **pptr,
 		      struct vm_operations_struct *vm_ops,
 		      void *vm_private_data);
-int rtdm_iomap_to_user(rtdm_user_info_t *user_info,
+int rtdm_iomap_to_user(struct rtdm_fd *context,
 		       phys_addr_t src_addr, size_t len,
 		       int prot, void **pptr,
 		       struct vm_operations_struct *vm_ops,
 		       void *vm_private_data);
-int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len);
+int rtdm_munmap(struct rtdm_fd *context, void *ptr, size_t len);
 
-static inline int rtdm_read_user_ok(rtdm_user_info_t *user_info,
+static inline int rtdm_read_user_ok(struct rtdm_fd *context,
 				    const void __user *ptr, size_t size)
 {
 	return access_rok(ptr, size);
 }
 
-static inline int rtdm_rw_user_ok(rtdm_user_info_t *user_info,
+static inline int rtdm_rw_user_ok(struct rtdm_fd *context,
 				  const void __user *ptr, size_t size)
 {
 	return access_wok(ptr, size);
 }
 
-static inline int rtdm_copy_from_user(rtdm_user_info_t *user_info,
+static inline int rtdm_copy_from_user(struct rtdm_fd *context,
 				      void *dst, const void __user *src,
 				      size_t size)
 {
 	return __xn_copy_from_user(dst, src, size) ? -EFAULT : 0;
 }
 
-static inline int rtdm_safe_copy_from_user(rtdm_user_info_t *user_info,
+static inline int rtdm_safe_copy_from_user(struct rtdm_fd *context,
 					   void *dst, const void __user *src,
 					   size_t size)
 {
@@ -1348,14 +1114,14 @@ static inline int rtdm_safe_copy_from_user(rtdm_user_info_t *user_info,
 		__xn_copy_from_user(dst, src, size)) ? -EFAULT : 0;
 }
 
-static inline int rtdm_copy_to_user(rtdm_user_info_t *user_info,
+static inline int rtdm_copy_to_user(struct rtdm_fd *context,
 				    void __user *dst, const void *src,
 				    size_t size)
 {
 	return __xn_copy_to_user(dst, src, size) ? -EFAULT : 0;
 }
 
-static inline int rtdm_safe_copy_to_user(rtdm_user_info_t *user_info,
+static inline int rtdm_safe_copy_to_user(struct rtdm_fd *context,
 					 void __user *dst, const void *src,
 					 size_t size)
 {
@@ -1363,7 +1129,7 @@ static inline int rtdm_safe_copy_to_user(rtdm_user_info_t *user_info,
 		__xn_copy_to_user(dst, src, size)) ? -EFAULT : 0;
 }
 
-static inline int rtdm_strncpy_from_user(rtdm_user_info_t *user_info,
+static inline int rtdm_strncpy_from_user(struct rtdm_fd *context,
 					 char *dst,
 					 const char __user *src, size_t count)
 {
@@ -1372,13 +1138,15 @@ static inline int rtdm_strncpy_from_user(rtdm_user_info_t *user_info,
 	return __xn_strncpy_from_user(dst, src, count);
 }
 
-static inline int rtdm_rt_capable(rtdm_user_info_t *user_info)
+static inline int rtdm_rt_capable(struct rtdm_fd *context)
 {
 	if (!XENO_ASSERT(RTDM, !xnsched_interrupt_p()))
 		return 0;
 
-	return (user_info ? xnshadow_thread(user_info) != NULL
-			  : !xnsched_root_p());
+	if (rtdm_fd_owner(context) == &__xnsys_global_ppd)
+		return !xnsched_root_p();
+
+	return xnshadow_thread(current) != NULL;
 }
 
 static inline int rtdm_in_rt_context(void)
@@ -1388,8 +1156,4 @@ static inline int rtdm_in_rt_context(void)
 
 #endif /* !DOXYGEN_CPP */
 
-int rtdm_exec_in_rt(struct rtdm_dev_context *context,
-		    rtdm_user_info_t *user_info, void *arg,
-		    rtdm_rt_handler_t handler);
-
 #endif /* _COBALT_RTDM_DRIVER_H */
diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
new file mode 100644
index 0000000..889c27a
--- /dev/null
+++ b/include/cobalt/kernel/rtdm/fd.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2005-2007 Jan Kiszka <jan.kiszka@web.de>
+ * Copyright (C) 2005 Joerg Langenberg <joerg.langenberg@gmx.net>
+ * Copyright (C) 2008,2013,2014 Gilles Chanteperdrix <gch@xenomai.org>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _COBALT_KERNEL_FD_H
+#define _COBALT_KERNEL_FD_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <cobalt/kernel/tree.h>
+
+struct rtdm_fd;
+struct xnselector;
+struct xnsys_ppd;
+
+/**
+ * IOCTL handler
+ *
+ * @param[in] fd File descriptor structure associated with opened device instance
+ * @param[in] request Request number as passed by the user
+ * @param[in,out] arg Request argument as passed by the user
+ *
+ * @return A positive value or 0 on success. On failure return either
+ * -ENOSYS, to request that the function be called again from the opposite
+ * realtime/non-realtime context, or another negative error code.
+ *
+ * @see @c ioctl() in IEEE Std 1003.1,
+ * http://www.opengroup.org/onlinepubs/009695399 
+ */
+typedef int rtdm_fd_ioctl_t(struct rtdm_fd *fd, unsigned int request, void __user *arg);
+
+/**
+ * Read handler
+ *
+ * @param[in] fd File descriptor structure associated with opened device instance
+ * @param[out] buf Input buffer as passed by the user
+ * @param[in] size Number of bytes the user requests to read
+ *
+ * @return On success, the number of bytes read. On failure return either
+ * -ENOSYS, to request that this handler be called again from the opposite
+ * realtime/non-realtime context, or another negative error code.
+ *
+ * @see @c read() in IEEE Std 1003.1,
+ * http://www.opengroup.org/onlinepubs/009695399 
+ */
+typedef ssize_t rtdm_fd_read_t(struct rtdm_fd *fd, void __user *buf, size_t size);
+
+/**
+ * Write handler
+ *
+ * @param[in] fd File descriptor structure associated with opened device instance
+ * @param[in] buf Output buffer as passed by the user
+ * @param[in] size Number of bytes the user requests to write
+ *
+ * @return On success, the number of bytes written. On failure return
+ * either -ENOSYS, to request that this handler be called again from the
+ * opposite realtime/non-realtime context, or another negative error code.
+ *
+ * @see @c write() in IEEE Std 1003.1,
+ * http://www.opengroup.org/onlinepubs/009695399 
+ */
+typedef ssize_t rtdm_fd_write_t(struct rtdm_fd *fd, const void __user *buf, size_t size);
+
+/**
+ * Receive message handler
+ *
+ * @param[in] fd File descriptor structure associated with opened device instance
+ * @param[in,out] msg Message descriptor as passed by the user, automatically
+ * mirrored to safe kernel memory in case of user mode call
+ * @param[in] flags Message flags as passed by the user
+ *
+ * @return On success, the number of bytes received. On failure return
+ * either -ENOSYS, to request that this handler be called again from the
+ * opposite realtime/non-realtime context, or another negative error code.
+ *
+ * @see @c recvmsg() in IEEE Std 1003.1,
+ * http://www.opengroup.org/onlinepubs/009695399 
+ */
+typedef ssize_t rtdm_fd_recvmsg_t(struct rtdm_fd *fd, struct msghdr *msg, int flags);
+
+/**
+ * Transmit message handler
+ *
+ * @param[in] fd File descriptor structure associated with opened device instance
+ * @param[in] user_info Opaque pointer to information about user mode caller,
+ * NULL if kernel mode call
+ * @param[in] msg Message descriptor as passed by the user, automatically
+ * mirrored to safe kernel memory in case of user mode call
+ * @param[in] flags Message flags as passed by the user
+ *
+ * @return On success, the number of bytes transmitted. On failure return
+ * either -ENOSYS, to request that this handler be called again from the
+ * opposite realtime/non-realtime context, or another negative error code.
+ *
+ * @see @c sendmsg() in IEEE Std 1003.1,
+ * http://www.opengroup.org/onlinepubs/009695399 
+ */
+typedef ssize_t rtdm_fd_sendmsg_t(struct rtdm_fd *fd, const struct msghdr *msg, int flags);
+
+struct rtdm_fd_ops {
+	rtdm_fd_ioctl_t *ioctl_rt;
+	rtdm_fd_ioctl_t *ioctl_nrt;
+	rtdm_fd_read_t *read_rt;
+	rtdm_fd_read_t *read_nrt;
+	rtdm_fd_write_t *write_rt;
+	rtdm_fd_write_t *write_nrt;
+	rtdm_fd_recvmsg_t *recvmsg_rt;
+	rtdm_fd_recvmsg_t *recvmsg_nrt;
+	rtdm_fd_sendmsg_t *sendmsg_rt;
+	rtdm_fd_sendmsg_t *sendmsg_nrt;
+	int (*select_bind)(struct rtdm_fd *fd, struct xnselector *selector,
+			unsigned type, unsigned index);
+	void (*close)(struct rtdm_fd *fd);
+};
+
+struct rtdm_fd {
+	unsigned magic;
+	struct rtdm_fd_ops *ops;
+	struct xnsys_ppd *cont;
+	unsigned refs;
+	struct list_head cleanup;
+};
+
+struct rtdm_fd_index {
+	struct xnid id;
+	struct rtdm_fd *fd;
+};	
+
+#define XNFD_MAGIC_ANY 0
+
+static inline struct xnsys_ppd *rtdm_fd_owner(struct rtdm_fd *fd)
+{
+	return fd->cont;
+}
+
+int rtdm_fd_enter(struct xnsys_ppd *p, struct rtdm_fd *rtdm_fd, int ufd, 
+	unsigned magic, struct rtdm_fd_ops *ops);
+
+struct rtdm_fd *rtdm_fd_get(struct xnsys_ppd *p, int ufd, unsigned magic);
+
+int rtdm_fd_lock(struct rtdm_fd *fd);
+
+void rtdm_fd_put(struct rtdm_fd *fd);
+
+void rtdm_fd_unlock(struct rtdm_fd *fd);
+
+int rtdm_fd_ioctl(struct xnsys_ppd *p, int fd, unsigned request, ...);
+
+ssize_t rtdm_fd_read(struct xnsys_ppd *p, int fd, void __user *buf, size_t size);
+
+ssize_t 
+rtdm_fd_write(struct xnsys_ppd *p, int fd, const void __user *buf, size_t size);
+
+int rtdm_fd_close(struct xnsys_ppd *p, int fd, unsigned magic);
+
+ssize_t 
+rtdm_fd_recvmsg(struct xnsys_ppd *p, int fd, struct msghdr *msg, int flags);
+
+ssize_t 
+rtdm_fd_sendmsg(struct xnsys_ppd *p, int fd, const struct msghdr *msg, int flags);
+
+int rtdm_fd_valid_p(int ufd);
+
+int rtdm_fd_select_bind(int ufd, struct xnselector *selector, unsigned type);
+
+void rtdm_fd_cleanup(struct xnsys_ppd *p);
+
+void rtdm_fd_init(void);
+
+#endif /* _COBALT_KERNEL_FD_H */
diff --git a/include/cobalt/kernel/rtdm/rtdm.h b/include/cobalt/kernel/rtdm/rtdm.h
index f90ecf0..51de97b 100644
--- a/include/cobalt/kernel/rtdm/rtdm.h
+++ b/include/cobalt/kernel/rtdm/rtdm.h
@@ -25,36 +25,20 @@
 #include <linux/ioctl.h>
 #include <linux/sched.h>
 #include <linux/socket.h>
+#include <cobalt/kernel/ppd.h>
+
+#define RTDM_FD_MAGIC 0x52544446
 
 typedef u32 socklen_t;
 typedef struct task_struct rtdm_user_info_t;
 
-int __rt_dev_open(rtdm_user_info_t *user_info,
-		  const char *path, int oflag);
-
-int __rt_dev_socket(rtdm_user_info_t *user_info,
-		    int protocol_family,
-		    int socket_type, int protocol);
-
-int __rt_dev_close(rtdm_user_info_t *user_info,
-		   int fd);
-
-int __rt_dev_ioctl(rtdm_user_info_t *user_info,
-		   int fd, int request, ...);
-
-ssize_t __rt_dev_read(rtdm_user_info_t *user_info,
-		      int fd, void *buf,
-		      size_t nbyte);
-
-ssize_t __rt_dev_write(rtdm_user_info_t *user_info,
-		       int fd, const void *buf,
-		       size_t nbyte);
+int __rt_dev_open(struct xnsys_ppd *p, int ufd, const char *path, int oflag);
 
-ssize_t __rt_dev_recvmsg(rtdm_user_info_t *user_info,
-			 int fd, struct msghdr *msg, int flags);
+int __rt_dev_socket(struct xnsys_ppd *p, int ufd, 
+		int protocol_family, int socket_type, int protocol);
 
-ssize_t __rt_dev_sendmsg(rtdm_user_info_t *user_info,
-			 int fd, const struct msghdr *msg, int flags);
+int 
+__rt_dev_ioctl_fallback(struct rtdm_fd *fd, unsigned request, void __user *arg);
 
 /*
  * Define RTDM_NO_DEFAULT_USER_API to switch off the default
@@ -63,28 +47,28 @@ ssize_t __rt_dev_sendmsg(rtdm_user_info_t *user_info,
 #ifndef RTDM_NO_DEFAULT_USER_API
 
 #define rt_dev_open(path, oflag, ...)				\
-	__rt_dev_open(NULL, path, oflag)
+	__rt_dev_open(&__xnsys_global_ppd, -1, path, oflag)
 
 #define rt_dev_socket(protocol_family, socket_type, protocol)	\
-	__rt_dev_socket(NULL, protocol_family, socket_type, protocol)
+	__rt_dev_socket(&__xnsys_global_ppd, -1, protocol_family, socket_type, protocol)
 
 #define rt_dev_close(fd)					\
-	__rt_dev_close(NULL, fd)
+	rtdm_fd_close(&__xnsys_global_ppd, fd, RTDM_FD_MAGIC)
 
 #define rt_dev_ioctl(fd, request, ...)				\
-	__rt_dev_ioctl(NULL, fd, request, __VA_ARGS__)
+	rtdm_fd_ioctl(&__xnsys_global_ppd, fd, request, __VA_ARGS__)
 
 #define rt_dev_read(fd, buf, nbyte)				\
-	__rt_dev_read(NULL, fd, buf, nbyte)
+	rtdm_fd_read(&__xnsys_global_ppd, fd, buf, nbyte)
 
 #define rt_dev_write(fd, buf, nbyte)				\
-	__rt_dev_write(NULL, fd, buf, nbyte)
+	rtdm_fd_write(&__xnsys_global_ppd, fd, buf, nbyte)
 
 #define rt_dev_recvmsg(fd, msg, flags)				\
-	__rt_dev_recvmsg(NULL, fd, msg, flags)
+	rtdm_fd_recvmsg(&__xnsys_global_ppd, fd, msg, flags)
 
 #define rt_dev_sendmsg(fd, msg, flags)				\
-	__rt_dev_sendmsg(NULL, fd, msg, flags)
+	rtdm_fd_sendmsg(&__xnsys_global_ppd, fd, msg, flags)
 
 static inline
 ssize_t rt_dev_recvfrom(int fd, void *buf, size_t len, int flags,
diff --git a/include/cobalt/uapi/rtdm/syscall.h b/include/cobalt/uapi/rtdm/syscall.h
index d6e161b..bfcdfb4 100644
--- a/include/cobalt/uapi/rtdm/syscall.h
+++ b/include/cobalt/uapi/rtdm/syscall.h
@@ -21,14 +21,13 @@
 
 #define RTDM_BINDING_MAGIC	0x5254444D
 
-#define sc_rtdm_fdcount		0
-#define sc_rtdm_open		1
-#define sc_rtdm_socket		2
-#define sc_rtdm_close		3
-#define sc_rtdm_ioctl		4
-#define sc_rtdm_read		5
-#define sc_rtdm_write		6
-#define sc_rtdm_recvmsg		7
-#define sc_rtdm_sendmsg		8
+#define sc_rtdm_open		0
+#define sc_rtdm_socket		1
+#define sc_rtdm_close		2
+#define sc_rtdm_ioctl		3
+#define sc_rtdm_read		4
+#define sc_rtdm_write		5
+#define sc_rtdm_recvmsg         6
+#define sc_rtdm_sendmsg         7
 
 #endif /* !_COBALT_UAPI_RTDM_SYSCALL_H */
diff --git a/kernel/cobalt/Kconfig b/kernel/cobalt/Kconfig
index 5436de6..ba4ffab 100644
--- a/kernel/cobalt/Kconfig
+++ b/kernel/cobalt/Kconfig
@@ -349,11 +349,9 @@ config XENO_OPT_RTDM_FILDES
 	default 128
 	help
 
-	This option defines the maximum number of RTDM file
-	descriptors which can be opened at the same time. RTDM file
-	descriptors are a global resource all applications share,
-	either via RTDM directly or via the embedded services of the
-	Cobalt API.
+	This option defines the maximum number of kernel-space RTDM
+	file descriptors which can be opened at the same time. RTDM
+	kernel-space file descriptors are a global resource.
 
 endmenu
 
diff --git a/kernel/cobalt/init.c b/kernel/cobalt/init.c
index 92de41d..af05ef1 100644
--- a/kernel/cobalt/init.c
+++ b/kernel/cobalt/init.c
@@ -33,6 +33,7 @@
 #include <cobalt/kernel/pipe.h>
 #include <cobalt/kernel/select.h>
 #include <cobalt/kernel/vdso.h>
+#include <rtdm/fd.h>
 #include "rtdm/internal.h"
 #include "posix/internal.h"
 #include "procfs.h"
@@ -420,6 +421,8 @@ static int __init xenomai_init(void)
 	if (ret)
 		goto cleanup_rtdm;
 
+	rtdm_fd_init();
+
 	printk(XENO_INFO "Cobalt v%s enabled%s\n",
 	       XENO_VERSION_STRING, boot_notice);
 
diff --git a/kernel/cobalt/posix/select.c b/kernel/cobalt/posix/select.c
index 6741331..e11b251 100644
--- a/kernel/cobalt/posix/select.c
+++ b/kernel/cobalt/posix/select.c
@@ -21,35 +21,14 @@
  */
 #include <linux/types.h>
 #include <linux/err.h>
+#include <cobalt/kernel/select.h>
 #include <rtdm/driver.h>
+#include <rtdm/fd.h>
 #include "internal.h"
 #include "clock.h"
 #include "mqueue.h"
 #include "select.h"
 
-#define RTDM_FD_MAX CONFIG_XENO_OPT_RTDM_FILDES
-
-static int fd_valid_p(int fd)
-{
-	const int rtdm_fd_start = __FD_SETSIZE - RTDM_FD_MAX;
-	struct rtdm_dev_context *ctx;
-	struct cobalt_process *cc;
-
-	if (fd >= rtdm_fd_start) {
-		ctx = rtdm_context_get(fd - rtdm_fd_start);
-		if (ctx == NULL)
-			return 0;
-		rtdm_context_unlock(ctx);
-		return 1;
-	}
-
-	cc = cobalt_process_context();
-	if (cc == NULL)
-		return 0;
-
-	return cobalt_assoc_lookup(&cc->uqds, fd) != NULL;
-}
-
 static int first_fd_valid_p(fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
 {
 	int i, fd;
@@ -57,7 +36,7 @@ static int first_fd_valid_p(fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
 	for (i = 0; i < XNSELECT_MAX_TYPES; i++)
 		if (fds[i]
 		    && (fd = find_first_bit(fds[i]->fds_bits, nfds)) < nfds)
-			return fd_valid_p(fd);
+			return rtdm_fd_valid_p(fd);
 
 	/* All empty is correct, used as a "sleep" mechanism by strange
 	   applications. */
@@ -66,23 +45,13 @@ static int first_fd_valid_p(fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
 
 static int select_bind_one(struct xnselector *selector, unsigned type, int fd)
 {
-	const int rtdm_fd_start = __FD_SETSIZE - RTDM_FD_MAX;
-	struct cobalt_process *cc;
-	cobalt_assoc_t *assoc;
-
-	if (fd >= rtdm_fd_start)
-		return rtdm_select_bind(fd - rtdm_fd_start,
-					selector, type, fd);
-
-	cc = cobalt_process_context();
-	if (cc == NULL)
-		return -EPERM;
+	int rc;
 
-	assoc = cobalt_assoc_lookup(&cc->uqds, fd);
-	if (assoc == NULL)
-		return -EBADF;
+	rc = rtdm_fd_select_bind(fd, selector, type);
+	if (rc != -ENOENT)
+		return rc;
 
-	return cobalt_mq_select_bind(assoc2ufd(assoc)->kfd, selector, type, fd);
+	return -EBADF;
 }
 
 static int select_bind_all(struct xnselector *selector,
diff --git a/kernel/cobalt/rtdm/Makefile b/kernel/cobalt/rtdm/Makefile
index 0339ef1..51e7011 100644
--- a/kernel/cobalt/rtdm/Makefile
+++ b/kernel/cobalt/rtdm/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_XENOMAI) += rtdm.o
 rtdm-y :=	core.o		\
 		device.o	\
 		drvlib.o	\
+		fd.o		\
 		init.o		\
 		syscall.o
 
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index b4f2a81..a673fca 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -37,96 +37,73 @@
 #define CLOSURE_RETRY_PERIOD_MS	100
 
 #define FD_BITMAP_SIZE  ((RTDM_FD_MAX + BITS_PER_LONG-1) / BITS_PER_LONG)
-
-struct rtdm_fildes fildes_table[RTDM_FD_MAX] =
-	{ [0 ... RTDM_FD_MAX-1] = { NULL } };
 static unsigned long used_fildes[FD_BITMAP_SIZE];
-int open_fildes;	/* number of used descriptors */
-
-static void close_callback(struct work_struct *work);
-static DECLARE_DELAYED_WORK(close_work, close_callback);
-static LIST_HEAD(cleanup_queue);
+int open_fildes;       /* number of used descriptors */
 
 DEFINE_XNLOCK(rt_fildes_lock);
 
-/**
- * @brief Retrieve and lock a device context
- *
- * @param[in] fd File descriptor
- *
- * @return Pointer to associated device context, or NULL on error
- *
- * @note The device context has to be unlocked using rtdm_context_put() when
- * it is no longer referenced.
- *
- * Environments:
- *
- * This service can be called from:
- *
- * - Kernel module initialization/cleanup code
- * - Interrupt service routine
- * - Kernel-based task
- * - User-space task (RT, non-RT)
- *
- * Rescheduling: never.
- */
-struct rtdm_dev_context *rtdm_context_get(int fd)
+static void cleanup_instance(struct rtdm_device *device,
+			     struct rtdm_dev_context *context)
 {
-	struct rtdm_dev_context *context;
-	spl_t s;
-
-	if ((unsigned int)fd >= RTDM_FD_MAX)
-		return NULL;
-
-	xnlock_get_irqsave(&rt_fildes_lock, s);
-
-	context = fildes_table[fd].context;
-	if (unlikely(!context)) {
-		xnlock_put_irqrestore(&rt_fildes_lock, s);
-		return NULL;
+	if (context) {
+		if (device->reserved.exclusive_context)
+			context->device = NULL;
+		else
+			kfree(context);
 	}
 
-	atomic_inc(&context->close_lock_count);
-
-	xnlock_put_irqrestore(&rt_fildes_lock, s);
+	rtdm_dereference_device(device);
+}
 
-	return context;
+void __rt_dev_close(struct rtdm_fd *fd)
+{
+	struct rtdm_dev_context *context = rtdm_context(fd);
+	context->reserved.close(fd);
+	cleanup_instance(context->device, context);
 }
 
-EXPORT_SYMBOL_GPL(rtdm_context_get);
+void __rt_dev_unref(struct rtdm_fd *fd, unsigned idx)
+{
+	if (fd->magic != RTDM_FD_MAGIC)
+		return;
+
+	xnlock_get(&rt_fildes_lock);
+	if (rtdm_fd_owner(fd) == &__xnsys_global_ppd) {
+		clear_bit(idx, used_fildes);
+		--open_fildes;
+	}
+	xnlock_put(&rt_fildes_lock);
+}
 
-static int create_instance(struct rtdm_device *device,
-			   struct rtdm_dev_context **context_ptr,
-			   struct rtdm_fildes **fildes_ptr,
-			   rtdm_user_info_t *user_info, int nrt_mem)
+static int create_instance(struct xnsys_ppd *p, int fd, 
+			struct rtdm_device *device,
+			struct rtdm_dev_context **context_ptr)
 {
 	struct rtdm_dev_context *context;
 	spl_t s;
-	int fd;
+	int err;
 
 	/*
 	 * Reset to NULL so that we can always use cleanup_files/instance to
 	 * revert also partially successful allocations.
 	 */
 	*context_ptr = NULL;
-	*fildes_ptr = NULL;
 
-	/* Reserve a file descriptor */
-	xnlock_get_irqsave(&rt_fildes_lock, s);
+	if (p == &__xnsys_global_ppd) {
+		xnlock_get_irqsave(&rt_fildes_lock, s);
+
+		if (unlikely(open_fildes >= RTDM_FD_MAX)) {
+			xnlock_put_irqrestore(&rt_fildes_lock, s);
+			return -ENFILE;
+		}
 
-	if (unlikely(open_fildes >= RTDM_FD_MAX)) {
+		fd = find_first_zero_bit(used_fildes, RTDM_FD_MAX);
+		__set_bit(fd, used_fildes);
+		open_fildes++;
+		
 		xnlock_put_irqrestore(&rt_fildes_lock, s);
-		return -ENFILE;
 	}
 
-	fd = find_first_zero_bit(used_fildes, RTDM_FD_MAX);
-	__set_bit(fd, used_fildes);
-	open_fildes++;
-
-	xnlock_put_irqrestore(&rt_fildes_lock, s);
-
-	*fildes_ptr = &fildes_table[fd];
-
 	context = device->reserved.exclusive_context;
 	if (context) {
 		xnlock_get_irqsave(&rt_dev_lock, s);
@@ -135,151 +112,53 @@ static int create_instance(struct rtdm_device *device,
 			xnlock_put_irqrestore(&rt_dev_lock, s);
 			return -EBUSY;
 		}
+
 		context->device = device;
 
 		xnlock_put_irqrestore(&rt_dev_lock, s);
 	} else {
-		if (nrt_mem)
-			context = kmalloc(sizeof(struct rtdm_dev_context) +
-					  device->context_size, GFP_KERNEL);
-		else
-			context = xnmalloc(sizeof(struct rtdm_dev_context) +
-					   device->context_size);
-		if (unlikely(!context))
+		context = kmalloc(sizeof(struct rtdm_dev_context) + 
+				device->context_size, GFP_KERNEL);
+		if (unlikely(context == NULL))
 			return -ENOMEM;
 
 		context->device = device;
 	}
 
-	*context_ptr = context;
-
-	context->fd = fd;
-	context->ops = &device->ops;
-	atomic_set(&context->close_lock_count, 1);
-
-	context->reserved.owner = xnshadow_private_get(__rtdm_muxid);
-	INIT_LIST_HEAD(&context->reserved.cleanup);
-
-	return 0;
-}
-
-static void __cleanup_fildes(struct rtdm_fildes *fildes)
-{
-	__clear_bit((fildes - fildes_table), used_fildes);
-	fildes->context = NULL;
-	open_fildes--;
-}
-
-static void cleanup_fildes(struct rtdm_fildes *fildes)
-{
-	spl_t s;
-
-	if (!fildes)
-		return;
-
-	xnlock_get_irqsave(&rt_fildes_lock, s);
-	__cleanup_fildes(fildes);
-	xnlock_put_irqrestore(&rt_fildes_lock, s);
-}
-
-static void cleanup_instance(struct rtdm_device *device,
-			     struct rtdm_dev_context *context,
-			     int nrt_mem)
-{
-	if (context) {
-		if (device->reserved.exclusive_context)
-			context->device = NULL;
-		else {
-			if (nrt_mem)
-				kfree(context);
-			else
-				xnfree(context);
-		}
-	}
-
-	rtdm_dereference_device(device);
-}
-
-static void close_callback(struct work_struct *work)
-{
-	struct rtdm_dev_context *context;
-	LIST_HEAD(deferred_list);
-	int reschedule = 0;
-	int err;
-	spl_t s;
-
-	xnlock_get_irqsave(&rt_fildes_lock, s);
-
-	while (!list_empty(&cleanup_queue)) {
-		context = list_first_entry(&cleanup_queue,
-					   struct rtdm_dev_context,
-					   reserved.cleanup);
-		list_del(&context->reserved.cleanup);
-		atomic_inc(&context->close_lock_count);
-
-		xnlock_put_irqrestore(&rt_fildes_lock, s);
-
-		err = context->ops->close_nrt(context, NULL);
-
-		if (err == -EAGAIN ||
-		    atomic_read(&context->close_lock_count) > 1) {
-			atomic_dec(&context->close_lock_count);
-			list_add_tail(&context->reserved.cleanup,
-				      &deferred_list);
-			if (err == -EAGAIN)
-				reschedule = 1;
-		} else {
-			trace_mark(xn_rtdm, fd_closed, "fd %d", context->fd);
-
-			cleanup_instance(context->device, context,
-					 test_bit(RTDM_CREATED_IN_NRT,
-						  &context->context_flags));
-		}
-
-		xnlock_get_irqsave(&rt_fildes_lock, s);
-	}
-
-	list_splice(&deferred_list, &cleanup_queue);
+	context->reserved.close = device->reserved.close;
+	if (p == &__xnsys_global_ppd)
+		context->reserved.owner = NULL;
+	else
+		context->reserved.owner = xnshadow_private_get(__rtdm_muxid);
 
-	xnlock_put_irqrestore(&rt_fildes_lock, s);
+	err = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
+	if (err < 0)
+		return err;
 
-	if (reschedule)
-		schedule_delayed_work(&close_work,
-				      (HZ * CLOSURE_RETRY_PERIOD_MS) / 1000);
-}
+	*context_ptr = context;
 
-void rtdm_apc_handler(void *cookie)
-{
-	schedule_delayed_work(&close_work, 0);
+	return fd;
 }
 
-
-int __rt_dev_open(rtdm_user_info_t *user_info, const char *path, int oflag)
+int __rt_dev_open(struct xnsys_ppd *p, int ufd, const char *path, int oflag)
 {
 	struct rtdm_device *device;
-	struct rtdm_fildes *fildes;
 	struct rtdm_dev_context *context;
 	int ret;
-	int nrt_mode = !rtdm_in_rt_context();
 
 	device = get_named_device(path);
-	trace_mark(xn_rtdm, open, "user_info %p path %s oflag %d device %p",
-		   user_info, path, oflag, device);
+	trace_mark(xn_rtdm, open, "sys_ppd %p path %s oflag %d device %p",
+		   p, path, oflag, device);
 	ret = -ENODEV;
 	if (!device)
 		goto err_out;
 
-	ret = create_instance(device, &context, &fildes, user_info, nrt_mode);
-	if (ret != 0)
+	ret = create_instance(p, ufd, device, &context);
+	if (ret < 0)
 		goto cleanup_out;
+	ufd = ret;
 
-	if (nrt_mode) {
-		context->context_flags = (1 << RTDM_CREATED_IN_NRT);
-		ret = device->open_nrt(context, user_info, oflag);
-	} else {
-		context->context_flags = 0;
-		ret = device->open_rt(context, user_info, oflag);
-	}
+	ret = device->open(&context->fd, oflag);
 
 	if (!XENO_ASSERT(RTDM, !spltest()))
 		splnone();
@@ -287,51 +166,40 @@ int __rt_dev_open(rtdm_user_info_t *user_info, const char *path, int oflag)
 	if (unlikely(ret < 0))
 		goto cleanup_out;
 
-	fildes->context = context;
-
 	trace_mark(xn_rtdm, fd_created,
-		   "device %p fd %d", device, context->fd);
+		"device %p fd %d", device, rtdm_fd_index(&context->fd));
 
-	return context->fd;
+	return ufd;
 
 cleanup_out:
-	cleanup_fildes(fildes);
-	cleanup_instance(device, context, nrt_mode);
+	cleanup_instance(device, context);
 
 err_out:
 	return ret;
 }
-
 EXPORT_SYMBOL_GPL(__rt_dev_open);
 
-int __rt_dev_socket(rtdm_user_info_t *user_info, int protocol_family,
+int __rt_dev_socket(struct xnsys_ppd *p, int ufd, int protocol_family,
 		    int socket_type, int protocol)
 {
 	struct rtdm_device *device;
-	struct rtdm_fildes *fildes;
 	struct rtdm_dev_context *context;
 	int ret;
-	int nrt_mode = !rtdm_in_rt_context();
 
 	device = get_protocol_device(protocol_family, socket_type);
-	trace_mark(xn_rtdm, socket, "user_info %p protocol_family %d "
+	trace_mark(xn_rtdm, socket, "sys_ppd %p protocol_family %d "
 		   "socket_type %d protocol %d device %p",
-		   user_info, protocol_family, socket_type, protocol, device);
+		   p, protocol_family, socket_type, protocol, device);
 	ret = -EAFNOSUPPORT;
 	if (!device)
 		goto err_out;
 
-	ret = create_instance(device, &context, &fildes, user_info, nrt_mode);
-	if (ret != 0)
+	ret = create_instance(p, ufd, device, &context);
+	if (ret < 0)
 		goto cleanup_out;
+	ufd = ret;
 
-	if (nrt_mode) {
-		context->context_flags = (1 << RTDM_CREATED_IN_NRT);
-		ret = device->socket_nrt(context, user_info, protocol);
-	} else {
-		context->context_flags = 0;
-		ret = device->socket_rt(context, user_info, protocol);
-	}
+	ret = device->socket(&context->fd, protocol);
 
 	if (!XENO_ASSERT(RTDM, !spltest()))
 		splnone();
@@ -339,302 +207,36 @@ int __rt_dev_socket(rtdm_user_info_t *user_info, int protocol_family,
 	if (unlikely(ret < 0))
 		goto cleanup_out;
 
-	fildes->context = context;
-
 	trace_mark(xn_rtdm, fd_created,
-		   "device %p fd %d", device, context->fd);
+		"device %p fd %d", device, rtdm_fd_index(&context->fd));
 
-	return context->fd;
+	return ufd;
 
 cleanup_out:
-	cleanup_fildes(fildes);
-	cleanup_instance(device, context, nrt_mode);
+	cleanup_instance(device, context);
 
 err_out:
 	return ret;
 }
-
 EXPORT_SYMBOL_GPL(__rt_dev_socket);
 
-int __rt_dev_close(rtdm_user_info_t *user_info, int fd)
-{
-	struct rtdm_dev_context *context;
-	spl_t s;
-	int ret;
-	int nrt_mode = !rtdm_in_rt_context();
-
-	trace_mark(xn_rtdm, close, "user_info %p fd %d", user_info, fd);
-
-	ret = -EBADF;
-	if (unlikely((unsigned int)fd >= RTDM_FD_MAX))
-		goto err_out;
-
-	xnlock_get_irqsave(&rt_fildes_lock, s);
-
-	context = fildes_table[fd].context;
-
-	if (unlikely(!context)) {
-		xnlock_put_irqrestore(&rt_fildes_lock, s);
-		goto err_out;	/* -EBADF */
-	}
-
-	/* Avoid asymmetric close context by switching to nrt. */
-	if (unlikely(test_bit(RTDM_CREATED_IN_NRT, &context->context_flags)) &&
-	    !nrt_mode) {
-		xnlock_put_irqrestore(&rt_fildes_lock, s);
-
-		ret = -ENOSYS;
-		goto err_out;
-	}
-
-	set_bit(RTDM_CLOSING, &context->context_flags);
-	atomic_inc(&context->close_lock_count);
-
-	__cleanup_fildes(&fildes_table[fd]);
-
-	xnlock_put_irqrestore(&rt_fildes_lock, s);
-
-	if (nrt_mode)
-		ret = context->ops->close_nrt(context, user_info);
-	else
-		ret = context->ops->close_rt(context, user_info);
-
-	if (!XENO_ASSERT(RTDM, !spltest()))
-		splnone();
-
-	xnlock_get_irqsave(&rt_fildes_lock, s);
-
-	if (ret == -EAGAIN || atomic_read(&context->close_lock_count) > 2) {
-		atomic_dec(&context->close_lock_count);
-		list_add(&context->reserved.cleanup, &cleanup_queue);
-
-		xnlock_put_irqrestore(&rt_fildes_lock, s);
-
-		if (ret == -EAGAIN) {
-			xnapc_schedule(rtdm_apc);
-			ret = 0;
-		}
-		goto unlock_out;
-	}
-
-	xnlock_put_irqrestore(&rt_fildes_lock, s);
-
-	trace_mark(xn_rtdm, fd_closed, "fd %d", context->fd);
-
-	cleanup_instance(context->device, context,
-			 test_bit(RTDM_CREATED_IN_NRT,
-				  &context->context_flags));
-
-	return ret;
-
-unlock_out:
-	rtdm_context_unlock(context);
-
-err_out:
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(__rt_dev_close);
-
-void cleanup_process_files(struct rtdm_process *owner)
+int 
+__rt_dev_ioctl_fallback(struct rtdm_fd *fd, unsigned request, void __user *arg)
 {
-	struct rtdm_dev_context *context;
-	unsigned int fd;
-	int ret;
-	spl_t s;
-
-	for (fd = 0; fd < RTDM_FD_MAX; fd++) {
-		xnlock_get_irqsave(&rt_fildes_lock, s);
-
-		context = fildes_table[fd].context;
-		if (context && context->reserved.owner != owner)
-			context = NULL;
-
-		xnlock_put_irqrestore(&rt_fildes_lock, s);
-
-		if (context) {
-			if (XENO_DEBUG(RTDM_APPL))
-				printk(XENO_INFO "closing RTDM file descriptor %d\n",
-				       fd);
-
-			ret = __rt_dev_close(NULL, fd);
-			XENO_ASSERT(RTDM, ret == 0 || ret == -EBADF);
-		}
-	}
+	struct rtdm_device *dev = rtdm_context(fd)->device;
+	struct rtdm_device_info dev_info;
+
+	if (fd->magic != RTDM_FD_MAGIC || request != RTIOC_DEVICE_INFO)
+		return -ENOSYS;
+	
+	dev_info.device_flags = dev->device_flags;
+	dev_info.device_class = dev->device_class;
+	dev_info.device_sub_class = dev->device_sub_class;
+	dev_info.profile_version = dev->profile_version;
+	
+	return rtdm_safe_copy_to_user(fd, arg, &dev_info,  sizeof(dev_info));
 }
 
-#define MAJOR_FUNCTION_WRAPPER_TH(operation, args...)			\
-do {									\
-	struct rtdm_dev_context *context;				\
-	struct rtdm_operations *ops;					\
-	int ret;							\
-									\
-	context = rtdm_context_get(fd);					\
-	ret = -EBADF;							\
-	if (unlikely(!context))						\
-		goto err_out;						\
-									\
-	ops = context->ops;						\
-									\
-	if (rtdm_in_rt_context())					\
-		ret = ops->operation##_rt(context, user_info, args);	\
-	else								\
-		ret = ops->operation##_nrt(context, user_info, args);	\
-									\
-	if (!XENO_ASSERT(RTDM, !spltest()))				\
-		    splnone();
-
-#define MAJOR_FUNCTION_WRAPPER_BH()					\
-	rtdm_context_unlock(context);					\
-									\
-err_out:								\
-	trace_mark(xn_rtdm, operation##_done, "result %d", ret);	\
-	return ret;							\
-} while (0)
-
-#define MAJOR_FUNCTION_WRAPPER(operation, args...)			\
-do {									\
-	MAJOR_FUNCTION_WRAPPER_TH(operation, args);			\
-	MAJOR_FUNCTION_WRAPPER_BH();					\
-} while (0)
-
-int __rt_dev_ioctl(rtdm_user_info_t *user_info, int fd, int request, ...)
-{
-	va_list args;
-	void __user *arg;
-
-	va_start(args, request);
-	arg = va_arg(args, void __user *);
-	va_end(args);
-
-	trace_mark(xn_rtdm, ioctl, "user_info %p fd %d request %d arg %p",
-		   user_info, fd, request, arg);
-
-	MAJOR_FUNCTION_WRAPPER_TH(ioctl, (unsigned int)request, arg);
-
-	if (unlikely(ret < 0) && (unsigned int)request == RTIOC_DEVICE_INFO) {
-		struct rtdm_device *dev = context->device;
-		struct rtdm_device_info dev_info;
-
-		dev_info.device_flags = dev->device_flags;
-		dev_info.device_class = dev->device_class;
-		dev_info.device_sub_class = dev->device_sub_class;
-		dev_info.profile_version = dev->profile_version;
-
-		ret = rtdm_safe_copy_to_user(user_info, arg, &dev_info,
-					     sizeof(dev_info));
-	}
-
-	MAJOR_FUNCTION_WRAPPER_BH();
-}
-
-EXPORT_SYMBOL_GPL(__rt_dev_ioctl);
-
-ssize_t __rt_dev_read(rtdm_user_info_t *user_info, int fd, void *buf,
-		      size_t nbyte)
-{
-	trace_mark(xn_rtdm, read, "user_info %p fd %d buf %p nbyte %zu",
-		   user_info, fd, buf, nbyte);
-	MAJOR_FUNCTION_WRAPPER(read, buf, nbyte);
-}
-
-EXPORT_SYMBOL_GPL(__rt_dev_read);
-
-ssize_t __rt_dev_write(rtdm_user_info_t *user_info, int fd, const void *buf,
-		       size_t nbyte)
-{
-	trace_mark(xn_rtdm, write, "user_info %p fd %d buf %p nbyte %zu",
-		   user_info, fd, buf, nbyte);
-	MAJOR_FUNCTION_WRAPPER(write, buf, nbyte);
-}
-
-EXPORT_SYMBOL_GPL(__rt_dev_write);
-
-ssize_t __rt_dev_recvmsg(rtdm_user_info_t *user_info, int fd,
-			 struct msghdr *msg, int flags)
-{
-	trace_mark(xn_rtdm, recvmsg, "user_info %p fd %d msg_name %p "
-		   "msg_namelen %u msg_iov %p msg_iovlen %zu "
-		   "msg_control %p msg_controllen %zu msg_flags %d",
-		   user_info, fd, msg->msg_name, msg->msg_namelen,
-		   msg->msg_iov, msg->msg_iovlen, msg->msg_control,
-		   msg->msg_controllen, msg->msg_flags);
-	MAJOR_FUNCTION_WRAPPER(recvmsg, msg, flags);
-}
-
-EXPORT_SYMBOL_GPL(__rt_dev_recvmsg);
-
-ssize_t __rt_dev_sendmsg(rtdm_user_info_t *user_info, int fd,
-			 const struct msghdr *msg, int flags)
-{
-	trace_mark(xn_rtdm, sendmsg, "user_info %p fd %d msg_name %p "
-		   "msg_namelen %u msg_iov %p msg_iovlen %zu "
-		   "msg_control %p msg_controllen %zu msg_flags %d",
-		   user_info, fd, msg->msg_name, msg->msg_namelen,
-		   msg->msg_iov, msg->msg_iovlen, msg->msg_control,
-		   msg->msg_controllen, msg->msg_flags);
-	MAJOR_FUNCTION_WRAPPER(sendmsg, msg, flags);
-}
-
-EXPORT_SYMBOL_GPL(__rt_dev_sendmsg);
-
-/**
- * @brief Bind a selector to specified event types of a given file descriptor
- * @internal
- *
- * This function is invoked by higher RTOS layers implementing select-like
- * services. It shall not be called directly by RTDM drivers.
- *
- * @param[in] fd File descriptor to bind to
- * @param[in,out] selector Selector object that shall be bound to the given
- * event
- * @param[in] type Event type the caller is interested in
- * @param[in] fd_index Index in the file descriptor set of the caller
- *
- * @return 0 on success, otherwise:
- *
- * - -EBADF is returned if the file descriptor @a fd cannot be resolved.
- *
- * - -EINVAL is returned if @a type or @a fd_index are invalid.
- *
- * Environments:
- *
- * This service can be called from:
- *
- * - Kernel module initialization/cleanup code
- * - Kernel-based task
- * - User-space task (RT, non-RT)
- *
- * Rescheduling: never.
- */
-int rtdm_select_bind(int fd, rtdm_selector_t *selector,
-		     enum rtdm_selecttype type, unsigned fd_index)
-{
-	struct rtdm_dev_context *context;
-	struct rtdm_operations  *ops;
-	int ret;
-
-	context = rtdm_context_get(fd);
-
-	ret = -EBADF;
-	if (unlikely(!context))
-		goto err_out;
-
-	ops = context->ops;
-
-	ret = ops->select_bind(context, selector, type, fd_index);
-
-	if (!XENO_ASSERT(RTDM, !spltest()))
-		    splnone();
-
-	rtdm_context_unlock(context);
-
-  err_out:
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(rtdm_select_bind);
-
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 
 /**
diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c
index 299c788..25d5120 100644
--- a/kernel/cobalt/rtdm/device.c
+++ b/kernel/cobalt/rtdm/device.c
@@ -49,23 +49,21 @@
 struct list_head rtdm_named_devices;	/* hash table */
 struct rb_root rtdm_protocol_devices;
 
-int rtdm_apc;
-EXPORT_SYMBOL_GPL(rtdm_apc);
-
 struct semaphore nrt_dev_lock;
 DEFINE_XNLOCK(rt_dev_lock);
 
 int rtdm_initialised = 0;
 
+extern void __rt_dev_close(struct rtdm_fd *fd);
+
 int rtdm_no_support(void)
 {
 	return -ENOSYS;
 }
 
-int rtdm_select_bind_no_support(struct rtdm_dev_context *context,
+int rtdm_select_bind_no_support(struct rtdm_fd *fd,
 				struct xnselector *selector,
-				unsigned type,
-				unsigned index)
+				unsigned type, unsigned index)
 {
 	return -EBADF;
 }
@@ -190,30 +188,20 @@ int rtdm_dev_register(struct rtdm_device *device)
 	switch (device->device_flags & RTDM_DEVICE_TYPE_MASK) {
 	case RTDM_NAMED_DEVICE:
 		/* Sanity check: any open handler? */
-		if (!XENO_ASSERT(RTDM, ANY_HANDLER(*device, open))) {
+		if (device->open == NULL) {
 			printk(XENO_ERR "missing open handler for RTDM device\n");
 			return -EINVAL;
 		}
-		if (device->open_rt &&
-		    device->socket_rt != (void *)rtdm_no_support)
-			printk(XENO_ERR "RT open handler is deprecated, "
-			       "RTDM driver requires update\n");
-		SET_DEFAULT_OP_IF_NULL(*device, open);
-		SET_DEFAULT_OP(*device, socket);
+		device->socket = (typeof(device->socket))rtdm_no_support;
 		break;
 
 	case RTDM_PROTOCOL_DEVICE:
 		/* Sanity check: any socket handler? */
-		if (!XENO_ASSERT(RTDM, ANY_HANDLER(*device, socket))) {
+		if (device->socket == NULL) {
 			printk(XENO_ERR "missing socket handler for RTDM device\n");
 			return -EINVAL;
 		}
-		if (device->socket_rt &&
-		    device->socket_rt != (void *)rtdm_no_support)
-			printk(XENO_ERR "RT socket creation handler is "
-			       "deprecated, RTDM driver requires update\n");
-		SET_DEFAULT_OP_IF_NULL(*device, socket);
-		SET_DEFAULT_OP(*device, open);
+		device->open = (typeof(device->open))rtdm_no_support;
 		break;
 
 	default:
@@ -222,16 +210,12 @@ int rtdm_dev_register(struct rtdm_device *device)
 
 	/* Sanity check: non-RT close handler?
 	 * (Always required for forced cleanup) */
-	if (!device->ops.close_nrt) {
-		printk(XENO_ERR "missing non-RT close handler for RTDM device\n");
+	if (!device->ops.close) {
+		printk(XENO_ERR "missing close handler for RTDM device\n");
 		return -EINVAL;
 	}
-	if (device->ops.close_rt &&
-	    device->ops.close_rt != (void *)rtdm_no_support)
-		printk(XENO_ERR "RT close handler is deprecated, RTDM driver "
-		       "requires update\n");
-	else
-		device->ops.close_rt = (void *)rtdm_no_support;
+	device->reserved.close = device->ops.close;
+	device->ops.close = __rt_dev_close;
 
 	SET_DEFAULT_OP_IF_NULL(device->ops, ioctl);
 	SET_DEFAULT_OP_IF_NULL(device->ops, read);
@@ -386,7 +370,7 @@ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay)
 
 		if (!__test_and_set_bit(0, &warned))
 			printk(XENO_WARN "RTDM device %s still in use - waiting for"
-			       "release...\n", reg_dev->device_name);
+			       " release...\n", reg_dev->device_name);
 		msleep(poll_delay);
 		trace_mark(xn_rtdm, dev_poll, "device %p", device);
 
@@ -423,11 +407,6 @@ int __init rtdm_dev_init(void)
 {
 	sema_init(&nrt_dev_lock, 1);
 
-	rtdm_apc = xnapc_alloc("deferred RTDM close", rtdm_apc_handler,
-				   NULL);
-	if (rtdm_apc < 0)
-		return rtdm_apc;
-
 	INIT_LIST_HEAD(&rtdm_named_devices);
 	xntree_init(&rtdm_protocol_devices);
 
@@ -440,7 +419,6 @@ void rtdm_dev_cleanup(void)
 	 * Note: no need to flush the cleanup_queue as no device is allowed
 	 * to deregister as long as there are references.
 	 */
-	xnapc_free(rtdm_apc);
 }
 
 /*@}*/
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index 17178ee..3c1d5d5 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -1884,7 +1884,7 @@ static struct file_operations rtdm_mmap_fops = {
 	.get_unmapped_area = rtdm_unmapped_area
 };
 
-static int rtdm_do_mmap(rtdm_user_info_t *user_info,
+static int rtdm_do_mmap(struct rtdm_fd *fd,
 			struct rtdm_mmap_data *mmap_data,
 			size_t len, int prot, void **pptr)
 {
@@ -1912,7 +1912,7 @@ static int rtdm_do_mmap(rtdm_user_info_t *user_info,
 	filp->f_op = (typeof(filp->f_op))old_fops;
 	filp->private_data = old_priv_data;
 
-	filp_close(filp, user_info->files);
+	filp_close(filp, current->files);
 
 	if (IS_ERR_VALUE(u_addr))
 		return (int)u_addr;
@@ -1976,7 +1976,7 @@ static int rtdm_do_mmap(rtdm_user_info_t *user_info,
  *
  * Rescheduling: possible.
  */
-int rtdm_mmap_to_user(rtdm_user_info_t *user_info,
+int rtdm_mmap_to_user(struct rtdm_fd *fd,
 		      void *src_addr, size_t len,
 		      int prot, void **pptr,
 		      struct vm_operations_struct *vm_ops,
@@ -1989,7 +1989,7 @@ int rtdm_mmap_to_user(rtdm_user_info_t *user_info,
 		.vm_private_data = vm_private_data
 	};
 
-	return rtdm_do_mmap(user_info, &mmap_data, len, prot, pptr);
+	return rtdm_do_mmap(fd, &mmap_data, len, prot, pptr);
 }
 
 EXPORT_SYMBOL_GPL(rtdm_mmap_to_user);
@@ -2044,7 +2044,7 @@ EXPORT_SYMBOL_GPL(rtdm_mmap_to_user);
  *
  * Rescheduling: possible.
  */
-int rtdm_iomap_to_user(rtdm_user_info_t *user_info,
+int rtdm_iomap_to_user(struct rtdm_fd *fd,
 		       phys_addr_t src_addr, size_t len,
 		       int prot, void **pptr,
 		       struct vm_operations_struct *vm_ops,
@@ -2057,7 +2057,7 @@ int rtdm_iomap_to_user(rtdm_user_info_t *user_info,
 		.vm_private_data = vm_private_data
 	};
 
-	return rtdm_do_mmap(user_info, &mmap_data, len, prot, pptr);
+	return rtdm_do_mmap(fd, &mmap_data, len, prot, pptr);
 }
 
 EXPORT_SYMBOL_GPL(rtdm_iomap_to_user);
@@ -2086,16 +2086,16 @@ EXPORT_SYMBOL_GPL(rtdm_iomap_to_user);
  *
  * Rescheduling: possible.
  */
-int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len)
+int rtdm_munmap(struct rtdm_fd *fd, void *ptr, size_t len)
 {
 	int err;
 
 	if (!XENO_ASSERT(RTDM, xnsched_root_p()))
 		return -EPERM;
 
-	down_write(&user_info->mm->mmap_sem);
-	err = do_munmap(user_info->mm, (unsigned long)ptr, len);
-	up_write(&user_info->mm->mmap_sem);
+	down_write(&current->mm->mmap_sem);
+	err = do_munmap(current->mm, (unsigned long)ptr, len);
+	up_write(&current->mm->mmap_sem);
 
 	return err;
 }
@@ -2263,7 +2263,7 @@ void rtdm_free(void *ptr);
  *
  * Rescheduling: never.
  */
-int rtdm_read_user_ok(rtdm_user_info_t *user_info, const void __user *ptr,
+int rtdm_read_user_ok(struct rtdm_fd *fd, const void __user *ptr,
 		      size_t size);
 
 /**
@@ -2287,7 +2287,7 @@ int rtdm_read_user_ok(rtdm_user_info_t *user_info, const void __user *ptr,
  *
  * Rescheduling: never.
  */
-int rtdm_rw_user_ok(rtdm_user_info_t *user_info, const void __user *ptr,
+int rtdm_rw_user_ok(struct rtdm_fd *fd, const void __user *ptr,
 		    size_t size);
 
 /**
@@ -2316,7 +2316,7 @@ int rtdm_rw_user_ok(rtdm_user_info_t *user_info, const void __user *ptr,
  *
  * Rescheduling: never.
  */
-int rtdm_copy_from_user(rtdm_user_info_t *user_info, void *dst,
+int rtdm_copy_from_user(struct rtdm_fd *fd, void *dst,
 			const void __user *src, size_t size);
 
 /**
@@ -2346,7 +2346,7 @@ int rtdm_copy_from_user(rtdm_user_info_t *user_info, void *dst,
  *
  * Rescheduling: never.
  */
-int rtdm_safe_copy_from_user(rtdm_user_info_t *user_info, void *dst,
+int rtdm_safe_copy_from_user(struct rtdm_fd *fd, void *dst,
 			     const void __user *src, size_t size);
 
 /**
@@ -2375,7 +2375,7 @@ int rtdm_safe_copy_from_user(rtdm_user_info_t *user_info, void *dst,
  *
  * Rescheduling: never.
  */
-int rtdm_copy_to_user(rtdm_user_info_t *user_info, void __user *dst,
+int rtdm_copy_to_user(struct rtdm_fd *fd, void __user *dst,
 		      const void *src, size_t size);
 
 /**
@@ -2405,7 +2405,7 @@ int rtdm_copy_to_user(rtdm_user_info_t *user_info, void __user *dst,
  *
  * Rescheduling: never.
  */
-int rtdm_safe_copy_to_user(rtdm_user_info_t *user_info, void __user *dst,
+int rtdm_safe_copy_to_user(struct rtdm_fd *fd, void __user *dst,
 			   const void *src, size_t size);
 
 /**
@@ -2436,7 +2436,7 @@ int rtdm_safe_copy_to_user(rtdm_user_info_t *user_info, void __user *dst,
  *
  * Rescheduling: never.
  */
-int rtdm_strncpy_from_user(rtdm_user_info_t *user_info, char *dst,
+int rtdm_strncpy_from_user(struct rtdm_fd *fd, char *dst,
 			   const char __user *src, size_t count);
 
 /**
@@ -2482,7 +2482,7 @@ int rtdm_in_rt_context(void);
  *
  * Rescheduling: never.
  */
-int rtdm_rt_capable(rtdm_user_info_t *user_info);
+int rtdm_rt_capable(struct rtdm_fd *fd);
 
 #endif /* DOXYGEN_CPP */
 
diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
new file mode 100644
index 0000000..1125842
--- /dev/null
+++ b/kernel/cobalt/rtdm/fd.c
@@ -0,0 +1,541 @@
+/*
+ * Copyright (C) 2005 Jan Kiszka <jan.kiszka@web.de>
+ * Copyright (C) 2005 Joerg Langenberg <joerg.langenberg@gmx.net>
+ * Copyright (C) 2013,2014 Gilles Chanteperdrix <gch@xenomai.org>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/kthread.h>
+#include <cobalt/kernel/registry.h>
+#include <cobalt/kernel/lock.h>
+#include <cobalt/kernel/ppd.h>
+#include <rtdm/fd.h>
+
+#ifdef CONFIG_SMP
+static DEFINE_XNLOCK(__rtdm_fd_lock);
+#endif
+static LIST_HEAD(rtdm_fd_cleanup_queue);
+static struct semaphore rtdm_fd_cleanup_sem;
+
+extern int 
+__rt_dev_ioctl_fallback(struct rtdm_fd *fd, unsigned request, void __user *arg);
+extern void __rt_dev_unref(struct rtdm_fd *fd, unsigned idx);
+
+static int enosys(void)
+{
+	return -ENOSYS;
+}
+
+static int ebadf(void)
+{
+	return -EBADF;
+}
+
+static void nop_close(struct rtdm_fd *fd)
+{
+}
+
+static inline struct rtdm_fd_index *
+rtdm_fd_index_fetch(struct xnsys_ppd *p, int ufd)
+{
+	struct xnid *id = xnid_fetch(&p->fds, ufd);
+	if (id == NULL)
+		return NULL;
+
+	return container_of(id, struct rtdm_fd_index, id);
+}
+
+static struct rtdm_fd *rtdm_fd_fetch(struct xnsys_ppd *p, int ufd)
+{
+	struct rtdm_fd_index *idx = rtdm_fd_index_fetch(p, ufd);
+	if (idx == NULL)
+		return NULL;
+
+	return idx->fd;
+}
+
+int rtdm_fd_enter(struct xnsys_ppd *p, struct rtdm_fd *fd, int ufd, 
+	unsigned magic, struct rtdm_fd_ops *ops)
+{
+	struct rtdm_fd_index *idx;
+	spl_t s;
+	int err;
+
+	secondary_mode_only();
+
+	if (magic == XNFD_MAGIC_ANY) {
+		err = -EINVAL;
+		goto err;
+	}
+
+	idx = kmalloc(sizeof(*idx), GFP_KERNEL);
+	if (idx == NULL) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	if (ops->ioctl_rt == NULL && ops->ioctl_nrt == NULL)
+		ops->ioctl_rt = ops->ioctl_nrt = (rtdm_fd_ioctl_t *)ebadf;
+	else {
+		if (ops->ioctl_rt == NULL)
+			ops->ioctl_rt = (rtdm_fd_ioctl_t *)enosys;
+		if (ops->ioctl_nrt == NULL)
+			ops->ioctl_nrt = (rtdm_fd_ioctl_t *)enosys;
+	}
+
+	if (ops->read_rt == NULL && ops->read_nrt == NULL)
+		ops->read_rt = ops->read_nrt = (rtdm_fd_read_t *)ebadf;
+	else {
+		if (ops->read_rt == NULL)
+			ops->read_rt = (rtdm_fd_read_t *)enosys;
+		if (ops->read_nrt == NULL)
+			ops->read_nrt = (rtdm_fd_read_t *)enosys;
+	}
+
+	if (ops->write_rt == NULL && ops->write_nrt == NULL)
+		ops->write_rt = ops->write_nrt = (rtdm_fd_write_t *)ebadf;
+	else {
+		if (ops->write_rt == NULL)
+			ops->write_rt = (rtdm_fd_write_t *)enosys;
+		if (ops->write_nrt == NULL)
+			ops->write_nrt = (rtdm_fd_write_t *)enosys;
+	}
+
+	if (ops->recvmsg_rt == NULL && ops->recvmsg_nrt == NULL)
+		ops->recvmsg_rt = ops->recvmsg_nrt = (rtdm_fd_recvmsg_t *)ebadf;
+	else {
+		if (ops->recvmsg_rt == NULL)
+			ops->recvmsg_rt = (rtdm_fd_recvmsg_t *)enosys;
+		if (ops->recvmsg_nrt == NULL)
+			ops->recvmsg_nrt = (rtdm_fd_recvmsg_t *)enosys;
+	}
+
+	if (ops->sendmsg_rt == NULL && ops->sendmsg_nrt == NULL)
+		ops->sendmsg_rt = ops->sendmsg_nrt = (rtdm_fd_sendmsg_t *)ebadf;
+	else {
+		if (ops->sendmsg_rt == NULL)
+			ops->sendmsg_rt = (rtdm_fd_sendmsg_t *)enosys;
+		if (ops->sendmsg_nrt == NULL)
+			ops->sendmsg_nrt = (rtdm_fd_sendmsg_t *)enosys;
+	}
+
+	if (ops->select_bind == NULL)
+		ops->select_bind = (typeof(ops->select_bind))ebadf;
+
+	if (ops->close == NULL)
+		ops->close = nop_close;
+
+	fd->magic = magic;
+	fd->ops = ops;
+	fd->cont = p;
+	fd->refs = 1;
+
+	idx->fd = fd;
+
+	xnlock_get_irqsave(&__rtdm_fd_lock, s);
+	err = xnid_enter(&p->fds, &idx->id, ufd);
+	if (err < 0) {
+		xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+		err = -EBUSY;
+		goto err_free_index;
+	}
+	xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+	
+	return 0;
+
+  err_free_index:
+	kfree(idx);
+  err:
+	if (ops->close)
+		ops->close(fd);
+	return err;
+}
+
+struct rtdm_fd *rtdm_fd_get(struct xnsys_ppd *p, int ufd, unsigned magic)
+{
+	struct rtdm_fd *res;
+	spl_t s;
+	
+	xnlock_get_irqsave(&__rtdm_fd_lock, s);
+	res = rtdm_fd_fetch(p, ufd);
+	if (res == NULL || (magic != XNFD_MAGIC_ANY && res->magic != magic)) {
+		res = ERR_PTR(-EBADF);
+		goto err_unlock;
+	}
+	
+	++res->refs;
+  err_unlock:
+	xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+	
+	return res;
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_get);
+
+struct lostage_trigger_close {
+	struct ipipe_work_header work; /* Must be first */
+};
+
+static void rtdm_fd_do_close(struct rtdm_fd *fd)
+{
+	secondary_mode_only();
+
+	fd->ops->close(fd);
+
+	if (!XENO_ASSERT(NUCLEUS, !spltest()))
+		splnone();
+}
+
+static int rtdm_fd_cleanup_thread(void *data)
+{
+	struct rtdm_fd *fd;
+	int err;
+	spl_t s;
+	
+	for (;;) {
+		set_cpus_allowed_ptr(current, cpu_online_mask);
+
+		do {
+			err = down_killable(&rtdm_fd_cleanup_sem);
+		} while (err && !kthread_should_stop());
+
+		if (kthread_should_stop())
+			break;
+
+		xnlock_get_irqsave(&__rtdm_fd_lock, s);
+		fd = list_first_entry(&rtdm_fd_cleanup_queue, 
+				struct rtdm_fd, cleanup);
+		list_del(&fd->cleanup);
+		xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+
+		rtdm_fd_do_close(fd);
+	}
+
+	return 0;
+}
+
+static void lostage_trigger_close(struct ipipe_work_header *work)
+{
+	up(&rtdm_fd_cleanup_sem);
+}
+
+static void rtdm_fd_put_inner(struct rtdm_fd *fd, spl_t s)
+{
+	int destroy;
+
+	destroy = --fd->refs == 0;
+	xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+	
+	if (!destroy)
+		return;
+	
+	if (ipipe_root_p)
+		rtdm_fd_do_close(fd);
+	else {
+		struct lostage_trigger_close closework = {
+			.work = {
+				.size = sizeof(closework),
+				.handler = lostage_trigger_close,
+			},
+		};
+		
+		xnlock_get_irqsave(&__rtdm_fd_lock, s);
+		list_add_tail(&fd->cleanup, &rtdm_fd_cleanup_queue);
+		xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+
+		ipipe_post_work_root(&closework, work);
+	}
+}
+
+void rtdm_fd_put(struct rtdm_fd *fd)
+{
+	spl_t s;
+	
+	xnlock_get_irqsave(&__rtdm_fd_lock, s);
+	rtdm_fd_put_inner(fd, s);
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_put);
+
+int rtdm_fd_lock(struct rtdm_fd *fd)
+{
+	spl_t s;
+
+	xnlock_get_irqsave(&__rtdm_fd_lock, s);
+	if (fd->refs == 0) {
+		xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+		return -EIDRM;
+	}
+	++fd->refs;
+	xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_lock);
+
+void rtdm_fd_unlock(struct rtdm_fd *fd)
+{
+	spl_t s;
+
+	xnlock_get_irqsave(&__rtdm_fd_lock, s);
+/* just warn if context was a dangling pointer */
+	XENO_ASSERT(NUCLEUS, fd->refs > 0);
+	rtdm_fd_put_inner(fd, s);
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_unlock);
+
+int rtdm_fd_ioctl(struct xnsys_ppd *p, int ufd, unsigned request, ...)
+{
+	void __user *arg;
+	struct rtdm_fd *fd;
+	va_list args;
+	int err;
+
+	va_start(args, request);
+	arg = va_arg(args, void __user *);
+	va_end(args);
+
+	trace_mark(xn_rtdm, ioctl, "sys_ppd %p fd %d request %d arg %p",
+		   p, ufd, request, arg);
+	
+	fd = rtdm_fd_get(p, ufd, XNFD_MAGIC_ANY);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
+	
+	if (ipipe_root_p)
+		err = fd->ops->ioctl_nrt(fd, request, arg);
+	else
+		err = fd->ops->ioctl_rt(fd, request, arg);
+	
+	if (!XENO_ASSERT(NUCLEUS, !spltest()))
+		    splnone();
+
+	if (err < 0) {
+		int ret = __rt_dev_ioctl_fallback(fd, request, arg);
+		if (ret != -ENOSYS)
+			err = ret;
+	}
+
+	rtdm_fd_put(fd);
+	
+	return err;
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_ioctl);
+
+ssize_t 
+rtdm_fd_read(struct xnsys_ppd *p, int ufd, void __user *buf, size_t size)
+{
+	struct rtdm_fd *fd;
+	ssize_t err;
+	
+	trace_mark(xn_rtdm, read, "sys_ppd %p fd %d buf %p nbyte %zu",
+		   p, ufd, buf, size);
+
+	fd = rtdm_fd_get(p, ufd, XNFD_MAGIC_ANY);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
+	
+	if (ipipe_root_p)
+		err = fd->ops->read_nrt(fd, buf, size);
+	else
+		err = fd->ops->read_rt(fd, buf, size);
+	
+	if (!XENO_ASSERT(NUCLEUS, !spltest()))
+		    splnone();
+
+	rtdm_fd_put(fd);
+	
+	return err;
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_read);
+
+ssize_t rtdm_fd_write(struct xnsys_ppd *p, int ufd,
+		const void __user *buf, size_t size)
+{
+	struct rtdm_fd *fd;
+	ssize_t err;
+	
+	trace_mark(xn_rtdm, write, "sys_ppd %p fd %d buf %p nbyte %zu",
+		   p, ufd, buf, size);
+
+	fd = rtdm_fd_get(p, ufd, XNFD_MAGIC_ANY);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
+	
+	if (ipipe_root_p)
+		err = fd->ops->write_nrt(fd, buf, size);
+	else
+		err = fd->ops->write_rt(fd, buf, size);
+	
+	if (!XENO_ASSERT(NUCLEUS, !spltest()))
+		    splnone();
+
+	rtdm_fd_put(fd);
+	
+	return err;
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_write);
+
+ssize_t 
+rtdm_fd_recvmsg(struct xnsys_ppd *p, int ufd, struct msghdr *msg, int flags)
+{
+	struct rtdm_fd *fd;
+	ssize_t err;
+	
+	trace_mark(xn_rtdm, recvmsg, "sys_ppd %p fd %d msg_name %p "
+		   "msg_namelen %u msg_iov %p msg_iovlen %zu "
+		   "msg_control %p msg_controllen %zu msg_flags %d",
+		   p, ufd, msg->msg_name, msg->msg_namelen,
+		   msg->msg_iov, msg->msg_iovlen, msg->msg_control,
+		   msg->msg_controllen, msg->msg_flags);
+
+	fd = rtdm_fd_get(p, ufd, XNFD_MAGIC_ANY);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
+	
+	if (ipipe_root_p)
+		err = fd->ops->recvmsg_nrt(fd, msg, flags);
+	else
+		err = fd->ops->recvmsg_rt(fd, msg, flags);
+	
+	if (!XENO_ASSERT(NUCLEUS, !spltest()))
+		    splnone();
+
+	rtdm_fd_put(fd);
+	
+	return err;
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_recvmsg);
+
+ssize_t 
+rtdm_fd_sendmsg(struct xnsys_ppd *p, int ufd, const struct msghdr *msg, int flags)
+{
+	struct rtdm_fd *fd;
+	ssize_t err;
+	
+	trace_mark(xn_rtdm, sendmsg, "sys_ppd %p fd %d msg_name %p "
+		   "msg_namelen %u msg_iov %p msg_iovlen %zu "
+		   "msg_control %p msg_controllen %zu msg_flags %d",
+		   p, ufd, msg->msg_name, msg->msg_namelen,
+		   msg->msg_iov, msg->msg_iovlen, msg->msg_control,
+		   msg->msg_controllen, msg->msg_flags);
+
+	fd = rtdm_fd_get(p, ufd, XNFD_MAGIC_ANY);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
+	
+	if (ipipe_root_p)
+		err = fd->ops->sendmsg_nrt(fd, msg, flags);
+	else
+		err = fd->ops->sendmsg_rt(fd, msg, flags);
+	
+	if (!XENO_ASSERT(NUCLEUS, !spltest()))
+		    splnone();
+
+	rtdm_fd_put(fd);
+	
+	return err;
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_sendmsg);
+
+static void 
+rtdm_fd_close_inner(struct xnsys_ppd *p, struct rtdm_fd_index *idx, spl_t s)
+{
+	xnid_remove(&p->fds, &idx->id);
+	rtdm_fd_put_inner(idx->fd, s);
+
+	kfree(idx);
+}
+
+int rtdm_fd_close(struct xnsys_ppd *p, int ufd, unsigned magic)
+{
+	struct rtdm_fd_index *idx;
+	struct rtdm_fd *fd;
+	spl_t s;
+
+	trace_mark(xn_rtdm, close, "sys_ppd %p fd %d", p, ufd);
+
+	xnlock_get_irqsave(&__rtdm_fd_lock, s);
+	idx = rtdm_fd_index_fetch(p, ufd);
+	if (idx == NULL)
+		goto ebadf;
+
+	fd = idx->fd;
+	if (magic != XNFD_MAGIC_ANY && fd->magic != magic) {
+	  ebadf:
+		xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+		return -EBADF;
+	}
+	__rt_dev_unref(fd, xnid_id(&idx->id));
+	rtdm_fd_close_inner(p, idx, s);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_close);
+
+int rtdm_fd_valid_p(int ufd)
+{
+	struct rtdm_fd *fd;
+	spl_t s;
+
+	xnlock_get_irqsave(&__rtdm_fd_lock, s);
+	fd = rtdm_fd_fetch(xnsys_ppd_get(0), ufd);
+	xnlock_put_irqrestore(&__rtdm_fd_lock, s);
+	
+	return fd != NULL;
+}
+
+int rtdm_fd_select_bind(int ufd, struct xnselector *selector, unsigned type)
+{
+	struct xnsys_ppd *p;
+	struct rtdm_fd *fd;
+	int rc;
+	
+	p = xnsys_ppd_get(0);
+	fd = rtdm_fd_get(p, ufd, XNFD_MAGIC_ANY);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
+	
+	rc = fd->ops->select_bind(fd, selector, type, ufd);
+
+	rtdm_fd_put(fd);
+	
+	return rc;
+}
+
+static void rtdm_fd_destroy(void *cookie, struct xnid *id)
+{
+	struct xnsys_ppd *p = cookie;
+	struct rtdm_fd_index *idx;
+	spl_t s;
+
+	idx = container_of(id, struct rtdm_fd_index, id);
+	xnlock_get_irqsave(&__rtdm_fd_lock, s);
+	rtdm_fd_close_inner(p, idx, XNFD_MAGIC_ANY);
+}
+
+void rtdm_fd_cleanup(struct xnsys_ppd *p)
+{
+	xntree_cleanup(&p->fds, p, rtdm_fd_destroy);
+}
+
+void rtdm_fd_init(void)
+{
+	sema_init(&rtdm_fd_cleanup_sem, 0);
+	kthread_run(rtdm_fd_cleanup_thread, NULL, "rtdm_fd");
+}
diff --git a/kernel/cobalt/rtdm/internal.h b/kernel/cobalt/rtdm/internal.h
index 3288068..6db80a6 100644
--- a/kernel/cobalt/rtdm/internal.h
+++ b/kernel/cobalt/rtdm/internal.h
@@ -31,10 +31,6 @@
 #define DEF_DEVNAME_HASHTAB_SIZE	256	/* entries in name hash table */
 #define DEF_PROTO_HASHTAB_SIZE		256	/* entries in protocol hash table */
 
-struct rtdm_fildes {
-	struct rtdm_dev_context *context;
-};
-
 struct rtdm_process {
 #ifdef CONFIG_XENO_OPT_VFILE
 	char name[32];
@@ -46,10 +42,8 @@ DECLARE_EXTERN_XNLOCK(rt_fildes_lock);
 DECLARE_EXTERN_XNLOCK(rt_dev_lock);
 
 extern int __rtdm_muxid;
-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 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 28ec6ab..f45bae7 100644
--- a/kernel/cobalt/rtdm/proc.c
+++ b/kernel/cobalt/rtdm/proc.c
@@ -184,40 +184,35 @@ 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, fd;
-	spl_t s;
+	int close_lock_count, i;
+	struct rtdm_fd *fd;
 
 	if (data == NULL) {
 		xnvfile_puts(it, "Index\tLocked\tDevice\t\t\t\tOwner [PID]\n");
 		return 0;
 	}
 
-	fd = (int)it->pos - 1;
+	i = (int)it->pos - 1;
 
-	xnlock_get_irqsave(&rt_fildes_lock, s);
-
-	context = fildes_table[fd].context;
-	if (context == NULL) {
-		xnlock_put_irqrestore(&rt_fildes_lock, s);
+	fd = rtdm_fd_get(&__xnsys_global_ppd, i, RTDM_FD_MAGIC);
+	if (fd == NULL)
 		return VFILE_SEQ_SKIP;
-	}
 
-	close_lock_count = atomic_read(&context->close_lock_count);
+	context = rtdm_context(fd);
+	close_lock_count = fd->refs;
 	device = context->device;
-	if (context->reserved.owner)
-		memcpy(&owner, context->reserved.owner, sizeof(owner));
-	else {
-		strcpy(owner.name, "<kernel>");
-		owner.pid = -1;
-	}
 
-	xnlock_put_irqrestore(&rt_fildes_lock, s);
+	strcpy(owner.name, "<kernel>");
+	owner.pid = -1;
 
-	xnvfile_printf(it, "%d\t%d\t%-31s %s [%d]\n", fd,
+	xnvfile_printf(it, "%d\t%d\t%-31s %s [%d]\n", i,
 		       close_lock_count,
 		       (device->device_flags & RTDM_NAMED_DEVICE) ?
 		       device->device_name : device->proc_name,
 		       owner.name, owner.pid);
+
+	rtdm_fd_put(fd);
+
 	return 0;
 }
 
@@ -230,7 +225,7 @@ static ssize_t openfd_store(struct xnvfile_input *input)
 	if (ret < 0)
 		return ret;
 
-	cret = __rt_dev_close(current, (int)val);
+	cret = rtdm_fd_close(&__xnsys_global_ppd, (int)val, RTDM_FD_MAGIC);
 	if (cret < 0)
 		return cret;
 
diff --git a/kernel/cobalt/rtdm/syscall.c b/kernel/cobalt/rtdm/syscall.c
index 24edd3a..d7bc2bb 100644
--- a/kernel/cobalt/rtdm/syscall.c
+++ b/kernel/cobalt/rtdm/syscall.c
@@ -24,83 +24,71 @@
 
 int __rtdm_muxid;
 
-static int sys_rtdm_fdcount(void)
-{
-	return RTDM_FD_MAX;
-}
-
-static int sys_rtdm_open(const char __user *u_path, int oflag)
+static int sys_rtdm_open(int fd, const char __user *u_path, int oflag)
 {
 	char krnl_path[RTDM_MAX_DEVNAME_LEN + 1];
-	struct task_struct *p = current;
 
 	if (unlikely(__xn_safe_strncpy_from_user(krnl_path, u_path,
 						 sizeof(krnl_path) - 1) < 0))
 		return -EFAULT;
 	krnl_path[sizeof(krnl_path) - 1] = '\0';
 
-	return __rt_dev_open(p, krnl_path, oflag);
-}
-
-static int sys_rtdm_socket(int protocol_family, int socket_type, int protocol)
-{
-	return __rt_dev_socket(current,
-			       protocol_family, socket_type, protocol);
+	return __rt_dev_open(xnsys_ppd_get(0), fd, krnl_path, oflag);
 }
 
-static int sys_rtdm_close(int fd)
+static int 
+sys_rtdm_socket(int fd, int protocol_family, int socket_type, int protocol)
 {
-	return __rt_dev_close(current, fd);
+	return __rt_dev_socket(xnsys_ppd_get(0), fd, 
+			protocol_family, socket_type, protocol);
 }
 
-static int sys_rtdm_ioctl(int fd, int request, void *arglist)
+int sys_rtdm_ioctl(int fd, unsigned int request, void __user *arg)
 {
-	return __rt_dev_ioctl(current, fd, request, arglist);
+	return rtdm_fd_ioctl(xnsys_ppd_get(0), fd, request, arg);
 }
 
-static int sys_rtdm_read(int fd, void __user *u_buf, size_t nbytes)
+ssize_t sys_rtdm_read(int fd, void __user *buf, size_t size)
 {
-	return __rt_dev_read(current, fd, u_buf, nbytes);
+	return rtdm_fd_read(xnsys_ppd_get(0), fd, buf, size);
 }
 
-static int sys_rtdm_write(int fd, const void __user *u_buf, size_t nbytes)
+ssize_t sys_rtdm_write(int fd, const void __user *buf, size_t size)
 {
-	return __rt_dev_write(current, fd, u_buf, nbytes);
+	return rtdm_fd_write(xnsys_ppd_get(0), fd, buf, size);
 }
 
-static int sys_rtdm_recvmsg(int fd, struct msghdr __user *u_msg, int flags)
+ssize_t sys_rtdm_recvmsg(int fd, struct msghdr __user *umsg, int flags)
 {
-	struct task_struct *p = current;
-	struct msghdr krnl_msg;
+	struct msghdr m;
 	int ret;
 
-	if (unlikely(!access_wok(u_msg, sizeof(krnl_msg)) ||
-		     __xn_copy_from_user(&krnl_msg, u_msg,
-					 sizeof(krnl_msg))))
+	if (__xn_copy_from_user(&m, umsg, sizeof(m)))
 		return -EFAULT;
 
-	ret = __rt_dev_recvmsg(p, fd, &krnl_msg, flags);
-	if (unlikely(ret < 0))
+	ret = rtdm_fd_recvmsg(xnsys_ppd_get(0), fd, &m, flags);
+	if (ret < 0)
 		return ret;
-
-	if (unlikely(__xn_copy_to_user(u_msg, &krnl_msg, sizeof(krnl_msg))))
+	
+	if (__xn_copy_to_user(umsg, &m, sizeof(*umsg)))
 		return -EFAULT;
-
+	
 	return ret;
 }
 
-static int sys_rtdm_sendmsg(int fd, const struct msghdr __user *u_msg,
-			    int flags)
+ssize_t sys_rtdm_sendmsg(int fd, struct msghdr __user *umsg, int flags)
 {
-	struct task_struct *p = current;
-	struct msghdr krnl_msg;
+	struct msghdr m;
 
-	if (unlikely(!access_rok(u_msg, sizeof(krnl_msg)) ||
-		     __xn_copy_from_user(&krnl_msg, u_msg,
-					 sizeof(krnl_msg))))
+	if (__xn_copy_from_user(&m, umsg, sizeof(m)))
 		return -EFAULT;
 
-	return __rt_dev_sendmsg(p, fd, &krnl_msg, flags);
+	return rtdm_fd_sendmsg(xnsys_ppd_get(0), fd, &m, flags);
+}
+
+int sys_rtdm_close(int fd)
+{
+	return rtdm_fd_close(xnsys_ppd_get(0), fd, XNFD_MAGIC_ANY);
 }
 
 static void *rtdm_process_attach(void)
@@ -123,12 +111,10 @@ static void rtdm_process_detach(void *arg)
 {
 	struct rtdm_process *process = arg;
 
-	cleanup_process_files(process);
 	kfree(process);
 }
 
 static struct xnsyscall rtdm_syscalls[] = {
-	SKINCALL_DEF(sc_rtdm_fdcount, sys_rtdm_fdcount, any),
 	SKINCALL_DEF(sc_rtdm_open, sys_rtdm_open, probing),
 	SKINCALL_DEF(sc_rtdm_socket, sys_rtdm_socket, probing),
 	SKINCALL_DEF(sc_rtdm_close, sys_rtdm_close, probing),
diff --git a/kernel/cobalt/shadow.c b/kernel/cobalt/shadow.c
index 0d045dc..3ed6e0f 100644
--- a/kernel/cobalt/shadow.c
+++ b/kernel/cobalt/shadow.c
@@ -58,6 +58,7 @@
 #include <cobalt/kernel/ppd.h>
 #include <cobalt/kernel/vdso.h>
 #include <cobalt/kernel/thread.h>
+#include <rtdm/fd.h>
 #include <asm/xenomai/features.h>
 #include <asm/xenomai/syscall.h>
 #include <asm-generic/xenomai/mayday.h>
@@ -1601,6 +1602,7 @@ static void user_process_detach(void *arg)
 
 	if (p->exe_path)
 		kfree(p->exe_path);
+	rtdm_fd_cleanup(p);
 	process_hash_remove(process);
 	xnheap_destroy_mapped(&p->sem_heap, post_ppd_release, NULL);
 	atomic_dec(&personalities[user_muxid]->refcnt);
@@ -1648,6 +1650,7 @@ static void *user_process_attach(void)
 		exe_path = NULL; /* Not lethal, but weird. */
 	}
 	p->exe_path = exe_path;
+	xntree_init(&p->fds);
 	atomic_set(&p->refcnt, 1);
 	atomic_inc(&personalities[user_muxid]->refcnt);
 
diff --git a/lib/cobalt/init.c b/lib/cobalt/init.c
index e68094b..f774f2d 100644
--- a/lib/cobalt/init.c
+++ b/lib/cobalt/init.c
@@ -49,8 +49,6 @@ pthread_t __cobalt_main_tid;
 
 int __rtdm_muxid = -1;
 
-int __rtdm_fd_start = INT_MAX;
-
 static void sigill_handler(int sig)
 {
 	const char m[] = "no Xenomai support in kernel?\n";
@@ -151,11 +149,8 @@ void __libcobalt_init(void)
 	breq.feat_req = XENOMAI_FEAT_DEP;
 	breq.abi_rev = XENOMAI_ABI_REV;
 	muxid = XENOMAI_SYSBIND(RTDM_BINDING_MAGIC, &breq);
-	if (muxid > 0) {
+	if (muxid > 0)
 		__rtdm_muxid = __xn_mux_shifted_id(muxid);
-		__rtdm_fd_start = FD_SETSIZE - XENOMAI_SKINCALL0(__rtdm_muxid,
-								 sc_rtdm_fdcount);
-	}
 
 	/*
 	 * Upon fork, in case the parent required init deferral, this
diff --git a/lib/cobalt/rtdm.c b/lib/cobalt/rtdm.c
index e789d76..cb27697 100644
--- a/lib/cobalt/rtdm.c
+++ b/lib/cobalt/rtdm.c
@@ -26,10 +26,11 @@
 #include <sys/socket.h>
 #include <rtdm/rtdm.h>
 #include <cobalt/uapi/rtdm/syscall.h>
+#include <cobalt/uapi/syscall.h>
 #include <asm/xenomai/syscall.h>
 
 extern int __rtdm_muxid;
-extern int __rtdm_fd_start;
+extern int __cobalt_muxid;
 
 static inline int set_errno(int ret)
 {
@@ -42,8 +43,13 @@ static inline int set_errno(int ret)
 
 COBALT_IMPL(int, open, (const char *path, int oflag, ...))
 {
-	int ret, oldtype;
+	int ret, fd, oldtype;
 	const char *rtdm_path = path;
+	va_list ap;
+
+	fd = __STD(open("/dev/null", O_RDONLY));
+	if (fd < 0)
+		return fd;
 
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
@@ -51,78 +57,78 @@ COBALT_IMPL(int, open, (const char *path, int oflag, ...))
 	if (strncmp(path, "/dev/", 5) == 0)
 		rtdm_path += 5;
 
-	ret = XENOMAI_SKINCALL2(__rtdm_muxid, sc_rtdm_open, rtdm_path, oflag);
+	ret = XENOMAI_SKINCALL3(__rtdm_muxid, 
+				sc_rtdm_open, 
+				fd, rtdm_path, oflag);
 
 	pthread_setcanceltype(oldtype, NULL);
 
-	if (ret >= 0)
-		ret += __rtdm_fd_start;
-	else if (ret == -ENODEV || ret == -ENOSYS) {
-		va_list ap;
-
-		va_start(ap, oflag);
-
-		ret = __STD(open(path, oflag, va_arg(ap, mode_t)));
+	if (ret == fd)
+		return fd;
+	__STD(close(fd));
 
-		va_end(ap);
+	if (ret != -ENODEV && ret != -ENOSYS)
+		return set_errno(ret);
 
-		if (ret >= __rtdm_fd_start) {
-			__STD(close(ret));
-			errno = EMFILE;
-			ret = -1;
-		}
-	} else {
-		errno = -ret;
-		ret = -1;
-	}
+	va_start(ap, oflag);
+	ret = __STD(open(path, oflag, va_arg(ap, mode_t)));
+	va_end(ap);
 
 	return ret;
 }
 
 COBALT_IMPL(int, socket, (int protocol_family, int socket_type, int protocol))
 {
-	int ret;
+	int ret, fd;
 
-	ret = XENOMAI_SKINCALL3(__rtdm_muxid,
+	fd = __STD(open("/dev/null", O_RDONLY));
+	if (fd < 0)
+		return fd;
+
+	ret = XENOMAI_SKINCALL4(__rtdm_muxid,
 				sc_rtdm_socket,
-				protocol_family, socket_type, protocol);
-	if (ret >= 0)
-		ret += __rtdm_fd_start;
-	else if (ret == -EAFNOSUPPORT || ret == -EPROTONOSUPPORT || 
-		 ret == -ENOSYS) {
-		ret = __STD(socket(protocol_family, socket_type, protocol));
-
-		if (ret >= __rtdm_fd_start) {
-			__STD(close(ret));
-			errno = -EMFILE;
-			ret = -1;
-		}
-	} else {
-		errno = -ret;
-		ret = -1;
-	}
+				fd, protocol_family, socket_type, protocol);
+	if (ret == fd)
+		return fd;
+	__STD(close(fd));
 
-	return ret;
+	if (ret != -EAFNOSUPPORT && ret != -EPROTONOSUPPORT && ret != -ENOSYS)
+		return set_errno(ret);
+	
+	return __STD(socket(protocol_family, socket_type, protocol));
 }
 
 COBALT_IMPL(int, close, (int fd))
 {
+	int oldtype;
 	int ret;
+	
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+	ret = XENOMAI_SKINCALL1(__rtdm_muxid, sc_rtdm_close, fd);
 
-	if (fd >= __rtdm_fd_start) {
-		int oldtype;
+	pthread_setcanceltype(oldtype, NULL);
 
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+	if (ret != -EBADF && ret != -ENOSYS) {
+		if (ret == 0)
+			__STD(close(fd));
+		return set_errno(ret);
+	}
 
-		ret = set_errno(XENOMAI_SKINCALL1(__rtdm_muxid,
-						  sc_rtdm_close,
-						  fd - __rtdm_fd_start));
+	return __STD(close(fd));
+}
 
-		pthread_setcanceltype(oldtype, NULL);
+static int __xn_ioctl(int fd, unsigned long request, void *arg)
+{
+	int ret, oldtype;
 
-		return ret;
-	} else
-		return __STD(close(fd));
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+	ret = XENOMAI_SKINCALL3(__rtdm_muxid,
+				sc_rtdm_ioctl, 
+				fd, request, arg);
+
+	pthread_setcanceltype(oldtype, NULL);
 
 	return ret;
 }
@@ -131,327 +137,269 @@ COBALT_IMPL(int, ioctl, (int fd, unsigned long int request, ...))
 {
 	va_list ap;
 	void *arg;
+	int ret;
 
 	va_start(ap, request);
 	arg = va_arg(ap, void *);
 	va_end(ap);
 
-	if (fd >= __rtdm_fd_start)
-		return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						   sc_rtdm_ioctl,
-						   fd - __rtdm_fd_start,
-						   request, arg));
-	else
-		return __STD(ioctl(fd, request, arg));
+	ret = __xn_ioctl(fd, request, arg);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+
+	return __STD(ioctl(fd, request, arg));
 }
 
 COBALT_IMPL(ssize_t, read, (int fd, void *buf, size_t nbyte))
 {
-	if (fd >= __rtdm_fd_start) {
-		int ret, oldtype;
-
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+	int ret, oldtype;
+	
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
-		ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						  sc_rtdm_read,
-						  fd - __rtdm_fd_start,
-						  buf, nbyte));
+	ret = XENOMAI_SKINCALL3(__rtdm_muxid, 
+				sc_rtdm_read, 
+				fd, buf, nbyte);
 
-		pthread_setcanceltype(oldtype, NULL);
+	pthread_setcanceltype(oldtype, NULL);
 
-		return ret;
-	} else
-		return __STD(read(fd, buf, nbyte));
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+		
+	return __STD(read(fd, buf, nbyte));
 }
 
 COBALT_IMPL(ssize_t, write, (int fd, const void *buf, size_t nbyte))
 {
-	if (fd >= __rtdm_fd_start) {
-		int ret, oldtype;
+	int ret, oldtype;
 
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
-		ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						  sc_rtdm_write,
-						  fd - __rtdm_fd_start,
-						  buf, nbyte));
+	ret = XENOMAI_SKINCALL3(__rtdm_muxid, 
+				sc_rtdm_write,
+				fd, buf, nbyte);
 
-		pthread_setcanceltype(oldtype, NULL);
+	pthread_setcanceltype(oldtype, NULL);
 
-		return ret;
-	} else
-		return __STD(write(fd, buf, nbyte));
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+
+	return __STD(write(fd, buf, nbyte));
 }
 
-COBALT_IMPL(ssize_t, recvmsg, (int fd, struct msghdr * msg, int flags))
+static ssize_t __xn_recvmsg(int fd, struct msghdr *msg, int flags)
 {
-	if (fd >= __rtdm_fd_start) {
-		int ret, oldtype;
+	int ret, oldtype;
 
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
-		ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						  sc_rtdm_recvmsg,
-						  fd - __rtdm_fd_start,
-						  msg, flags));
+	ret = XENOMAI_SKINCALL3(__rtdm_muxid, 
+				sc_rtdm_recvmsg, 
+				fd, msg, flags);
 
-		pthread_setcanceltype(oldtype, NULL);
+	pthread_setcanceltype(oldtype, NULL);
 
-		return ret;
-	} else
-		return __STD(recvmsg(fd, msg, flags));
+	return ret;
 }
 
-COBALT_IMPL(ssize_t, sendmsg, (int fd, const struct msghdr * msg, int flags))
+COBALT_IMPL(ssize_t, recvmsg, (int fd, struct msghdr *msg, int flags))
 {
-	if (fd >= __rtdm_fd_start) {
-		int ret, oldtype;
-
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
-
-		ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						  sc_rtdm_sendmsg,
-						  fd - __rtdm_fd_start,
-						  msg, flags));
+	int ret;
 
-		pthread_setcanceltype(oldtype, NULL);
+	ret = __xn_recvmsg(fd, msg, flags);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
 
-		return ret;
-	} else
-		return __STD(sendmsg(fd, msg, flags));
+	return __STD(recvmsg(fd, msg, flags));
 }
 
-COBALT_IMPL(ssize_t, recvfrom, (int fd, void *buf, size_t len, int flags,
-				struct sockaddr * from, socklen_t * fromlen))
+static ssize_t __xn_sendmsg(int fd, const struct msghdr *msg, int flags)
 {
-	if (fd >= __rtdm_fd_start) {
-		struct iovec iov = { buf, len };
-		struct msghdr msg =
-		    { from, (from != NULL) ? *fromlen : 0, &iov, 1, NULL, 0 };
-		int ret, oldtype;
+	int ret, oldtype;
 
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
-		ret = XENOMAI_SKINCALL3(__rtdm_muxid,
-					sc_rtdm_recvmsg,
-					fd - __rtdm_fd_start, &msg, flags);
+	ret = XENOMAI_SKINCALL3(__rtdm_muxid, 
+				sc_rtdm_sendmsg,
+				fd, msg, flags);
 
-		pthread_setcanceltype(oldtype, NULL);
+	pthread_setcanceltype(oldtype, NULL);
 
-		if (ret < 0) {
-			errno = -ret;
-			ret = -1;
-		} else if (from != NULL)
-			*fromlen = msg.msg_namelen;
-		return ret;
-	} else
-		return __STD(recvfrom(fd, buf, len, flags, from, fromlen));
+	return ret;
 }
 
-COBALT_IMPL(ssize_t, sendto, (int fd, const void *buf, size_t len, int flags,
-			      const struct sockaddr * to, socklen_t tolen))
+COBALT_IMPL(ssize_t, sendmsg, (int fd, const struct msghdr *msg, int flags))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct iovec iov = { (void *)buf, len };
-		struct msghdr msg =
-		    { (struct sockaddr *)to, tolen, &iov, 1, NULL, 0 };
-		int ret, oldtype;
+	int ret;
+	
+	ret = __xn_sendmsg(fd, msg, flags);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
 
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+	return __STD(sendmsg(fd, msg, flags));
+}
 
-		ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						  sc_rtdm_sendmsg,
-						  fd - __rtdm_fd_start,
-						  &msg, flags));
+COBALT_IMPL(ssize_t, recvfrom, (int fd, void *buf, size_t len, int flags,
+				struct sockaddr *from, socklen_t *fromlen))
+{
+	struct iovec iov = { buf, len };
+	struct msghdr msg =
+		{ from, (from != NULL) ? *fromlen : 0, &iov, 1, NULL, 0 };
+	int ret;
 
-		pthread_setcanceltype(oldtype, NULL);
+	ret = __xn_recvmsg(fd, &msg, flags);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
 
-		return ret;
-	} else
-		return __STD(sendto(fd, buf, len, flags, to, tolen));
+	return __STD(recvfrom(fd, buf, len, flags, from, fromlen));
 }
 
-COBALT_IMPL(ssize_t, recv, (int fd, void *buf, size_t len, int flags))
+COBALT_IMPL(ssize_t, sendto, (int fd, const void *buf, size_t len, int flags,
+			      const struct sockaddr *to, socklen_t tolen))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct iovec iov = { buf, len };
-		struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0 };
-		int ret, oldtype;
-
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+	struct iovec iov = { (void *)buf, len };
+	struct msghdr msg =
+		{ (struct sockaddr *)to, tolen, &iov, 1, NULL, 0 };
+	int ret;
+	
+	ret = __xn_sendmsg(fd, &msg, flags);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
 
-		ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						  sc_rtdm_recvmsg,
-						  fd - __rtdm_fd_start,
-						  &msg, flags));
+	return __STD(sendto(fd, buf, len, flags, to, tolen));
+}
 
-		pthread_setcanceltype(oldtype, NULL);
+COBALT_IMPL(ssize_t, recv, (int fd, void *buf, size_t len, int flags))
+{
+	struct iovec iov = { buf, len };
+	struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0 };
+	int ret;
+	
+	ret = __xn_recvmsg(fd, &msg, flags);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);	
 
-		return ret;
-	} else
-		return __STD(recv(fd, buf, len, flags));
+	return __STD(recv(fd, buf, len, flags));
 }
 
 COBALT_IMPL(ssize_t, send, (int fd, const void *buf, size_t len, int flags))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct iovec iov = { (void *)buf, len };
-		struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0 };
-		int ret, oldtype;
-
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
-
-		ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						  sc_rtdm_sendmsg,
-						  fd - __rtdm_fd_start,
-						  &msg, flags));
+	struct iovec iov = { (void *)buf, len };
+	struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0 };
+	int ret;
 
-		pthread_setcanceltype(oldtype, NULL);
+	ret = __xn_sendmsg(fd, &msg, flags);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);	
 
-		return ret;
-	} else
-		return __STD(send(fd, buf, len, flags));
+	return __STD(send(fd, buf, len, flags));
 }
 
 COBALT_IMPL(int, getsockopt, (int fd, int level, int optname, void *optval,
-			      socklen_t * optlen))
+			      socklen_t *optlen))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct _rtdm_getsockopt_args args =
-		    { level, optname, optval, optlen };
-
-		return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						   sc_rtdm_ioctl,
-						   fd - __rtdm_fd_start,
-						   _RTIOC_GETSOCKOPT, &args));
-	} else
-		return __STD(getsockopt(fd, level, optname, optval, optlen));
+	struct _rtdm_getsockopt_args args = { level, optname, optval, optlen };
+	int ret;
+	
+	ret = __xn_ioctl(fd, _RTIOC_GETSOCKOPT, &args);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+
+	return __STD(getsockopt(fd, level, optname, optval, optlen));
 }
 
 COBALT_IMPL(int, setsockopt, (int fd, int level, int optname, const void *optval,
 			      socklen_t optlen))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct _rtdm_setsockopt_args args =
-		    { level, optname, (void *)optval, optlen };
-
-		return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						   sc_rtdm_ioctl,
-						   fd - __rtdm_fd_start,
-						   _RTIOC_SETSOCKOPT, &args));
-	} else
-		return __STD(setsockopt(fd, level, optname, optval, optlen));
+	struct _rtdm_setsockopt_args args = { 
+		level, optname, (void *)optval, optlen 
+	};
+	int ret;
+	
+	ret = __xn_ioctl(fd, _RTIOC_SETSOCKOPT, &args);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+
+	return __STD(setsockopt(fd, level, optname, optval, optlen));
 }
 
 COBALT_IMPL(int, bind, (int fd, const struct sockaddr *my_addr, socklen_t addrlen))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct _rtdm_setsockaddr_args args = { my_addr, addrlen };
-
-		return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						   sc_rtdm_ioctl,
-						   fd - __rtdm_fd_start,
-						   _RTIOC_BIND, &args));
-	} else
-		return __STD(bind(fd, my_addr, addrlen));
+	struct _rtdm_setsockaddr_args args = { my_addr, addrlen };
+	int ret;
+	
+	ret = __xn_ioctl(fd, _RTIOC_BIND, &args);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+
+	return __STD(bind(fd, my_addr, addrlen));
 }
 
 COBALT_IMPL(int, connect, (int fd, const struct sockaddr *serv_addr, socklen_t addrlen))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct _rtdm_setsockaddr_args args = { serv_addr, addrlen };
-		int ret, oldtype;
-
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
-
-		ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						  sc_rtdm_ioctl,
-						  fd - __rtdm_fd_start,
-						  _RTIOC_CONNECT, &args));
-
-		pthread_setcanceltype(oldtype, NULL);
+	struct _rtdm_setsockaddr_args args = { serv_addr, addrlen };
+	int ret;
+	
+	ret = __xn_ioctl(fd, _RTIOC_CONNECT, &args);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
 
-		return ret;
-	} else
-		return __STD(connect(fd, serv_addr, addrlen));
+	return __STD(connect(fd, serv_addr, addrlen));
 }
 
 COBALT_IMPL(int, listen, (int fd, int backlog))
 {
-	if (fd >= __rtdm_fd_start) {
-		return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						   sc_rtdm_ioctl,
-						   fd - __rtdm_fd_start,
-						   _RTIOC_LISTEN, backlog));
-	} else
-		return __STD(listen(fd, backlog));
-}
-
-COBALT_IMPL(int, accept, (int fd, struct sockaddr *addr, socklen_t * addrlen))
-{
-	if (fd >= __rtdm_fd_start) {
-		struct _rtdm_getsockaddr_args args = { addr, addrlen };
-		int oldtype;
-
-		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
-
-		fd = XENOMAI_SKINCALL3(__rtdm_muxid,
-				       sc_rtdm_ioctl,
-				       fd - __rtdm_fd_start,
-				       _RTIOC_ACCEPT, &args);
-
-		pthread_setcanceltype(oldtype, NULL);
+	int ret;
 
-		if (fd < 0)
-			return set_errno(fd);
+	ret = __xn_ioctl(fd, _RTIOC_LISTEN, (void *)(long)backlog);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
 
-		return fd + __rtdm_fd_start;
-	} else {
-		fd = __STD(accept(fd, addr, addrlen));
+	return __STD(listen(fd, backlog));
+}
 
-		if (fd >= __rtdm_fd_start) {
-			__STD(close(fd));
-			errno = EMFILE;
-			fd = -1;
-		}
+COBALT_IMPL(int, accept, (int fd, struct sockaddr *addr, socklen_t *addrlen))
+{
+	struct _rtdm_getsockaddr_args args = { addr, addrlen };
+	int ret;
+	
+	ret = __xn_ioctl(fd, _RTIOC_ACCEPT, &args);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
 
-		return fd;
-	}
+	return __STD(accept(fd, addr, addrlen));
 }
 
 COBALT_IMPL(int, getsockname, (int fd, struct sockaddr *name, socklen_t *namelen))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct _rtdm_getsockaddr_args args = { name, namelen };
-
-		return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						   sc_rtdm_ioctl,
-						   fd - __rtdm_fd_start,
-						   _RTIOC_GETSOCKNAME, &args));
-	} else
-		return __STD(getsockname(fd, name, namelen));
+	struct _rtdm_getsockaddr_args args = { name, namelen };
+	int ret;
+	
+	ret = __xn_ioctl(fd, _RTIOC_GETSOCKNAME, &args);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+
+	return __STD(getsockname(fd, name, namelen));
 }
 
 COBALT_IMPL(int, getpeername, (int fd, struct sockaddr *name, socklen_t *namelen))
 {
-	if (fd >= __rtdm_fd_start) {
-		struct _rtdm_getsockaddr_args args = { name, namelen };
-
-		return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						   sc_rtdm_ioctl,
-						   fd - __rtdm_fd_start,
-						   _RTIOC_GETPEERNAME, &args));
-	} else
-		return __STD(getpeername(fd, name, namelen));
+	struct _rtdm_getsockaddr_args args = { name, namelen };
+	int ret;
+	
+	ret = __xn_ioctl(fd, _RTIOC_GETPEERNAME, &args);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+
+	return __STD(getpeername(fd, name, namelen));
 }
 
 COBALT_IMPL(int, shutdown, (int fd, int how))
 {
-	if (fd >= __rtdm_fd_start) {
-		return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
-						   sc_rtdm_ioctl,
-						   fd - __rtdm_fd_start,
-						   _RTIOC_SHUTDOWN, how));
-	} else
-		return __STD(shutdown(fd, how));
+	int ret;
+
+	ret = __xn_ioctl(fd, _RTIOC_SHUTDOWN, (void *)(long)how);
+	if (ret != -EBADF && ret != -ENOSYS)
+		return set_errno(ret);
+
+	return __STD(shutdown(fd, how));
 }
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 4/9] drivers/testing: adapt timerbench after RTDM changes
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 2/9] cobalt/rtdm: base named devices on nucleus registry Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 3/9] cobalt/rtdm: extract fd API Gilles Chanteperdrix
@ 2014-03-07 20:20   ` Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 5/9] drivers/testing: adapt switchtest " Gilles Chanteperdrix
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

---
 kernel/drivers/testing/timerbench.c |   90 +++++++++++++++--------------------
 1 file changed, 39 insertions(+), 51 deletions(-)

diff --git a/kernel/drivers/testing/timerbench.c b/kernel/drivers/testing/timerbench.c
index efb5ca2..4852703 100644
--- a/kernel/drivers/testing/timerbench.c
+++ b/kernel/drivers/testing/timerbench.c
@@ -189,12 +189,11 @@ static void timer_proc(rtdm_timer_t *timer)
 	} while (err);
 }
 
-static int rt_tmbench_open(struct rtdm_dev_context *context,
-			   rtdm_user_info_t *user_info, int oflags)
+static int rt_tmbench_open(struct rtdm_fd *context, int oflags)
 {
 	struct rt_tmbench_context *ctx;
 
-	ctx = (struct rt_tmbench_context *)context->dev_private;
+	ctx = rtdm_context_to_private(context);
 
 	ctx->mode = RTTST_TMBENCH_INVALID;
 	sema_init(&ctx->nrt_mutex, 1);
@@ -202,12 +201,11 @@ static int rt_tmbench_open(struct rtdm_dev_context *context,
 	return 0;
 }
 
-static int rt_tmbench_close(struct rtdm_dev_context *context,
-			    rtdm_user_info_t *user_info)
+static void rt_tmbench_close(struct rtdm_fd *context)
 {
 	struct rt_tmbench_context *ctx;
 
-	ctx = (struct rt_tmbench_context *)context->dev_private;
+	ctx = rtdm_context_to_private(context);
 
 	down(&ctx->nrt_mutex);
 
@@ -227,13 +225,10 @@ static int rt_tmbench_close(struct rtdm_dev_context *context,
 	}
 
 	up(&ctx->nrt_mutex);
-
-	return 0;
 }
 
-static int rt_tmbench_start(struct rtdm_dev_context *context,
+static int rt_tmbench_start(struct rtdm_fd *context,
 			    struct rt_tmbench_context *ctx,
-			    rtdm_user_info_t *user_info,
 			    struct rttst_tmbench_config __user *user_config)
 {
 	int err = 0;
@@ -242,9 +237,9 @@ static int rt_tmbench_start(struct rtdm_dev_context *context,
 	struct rttst_tmbench_config *config =
 		(struct rttst_tmbench_config *)user_config;
 
-	if (user_info) {
+	if (rtdm_context_user_p(context)) {
 		if (rtdm_safe_copy_from_user
-		    (user_info, &config_buf,user_config,
+		    (context, &config_buf,user_config,
 		     sizeof(struct rttst_tmbench_config)) < 0)
 			return -EFAULT;
 
@@ -295,33 +290,28 @@ static int rt_tmbench_start(struct rtdm_dev_context *context,
 	rtdm_event_init(&ctx->result_event, 0);
 
 	if (config->mode == RTTST_TMBENCH_TASK) {
-		if (!test_bit(RTDM_CLOSING, &context->context_flags)) {
-			err = rtdm_task_init(&ctx->timer_task, "timerbench",
-					     timer_task_proc, ctx,
-					     config->priority, 0);
-			if (!err)
-				ctx->mode = RTTST_TMBENCH_TASK;
-		}
+		err = rtdm_task_init(&ctx->timer_task, "timerbench",
+				timer_task_proc, ctx,
+				config->priority, 0);
+		if (!err)
+			ctx->mode = RTTST_TMBENCH_TASK;
 	} else {
 		rtdm_timer_init(&ctx->timer, timer_proc,
-				context->device->device_name);
+				rtdm_context_device(context)->device_name);
 
 		ctx->curr.test_loops = 0;
 
-		if (!test_bit(RTDM_CLOSING, &context->context_flags)) {
-			ctx->mode = RTTST_TMBENCH_HANDLER;
+		ctx->mode = RTTST_TMBENCH_HANDLER;
 
-			RTDM_EXECUTE_ATOMICALLY(
-				ctx->start_time = rtdm_clock_read_monotonic();
+		RTDM_EXECUTE_ATOMICALLY(
+			ctx->start_time = rtdm_clock_read_monotonic();
 
-				/* first event: one millisecond from now. */
-				ctx->date = ctx->start_time + 1000000;
+			/* first event: one millisecond from now. */
+			ctx->date = ctx->start_time + 1000000;
 
-				err =
-				    rtdm_timer_start(&ctx->timer, ctx->date, 0,
-						     RTDM_TIMERMODE_ABSOLUTE);
-			);
-		}
+			err = rtdm_timer_start(&ctx->timer, ctx->date, 0,
+					RTDM_TIMERMODE_ABSOLUTE);
+					);
 	}
 
 	up(&ctx->nrt_mutex);
@@ -330,9 +320,9 @@ static int rt_tmbench_start(struct rtdm_dev_context *context,
 }
 
 static int rt_tmbench_stop(struct rt_tmbench_context *ctx,
-			   rtdm_user_info_t *user_info,
 			   struct rttst_overall_bench_res __user *user_res)
 {
+	struct rtdm_fd *context = rtdm_private_to_context(ctx);
 	int err = 0;
 
 	down(&ctx->nrt_mutex);
@@ -356,8 +346,8 @@ static int rt_tmbench_stop(struct rt_tmbench_context *ctx,
 		   ((ctx->result.overall.test_loops) > 1 ?
 		    ctx->result.overall.test_loops : 2) - 1);
 
-	if (user_info)
-		err = rtdm_safe_copy_to_user(user_info, &user_res->result,
+	if (rtdm_context_user_p(context))
+		err = rtdm_safe_copy_to_user(context, &user_res->result,
 					     &ctx->result.overall,
 					     sizeof(struct rttst_bench_res));
 		/* Do not break on error here - we may have to free a
@@ -373,19 +363,19 @@ static int rt_tmbench_stop(struct rt_tmbench_context *ctx,
 	if (ctx->histogram_size > 0) {
 		int size = ctx->histogram_size * sizeof(long);
 
-		if (user_info) {
+		if (rtdm_context_user_p(context)) {
 			struct rttst_overall_bench_res res_buf;
 
-			if (rtdm_safe_copy_from_user(user_info,
+			if (rtdm_safe_copy_from_user(context,
 						     &res_buf, user_res,
 						     sizeof(res_buf)) < 0 ||
-			    rtdm_safe_copy_to_user(user_info,
+			    rtdm_safe_copy_to_user(context,
 				    (void __user *)res_buf.histogram_min,
 				    ctx->histogram_min, size) < 0 ||
-			    rtdm_safe_copy_to_user(user_info,
+			    rtdm_safe_copy_to_user(context,
 				    (void __user *)res_buf.histogram_max,
 				    ctx->histogram_max, size) < 0 ||
-			    rtdm_safe_copy_to_user(user_info,
+			    rtdm_safe_copy_to_user(context,
 				    (void __user *)res_buf.histogram_avg,
 				    ctx->histogram_avg, size) < 0)
 				err = -EFAULT;
@@ -406,22 +396,21 @@ static int rt_tmbench_stop(struct rt_tmbench_context *ctx,
 	return err;
 }
 
-static int rt_tmbench_ioctl_nrt(struct rtdm_dev_context *context,
-				rtdm_user_info_t *user_info,
+static int rt_tmbench_ioctl_nrt(struct rtdm_fd *context,
 				unsigned int request, void __user *arg)
 {
 	struct rt_tmbench_context *ctx;
 	int err = 0;
 
-	ctx = (struct rt_tmbench_context *)context->dev_private;
+	ctx = rtdm_context_to_private(context);
 
 	switch (request) {
 	case RTTST_RTIOC_TMBENCH_START:
-		err = rt_tmbench_start(context, ctx, user_info, arg);
+		err = rt_tmbench_start(context, ctx, arg);
 		break;
 
 	case RTTST_RTIOC_TMBENCH_STOP:
-		err = rt_tmbench_stop(ctx, user_info, arg);
+		err = rt_tmbench_stop(ctx, arg);
 		break;
 
 	case RTTST_RTIOC_INTERM_BENCH_RES:
@@ -435,14 +424,13 @@ static int rt_tmbench_ioctl_nrt(struct rtdm_dev_context *context,
 	return err;
 }
 
-static int rt_tmbench_ioctl_rt(struct rtdm_dev_context *context,
-			       rtdm_user_info_t *user_info,
+static int rt_tmbench_ioctl_rt(struct rtdm_fd *context,
 			       unsigned int request, void __user *arg)
 {
 	struct rt_tmbench_context *ctx;
 	int err = 0;
 
-	ctx = (struct rt_tmbench_context *)context->dev_private;
+	ctx = rtdm_context_to_private(context);
 
 	switch (request) {
 	case RTTST_RTIOC_INTERM_BENCH_RES:
@@ -450,10 +438,10 @@ static int rt_tmbench_ioctl_rt(struct rtdm_dev_context *context,
 		if (err)
 			return err;
 
-		if (user_info) {
+		if (rtdm_context_user_p(context)) {
 			struct rttst_interm_bench_res __user *user_res = arg;
 
-			err = rtdm_safe_copy_to_user(user_info, user_res,
+			err = rtdm_safe_copy_to_user(context, user_res,
 						     &ctx->result,
 						     sizeof(*user_res));
 		} else {
@@ -483,10 +471,10 @@ static struct rtdm_device device = {
 	.context_size		= sizeof(struct rt_tmbench_context),
 	.device_name		= "",
 
-	.open_nrt		= rt_tmbench_open,
+	.open			= rt_tmbench_open,
 
 	.ops = {
-		.close_nrt	= rt_tmbench_close,
+		.close		= rt_tmbench_close,
 
 		.ioctl_rt	= rt_tmbench_ioctl_rt,
 		.ioctl_nrt	= rt_tmbench_ioctl_nrt,
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 5/9] drivers/testing: adapt switchtest after RTDM changes
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
                     ` (2 preceding siblings ...)
  2014-03-07 20:20   ` [Xenomai] [PATCH 4/9] drivers/testing: adapt timerbench after RTDM changes Gilles Chanteperdrix
@ 2014-03-07 20:20   ` Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 6/9] drivers/testing: adapt rtdmtest " Gilles Chanteperdrix
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

---
 kernel/drivers/testing/switchtest.c |  111 ++++++++++++++---------------------
 1 file changed, 45 insertions(+), 66 deletions(-)

diff --git a/kernel/drivers/testing/switchtest.c b/kernel/drivers/testing/switchtest.c
index f48c4e2..d88625b 100644
--- a/kernel/drivers/testing/switchtest.c
+++ b/kernel/drivers/testing/switchtest.c
@@ -511,11 +511,9 @@ static void rtswitch_utask_waker(rtdm_nrtsig_t sig, void *arg)
 	up(&ctx->utask->nrt_synch);
 }
 
-static int rtswitch_open(struct rtdm_dev_context *context,
-			 rtdm_user_info_t *user_info,
-			 int oflags)
+static int rtswitch_open(struct rtdm_fd *context, int oflags)
 {
-	rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private;
+	rtswitch_context_t *ctx = rtdm_context_to_private(context);
 	int err;
 
 	ctx->tasks = NULL;
@@ -534,10 +532,9 @@ static int rtswitch_open(struct rtdm_dev_context *context,
 	return 0;
 }
 
-static int rtswitch_close(struct rtdm_dev_context *context,
-			  rtdm_user_info_t *user_info)
+static void rtswitch_close(struct rtdm_fd *context)
 {
-	rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private;
+	rtswitch_context_t *ctx = rtdm_context_to_private(context);
 	unsigned i;
 
 	if (ctx->tasks) {
@@ -556,16 +553,13 @@ static int rtswitch_close(struct rtdm_dev_context *context,
 	}
 	rtdm_timer_destroy(&ctx->wake_up_delay);
 	rtdm_nrtsig_destroy(&ctx->wake_utask);
-
-	return 0;
 }
 
-static int rtswitch_ioctl_nrt(struct rtdm_dev_context *context,
-			      rtdm_user_info_t *user_info,
+static int rtswitch_ioctl_nrt(struct rtdm_fd *context,
 			      unsigned int request,
 			      void *arg)
 {
-	rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private;
+	rtswitch_context_t *ctx = rtdm_context_to_private(context);
 	struct rttst_swtest_task task;
 	struct rttst_swtest_dir fromto;
 	unsigned long count;
@@ -588,15 +582,15 @@ static int rtswitch_ioctl_nrt(struct rtdm_dev_context *context,
 		return 0;
 
 	case RTTST_RTIOC_SWTEST_REGISTER_UTASK:
-		if (!rtdm_rw_user_ok(user_info, arg, sizeof(task)))
+		if (!rtdm_rw_user_ok(context, arg, sizeof(task)))
 			return -EFAULT;
 
-		rtdm_copy_from_user(user_info, &task, arg, sizeof(task));
+		rtdm_copy_from_user(context, &task, arg, sizeof(task));
 
 		err = rtswitch_register_task(ctx, &task);
 
 		if (!err)
-			rtdm_copy_to_user(user_info,
+			rtdm_copy_to_user(context,
 					  arg,
 					  &task,
 					  sizeof(task));
@@ -604,15 +598,15 @@ static int rtswitch_ioctl_nrt(struct rtdm_dev_context *context,
 		return err;
 
 	case RTTST_RTIOC_SWTEST_CREATE_KTASK:
-		if (!rtdm_rw_user_ok(user_info, arg, sizeof(task)))
+		if (!rtdm_rw_user_ok(context, arg, sizeof(task)))
 			return -EFAULT;
 
-		rtdm_copy_from_user(user_info, &task, arg, sizeof(task));
+		rtdm_copy_from_user(context, &task, arg, sizeof(task));
 
 		err = rtswitch_create_ktask(ctx, &task);
 
 		if (!err)
-			rtdm_copy_to_user(user_info,
+			rtdm_copy_to_user(context,
 					  arg,
 					  &task,
 					  sizeof(task));
@@ -620,18 +614,18 @@ static int rtswitch_ioctl_nrt(struct rtdm_dev_context *context,
 		return err;
 
 	case RTTST_RTIOC_SWTEST_PEND:
-		if (!rtdm_read_user_ok(user_info, arg, sizeof(task)))
+		if (!rtdm_read_user_ok(context, arg, sizeof(task)))
 			return -EFAULT;
 
-		rtdm_copy_from_user(user_info, &task, arg, sizeof(task));
+		rtdm_copy_from_user(context, &task, arg, sizeof(task));
 
 		return rtswitch_pend_nrt(ctx, task.index);
 
 	case RTTST_RTIOC_SWTEST_SWITCH_TO:
-		if (!rtdm_read_user_ok(user_info, arg, sizeof(fromto)))
+		if (!rtdm_read_user_ok(context, arg, sizeof(fromto)))
 			return -EFAULT;
 
-		rtdm_copy_from_user(user_info,
+		rtdm_copy_from_user(context,
 				    &fromto,
 				    arg,
 				    sizeof(fromto));
@@ -639,20 +633,20 @@ static int rtswitch_ioctl_nrt(struct rtdm_dev_context *context,
 		return rtswitch_to_nrt(ctx, fromto.from, fromto.to);
 
 	case RTTST_RTIOC_SWTEST_GET_SWITCHES_COUNT:
-		if (!rtdm_rw_user_ok(user_info, arg, sizeof(count)))
+		if (!rtdm_rw_user_ok(context, arg, sizeof(count)))
 			return -EFAULT;
 
 		count = ctx->switches_count;
 
-		rtdm_copy_to_user(user_info, arg, &count, sizeof(count));
+		rtdm_copy_to_user(context, arg, &count, sizeof(count));
 
 		return 0;
 
 	case RTTST_RTIOC_SWTEST_GET_LAST_ERROR:
-		if (!rtdm_rw_user_ok(user_info, arg, sizeof(ctx->error)))
+		if (!rtdm_rw_user_ok(context, arg, sizeof(ctx->error)))
 			return -EFAULT;
 
-		rtdm_copy_to_user(user_info,
+		rtdm_copy_to_user(context,
 				  arg,
 				  &ctx->error,
 				  sizeof(ctx->error));
@@ -664,12 +658,11 @@ static int rtswitch_ioctl_nrt(struct rtdm_dev_context *context,
 	}
 }
 
-static int rtswitch_ioctl_rt(struct rtdm_dev_context *context,
-			     rtdm_user_info_t *user_info,
+static int rtswitch_ioctl_rt(struct rtdm_fd *context,
 			     unsigned int request,
 			     void *arg)
 {
-	rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private;
+	rtswitch_context_t *ctx = rtdm_context_to_private(context);
 	struct rttst_swtest_task task;
 	struct rttst_swtest_dir fromto;
 
@@ -680,18 +673,18 @@ static int rtswitch_ioctl_rt(struct rtdm_dev_context *context,
 		return -ENOSYS;
 
 	case RTTST_RTIOC_SWTEST_PEND:
-		if (!rtdm_read_user_ok(user_info, arg, sizeof(task)))
+		if (!rtdm_read_user_ok(context, arg, sizeof(task)))
 			return -EFAULT;
 
-		rtdm_copy_from_user(user_info, &task, arg, sizeof(task));
+		rtdm_copy_from_user(context, &task, arg, sizeof(task));
 
 		return rtswitch_pend_rt(ctx, task.index);
 
 	case RTTST_RTIOC_SWTEST_SWITCH_TO:
-		if (!rtdm_read_user_ok(user_info, arg, sizeof(fromto)))
+		if (!rtdm_read_user_ok(context, arg, sizeof(fromto)))
 			return -EFAULT;
 
-		rtdm_copy_from_user(user_info,
+		rtdm_copy_from_user(context,
 				    &fromto,
 				    arg,
 				    sizeof(fromto));
@@ -699,10 +692,10 @@ static int rtswitch_ioctl_rt(struct rtdm_dev_context *context,
 		return rtswitch_to_rt(ctx, fromto.from, fromto.to);
 
 	case RTTST_RTIOC_SWTEST_GET_LAST_ERROR:
-		if (!rtdm_rw_user_ok(user_info, arg, sizeof(ctx->error)))
+		if (!rtdm_rw_user_ok(context, arg, sizeof(ctx->error)))
 			return -EFAULT;
 
-		rtdm_copy_to_user(user_info,
+		rtdm_copy_to_user(context,
 				  arg,
 				  &ctx->error,
 				  sizeof(ctx->error));
@@ -715,43 +708,29 @@ static int rtswitch_ioctl_rt(struct rtdm_dev_context *context,
 }
 
 static struct rtdm_device device = {
-	struct_version: RTDM_DEVICE_STRUCT_VER,
-
-	device_flags: RTDM_NAMED_DEVICE,
-	context_size: sizeof(rtswitch_context_t),
-	device_name:  "",
-
-	open_rt: NULL,
-	open_nrt: rtswitch_open,
-
-	ops: {
-		close_rt: NULL,
-		close_nrt: rtswitch_close,
-
-		ioctl_rt: rtswitch_ioctl_rt,
-		ioctl_nrt: rtswitch_ioctl_nrt,
+	.struct_version = RTDM_DEVICE_STRUCT_VER,
 
-		read_rt: NULL,
-		read_nrt: NULL,
+	.device_flags = RTDM_NAMED_DEVICE,
+	.context_size = sizeof(rtswitch_context_t),
+	.device_name = "",
 
-		write_rt: NULL,
-		write_nrt: NULL,
+	.open = rtswitch_open,
 
-		recvmsg_rt: NULL,
-		recvmsg_nrt: NULL,
+	.ops = {
+		.close = rtswitch_close,
 
-		sendmsg_rt: NULL,
-		sendmsg_nrt: NULL,
+		.ioctl_rt = rtswitch_ioctl_rt,
+		.ioctl_nrt = rtswitch_ioctl_nrt,
 	},
 
-	device_class: RTDM_CLASS_TESTING,
-	device_sub_class: RTDM_SUBCLASS_SWITCHTEST,
-	profile_version: RTTST_PROFILE_VER,
-	driver_name: "xeno_switchtest",
-	driver_version: RTDM_DRIVER_VER(0, 1, 1),
-	peripheral_name: "Context Switch Test",
-	provider_name: "Gilles Chanteperdrix",
-	proc_name: device.device_name,
+	.device_class = RTDM_CLASS_TESTING,
+	.device_sub_class = RTDM_SUBCLASS_SWITCHTEST,
+	.profile_version = RTTST_PROFILE_VER,
+	.driver_name = "xeno_switchtest",
+	.driver_version = RTDM_DRIVER_VER(0, 1, 1),
+	.peripheral_name = "Context Switch Test",
+	.provider_name = "Gilles Chanteperdrix",
+	.proc_name = device.device_name,
 };
 
 int __init __switchtest_init(void)
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 6/9] drivers/testing: adapt rtdmtest after RTDM changes
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
                     ` (3 preceding siblings ...)
  2014-03-07 20:20   ` [Xenomai] [PATCH 5/9] drivers/testing: adapt switchtest " Gilles Chanteperdrix
@ 2014-03-07 20:20   ` Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 7/9] drivers/ipc: adapt XDDP " Gilles Chanteperdrix
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

---
 include/rtdm/uapi/testing.h       |    3 +--
 kernel/drivers/testing/rtdmtest.c |   54 ++++++++++++-------------------------
 testsuite/unit/rtdm.c             |   11 --------
 3 files changed, 18 insertions(+), 50 deletions(-)

diff --git a/include/rtdm/uapi/testing.h b/include/rtdm/uapi/testing.h
index 87a97fd..76d9678 100644
--- a/include/rtdm/uapi/testing.h
+++ b/include/rtdm/uapi/testing.h
@@ -103,8 +103,7 @@ struct rttst_swtest_error {
 };
 
 #define RTTST_RTDM_NORMAL_CLOSE		0
-#define RTTST_RTDM_DEFER_CLOSE_HANDLER	1
-#define RTTST_RTDM_DEFER_CLOSE_CONTEXT	2
+#define RTTST_RTDM_DEFER_CLOSE_CONTEXT	1
 
 #define RTIOC_TYPE_TESTING		RTDM_CLASS_TESTING
 
diff --git a/kernel/drivers/testing/rtdmtest.c b/kernel/drivers/testing/rtdmtest.c
index c107d07..ddb8786 100644
--- a/kernel/drivers/testing/rtdmtest.c
+++ b/kernel/drivers/testing/rtdmtest.c
@@ -48,11 +48,9 @@ static void close_timer_proc(rtdm_timer_t *timer)
 	rtdm_context_unlock(rtdm_private_to_context(ctx));
 }
 
-static int rtdm_test_open(struct rtdm_dev_context *context,
-			  rtdm_user_info_t *user_info, int oflags)
+static int rtdm_test_open(struct rtdm_fd *context, int oflags)
 {
-	struct rtdm_test_context *ctx =
-		(struct rtdm_test_context *)context->dev_private;
+	struct rtdm_test_context *ctx = rtdm_context_to_private(context);
 
 	rtdm_timer_init(&ctx->close_timer, close_timer_proc,
 			"rtdm close test");
@@ -62,60 +60,42 @@ static int rtdm_test_open(struct rtdm_dev_context *context,
 	return 0;
 }
 
-static int rtdm_test_close(struct rtdm_dev_context *context,
-			   rtdm_user_info_t *user_info)
+static void rtdm_test_close(struct rtdm_fd *context)
 {
-	struct rtdm_test_context *ctx =
-		(struct rtdm_test_context *)context->dev_private;
+	struct rtdm_test_context *ctx = rtdm_context_to_private(context);
 
 	ctx->close_counter++;
 
 	switch (ctx->close_deferral) {
-	case RTTST_RTDM_DEFER_CLOSE_HANDLER:
-		if (ctx->close_counter <= 3)
-			return -EAGAIN;
-		if (ctx->close_counter > 4) {
-			printk(KERN_ERR
-			       "rtdmtest: %s: close_counter is %lu, "
-			       "should be 2!\n",
-			       __FUNCTION__, ctx->close_counter);
-			return 0;
-		}
-		break;
-
 	case RTTST_RTDM_DEFER_CLOSE_CONTEXT:
-		if (ctx->close_counter == 1) {
-			rtdm_context_lock(context);
-			rtdm_timer_start(&ctx->close_timer, 300000000ULL, 0,
-					 RTDM_TIMERMODE_RELATIVE);
-			return 0;
-		}
-		if (ctx->close_counter > 2) {
+		if (ctx->close_counter != 2) {
 			printk(KERN_ERR
 			       "rtdmtest: %s: close_counter is %lu, "
 			       "should be 2!\n",
 			       __FUNCTION__, ctx->close_counter);
-			return 0;
+			return;
 		}
 		break;
 	}
 
 	rtdm_timer_destroy(&ctx->close_timer);
-
-	return 0;
 }
 
-static int rtdm_test_ioctl(struct rtdm_dev_context *context,
-			   rtdm_user_info_t *user_info,
-			   unsigned int request, void __user *arg)
+static int 
+rtdm_test_ioctl(struct rtdm_fd *context, unsigned int request, void __user *arg)
 {
-	struct rtdm_test_context *ctx =
-		(struct rtdm_test_context *)context->dev_private;
+	struct rtdm_test_context *ctx = rtdm_context_to_private(context);
 	int err = 0;
 
 	switch (request) {
 	case RTTST_RTIOC_RTDM_DEFER_CLOSE:
 		ctx->close_deferral = (unsigned long)arg;
+		if (ctx->close_deferral == RTTST_RTDM_DEFER_CLOSE_CONTEXT) {
+			++ctx->close_counter;
+			rtdm_context_lock(context);
+			rtdm_timer_start(&ctx->close_timer, 300000000ULL, 0,
+					RTDM_TIMERMODE_RELATIVE);
+		}
 		break;
 
 	default:
@@ -132,10 +112,10 @@ static struct rtdm_device device[2] = { [0 ... 1] = {
 	.context_size		= sizeof(struct rtdm_test_context),
 	.device_name		= "",
 
-	.open_nrt		= rtdm_test_open,
+	.open			= rtdm_test_open,
 
 	.ops = {
-		.close_nrt	= rtdm_test_close,
+		.close		= rtdm_test_close,
 
 		.ioctl_rt	= rtdm_test_ioctl,
 		.ioctl_nrt	= rtdm_test_ioctl,
diff --git a/testsuite/unit/rtdm.c b/testsuite/unit/rtdm.c
index ba39ab8..890badd 100644
--- a/testsuite/unit/rtdm.c
+++ b/testsuite/unit/rtdm.c
@@ -75,17 +75,6 @@ int main(int argc, const char *argv[])
 	dev2 = check("open", open(devname2, O_RDWR), dev + 1);
 	check("close", close(dev2), 0);
 
-	printf("Defer close by driver handler\n");
-	check("ioctl", ioctl(dev, RTTST_RTIOC_RTDM_DEFER_CLOSE,
-			     RTTST_RTDM_DEFER_CLOSE_HANDLER), 0);
-	start = rt_timer_tsc();
-	check("close", close(dev), 0);
-	check("open", open(devname, O_RDWR), -EBUSY);
-	dev2 = check("open", open(devname2, O_RDWR), dev);
-	check("close", close(dev2), 0);
-	usleep(300000);
-	dev = check("open", open(devname, O_RDWR), dev);
-
 	printf("Defer close by pending reference\n");
 	check("ioctl", ioctl(dev, RTTST_RTIOC_RTDM_DEFER_CLOSE,
 			     RTTST_RTDM_DEFER_CLOSE_CONTEXT), 0);
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 7/9] drivers/ipc: adapt XDDP after RTDM changes
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
                     ` (4 preceding siblings ...)
  2014-03-07 20:20   ` [Xenomai] [PATCH 6/9] drivers/testing: adapt rtdmtest " Gilles Chanteperdrix
@ 2014-03-07 20:20   ` Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 8/9] drivers/ipc: adapt IDDP " Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 9/9] drivers/ipc: adapt BUFP " Gilles Chanteperdrix
  7 siblings, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

---
 kernel/drivers/ipc/internal.h |   26 +++++-----
 kernel/drivers/ipc/rtipc.c    |   67 +++++++++++-------------
 kernel/drivers/ipc/xddp.c     |  115 ++++++++++++++++++++++-------------------
 3 files changed, 104 insertions(+), 104 deletions(-)

diff --git a/kernel/drivers/ipc/internal.h b/kernel/drivers/ipc/internal.h
index 34985df..4422ba0 100644
--- a/kernel/drivers/ipc/internal.h
+++ b/kernel/drivers/ipc/internal.h
@@ -42,28 +42,28 @@ struct rtipc_protocol {
 	void (*proto_exit)(void);
 	struct {
 		int (*socket)(struct rtipc_private *priv,
-			      rtdm_user_info_t *user_info);
-		int (*close)(struct rtipc_private *priv,
-			     rtdm_user_info_t *user_info);
+			      struct rtdm_fd *context);
+		void (*close)(struct rtipc_private *priv,
+			struct rtdm_fd *context);
 		ssize_t (*recvmsg)(struct rtipc_private *priv,
-				   rtdm_user_info_t *user_info,
+				   struct rtdm_fd *context,
 				   struct msghdr *msg, int flags);
 		ssize_t (*sendmsg)(struct rtipc_private *priv,
-				   rtdm_user_info_t *user_info,
+				   struct rtdm_fd *context,
 				   const struct msghdr *msg, int flags);
 		ssize_t (*read)(struct rtipc_private *priv,
-				rtdm_user_info_t *user_info,
+				struct rtdm_fd *context,
 				void *buf, size_t len);
 		ssize_t (*write)(struct rtipc_private *priv,
-				 rtdm_user_info_t *user_info,
+				 struct rtdm_fd *context,
 				 const void *buf, size_t len);
 		int (*ioctl)(struct rtipc_private *priv,
-			     rtdm_user_info_t *user_info,
+			     struct rtdm_fd *context,
 			     unsigned int request, void *arg);
 	} proto_ops;
 };
 
-static inline void *rtipc_context_to_state(struct rtdm_dev_context *context)
+static inline void *rtipc_context_to_state(struct rtdm_fd *context)
 {
 	struct rtipc_private *p = rtdm_context_to_private(context);
 	return p->state;
@@ -97,16 +97,16 @@ static inline void rtipc_ns_to_timeval(struct timeval *tv, nanosecs_rel_t ns)
 	tv->tv_usec = nsecs / 1000;
 }
 
-int rtipc_get_arg(rtdm_user_info_t *user_info,
+int rtipc_get_arg(struct rtdm_fd *fd,
 		  void *dst, const void *src, size_t len);
 
-int rtipc_put_arg(rtdm_user_info_t *user_info,
+int rtipc_put_arg(struct rtdm_fd *fd,
 		  void *dst, const void *src, size_t len);
 
-int rtipc_get_sockaddr(rtdm_user_info_t *user_info,
+int rtipc_get_sockaddr(struct rtdm_fd *fd,
 		       const void *arg, struct sockaddr_ipc **saddrp);
 
-int rtipc_put_sockaddr(rtdm_user_info_t *user_info, void *arg,
+int rtipc_put_sockaddr(struct rtdm_fd *fd, void *arg,
 		       const struct sockaddr_ipc *saddr);
 
 ssize_t rtipc_get_iov_flatlen(struct iovec *iov, int iovlen);
diff --git a/kernel/drivers/ipc/rtipc.c b/kernel/drivers/ipc/rtipc.c
index 20c2a74..e9e815b 100644
--- a/kernel/drivers/ipc/rtipc.c
+++ b/kernel/drivers/ipc/rtipc.c
@@ -37,11 +37,11 @@ static struct rtipc_protocol *protocols[IPCPROTO_MAX] = {
 
 DEFINE_XNPTREE(rtipc_ptree, "rtipc");
 
-int rtipc_get_arg(rtdm_user_info_t *user_info,
+int rtipc_get_arg(struct rtdm_fd *context,
 		  void *dst, const void *src, size_t len)
 {
-	if (user_info) {
-		if (rtdm_safe_copy_from_user(user_info, dst, src, len))
+	if (rtdm_context_user_p(context)) {
+		if (rtdm_safe_copy_from_user(context, dst, src, len))
 			return -EFAULT;
 	} else
 		memcpy(dst, src, len);
@@ -49,11 +49,11 @@ int rtipc_get_arg(rtdm_user_info_t *user_info,
 	return 0;
 }
 
-int rtipc_put_arg(rtdm_user_info_t *user_info,
+int rtipc_put_arg(struct rtdm_fd *context,
 		  void *dst, const void *src, size_t len)
 {
-	if (user_info) {
-		if (rtdm_safe_copy_to_user(user_info, dst, src, len))
+	if (rtdm_context_user_p(context)) {
+		if (rtdm_safe_copy_to_user(context, dst, src, len))
 			return -EFAULT;
 	} else
 		memcpy(dst, src, len);
@@ -61,12 +61,12 @@ int rtipc_put_arg(rtdm_user_info_t *user_info,
 	return 0;
 }
 
-int rtipc_get_sockaddr(rtdm_user_info_t *user_info,
+int rtipc_get_sockaddr(struct rtdm_fd *context,
 		       const void *arg, struct sockaddr_ipc **saddrp)
 {
 	struct _rtdm_setsockaddr_args setaddr;
 
-	if (rtipc_get_arg(user_info,
+	if (rtipc_get_arg(context,
 			  &setaddr, arg, sizeof(setaddr)))
 		return -EFAULT;
 
@@ -74,7 +74,7 @@ int rtipc_get_sockaddr(rtdm_user_info_t *user_info,
 		if (setaddr.addrlen != sizeof(**saddrp))
 			return -EINVAL;
 
-		if (rtipc_get_arg(user_info, *saddrp,
+		if (rtipc_get_arg(context, *saddrp,
 				  setaddr.addr, sizeof(**saddrp)))
 			return -EFAULT;
 	} else {
@@ -86,29 +86,29 @@ int rtipc_get_sockaddr(rtdm_user_info_t *user_info,
 	return 0;
 }
 
-int rtipc_put_sockaddr(rtdm_user_info_t *user_info, void *arg,
+int rtipc_put_sockaddr(struct rtdm_fd *context, void *arg,
 		       const struct sockaddr_ipc *saddr)
 {
 	struct _rtdm_getsockaddr_args getaddr;
 	socklen_t len;
 
-	if (rtipc_get_arg(user_info,
+	if (rtipc_get_arg(context,
 			  &getaddr, arg, sizeof(getaddr)))
 		return -EFAULT;
 
-	if (rtipc_get_arg(user_info,
+	if (rtipc_get_arg(context,
 			  &len, getaddr.addrlen, sizeof(len)))
 		return -EFAULT;
 
 	if (len < sizeof(*saddr))
 		return -EINVAL;
 
-	if (rtipc_put_arg(user_info,
+	if (rtipc_put_arg(context,
 			  getaddr.addr, saddr, sizeof(*saddr)))
 		return -EFAULT;
 
 	len = sizeof(*saddr);
-	if (rtipc_put_arg(user_info,
+	if (rtipc_put_arg(context,
 			  getaddr.addrlen, &len, sizeof(len)))
 		return -EFAULT;
 
@@ -131,8 +131,7 @@ ssize_t rtipc_get_iov_flatlen(struct iovec *iov, int iovlen)
 	return len;
 }
 
-static int rtipc_socket(struct rtdm_dev_context *context,
-			rtdm_user_info_t *user_info, int protocol)
+static int rtipc_socket(struct rtdm_fd *context, int protocol)
 {
 	struct rtipc_protocol *proto;
 	struct rtipc_private *p;
@@ -155,15 +154,14 @@ static int rtipc_socket(struct rtdm_dev_context *context,
 	if (p->state == NULL)
 		return -ENOMEM;
 
-	ret = proto->proto_ops.socket(p, user_info);
+	ret = proto->proto_ops.socket(p, context);
 	if (ret)
 		kfree(p->state);
 
 	return ret;
 }
 
-static int rtipc_close(struct rtdm_dev_context *context,
-		       rtdm_user_info_t *user_info)
+static void rtipc_close(struct rtdm_fd *context)
 {
 	struct rtipc_private *p;
 
@@ -173,47 +171,42 @@ static int rtipc_close(struct rtdm_dev_context *context,
 	 * proto_ops.close() handler when appropriate (which may be
 	 * done asynchronously later, see XDDP).
 	 */
-	return p->proto->proto_ops.close(p, user_info);
+	p->proto->proto_ops.close(p, context);
 }
 
-static ssize_t rtipc_recvmsg(struct rtdm_dev_context *context,
-			     rtdm_user_info_t *user_info,
+static ssize_t rtipc_recvmsg(struct rtdm_fd *context,
 			     struct msghdr *msg, int flags)
 {
 	struct rtipc_private *p = rtdm_context_to_private(context);
-	return p->proto->proto_ops.recvmsg(p, user_info, msg, flags);
+	return p->proto->proto_ops.recvmsg(p, context, msg, flags);
 }
 
-static ssize_t rtipc_sendmsg(struct rtdm_dev_context *context,
-			     rtdm_user_info_t *user_info,
+static ssize_t rtipc_sendmsg(struct rtdm_fd *context,
 			     const struct msghdr *msg, int flags)
 {
 	struct rtipc_private *p = rtdm_context_to_private(context);
-	return p->proto->proto_ops.sendmsg(p, user_info, msg, flags);
+	return p->proto->proto_ops.sendmsg(p, context, msg, flags);
 }
 
-static ssize_t rtipc_read(struct rtdm_dev_context *context,
-			  rtdm_user_info_t *user_info,
+static ssize_t rtipc_read(struct rtdm_fd *context,
 			  void *buf, size_t len)
 {
 	struct rtipc_private *p = rtdm_context_to_private(context);
-	return p->proto->proto_ops.read(p, user_info, buf, len);
+	return p->proto->proto_ops.read(p, context, buf, len);
 }
 
-static ssize_t rtipc_write(struct rtdm_dev_context *context,
-			   rtdm_user_info_t *user_info,
+static ssize_t rtipc_write(struct rtdm_fd *context,
 			   const void *buf, size_t len)
 {
 	struct rtipc_private *p = rtdm_context_to_private(context);
-	return p->proto->proto_ops.write(p, user_info, buf, len);
+	return p->proto->proto_ops.write(p, context, buf, len);
 }
 
-static int rtipc_ioctl(struct rtdm_dev_context *context,
-		       rtdm_user_info_t *user_info,
+static int rtipc_ioctl(struct rtdm_fd *context,
 		       unsigned int request, void *arg)
 {
 	struct rtipc_private *p = rtdm_context_to_private(context);
-	return p->proto->proto_ops.ioctl(p, user_info, request, arg);
+	return p->proto->proto_ops.ioctl(p, context, request, arg);
 }
 
 static struct rtdm_device device = {
@@ -223,9 +216,9 @@ static struct rtdm_device device = {
 	.device_name	=	"rtipc",
 	.protocol_family=	PF_RTIPC,
 	.socket_type	=	SOCK_DGRAM,
-	.socket_nrt	=	rtipc_socket,
+	.socket		=	rtipc_socket,
 	.ops = {
-		.close_nrt	=	rtipc_close,
+		.close		=	rtipc_close,
 		.recvmsg_rt	=	rtipc_recvmsg,
 		.recvmsg_nrt	=	NULL,
 		.sendmsg_rt	=	rtipc_sendmsg,
diff --git a/kernel/drivers/ipc/xddp.c b/kernel/drivers/ipc/xddp.c
index 728a6ed..eef1ed7 100644
--- a/kernel/drivers/ipc/xddp.c
+++ b/kernel/drivers/ipc/xddp.c
@@ -42,7 +42,7 @@ struct xddp_socket {
 	size_t poolsz;
 	xnhandle_t handle;
 	char label[XNOBJECT_NAME_LEN];
-	int fd;			/* i.e. RTDM socket fd */
+	struct rtdm_fd *fd;			/* i.e. RTDM socket fd */
 
 	struct xddp_message *buffer;
 	int buffer_port;
@@ -56,7 +56,7 @@ struct xddp_socket {
 	nanosecs_rel_t timeout;	/* connect()/recvmsg() timeout */
 	size_t reqbufsz;	/* Requested streaming buffer size */
 
-	int (*monitor)(int s, int event, long arg);
+	int (*monitor)(struct rtdm_fd *fd, int event, long arg);
 	struct rtipc_private *priv;
 };
 
@@ -65,7 +65,7 @@ static struct sockaddr_ipc nullsa = {
 	.sipc_port = -1
 };
 
-static int portmap[CONFIG_XENO_OPT_PIPE_NRDEV]; /* indexes RTDM fildes */
+static struct rtdm_fd *portmap[CONFIG_XENO_OPT_PIPE_NRDEV]; /* indexes RTDM fildes */
 
 #define _XDDP_SYNCWAIT  0
 #define _XDDP_ATOMIC    1
@@ -219,7 +219,7 @@ static void __xddp_release_handler(void *skarg) /* nklock free */
 }
 
 static int xddp_socket(struct rtipc_private *priv,
-		       rtdm_user_info_t *user_info)
+		       struct rtdm_fd *context)
 {
 	struct xddp_socket *sk = priv->state;
 
@@ -245,26 +245,28 @@ static int xddp_socket(struct rtipc_private *priv,
 	return 0;
 }
 
-static int xddp_close(struct rtipc_private *priv,
-		      rtdm_user_info_t *user_info)
+static void xddp_close(struct rtipc_private *priv,
+		      struct rtdm_fd *context)
 {
 	struct xddp_socket *sk = priv->state;
 
 	sk->monitor = NULL;
 
 	if (!test_bit(_XDDP_BOUND, &sk->status))
-		return 0;
+		return;
 
-	portmap[sk->name.sipc_port] = -1;
+	RTDM_EXECUTE_ATOMICALLY(
+		portmap[sk->name.sipc_port] = NULL;
+	);
 
 	if (sk->handle)
 		xnregistry_remove(sk->handle);
 
-	return xnpipe_disconnect(sk->minor);
+	xnpipe_disconnect(sk->minor);
 }
 
 static ssize_t __xddp_recvmsg(struct rtipc_private *priv,
-			      rtdm_user_info_t *user_info,
+			      struct rtdm_fd *context,
 			      struct iovec *iov, int iovlen, int flags,
 			      struct sockaddr_ipc *saddr)
 {
@@ -304,7 +306,7 @@ static ssize_t __xddp_recvmsg(struct rtipc_private *priv,
 		if (iov[nvec].iov_len == 0)
 			continue;
 		vlen = wrlen >= iov[nvec].iov_len ? iov[nvec].iov_len : wrlen;
-		if (user_info) {
+		if (rtdm_context_user_p(context)) {
 			xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen);
 			ret = xnbufd_copy_from_kmem(&bufd, mbuf->data + rdoff, vlen);
 			xnbufd_unmap_uread(&bufd);
@@ -328,7 +330,7 @@ out:
 }
 
 static ssize_t xddp_recvmsg(struct rtipc_private *priv,
-			    rtdm_user_info_t *user_info,
+			    struct rtdm_fd *context,
 			    struct msghdr *msg, int flags)
 {
 	struct iovec iov[RTIPC_IOV_MAX];
@@ -348,23 +350,23 @@ static ssize_t xddp_recvmsg(struct rtipc_private *priv,
 		return -EINVAL;
 
 	/* Copy I/O vector in */
-	if (rtipc_get_arg(user_info, iov, msg->msg_iov,
+	if (rtipc_get_arg(context, iov, msg->msg_iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
-	ret = __xddp_recvmsg(priv, user_info,
+	ret = __xddp_recvmsg(priv, context,
 			     iov, msg->msg_iovlen, flags, &saddr);
 	if (ret <= 0)
 		return ret;
 
 	/* Copy the updated I/O vector back */
-	if (rtipc_put_arg(user_info, msg->msg_iov, iov,
+	if (rtipc_put_arg(context, msg->msg_iov, iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
 	/* Copy the source address if required. */
 	if (msg->msg_name) {
-		if (rtipc_put_arg(user_info, msg->msg_name,
+		if (rtipc_put_arg(context, msg->msg_name,
 				  &saddr, sizeof(saddr)))
 			return -EFAULT;
 		msg->msg_namelen = sizeof(struct sockaddr_ipc);
@@ -374,11 +376,11 @@ static ssize_t xddp_recvmsg(struct rtipc_private *priv,
 }
 
 static ssize_t xddp_read(struct rtipc_private *priv,
-			 rtdm_user_info_t *user_info,
+			 struct rtdm_fd *context,
 			 void *buf, size_t len)
 {
 	struct iovec iov = { .iov_base = buf, .iov_len = len };
-	return __xddp_recvmsg(priv, user_info, &iov, 1, 0, NULL);
+	return __xddp_recvmsg(priv, context, &iov, 1, 0, NULL);
 }
 
 static ssize_t __xddp_stream(struct xddp_socket *sk,
@@ -456,15 +458,15 @@ out:
 }
 
 static ssize_t __xddp_sendmsg(struct rtipc_private *priv,
-			      rtdm_user_info_t *user_info,
+			      struct rtdm_fd *context,
 			      struct iovec *iov, int iovlen, int flags,
 			      const struct sockaddr_ipc *daddr)
 {
 	ssize_t len, rdlen, wrlen, vlen, ret, sublen;
 	struct xddp_socket *sk = priv->state;
-	struct rtdm_dev_context *rcontext;
 	struct xddp_message *mbuf;
 	struct xddp_socket *rsk;
+	struct rtdm_fd *rcontext;
 	int nvec, to, from;
 	struct xnbufd bufd;
 
@@ -475,7 +477,12 @@ static ssize_t __xddp_sendmsg(struct rtipc_private *priv,
 	from = sk->name.sipc_port;
 	to = daddr->sipc_port;
 
-	rcontext = rtdm_context_get(portmap[to]);
+	RTDM_EXECUTE_ATOMICALLY(
+		rcontext = portmap[to];
+		if (rcontext && rtdm_context_lock(rcontext) < 0)
+			rcontext = NULL;
+	);
+	
 	if (rcontext == NULL)
 		return -ECONNRESET;
 
@@ -501,7 +508,7 @@ static ssize_t __xddp_sendmsg(struct rtipc_private *priv,
 			if (iov[nvec].iov_len == 0)
 				continue;
 			vlen = rdlen >= iov[nvec].iov_len ? iov[nvec].iov_len : rdlen;
-			if (user_info) {
+			if (rtdm_context_user_p(context)) {
 				xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen);
 				ret = __xddp_stream(rsk, from, &bufd);
 				xnbufd_unmap_uread(&bufd);
@@ -544,7 +551,7 @@ nostream:
 		if (iov[nvec].iov_len == 0)
 			continue;
 		vlen = rdlen >= iov[nvec].iov_len ? iov[nvec].iov_len : rdlen;
-		if (user_info) {
+		if (rtdm_context_user_p(context)) {
 			xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen);
 			ret = xnbufd_copy_to_kmem(mbuf->data + wrlen, &bufd, vlen);
 			xnbufd_unmap_uread(&bufd);
@@ -580,7 +587,7 @@ nostream:
 }
 
 static ssize_t xddp_sendmsg(struct rtipc_private *priv,
-			    rtdm_user_info_t *user_info,
+			    struct rtdm_fd *context,
 			    const struct msghdr *msg, int flags)
 {
 	struct xddp_socket *sk = priv->state;
@@ -608,7 +615,7 @@ static ssize_t xddp_sendmsg(struct rtipc_private *priv,
 			return -EINVAL;
 
 		/* Fetch the destination address to send to. */
-		if (rtipc_get_arg(user_info, &daddr,
+		if (rtipc_get_arg(context, &daddr,
 				  msg->msg_name, sizeof(daddr)))
 			return -EFAULT;
 
@@ -627,17 +634,17 @@ static ssize_t xddp_sendmsg(struct rtipc_private *priv,
 		return -EINVAL;
 
 	/* Copy I/O vector in */
-	if (rtipc_get_arg(user_info, iov, msg->msg_iov,
+	if (rtipc_get_arg(context, iov, msg->msg_iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
-	ret = __xddp_sendmsg(priv, user_info, iov,
+	ret = __xddp_sendmsg(priv, context, iov,
 			     msg->msg_iovlen, flags, &daddr);
 	if (ret <= 0)
 		return ret;
 
 	/* Copy updated I/O vector back */
-	if (rtipc_put_arg(user_info, msg->msg_iov, iov,
+	if (rtipc_put_arg(context, msg->msg_iov, iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
@@ -645,7 +652,7 @@ static ssize_t xddp_sendmsg(struct rtipc_private *priv,
 }
 
 static ssize_t xddp_write(struct rtipc_private *priv,
-			  rtdm_user_info_t *user_info,
+			  struct rtdm_fd *context,
 			  const void *buf, size_t len)
 {
 	struct iovec iov = { .iov_base = (void *)buf, .iov_len = len };
@@ -654,7 +661,7 @@ static ssize_t xddp_write(struct rtipc_private *priv,
 	if (sk->peer.sipc_port < 0)
 		return -EDESTADDRREQ;
 
-	return __xddp_sendmsg(priv, user_info, &iov, 1, 0, &sk->peer);
+	return __xddp_sendmsg(priv, context, &iov, 1, 0, &sk->peer);
 }
 
 static int __xddp_bind_socket(struct rtipc_private *priv,
@@ -711,7 +718,7 @@ static int __xddp_bind_socket(struct rtipc_private *priv,
 		sk->curbufsz = sk->reqbufsz;
 	}
 
-	sk->fd = rtdm_private_to_context(priv)->fd;
+	sk->fd = rtdm_private_to_context(priv);
 
 	ops.output = &__xddp_output_handler;
 	ops.input = &__xddp_input_handler;
@@ -753,7 +760,7 @@ static int __xddp_bind_socket(struct rtipc_private *priv,
 	}
 
 	RTDM_EXECUTE_ATOMICALLY(
-		portmap[sk->minor] = sk->fd;
+		portmap[sk->minor] = rtdm_private_to_context(priv);
 		__clear_bit(_XDDP_BINDING, &sk->status);
 		__set_bit(_XDDP_BOUND, &sk->status);
 	);
@@ -827,10 +834,10 @@ set_assoc:
 }
 
 static int __xddp_setsockopt(struct xddp_socket *sk,
-			     rtdm_user_info_t *user_info,
+			     struct rtdm_fd *context,
 			     void *arg)
 {
-	int (*monitor)(int s, int event, long arg);
+	int (*monitor)(struct rtdm_fd *fd, int event, long arg);
 	struct _rtdm_setsockopt_args sopt;
 	struct rtipc_port_label plabel;
 	rtdm_lockctx_t lockctx;
@@ -838,7 +845,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 	int ret = 0;
 	size_t len;
 
-	if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt)))
+	if (rtipc_get_arg(context, &sopt, arg, sizeof(sopt)))
 		return -EFAULT;
 
 	if (sopt.level == SOL_SOCKET) {
@@ -847,7 +854,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 		case SO_RCVTIMEO:
 			if (sopt.optlen != sizeof(tv))
 				return -EINVAL;
-			if (rtipc_get_arg(user_info, &tv,
+			if (rtipc_get_arg(context, &tv,
 					  sopt.optval, sizeof(tv)))
 				return -EFAULT;
 			sk->timeout = rtipc_timeval_to_ns(&tv);
@@ -868,7 +875,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 	case XDDP_BUFSZ:
 		if (sopt.optlen != sizeof(len))
 			return -EINVAL;
-		if (rtipc_get_arg(user_info, &len,
+		if (rtipc_get_arg(context, &len,
 				  sopt.optval, sizeof(len)))
 			return -EFAULT;
 		if (len > 0) {
@@ -890,7 +897,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 	case XDDP_POOLSZ:
 		if (sopt.optlen != sizeof(len))
 			return -EINVAL;
-		if (rtipc_get_arg(user_info, &len,
+		if (rtipc_get_arg(context, &len,
 				  sopt.optval, sizeof(len)))
 			return -EFAULT;
 		if (len == 0)
@@ -906,7 +913,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 
 	case XDDP_MONITOR:
 		/* Monitoring is available from kernel-space only. */
-		if (user_info)
+		if (rtdm_context_user_p(context))
 			return -EPERM;
 		if (sopt.optlen != sizeof(monitor))
 			return -EINVAL;
@@ -919,7 +926,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 	case XDDP_LABEL:
 		if (sopt.optlen < sizeof(plabel))
 			return -EINVAL;
-		if (rtipc_get_arg(user_info, &plabel,
+		if (rtipc_get_arg(context, &plabel,
 				  sopt.optval, sizeof(plabel)))
 			return -EFAULT;
 		RTDM_EXECUTE_ATOMICALLY(
@@ -941,7 +948,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 }
 
 static int __xddp_getsockopt(struct xddp_socket *sk,
-			     rtdm_user_info_t *user_info,
+			     struct rtdm_fd *context,
 			     void *arg)
 {
 	struct _rtdm_getsockopt_args sopt;
@@ -950,10 +957,10 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
 	socklen_t len;
 	int ret = 0;
 
-	if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt)))
+	if (rtipc_get_arg(context, &sopt, arg, sizeof(sopt)))
 		return -EFAULT;
 
-	if (rtipc_get_arg(user_info, &len, sopt.optlen, sizeof(len)))
+	if (rtipc_get_arg(context, &len, sopt.optlen, sizeof(len)))
 		return -EFAULT;
 
 	if (sopt.level == SOL_SOCKET) {
@@ -963,7 +970,7 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
 			if (len != sizeof(tv))
 				return -EINVAL;
 			rtipc_ns_to_timeval(&tv, sk->timeout);
-			if (rtipc_put_arg(user_info, sopt.optval,
+			if (rtipc_put_arg(context, sopt.optval,
 					  &tv, sizeof(tv)))
 				return -EFAULT;
 			break;
@@ -986,7 +993,7 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
 		RTDM_EXECUTE_ATOMICALLY(
 			strcpy(plabel.label, sk->label);
 		);
-		if (rtipc_put_arg(user_info, sopt.optval,
+		if (rtipc_put_arg(context, sopt.optval,
 				  &plabel, sizeof(plabel)))
 			return -EFAULT;
 		break;
@@ -999,7 +1006,7 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
 }
 
 static int __xddp_ioctl(struct rtipc_private *priv,
-			rtdm_user_info_t *user_info,
+			struct rtdm_fd *context,
 			unsigned int request, void *arg)
 {
 	struct sockaddr_ipc saddr, *saddrp = &saddr;
@@ -1009,13 +1016,13 @@ static int __xddp_ioctl(struct rtipc_private *priv,
 	switch (request) {
 
 	case _RTIOC_CONNECT:
-		ret = rtipc_get_sockaddr(user_info, arg, &saddrp);
+		ret = rtipc_get_sockaddr(context, arg, &saddrp);
 		if (ret == 0)
 			ret = __xddp_connect_socket(sk, saddrp);
 		break;
 
 	case _RTIOC_BIND:
-		ret = rtipc_get_sockaddr(user_info, arg, &saddrp);
+		ret = rtipc_get_sockaddr(context, arg, &saddrp);
 		if (ret)
 			return ret;
 		if (saddrp == NULL)
@@ -1024,19 +1031,19 @@ static int __xddp_ioctl(struct rtipc_private *priv,
 		break;
 
 	case _RTIOC_GETSOCKNAME:
-		ret = rtipc_put_sockaddr(user_info, arg, &sk->name);
+		ret = rtipc_put_sockaddr(context, arg, &sk->name);
 		break;
 
 	case _RTIOC_GETPEERNAME:
-		ret = rtipc_put_sockaddr(user_info, arg, &sk->peer);
+		ret = rtipc_put_sockaddr(context, arg, &sk->peer);
 		break;
 
 	case _RTIOC_SETSOCKOPT:
-		ret = __xddp_setsockopt(sk, user_info, arg);
+		ret = __xddp_setsockopt(sk, context, arg);
 		break;
 
 	case _RTIOC_GETSOCKOPT:
-		ret = __xddp_getsockopt(sk, user_info, arg);
+		ret = __xddp_getsockopt(sk, context, arg);
 		break;
 
 	case _RTIOC_LISTEN:
@@ -1056,13 +1063,13 @@ static int __xddp_ioctl(struct rtipc_private *priv,
 }
 
 static int xddp_ioctl(struct rtipc_private *priv,
-		      rtdm_user_info_t *user_info,
+		      struct rtdm_fd *context,
 		      unsigned int request, void *arg)
 {
 	if (rtdm_in_rt_context() && request == _RTIOC_BIND)
 		return -ENOSYS;	/* Try downgrading to NRT */
 
-	return __xddp_ioctl(priv, user_info, request, arg);
+	return __xddp_ioctl(priv, context, request, arg);
 }
 
 struct rtipc_protocol xddp_proto_driver = {
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 8/9] drivers/ipc: adapt IDDP after RTDM changes
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
                     ` (5 preceding siblings ...)
  2014-03-07 20:20   ` [Xenomai] [PATCH 7/9] drivers/ipc: adapt XDDP " Gilles Chanteperdrix
@ 2014-03-07 20:20   ` Gilles Chanteperdrix
  2014-03-07 20:20   ` [Xenomai] [PATCH 9/9] drivers/ipc: adapt BUFP " Gilles Chanteperdrix
  7 siblings, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

---
 kernel/drivers/ipc/iddp.c     |  114 +++++++++++++++++++++--------------------
 kernel/drivers/ipc/internal.h |   10 ----
 2 files changed, 59 insertions(+), 65 deletions(-)

diff --git a/kernel/drivers/ipc/iddp.c b/kernel/drivers/ipc/iddp.c
index 3fe43db..86b699a 100644
--- a/kernel/drivers/ipc/iddp.c
+++ b/kernel/drivers/ipc/iddp.c
@@ -192,7 +192,7 @@ static void __iddp_flush_pool(struct xnheap *heap,
 }
 
 static int iddp_socket(struct rtipc_private *priv,
-		       rtdm_user_info_t *user_info)
+		       struct rtdm_fd *context)
 {
 	struct iddp_socket *sk = priv->state;
 
@@ -217,14 +217,16 @@ static int iddp_socket(struct rtipc_private *priv,
 	return 0;
 }
 
-static int iddp_close(struct rtipc_private *priv,
-		      rtdm_user_info_t *user_info)
+static void iddp_close(struct rtipc_private *priv,
+		struct rtdm_fd *context)
 {
 	struct iddp_socket *sk = priv->state;
 	struct iddp_message *mbuf;
 
 	if (sk->name.sipc_port > -1)
-		xnmap_remove(portmap, sk->name.sipc_port);
+		RTDM_EXECUTE_ATOMICALLY(
+			xnmap_remove(portmap, sk->name.sipc_port);
+		);
 
 	rtdm_sem_destroy(&sk->insem);
 	rtdm_event_destroy(&sk->privevt);
@@ -234,7 +236,7 @@ static int iddp_close(struct rtipc_private *priv,
 
 	if (sk->bufpool != &kheap) {
 		xnheap_destroy(&sk->privpool, __iddp_flush_pool, NULL);
-		return 0;
+		return;
 	}
 
 	/* Send unread datagrams back to the system heap. */
@@ -246,11 +248,11 @@ static int iddp_close(struct rtipc_private *priv,
 
 	kfree(sk);
 
-	return 0;
+	return;
 }
 
 static ssize_t __iddp_recvmsg(struct rtipc_private *priv,
-			      rtdm_user_info_t *user_info,
+			      struct rtdm_fd *context,
 			      struct iovec *iov, int iovlen, int flags,
 			      struct sockaddr_ipc *saddr)
 {
@@ -303,7 +305,7 @@ static ssize_t __iddp_recvmsg(struct rtipc_private *priv,
 		if (iov[nvec].iov_len == 0)
 			continue;
 		vlen = wrlen >= iov[nvec].iov_len ? iov[nvec].iov_len : wrlen;
-		if (user_info) {
+		if (rtdm_context_user_p(context)) {
 			xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen);
 			ret = xnbufd_copy_from_kmem(&bufd, mbuf->data + rdoff, vlen);
 			xnbufd_unmap_uread(&bufd);
@@ -327,7 +329,7 @@ static ssize_t __iddp_recvmsg(struct rtipc_private *priv,
 }
 
 static ssize_t iddp_recvmsg(struct rtipc_private *priv,
-			    rtdm_user_info_t *user_info,
+			    struct rtdm_fd *context,
 			    struct msghdr *msg, int flags)
 {
 	struct iovec iov[RTIPC_IOV_MAX];
@@ -347,23 +349,23 @@ static ssize_t iddp_recvmsg(struct rtipc_private *priv,
 		return -EINVAL;
 
 	/* Copy I/O vector in */
-	if (rtipc_get_arg(user_info, iov, msg->msg_iov,
+	if (rtipc_get_arg(context, iov, msg->msg_iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
-	ret = __iddp_recvmsg(priv, user_info,
+	ret = __iddp_recvmsg(priv, context,
 			     iov, msg->msg_iovlen, flags, &saddr);
 	if (ret <= 0)
 		return ret;
 
 	/* Copy the updated I/O vector back */
-	if (rtipc_put_arg(user_info, msg->msg_iov, iov,
+	if (rtipc_put_arg(context, msg->msg_iov, iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
 	/* Copy the source address if required. */
 	if (msg->msg_name) {
-		if (rtipc_put_arg(user_info, msg->msg_name,
+		if (rtipc_put_arg(context, msg->msg_name,
 				  &saddr, sizeof(saddr)))
 			return -EFAULT;
 		msg->msg_namelen = sizeof(struct sockaddr_ipc);
@@ -373,35 +375,34 @@ static ssize_t iddp_recvmsg(struct rtipc_private *priv,
 }
 
 static ssize_t iddp_read(struct rtipc_private *priv,
-			 rtdm_user_info_t *user_info,
+			 struct rtdm_fd *context,
 			 void *buf, size_t len)
 {
 	struct iovec iov = { .iov_base = buf, .iov_len = len };
-	return __iddp_recvmsg(priv, user_info, &iov, 1, 0, NULL);
+	return __iddp_recvmsg(priv, context, &iov, 1, 0, NULL);
 }
 
 static ssize_t __iddp_sendmsg(struct rtipc_private *priv,
-			      rtdm_user_info_t *user_info,
+			      struct rtdm_fd *context,
 			      struct iovec *iov, int iovlen, int flags,
 			      const struct sockaddr_ipc *daddr)
 {
 	struct iddp_socket *sk = priv->state, *rsk;
-	struct rtdm_dev_context *rcontext;
 	struct iddp_message *mbuf;
 	ssize_t len, rdlen, vlen;
+	struct rtdm_fd *rcontext;
 	int nvec, wroff, ret;
 	struct xnbufd bufd;
-	void *p;
 
 	len = rtipc_get_iov_flatlen(iov, iovlen);
 	if (len == 0)
 		return 0;
 
-	p = xnmap_fetch_nocheck(portmap, daddr->sipc_port);
-	if (p == NULL)
-		return -ECONNRESET;
-
-	rcontext = rtdm_context_get(rtipc_map2fd(p));
+	RTDM_EXECUTE_ATOMICALLY(
+		rcontext = xnmap_fetch_nocheck(portmap, daddr->sipc_port);
+		if (rcontext && rtdm_context_lock(rcontext) < 0)
+			rcontext = NULL;
+	);
 	if (rcontext == NULL)
 		return -ECONNRESET;
 
@@ -423,7 +424,7 @@ static ssize_t __iddp_sendmsg(struct rtipc_private *priv,
 		if (iov[nvec].iov_len == 0)
 			continue;
 		vlen = rdlen >= iov[nvec].iov_len ? iov[nvec].iov_len : rdlen;
-		if (user_info) {
+		if (rtdm_context_user_p(context)) {
 			xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen);
 			ret = xnbufd_copy_to_kmem(mbuf->data + wroff, &bufd, vlen);
 			xnbufd_unmap_uread(&bufd);
@@ -462,7 +463,7 @@ fail:
 }
 
 static ssize_t iddp_sendmsg(struct rtipc_private *priv,
-			    rtdm_user_info_t *user_info,
+			    struct rtdm_fd *context,
 			    const struct msghdr *msg, int flags)
 {
 	struct iddp_socket *sk = priv->state;
@@ -478,7 +479,7 @@ static ssize_t iddp_sendmsg(struct rtipc_private *priv,
 			return -EINVAL;
 
 		/* Fetch the destination address to send to. */
-		if (rtipc_get_arg(user_info, &daddr,
+		if (rtipc_get_arg(context, &daddr,
 				  msg->msg_name, sizeof(daddr)))
 			return -EFAULT;
 
@@ -497,17 +498,17 @@ static ssize_t iddp_sendmsg(struct rtipc_private *priv,
 		return -EINVAL;
 
 	/* Copy I/O vector in */
-	if (rtipc_get_arg(user_info, iov, msg->msg_iov,
+	if (rtipc_get_arg(context, iov, msg->msg_iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
-	ret = __iddp_sendmsg(priv, user_info, iov,
+	ret = __iddp_sendmsg(priv, context, iov,
 			     msg->msg_iovlen, flags, &daddr);
 	if (ret <= 0)
 		return ret;
 
 	/* Copy updated I/O vector back */
-	if (rtipc_put_arg(user_info, msg->msg_iov, iov,
+	if (rtipc_put_arg(context, msg->msg_iov, iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
@@ -515,7 +516,7 @@ static ssize_t iddp_sendmsg(struct rtipc_private *priv,
 }
 
 static ssize_t iddp_write(struct rtipc_private *priv,
-			  rtdm_user_info_t *user_info,
+			  struct rtdm_fd *context,
 			  const void *buf, size_t len)
 {
 	struct iovec iov = { .iov_base = (void *)buf, .iov_len = len };
@@ -524,14 +525,15 @@ static ssize_t iddp_write(struct rtipc_private *priv,
 	if (sk->peer.sipc_port < 0)
 		return -EDESTADDRREQ;
 
-	return __iddp_sendmsg(priv, user_info, &iov, 1, 0, &sk->peer);
+	return __iddp_sendmsg(priv, context, &iov, 1, 0, &sk->peer);
 }
 
 static int __iddp_bind_socket(struct rtipc_private *priv,
 			      struct sockaddr_ipc *sa)
 {
 	struct iddp_socket *sk = priv->state;
-	int ret = 0, port, fd;
+	int ret = 0, port;
+	struct rtdm_fd *fd;
 	void *poolmem;
 	size_t poolsz;
 
@@ -552,8 +554,10 @@ static int __iddp_bind_socket(struct rtipc_private *priv,
 
 	/* Will auto-select a free port number if unspec (-1). */
 	port = sa->sipc_port;
-	fd = rtdm_private_to_context(priv)->fd;
-	port = xnmap_enter(portmap, port, rtipc_fd2map(fd));
+	fd = rtdm_private_to_context(priv);
+	RTDM_EXECUTE_ATOMICALLY(
+		port = xnmap_enter(portmap, port, fd);
+	);
 	if (port < 0)
 		return port == -EEXIST ? -EADDRINUSE : -ENOMEM;
 
@@ -680,7 +684,7 @@ set_assoc:
 }
 
 static int __iddp_setsockopt(struct iddp_socket *sk,
-			     rtdm_user_info_t *user_info,
+			     struct rtdm_fd *context,
 			     void *arg)
 {
 	struct _rtdm_setsockopt_args sopt;
@@ -689,7 +693,7 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 	int ret = 0;
 	size_t len;
 
-	if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt)))
+	if (rtipc_get_arg(context, &sopt, arg, sizeof(sopt)))
 		return -EFAULT;
 
 	if (sopt.level == SOL_SOCKET) {
@@ -698,7 +702,7 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 		case SO_RCVTIMEO:
 			if (sopt.optlen != sizeof(tv))
 				return -EINVAL;
-			if (rtipc_get_arg(user_info, &tv,
+			if (rtipc_get_arg(context, &tv,
 					  sopt.optval, sizeof(tv)))
 				return -EFAULT;
 			sk->rx_timeout = rtipc_timeval_to_ns(&tv);
@@ -707,7 +711,7 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 		case SO_SNDTIMEO:
 			if (sopt.optlen != sizeof(tv))
 				return -EINVAL;
-			if (rtipc_get_arg(user_info, &tv,
+			if (rtipc_get_arg(context, &tv,
 					  sopt.optval, sizeof(tv)))
 				return -EFAULT;
 			sk->tx_timeout = rtipc_timeval_to_ns(&tv);
@@ -728,7 +732,7 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 	case IDDP_POOLSZ:
 		if (sopt.optlen != sizeof(len))
 			return -EINVAL;
-		if (rtipc_get_arg(user_info, &len,
+		if (rtipc_get_arg(context, &len,
 				  sopt.optval, sizeof(len)))
 			return -EFAULT;
 		if (len == 0)
@@ -749,7 +753,7 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 	case IDDP_LABEL:
 		if (sopt.optlen < sizeof(plabel))
 			return -EINVAL;
-		if (rtipc_get_arg(user_info, &plabel,
+		if (rtipc_get_arg(context, &plabel,
 				  sopt.optval, sizeof(plabel)))
 			return -EFAULT;
 		RTDM_EXECUTE_ATOMICALLY(
@@ -774,7 +778,7 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 }
 
 static int __iddp_getsockopt(struct iddp_socket *sk,
-			     rtdm_user_info_t *user_info,
+			     struct rtdm_fd *context,
 			     void *arg)
 {
 	struct _rtdm_getsockopt_args sopt;
@@ -783,10 +787,10 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
 	socklen_t len;
 	int ret = 0;
 
-	if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt)))
+	if (rtipc_get_arg(context, &sopt, arg, sizeof(sopt)))
 		return -EFAULT;
 
-	if (rtipc_get_arg(user_info, &len, sopt.optlen, sizeof(len)))
+	if (rtipc_get_arg(context, &len, sopt.optlen, sizeof(len)))
 		return -EFAULT;
 
 	if (sopt.level == SOL_SOCKET) {
@@ -796,7 +800,7 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
 			if (len != sizeof(tv))
 				return -EINVAL;
 			rtipc_ns_to_timeval(&tv, sk->rx_timeout);
-			if (rtipc_put_arg(user_info, sopt.optval,
+			if (rtipc_put_arg(context, sopt.optval,
 					  &tv, sizeof(tv)))
 				return -EFAULT;
 			break;
@@ -805,7 +809,7 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
 			if (len != sizeof(tv))
 				return -EINVAL;
 			rtipc_ns_to_timeval(&tv, sk->tx_timeout);
-			if (rtipc_put_arg(user_info, sopt.optval,
+			if (rtipc_put_arg(context, sopt.optval,
 					  &tv, sizeof(tv)))
 				return -EFAULT;
 			break;
@@ -828,7 +832,7 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
 		RTDM_EXECUTE_ATOMICALLY(
 			strcpy(plabel.label, sk->label);
 		);
-		if (rtipc_put_arg(user_info, sopt.optval,
+		if (rtipc_put_arg(context, sopt.optval,
 				  &plabel, sizeof(plabel)))
 			return -EFAULT;
 		break;
@@ -841,7 +845,7 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
 }
 
 static int __iddp_ioctl(struct rtipc_private *priv,
-			rtdm_user_info_t *user_info,
+			struct rtdm_fd *context,
 			unsigned int request, void *arg)
 {
 	struct sockaddr_ipc saddr, *saddrp = &saddr;
@@ -851,14 +855,14 @@ static int __iddp_ioctl(struct rtipc_private *priv,
 	switch (request) {
 
 	case _RTIOC_CONNECT:
-		ret = rtipc_get_sockaddr(user_info, arg, &saddrp);
+		ret = rtipc_get_sockaddr(context, arg, &saddrp);
 		if (ret)
 		  return ret;
 		ret = __iddp_connect_socket(sk, saddrp);
 		break;
 
 	case _RTIOC_BIND:
-		ret = rtipc_get_sockaddr(user_info, arg, &saddrp);
+		ret = rtipc_get_sockaddr(context, arg, &saddrp);
 		if (ret)
 			return ret;
 		if (saddrp == NULL)
@@ -867,19 +871,19 @@ static int __iddp_ioctl(struct rtipc_private *priv,
 		break;
 
 	case _RTIOC_GETSOCKNAME:
-		ret = rtipc_put_sockaddr(user_info, arg, &sk->name);
+		ret = rtipc_put_sockaddr(context, arg, &sk->name);
 		break;
 
 	case _RTIOC_GETPEERNAME:
-		ret = rtipc_put_sockaddr(user_info, arg, &sk->peer);
+		ret = rtipc_put_sockaddr(context, arg, &sk->peer);
 		break;
 
 	case _RTIOC_SETSOCKOPT:
-		ret = __iddp_setsockopt(sk, user_info, arg);
+		ret = __iddp_setsockopt(sk, context, arg);
 		break;
 
 	case _RTIOC_GETSOCKOPT:
-		ret = __iddp_getsockopt(sk, user_info, arg);
+		ret = __iddp_getsockopt(sk, context, arg);
 		break;
 
 	case _RTIOC_LISTEN:
@@ -899,13 +903,13 @@ static int __iddp_ioctl(struct rtipc_private *priv,
 }
 
 static int iddp_ioctl(struct rtipc_private *priv,
-		      rtdm_user_info_t *user_info,
+		      struct rtdm_fd *context,
 		      unsigned int request, void *arg)
 {
 	if (rtdm_in_rt_context() && request == _RTIOC_BIND)
 		return -ENOSYS;	/* Try downgrading to NRT */
 
-	return __iddp_ioctl(priv, user_info, request, arg);
+	return __iddp_ioctl(priv, context, request, arg);
 }
 
 static int iddp_init(void)
diff --git a/kernel/drivers/ipc/internal.h b/kernel/drivers/ipc/internal.h
index 4422ba0..7470342 100644
--- a/kernel/drivers/ipc/internal.h
+++ b/kernel/drivers/ipc/internal.h
@@ -69,16 +69,6 @@ static inline void *rtipc_context_to_state(struct rtdm_fd *context)
 	return p->state;
 }
 
-static inline void *rtipc_fd2map(int fd)
-{
-	return (void *)(long)(fd + 1);
-}
-
-static inline int rtipc_map2fd(void *p)
-{
-	return (long)p - 1;
-}
-
 static inline nanosecs_rel_t rtipc_timeval_to_ns(const struct timeval *tv)
 {
 	nanosecs_rel_t ns = tv->tv_usec * 1000;
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Xenomai] [PATCH 9/9] drivers/ipc: adapt BUFP after RTDM changes
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
                     ` (6 preceding siblings ...)
  2014-03-07 20:20   ` [Xenomai] [PATCH 8/9] drivers/ipc: adapt IDDP " Gilles Chanteperdrix
@ 2014-03-07 20:20   ` Gilles Chanteperdrix
  7 siblings, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-03-07 20:20 UTC (permalink / raw)
  To: xenomai

---
 kernel/drivers/ipc/bufp.c |  114 +++++++++++++++++++++++----------------------
 1 file changed, 58 insertions(+), 56 deletions(-)

diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 4363c68..6e80148 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -113,7 +113,7 @@ static struct xnpnode_link __bufp_pnode = {
 #endif /* !CONFIG_XENO_OPT_VFILE */
 
 static int bufp_socket(struct rtipc_private *priv,
-		       rtdm_user_info_t *user_info)
+		       struct rtdm_fd *context)
 {
 	struct bufp_socket *sk = priv->state;
 
@@ -139,8 +139,8 @@ static int bufp_socket(struct rtipc_private *priv,
 	return 0;
 }
 
-static int bufp_close(struct rtipc_private *priv,
-		      rtdm_user_info_t *user_info)
+static void bufp_close(struct rtipc_private *priv,
+		struct rtdm_fd *context)
 {
 	struct bufp_socket *sk = priv->state;
 
@@ -148,7 +148,9 @@ static int bufp_close(struct rtipc_private *priv,
 	rtdm_event_destroy(&sk->o_event);
 
 	if (sk->name.sipc_port > -1)
-		xnmap_remove(portmap, sk->name.sipc_port);
+		RTDM_EXECUTE_ATOMICALLY(
+			xnmap_remove(portmap, sk->name.sipc_port);
+		);
 
 	if (sk->handle)
 		xnregistry_remove(sk->handle);
@@ -157,8 +159,6 @@ static int bufp_close(struct rtipc_private *priv,
 		free_pages_exact(sk->bufmem, sk->bufsz);
 
 	kfree(sk);
-
-	return 0;
 }
 
 static ssize_t __bufp_readbuf(struct bufp_socket *sk,
@@ -290,7 +290,7 @@ out:
 }
 
 static ssize_t __bufp_recvmsg(struct rtipc_private *priv,
-			      rtdm_user_info_t *user_info,
+			      struct rtdm_fd *context,
 			      struct iovec *iov, int iovlen, int flags,
 			      struct sockaddr_ipc *saddr)
 {
@@ -321,7 +321,7 @@ static ssize_t __bufp_recvmsg(struct rtipc_private *priv,
 		if (iov[nvec].iov_len == 0)
 			continue;
 		vlen = wrlen >= iov[nvec].iov_len ? iov[nvec].iov_len : wrlen;
-		if (user_info) {
+		if (rtdm_context_user_p(context)) {
 			xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen);
 			ret = __bufp_readbuf(sk, &bufd, flags);
 			xnbufd_unmap_uread(&bufd);
@@ -352,7 +352,7 @@ static ssize_t __bufp_recvmsg(struct rtipc_private *priv,
 }
 
 static ssize_t bufp_recvmsg(struct rtipc_private *priv,
-			    rtdm_user_info_t *user_info,
+			    struct rtdm_fd *context,
 			    struct msghdr *msg, int flags)
 {
 	struct iovec iov[RTIPC_IOV_MAX];
@@ -372,23 +372,23 @@ static ssize_t bufp_recvmsg(struct rtipc_private *priv,
 		return -EINVAL;
 
 	/* Copy I/O vector in */
-	if (rtipc_get_arg(user_info, iov, msg->msg_iov,
+	if (rtipc_get_arg(context, iov, msg->msg_iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
-	ret = __bufp_recvmsg(priv, user_info,
+	ret = __bufp_recvmsg(priv, context,
 			     iov, msg->msg_iovlen, flags, &saddr);
 	if (ret <= 0)
 		return ret;
 
 	/* Copy the updated I/O vector back */
-	if (rtipc_put_arg(user_info, msg->msg_iov, iov,
+	if (rtipc_put_arg(context, msg->msg_iov, iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
 	/* Copy the source address if required. */
 	if (msg->msg_name) {
-		if (rtipc_put_arg(user_info, msg->msg_name,
+		if (rtipc_put_arg(context, msg->msg_name,
 				  &saddr, sizeof(saddr)))
 			return -EFAULT;
 		msg->msg_namelen = sizeof(struct sockaddr_ipc);
@@ -398,11 +398,11 @@ static ssize_t bufp_recvmsg(struct rtipc_private *priv,
 }
 
 static ssize_t bufp_read(struct rtipc_private *priv,
-			 rtdm_user_info_t *user_info,
+			 struct rtdm_fd *context,
 			 void *buf, size_t len)
 {
 	struct iovec iov = { .iov_base = buf, .iov_len = len };
-	return __bufp_recvmsg(priv, user_info, &iov, 1, 0, NULL);
+	return __bufp_recvmsg(priv, context, &iov, 1, 0, NULL);
 }
 
 static ssize_t __bufp_writebuf(struct bufp_socket *rsk,
@@ -522,26 +522,25 @@ out:
 }
 
 static ssize_t __bufp_sendmsg(struct rtipc_private *priv,
-			      rtdm_user_info_t *user_info,
+			      struct rtdm_fd *context,
 			      struct iovec *iov, int iovlen, int flags,
 			      const struct sockaddr_ipc *daddr)
 {
 	struct bufp_socket *sk = priv->state, *rsk;
-	struct rtdm_dev_context *rcontext;
 	ssize_t len, rdlen, vlen, ret = 0;
+	struct rtdm_fd *rcontext;
 	struct xnbufd bufd;
 	int nvec;
-	void *p;
 
 	len = rtipc_get_iov_flatlen(iov, iovlen);
 	if (len == 0)
 		return 0;
-
-	p = xnmap_fetch_nocheck(portmap, daddr->sipc_port);
-	if (p == NULL)
-		return -ECONNRESET;
-
-	rcontext = rtdm_context_get(rtipc_map2fd(p));
+	
+	RTDM_EXECUTE_ATOMICALLY(
+		rcontext = xnmap_fetch_nocheck(portmap, daddr->sipc_port);
+		if (rcontext && rtdm_context_lock(rcontext) < 0)
+			rcontext = NULL;
+	);
 	if (rcontext == NULL)
 		return -ECONNRESET;
 
@@ -569,7 +568,7 @@ static ssize_t __bufp_sendmsg(struct rtipc_private *priv,
 		if (iov[nvec].iov_len == 0)
 			continue;
 		vlen = rdlen >= iov[nvec].iov_len ? iov[nvec].iov_len : rdlen;
-		if (user_info) {
+		if (rtdm_context_user_p(context)) {
 			xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen);
 			ret = __bufp_writebuf(rsk, sk, &bufd, flags);
 			xnbufd_unmap_uread(&bufd);
@@ -596,7 +595,7 @@ fail:
 }
 
 static ssize_t bufp_sendmsg(struct rtipc_private *priv,
-			    rtdm_user_info_t *user_info,
+			    struct rtdm_fd *context,
 			    const struct msghdr *msg, int flags)
 {
 	struct bufp_socket *sk = priv->state;
@@ -612,7 +611,7 @@ static ssize_t bufp_sendmsg(struct rtipc_private *priv,
 			return -EINVAL;
 
 		/* Fetch the destination address to send to. */
-		if (rtipc_get_arg(user_info, &daddr,
+		if (rtipc_get_arg(context, &daddr,
 				  msg->msg_name, sizeof(daddr)))
 			return -EFAULT;
 
@@ -631,17 +630,17 @@ static ssize_t bufp_sendmsg(struct rtipc_private *priv,
 		return -EINVAL;
 
 	/* Copy I/O vector in */
-	if (rtipc_get_arg(user_info, iov, msg->msg_iov,
+	if (rtipc_get_arg(context, iov, msg->msg_iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
-	ret = __bufp_sendmsg(priv, user_info, iov,
+	ret = __bufp_sendmsg(priv, context, iov,
 			     msg->msg_iovlen, flags, &daddr);
 	if (ret <= 0)
 		return ret;
 
 	/* Copy updated I/O vector back */
-	if (rtipc_put_arg(user_info, msg->msg_iov, iov,
+	if (rtipc_put_arg(context, msg->msg_iov, iov,
 			  sizeof(iov[0]) * msg->msg_iovlen))
 		return -EFAULT;
 
@@ -649,7 +648,7 @@ static ssize_t bufp_sendmsg(struct rtipc_private *priv,
 }
 
 static ssize_t bufp_write(struct rtipc_private *priv,
-			  rtdm_user_info_t *user_info,
+			  struct rtdm_fd *context,
 			  const void *buf, size_t len)
 {
 	struct iovec iov = { .iov_base = (void *)buf, .iov_len = len };
@@ -658,14 +657,15 @@ static ssize_t bufp_write(struct rtipc_private *priv,
 	if (sk->peer.sipc_port < 0)
 		return -EDESTADDRREQ;
 
-	return __bufp_sendmsg(priv, user_info, &iov, 1, 0, &sk->peer);
+	return __bufp_sendmsg(priv, context, &iov, 1, 0, &sk->peer);
 }
 
 static int __bufp_bind_socket(struct rtipc_private *priv,
 			      struct sockaddr_ipc *sa)
 {
 	struct bufp_socket *sk = priv->state;
-	int ret = 0, port, fd;
+	int ret = 0, port;
+	struct rtdm_fd *fd;
 
 	if (sa->sipc_family != AF_RTIPC)
 		return -EINVAL;
@@ -684,8 +684,10 @@ static int __bufp_bind_socket(struct rtipc_private *priv,
 
 	/* Will auto-select a free port number if unspec (-1). */
 	port = sa->sipc_port;
-	fd = rtdm_private_to_context(priv)->fd;
-	port = xnmap_enter(portmap, port, rtipc_fd2map(fd));
+	fd = rtdm_private_to_context(priv);
+	RTDM_EXECUTE_ATOMICALLY(
+		port = xnmap_enter(portmap, port, fd);
+	);
 	if (port < 0)
 		return port == -EEXIST ? -EADDRINUSE : -ENOMEM;
 
@@ -797,7 +799,7 @@ set_assoc:
 }
 
 static int __bufp_setsockopt(struct bufp_socket *sk,
-			     rtdm_user_info_t *user_info,
+			     struct rtdm_fd *context,
 			     void *arg)
 {
 	struct _rtdm_setsockopt_args sopt;
@@ -806,7 +808,7 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 	int ret = 0;
 	size_t len;
 
-	if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt)))
+	if (rtipc_get_arg(context, &sopt, arg, sizeof(sopt)))
 		return -EFAULT;
 
 	if (sopt.level == SOL_SOCKET) {
@@ -815,7 +817,7 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 		case SO_RCVTIMEO:
 			if (sopt.optlen != sizeof(tv))
 				return -EINVAL;
-			if (rtipc_get_arg(user_info, &tv,
+			if (rtipc_get_arg(context, &tv,
 					  sopt.optval, sizeof(tv)))
 				return -EFAULT;
 			sk->rx_timeout = rtipc_timeval_to_ns(&tv);
@@ -824,7 +826,7 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 		case SO_SNDTIMEO:
 			if (sopt.optlen != sizeof(tv))
 				return -EINVAL;
-			if (rtipc_get_arg(user_info, &tv,
+			if (rtipc_get_arg(context, &tv,
 					  sopt.optval, sizeof(tv)))
 				return -EFAULT;
 			sk->tx_timeout = rtipc_timeval_to_ns(&tv);
@@ -845,7 +847,7 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 	case BUFP_BUFSZ:
 		if (sopt.optlen != sizeof(len))
 			return -EINVAL;
-		if (rtipc_get_arg(user_info, &len,
+		if (rtipc_get_arg(context, &len,
 				  sopt.optval, sizeof(len)))
 			return -EFAULT;
 		if (len == 0)
@@ -866,7 +868,7 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 	case BUFP_LABEL:
 		if (sopt.optlen < sizeof(plabel))
 			return -EINVAL;
-		if (rtipc_get_arg(user_info, &plabel,
+		if (rtipc_get_arg(context, &plabel,
 				  sopt.optval, sizeof(plabel)))
 			return -EFAULT;
 		RTDM_EXECUTE_ATOMICALLY(
@@ -891,7 +893,7 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 }
 
 static int __bufp_getsockopt(struct bufp_socket *sk,
-			     rtdm_user_info_t *user_info,
+			     struct rtdm_fd *context,
 			     void *arg)
 {
 	struct _rtdm_getsockopt_args sopt;
@@ -900,10 +902,10 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
 	socklen_t len;
 	int ret = 0;
 
-	if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt)))
+	if (rtipc_get_arg(context, &sopt, arg, sizeof(sopt)))
 		return -EFAULT;
 
-	if (rtipc_get_arg(user_info, &len, sopt.optlen, sizeof(len)))
+	if (rtipc_get_arg(context, &len, sopt.optlen, sizeof(len)))
 		return -EFAULT;
 
 	if (sopt.level == SOL_SOCKET) {
@@ -913,7 +915,7 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
 			if (len != sizeof(tv))
 				return -EINVAL;
 			rtipc_ns_to_timeval(&tv, sk->rx_timeout);
-			if (rtipc_put_arg(user_info, sopt.optval,
+			if (rtipc_put_arg(context, sopt.optval,
 					  &tv, sizeof(tv)))
 				return -EFAULT;
 			break;
@@ -922,7 +924,7 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
 			if (len != sizeof(tv))
 				return -EINVAL;
 			rtipc_ns_to_timeval(&tv, sk->tx_timeout);
-			if (rtipc_put_arg(user_info, sopt.optval,
+			if (rtipc_put_arg(context, sopt.optval,
 					  &tv, sizeof(tv)))
 				return -EFAULT;
 			break;
@@ -945,7 +947,7 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
 		RTDM_EXECUTE_ATOMICALLY(
 			strcpy(plabel.label, sk->label);
 		);
-		if (rtipc_put_arg(user_info, sopt.optval,
+		if (rtipc_put_arg(context, sopt.optval,
 				  &plabel, sizeof(plabel)))
 			return -EFAULT;
 		break;
@@ -958,7 +960,7 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
 }
 
 static int __bufp_ioctl(struct rtipc_private *priv,
-			rtdm_user_info_t *user_info,
+			struct rtdm_fd *context,
 			unsigned int request, void *arg)
 {
 	struct sockaddr_ipc saddr, *saddrp = &saddr;
@@ -968,14 +970,14 @@ static int __bufp_ioctl(struct rtipc_private *priv,
 	switch (request) {
 
 	case _RTIOC_CONNECT:
-		ret = rtipc_get_sockaddr(user_info, arg, &saddrp);
+		ret = rtipc_get_sockaddr(context, arg, &saddrp);
 		if (ret)
 		  return ret;
 		ret = __bufp_connect_socket(sk, saddrp);
 		break;
 
 	case _RTIOC_BIND:
-		ret = rtipc_get_sockaddr(user_info, arg, &saddrp);
+		ret = rtipc_get_sockaddr(context, arg, &saddrp);
 		if (ret)
 			return ret;
 		if (saddrp == NULL)
@@ -984,19 +986,19 @@ static int __bufp_ioctl(struct rtipc_private *priv,
 		break;
 
 	case _RTIOC_GETSOCKNAME:
-		ret = rtipc_put_sockaddr(user_info, arg, &sk->name);
+		ret = rtipc_put_sockaddr(context, arg, &sk->name);
 		break;
 
 	case _RTIOC_GETPEERNAME:
-		ret = rtipc_put_sockaddr(user_info, arg, &sk->peer);
+		ret = rtipc_put_sockaddr(context, arg, &sk->peer);
 		break;
 
 	case _RTIOC_SETSOCKOPT:
-		ret = __bufp_setsockopt(sk, user_info, arg);
+		ret = __bufp_setsockopt(sk, context, arg);
 		break;
 
 	case _RTIOC_GETSOCKOPT:
-		ret = __bufp_getsockopt(sk, user_info, arg);
+		ret = __bufp_getsockopt(sk, context, arg);
 		break;
 
 	case _RTIOC_LISTEN:
@@ -1016,13 +1018,13 @@ static int __bufp_ioctl(struct rtipc_private *priv,
 }
 
 static int bufp_ioctl(struct rtipc_private *priv,
-		      rtdm_user_info_t *user_info,
+		      struct rtdm_fd *context,
 		      unsigned int request, void *arg)
 {
 	if (rtdm_in_rt_context() && request == _RTIOC_BIND)
 		return -ENOSYS;	/* Try downgrading to NRT */
 
-	return __bufp_ioctl(priv, user_info, request, arg);
+	return __bufp_ioctl(priv, context, request, arg);
 }
 
 static int bufp_init(void)
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-03-07 20:19 [Xenomai] RTDM rework (2) Gilles Chanteperdrix
  2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
@ 2014-04-05 12:14 ` Gilles Chanteperdrix
  2014-04-25 10:40   ` Jan Kiszka
  1 sibling, 1 reply; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-04-05 12:14 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai

On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
> 
> Hi,
> 
> here comes a second attempt at introducing a file descriptor support for
> other purposes than RTDM drivers.
> 
> This time, the file descriptors are called rtdm_fd and are part of the
> RTDM API, but can be used by the POSIX personality. The actual RB-tree
> where they are stored is part of the xnsys_ppd structure, as this way it
> can be used by one of the RTDM and POSIX personalities, even if the
> current process is not bound to the other personality.
> 
> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
> iddp and bufp drivers to allow seeing the API changes.

Hi Jan,

ping?

I have a pile of code needing to be rebased on these patches, I would
very much like to get all this merged before it bitrots too much.

Regards.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-04-05 12:14 ` [Xenomai] RTDM rework (2) Gilles Chanteperdrix
@ 2014-04-25 10:40   ` Jan Kiszka
  2014-04-25 12:00     ` Gilles Chanteperdrix
  0 siblings, 1 reply; 23+ messages in thread
From: Jan Kiszka @ 2014-04-25 10:40 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: Xenomai

On 2014-04-05 14:14, Gilles Chanteperdrix wrote:
> On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
>>
>> Hi,
>>
>> here comes a second attempt at introducing a file descriptor support for
>> other purposes than RTDM drivers.
>>
>> This time, the file descriptors are called rtdm_fd and are part of the
>> RTDM API, but can be used by the POSIX personality. The actual RB-tree
>> where they are stored is part of the xnsys_ppd structure, as this way it
>> can be used by one of the RTDM and POSIX personalities, even if the
>> current process is not bound to the other personality.
>>
>> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
>> iddp and bufp drivers to allow seeing the API changes.
> 
> Hi Jan,
> 
> ping?
> 
> I have a pile of code needing to be rebased on these patches, I would
> very much like to get all this merged before it bitrots too much.

Finally looking into them now. Do you happen to have them in git
somewhere? Or what was the revision they once applied to?

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-04-25 10:40   ` Jan Kiszka
@ 2014-04-25 12:00     ` Gilles Chanteperdrix
  2014-04-29 15:39       ` Jan Kiszka
  0 siblings, 1 reply; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-04-25 12:00 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai

On 04/25/2014 12:40 PM, Jan Kiszka wrote:
> On 2014-04-05 14:14, Gilles Chanteperdrix wrote:
>> On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
>>>
>>> Hi,
>>>
>>> here comes a second attempt at introducing a file descriptor support for
>>> other purposes than RTDM drivers.
>>>
>>> This time, the file descriptors are called rtdm_fd and are part of the
>>> RTDM API, but can be used by the POSIX personality. The actual RB-tree
>>> where they are stored is part of the xnsys_ppd structure, as this way it
>>> can be used by one of the RTDM and POSIX personalities, even if the
>>> current process is not bound to the other personality.
>>>
>>> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
>>> iddp and bufp drivers to allow seeing the API changes.
>>
>> Hi Jan,
>>
>> ping?
>>
>> I have a pile of code needing to be rebased on these patches, I would
>> very much like to get all this merged before it bitrots too much.
> 
> Finally looking into them now. Do you happen to have them in git
> somewhere? Or what was the revision they once applied to?

Branch for-forge-rtdm-rework in xenomai-gch.git.


-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-04-25 12:00     ` Gilles Chanteperdrix
@ 2014-04-29 15:39       ` Jan Kiszka
  2014-04-30 12:44         ` Gilles Chanteperdrix
  2014-05-05 20:48         ` Gilles Chanteperdrix
  0 siblings, 2 replies; 23+ messages in thread
From: Jan Kiszka @ 2014-04-29 15:39 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: Xenomai

On 2014-04-25 14:00, Gilles Chanteperdrix wrote:
> On 04/25/2014 12:40 PM, Jan Kiszka wrote:
>> On 2014-04-05 14:14, Gilles Chanteperdrix wrote:
>>> On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
>>>>
>>>> Hi,
>>>>
>>>> here comes a second attempt at introducing a file descriptor support for
>>>> other purposes than RTDM drivers.
>>>>
>>>> This time, the file descriptors are called rtdm_fd and are part of the
>>>> RTDM API, but can be used by the POSIX personality. The actual RB-tree
>>>> where they are stored is part of the xnsys_ppd structure, as this way it
>>>> can be used by one of the RTDM and POSIX personalities, even if the
>>>> current process is not bound to the other personality.
>>>>
>>>> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
>>>> iddp and bufp drivers to allow seeing the API changes.
>>>
>>> Hi Jan,
>>>
>>> ping?
>>>
>>> I have a pile of code needing to be rebased on these patches, I would
>>> very much like to get all this merged before it bitrots too much.
>>
>> Finally looking into them now. Do you happen to have them in git
>> somewhere? Or what was the revision they once applied to?
> 
> Branch for-forge-rtdm-rework in xenomai-gch.git.

Thanks, worked through this now. I'm fine with the general approach. We
should prepare it for merge.

Some minor things I stumbled over while reading:

- rtdm_context_user_p (I personally still prefer something like
  "is_user") and rtdm_context_device (to_device?) are apparently public
  APIs and, thus, need documentation
- there are still things (arguments, functions etc.) called "context"
  that are of type rtdm_fd, thus should rather be called "fd", no?
- outdated documentation of rtdm_device
- diff highlighted quite a lot of trailing white spaces here
- API and struct versions should be increased to reflect the changes
  and allow drivers to wrap the difference if desired

BTW, some compat wrapping would be helpful, i.e. something to allow the
same driver sources to be used for both Xenomai 2.x and 3.x. Have you
already thought about any helpers/macros that could be provided by
Xenomai (for copying over into out-of-tree drivers)?

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-04-29 15:39       ` Jan Kiszka
@ 2014-04-30 12:44         ` Gilles Chanteperdrix
  2014-05-05 20:48         ` Gilles Chanteperdrix
  1 sibling, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-04-30 12:44 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai

On 04/29/2014 05:39 PM, Jan Kiszka wrote:
> On 2014-04-25 14:00, Gilles Chanteperdrix wrote:
>> On 04/25/2014 12:40 PM, Jan Kiszka wrote:
>>> On 2014-04-05 14:14, Gilles Chanteperdrix wrote:
>>>> On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> here comes a second attempt at introducing a file descriptor support for
>>>>> other purposes than RTDM drivers.
>>>>>
>>>>> This time, the file descriptors are called rtdm_fd and are part of the
>>>>> RTDM API, but can be used by the POSIX personality. The actual RB-tree
>>>>> where they are stored is part of the xnsys_ppd structure, as this way it
>>>>> can be used by one of the RTDM and POSIX personalities, even if the
>>>>> current process is not bound to the other personality.
>>>>>
>>>>> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
>>>>> iddp and bufp drivers to allow seeing the API changes.
>>>>
>>>> Hi Jan,
>>>>
>>>> ping?
>>>>
>>>> I have a pile of code needing to be rebased on these patches, I would
>>>> very much like to get all this merged before it bitrots too much.
>>>
>>> Finally looking into them now. Do you happen to have them in git
>>> somewhere? Or what was the revision they once applied to?
>>
>> Branch for-forge-rtdm-rework in xenomai-gch.git.
>
> Thanks, worked through this now. I'm fine with the general approach. We
> should prepare it for merge.
>
> Some minor things I stumbled over while reading:
>
> - rtdm_context_user_p (I personally still prefer something like
>    "is_user") and rtdm_context_device (to_device?) are apparently public
>    APIs and, thus, need documentation
> - there are still things (arguments, functions etc.) called "context"
>    that are of type rtdm_fd, thus should rather be called "fd", no?
> - outdated documentation of rtdm_device
> - diff highlighted quite a lot of trailing white spaces here
> - API and struct versions should be increased to reflect the changes
>    and allow drivers to wrap the difference if desired

Ok, will cleanup the patches during the long week-end.

>
> BTW, some compat wrapping would be helpful, i.e. something to allow the
> same driver sources to be used for both Xenomai 2.x and 3.x. Have you
> already thought about any helpers/macros that could be provided by
> Xenomai (for copying over into out-of-tree drivers)?

No, I have not tried thinking about this. Note that we could add the 
compatibility macros to xenomai 2.6 as well.

-- 
					    Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-04-29 15:39       ` Jan Kiszka
  2014-04-30 12:44         ` Gilles Chanteperdrix
@ 2014-05-05 20:48         ` Gilles Chanteperdrix
  2014-05-06  5:14           ` Jan Kiszka
  1 sibling, 1 reply; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-05-05 20:48 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai

On 04/29/2014 05:39 PM, Jan Kiszka wrote:
> On 2014-04-25 14:00, Gilles Chanteperdrix wrote:
>> On 04/25/2014 12:40 PM, Jan Kiszka wrote:
>>> On 2014-04-05 14:14, Gilles Chanteperdrix wrote:
>>>> On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> here comes a second attempt at introducing a file descriptor support for
>>>>> other purposes than RTDM drivers.
>>>>>
>>>>> This time, the file descriptors are called rtdm_fd and are part of the
>>>>> RTDM API, but can be used by the POSIX personality. The actual RB-tree
>>>>> where they are stored is part of the xnsys_ppd structure, as this way it
>>>>> can be used by one of the RTDM and POSIX personalities, even if the
>>>>> current process is not bound to the other personality.
>>>>>
>>>>> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
>>>>> iddp and bufp drivers to allow seeing the API changes.
>>>>
>>>> Hi Jan,
>>>>
>>>> ping?
>>>>
>>>> I have a pile of code needing to be rebased on these patches, I would
>>>> very much like to get all this merged before it bitrots too much.
>>>
>>> Finally looking into them now. Do you happen to have them in git
>>> somewhere? Or what was the revision they once applied to?
>>
>> Branch for-forge-rtdm-rework in xenomai-gch.git.
> 
> Thanks, worked through this now. I'm fine with the general approach. We
> should prepare it for merge.
> 
> Some minor things I stumbled over while reading:
> 
> - rtdm_context_user_p (I personally still prefer something like
>   "is_user") and rtdm_context_device (to_device?) are apparently public
>   APIs and, thus, need documentation
> - there are still things (arguments, functions etc.) called "context"
>   that are of type rtdm_fd, thus should rather be called "fd", no?

Hi Jan,

I have started cleaning up the patches, however, about the last remark,
do you propose to rename rtdm_private_to_context to rtdm_private_to_fd
for instance? I was thinking that rtdm_fd was the new context, so we
could keep the context everywhere? Keeping the old API names would limit
the need for wrappers.

Regards.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-05-05 20:48         ` Gilles Chanteperdrix
@ 2014-05-06  5:14           ` Jan Kiszka
  2014-05-10 16:11             ` Gilles Chanteperdrix
  0 siblings, 1 reply; 23+ messages in thread
From: Jan Kiszka @ 2014-05-06  5:14 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: Xenomai

On 2014-05-05 22:48, Gilles Chanteperdrix wrote:
> On 04/29/2014 05:39 PM, Jan Kiszka wrote:
>> On 2014-04-25 14:00, Gilles Chanteperdrix wrote:
>>> On 04/25/2014 12:40 PM, Jan Kiszka wrote:
>>>> On 2014-04-05 14:14, Gilles Chanteperdrix wrote:
>>>>> On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> here comes a second attempt at introducing a file descriptor support for
>>>>>> other purposes than RTDM drivers.
>>>>>>
>>>>>> This time, the file descriptors are called rtdm_fd and are part of the
>>>>>> RTDM API, but can be used by the POSIX personality. The actual RB-tree
>>>>>> where they are stored is part of the xnsys_ppd structure, as this way it
>>>>>> can be used by one of the RTDM and POSIX personalities, even if the
>>>>>> current process is not bound to the other personality.
>>>>>>
>>>>>> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
>>>>>> iddp and bufp drivers to allow seeing the API changes.
>>>>>
>>>>> Hi Jan,
>>>>>
>>>>> ping?
>>>>>
>>>>> I have a pile of code needing to be rebased on these patches, I would
>>>>> very much like to get all this merged before it bitrots too much.
>>>>
>>>> Finally looking into them now. Do you happen to have them in git
>>>> somewhere? Or what was the revision they once applied to?
>>>
>>> Branch for-forge-rtdm-rework in xenomai-gch.git.
>>
>> Thanks, worked through this now. I'm fine with the general approach. We
>> should prepare it for merge.
>>
>> Some minor things I stumbled over while reading:
>>
>> - rtdm_context_user_p (I personally still prefer something like
>>   "is_user") and rtdm_context_device (to_device?) are apparently public
>>   APIs and, thus, need documentation
>> - there are still things (arguments, functions etc.) called "context"
>>   that are of type rtdm_fd, thus should rather be called "fd", no?
> 
> Hi Jan,
> 
> I have started cleaning up the patches, however, about the last remark,
> do you propose to rename rtdm_private_to_context to rtdm_private_to_fd
> for instance? I was thinking that rtdm_fd was the new context, so we
> could keep the context everywhere? Keeping the old API names would limit
> the need for wrappers.

We can still keep (undocumented) legacy wrappers for a while, but it
would be better to call the new API after what it is really translating.

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-05-06  5:14           ` Jan Kiszka
@ 2014-05-10 16:11             ` Gilles Chanteperdrix
  2014-05-11 20:08               ` Gilles Chanteperdrix
  2014-05-14 14:30               ` Jan Kiszka
  0 siblings, 2 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-05-10 16:11 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai

On 05/06/2014 07:14 AM, Jan Kiszka wrote:
> On 2014-05-05 22:48, Gilles Chanteperdrix wrote:
>> On 04/29/2014 05:39 PM, Jan Kiszka wrote:
>>> On 2014-04-25 14:00, Gilles Chanteperdrix wrote:
>>>> On 04/25/2014 12:40 PM, Jan Kiszka wrote:
>>>>> On 2014-04-05 14:14, Gilles Chanteperdrix wrote:
>>>>>> On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> here comes a second attempt at introducing a file descriptor support for
>>>>>>> other purposes than RTDM drivers.
>>>>>>>
>>>>>>> This time, the file descriptors are called rtdm_fd and are part of the
>>>>>>> RTDM API, but can be used by the POSIX personality. The actual RB-tree
>>>>>>> where they are stored is part of the xnsys_ppd structure, as this way it
>>>>>>> can be used by one of the RTDM and POSIX personalities, even if the
>>>>>>> current process is not bound to the other personality.
>>>>>>>
>>>>>>> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
>>>>>>> iddp and bufp drivers to allow seeing the API changes.
>>>>>>
>>>>>> Hi Jan,
>>>>>>
>>>>>> ping?
>>>>>>
>>>>>> I have a pile of code needing to be rebased on these patches, I would
>>>>>> very much like to get all this merged before it bitrots too much.
>>>>>
>>>>> Finally looking into them now. Do you happen to have them in git
>>>>> somewhere? Or what was the revision they once applied to?
>>>>
>>>> Branch for-forge-rtdm-rework in xenomai-gch.git.
>>>
>>> Thanks, worked through this now. I'm fine with the general approach. We
>>> should prepare it for merge.
>>>
>>> Some minor things I stumbled over while reading:
>>>
>>> - rtdm_context_user_p (I personally still prefer something like
>>>   "is_user") and rtdm_context_device (to_device?) are apparently public
>>>   APIs and, thus, need documentation
>>> - there are still things (arguments, functions etc.) called "context"
>>>   that are of type rtdm_fd, thus should rather be called "fd", no?
>>
>> Hi Jan,
>>
>> I have started cleaning up the patches, however, about the last remark,
>> do you propose to rename rtdm_private_to_context to rtdm_private_to_fd
>> for instance? I was thinking that rtdm_fd was the new context, so we
>> could keep the context everywhere? Keeping the old API names would limit
>> the need for wrappers.
> 
> We can still keep (undocumented) legacy wrappers for a while, but it
> would be better to call the new API after what it is really translating.

Hi Jan,

I have pushed a new version which addresses your comments in the
"for-forge-rtdm-rework" branch.

You can ignore the "whitespace cleanup" commit, it is just there to
allow me to simply commit without whitespace issues, it will be removed
later on.

Note that analogy has not been updated to the API change, I will address
this later, if you agree with the current version.

Regards.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-05-10 16:11             ` Gilles Chanteperdrix
@ 2014-05-11 20:08               ` Gilles Chanteperdrix
  2014-05-14 14:30               ` Jan Kiszka
  1 sibling, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-05-11 20:08 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai

On 05/10/2014 06:11 PM, Gilles Chanteperdrix wrote:
> On 05/06/2014 07:14 AM, Jan Kiszka wrote:
>> On 2014-05-05 22:48, Gilles Chanteperdrix wrote:
>>> On 04/29/2014 05:39 PM, Jan Kiszka wrote:
>>>> On 2014-04-25 14:00, Gilles Chanteperdrix wrote:
>>>>> On 04/25/2014 12:40 PM, Jan Kiszka wrote:
>>>>>> On 2014-04-05 14:14, Gilles Chanteperdrix wrote:
>>>>>>> On 03/07/2014 09:19 PM, Gilles Chanteperdrix wrote:
>>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> here comes a second attempt at introducing a file descriptor support for
>>>>>>>> other purposes than RTDM drivers.
>>>>>>>>
>>>>>>>> This time, the file descriptors are called rtdm_fd and are part of the
>>>>>>>> RTDM API, but can be used by the POSIX personality. The actual RB-tree
>>>>>>>> where they are stored is part of the xnsys_ppd structure, as this way it
>>>>>>>> can be used by one of the RTDM and POSIX personalities, even if the
>>>>>>>> current process is not bound to the other personality.
>>>>>>>>
>>>>>>>> I have posted the patches to the timerbench, switchtest, rtdm, xddp,
>>>>>>>> iddp and bufp drivers to allow seeing the API changes.
>>>>>>>
>>>>>>> Hi Jan,
>>>>>>>
>>>>>>> ping?
>>>>>>>
>>>>>>> I have a pile of code needing to be rebased on these patches, I would
>>>>>>> very much like to get all this merged before it bitrots too much.
>>>>>>
>>>>>> Finally looking into them now. Do you happen to have them in git
>>>>>> somewhere? Or what was the revision they once applied to?
>>>>>
>>>>> Branch for-forge-rtdm-rework in xenomai-gch.git.
>>>>
>>>> Thanks, worked through this now. I'm fine with the general approach. We
>>>> should prepare it for merge.
>>>>
>>>> Some minor things I stumbled over while reading:
>>>>
>>>> - rtdm_context_user_p (I personally still prefer something like
>>>>   "is_user") and rtdm_context_device (to_device?) are apparently public
>>>>   APIs and, thus, need documentation
>>>> - there are still things (arguments, functions etc.) called "context"
>>>>   that are of type rtdm_fd, thus should rather be called "fd", no?
>>>
>>> Hi Jan,
>>>
>>> I have started cleaning up the patches, however, about the last remark,
>>> do you propose to rename rtdm_private_to_context to rtdm_private_to_fd
>>> for instance? I was thinking that rtdm_fd was the new context, so we
>>> could keep the context everywhere? Keeping the old API names would limit
>>> the need for wrappers.
>>
>> We can still keep (undocumented) legacy wrappers for a while, but it
>> would be better to call the new API after what it is really translating.
> 
> Hi Jan,
> 
> I have pushed a new version which addresses your comments in the
> "for-forge-rtdm-rework" branch.
> 
> You can ignore the "whitespace cleanup" commit, it is just there to
> allow me to simply commit without whitespace issues, it will be removed
> later on.
> 
> Note that analogy has not been updated to the API change, I will address
> this later, if you agree with the current version.

I finally also pushed the analogy changes.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-05-10 16:11             ` Gilles Chanteperdrix
  2014-05-11 20:08               ` Gilles Chanteperdrix
@ 2014-05-14 14:30               ` Jan Kiszka
  2014-05-14 15:23                 ` Gilles Chanteperdrix
  2014-05-15 18:40                 ` Gilles Chanteperdrix
  1 sibling, 2 replies; 23+ messages in thread
From: Jan Kiszka @ 2014-05-14 14:30 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: Xenomai

Hi Gilles,

On 2014-05-10 18:11, Gilles Chanteperdrix wrote:
> Hi Jan,
> 
> I have pushed a new version which addresses your comments in the
> "for-forge-rtdm-rework" branch.
> 
> You can ignore the "whitespace cleanup" commit, it is just there to
> allow me to simply commit without whitespace issues, it will be removed
> later on.
> 
> Note that analogy has not been updated to the API change, I will address
> this later, if you agree with the current version.

Looks good.

Minor note on rtdm_device::open/socket doc: They are running
non-real-time context, and the documentation should mention this clearly
(compare to the regular file ops with their two variants).

I can't look at the implementation, unfortunately.

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-05-14 14:30               ` Jan Kiszka
@ 2014-05-14 15:23                 ` Gilles Chanteperdrix
  2014-05-15 18:40                 ` Gilles Chanteperdrix
  1 sibling, 0 replies; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-05-14 15:23 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai

On 05/14/2014 04:30 PM, Jan Kiszka wrote:
> Hi Gilles,
>
> On 2014-05-10 18:11, Gilles Chanteperdrix wrote:
>> Hi Jan,
>>
>> I have pushed a new version which addresses your comments in the
>> "for-forge-rtdm-rework" branch.
>>
>> You can ignore the "whitespace cleanup" commit, it is just there to
>> allow me to simply commit without whitespace issues, it will be removed
>> later on.
>>
>> Note that analogy has not been updated to the API change, I will address
>> this later, if you agree with the current version.
>
> Looks good.
>
> Minor note on rtdm_device::open/socket doc: They are running
> non-real-time context, and the documentation should mention this clearly
> (compare to the regular file ops with their two variants).
>
> I can't look at the implementation, unfortunately.

Ok, one change you may have missed: the close callback now returns void. 
Since the close callback is now invoked when the reference count reaches 
0, it is not always possible to return the error to the user. The 
automatic periodic invocation of close when it returns EAGAIN is also 
removed: it is possible to get the same result by using 
rtdm_fd_lock/rtdm_fd_unlock, so for the sake of simplicity, only this 
solution was kept.

-- 
					    Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-05-14 14:30               ` Jan Kiszka
  2014-05-14 15:23                 ` Gilles Chanteperdrix
@ 2014-05-15 18:40                 ` Gilles Chanteperdrix
  2014-05-15 19:35                   ` Jan Kiszka
  1 sibling, 1 reply; 23+ messages in thread
From: Gilles Chanteperdrix @ 2014-05-15 18:40 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai

On 05/14/2014 04:30 PM, Jan Kiszka wrote:
> Hi Gilles,
> 
> On 2014-05-10 18:11, Gilles Chanteperdrix wrote:
>> Hi Jan,
>>
>> I have pushed a new version which addresses your comments in the
>> "for-forge-rtdm-rework" branch.
>>
>> You can ignore the "whitespace cleanup" commit, it is just there to
>> allow me to simply commit without whitespace issues, it will be removed
>> later on.
>>
>> Note that analogy has not been updated to the API change, I will address
>> this later, if you agree with the current version.
> 
> Looks good.
> 
> Minor note on rtdm_device::open/socket doc: They are running
> non-real-time context, and the documentation should mention this clearly
> (compare to the regular file ops with their two variants).
> 
> I can't look at the implementation, unfortunately.

I have submitted the pull request in order to move forward, but we can
still do some changes afterward.

Regards.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Xenomai] RTDM rework (2)
  2014-05-15 18:40                 ` Gilles Chanteperdrix
@ 2014-05-15 19:35                   ` Jan Kiszka
  0 siblings, 0 replies; 23+ messages in thread
From: Jan Kiszka @ 2014-05-15 19:35 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: Xenomai

On 2014-05-15 20:40, Gilles Chanteperdrix wrote:
> On 05/14/2014 04:30 PM, Jan Kiszka wrote:
>> Hi Gilles,
>>
>> On 2014-05-10 18:11, Gilles Chanteperdrix wrote:
>>> Hi Jan,
>>>
>>> I have pushed a new version which addresses your comments in the
>>> "for-forge-rtdm-rework" branch.
>>>
>>> You can ignore the "whitespace cleanup" commit, it is just there to
>>> allow me to simply commit without whitespace issues, it will be removed
>>> later on.
>>>
>>> Note that analogy has not been updated to the API change, I will address
>>> this later, if you agree with the current version.
>>
>> Looks good.
>>
>> Minor note on rtdm_device::open/socket doc: They are running
>> non-real-time context, and the documentation should mention this clearly
>> (compare to the regular file ops with their two variants).
>>
>> I can't look at the implementation, unfortunately.
> 
> I have submitted the pull request in order to move forward, but we can
> still do some changes afterward.

Ack.

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-05-15 19:35 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-07 20:19 [Xenomai] RTDM rework (2) Gilles Chanteperdrix
2014-03-07 20:20 ` [Xenomai] [PATCH 1/9] cobalt/rtdm: base protocol devices on xnid Gilles Chanteperdrix
2014-03-07 20:20   ` [Xenomai] [PATCH 2/9] cobalt/rtdm: base named devices on nucleus registry Gilles Chanteperdrix
2014-03-07 20:20   ` [Xenomai] [PATCH 3/9] cobalt/rtdm: extract fd API Gilles Chanteperdrix
2014-03-07 20:20   ` [Xenomai] [PATCH 4/9] drivers/testing: adapt timerbench after RTDM changes Gilles Chanteperdrix
2014-03-07 20:20   ` [Xenomai] [PATCH 5/9] drivers/testing: adapt switchtest " Gilles Chanteperdrix
2014-03-07 20:20   ` [Xenomai] [PATCH 6/9] drivers/testing: adapt rtdmtest " Gilles Chanteperdrix
2014-03-07 20:20   ` [Xenomai] [PATCH 7/9] drivers/ipc: adapt XDDP " Gilles Chanteperdrix
2014-03-07 20:20   ` [Xenomai] [PATCH 8/9] drivers/ipc: adapt IDDP " Gilles Chanteperdrix
2014-03-07 20:20   ` [Xenomai] [PATCH 9/9] drivers/ipc: adapt BUFP " Gilles Chanteperdrix
2014-04-05 12:14 ` [Xenomai] RTDM rework (2) Gilles Chanteperdrix
2014-04-25 10:40   ` Jan Kiszka
2014-04-25 12:00     ` Gilles Chanteperdrix
2014-04-29 15:39       ` Jan Kiszka
2014-04-30 12:44         ` Gilles Chanteperdrix
2014-05-05 20:48         ` Gilles Chanteperdrix
2014-05-06  5:14           ` Jan Kiszka
2014-05-10 16:11             ` Gilles Chanteperdrix
2014-05-11 20:08               ` Gilles Chanteperdrix
2014-05-14 14:30               ` Jan Kiszka
2014-05-14 15:23                 ` Gilles Chanteperdrix
2014-05-15 18:40                 ` Gilles Chanteperdrix
2014-05-15 19:35                   ` Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.