Module: xenomai-forge Branch: next Commit: c242e4834ade1974d78fb85bc761128c7b0e026f URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=c242e4834ade1974d78fb85bc761128c7b0e026f
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Sun Jan 26 21:38:14 2014 +0100 cobalt/rtdm: base protocol devices on xnid --- include/cobalt/kernel/rtdm/driver.h | 6 +- kernel/cobalt/rtdm/device.c | 110 ++++++++++++++--------------------- kernel/cobalt/rtdm/internal.h | 4 +- kernel/cobalt/rtdm/proc.c | 58 +++++++++--------- 4 files changed, 78 insertions(+), 100 deletions(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index d64ccf4..27cddcb 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/ancillaries.h> +#include <cobalt/kernel/tree.h> #include <rtdm/rtdm.h> /* debug support */ @@ -446,7 +447,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 b9639a2..e6d7bfe 100644 --- a/kernel/cobalt/rtdm/device.c +++ b/kernel/cobalt/rtdm/device.c @@ -46,19 +46,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); @@ -93,9 +87,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) @@ -133,31 +128,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); + xnid = xnid_fetch(&rtdm_protocol_devices, id); + if (xnid) { + device = container_of(xnid, struct rtdm_device, reserved.id); - xnlock_put_irqrestore(&rt_dev_lock, s); - - return device; - } - } + rtdm_reference_device(device); + } else + device = NULL; xnlock_put_irqrestore(&rt_dev_lock, s); - return NULL; + return device; } /*! @@ -194,6 +184,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; @@ -320,34 +311,33 @@ int rtdm_dev_register(struct rtdm_device *device) up(&nrt_dev_lock); } else { - hashkey = get_proto_hash(device->protocol_family, - device->socket_type); + id = get_proto_id(device->protocol_family, + device->socket_type); + + trace_mark(xn_rtdm, protocol_register, "device %p " + "protocol_family %d socket_type %d flags %d " + "class %d sub_class %d profile_version %d " + "driver_version %d", device, + device->protocol_family, device->socket_type, + device->device_flags, device->device_class, + device->device_sub_class, device->profile_version, + device->driver_version); - 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); } @@ -424,7 +414,10 @@ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay) xnlock_get_irqsave(&rt_dev_lock, s); } - list_del(®_dev->reserved.entry); + if ((device->device_flags & RTDM_DEVICE_TYPE_MASK) == RTDM_NAMED_DEVICE) + list_del(®_dev->reserved.entry); + else + xnid_remove(&rtdm_protocol_devices, ®_dev->reserved.id); xnlock_put_irqrestore(&rt_dev_lock, s); @@ -453,9 +446,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; } @@ -471,22 +462,10 @@ 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); @@ -501,7 +480,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 930e50e..0d15385 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; - - devlist = next_devlist(priv); - if (devlist == NULL) - return NULL; /* All devlists empty. */ + xntree_for_each_entry(dev, &rtdm_protocol_devices, reserved.id) + if (pos++ >= it->pos) + break; - priv->curr = devlist->next; /* Skip head. */ + if (dev == NULL) + return NULL; /* Empty */ - /* - * 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); - ksformat(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; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git