summaryrefslogtreecommitdiff
path: root/kernel/zttranscode.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/zttranscode.c')
-rw-r--r--kernel/zttranscode.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/kernel/zttranscode.c b/kernel/zttranscode.c
index 58d098c..5f1b3c0 100644
--- a/kernel/zttranscode.c
+++ b/kernel/zttranscode.c
@@ -3,7 +3,7 @@
*
* Written by Mark Spencer <markster@digium.com>
*
- * Copyright (C) 2006-2008, Digium, Inc.
+ * Copyright (C) 2006-2009, Digium, Inc.
*
* All rights reserved.
*
@@ -39,7 +39,13 @@
#include <zaptel.h>
static int debug;
-LIST_HEAD(trans);
+/* The registration list contains transcoders in the order in which they were
+ * registered. */
+static LIST_HEAD(registration_list);
+/* The active list is sorted by the most recently used transcoder is last. This
+ * is used as a simplistic way to spread the load amongst the different hardware
+ * transcoders in the system. */
+static LIST_HEAD(active_list);
static spinlock_t translock = SPIN_LOCK_UNLOCKED;
EXPORT_SYMBOL(zt_transcoder_register);
@@ -60,7 +66,9 @@ struct zt_transcoder *zt_transcoder_alloc(int numchans)
memset(tc, 0, size);
strcpy(tc->name, "<unspecified>");
tc->numchannels = numchans;
- INIT_LIST_HEAD(&tc->node);
+ INIT_LIST_HEAD(&tc->registration_list_node);
+ INIT_LIST_HEAD(&tc->active_list_node);
+
for (x=0;x<tc->numchannels;x++) {
init_waitqueue_head(&tc->channels[x].ready);
tc->channels[x].parent = tc;
@@ -93,11 +101,10 @@ static int is_on_list(struct list_head *entry, struct list_head *head)
/* Register a transcoder */
int zt_transcoder_register(struct zt_transcoder *tc)
{
- static int count = 0;
- tc->pos = count++;
spin_lock(&translock);
- BUG_ON(is_on_list(&tc->node, &trans));
- list_add_tail(&tc->node, &trans);
+ BUG_ON(is_on_list(&tc->registration_list_node, &registration_list));
+ list_add_tail(&tc->registration_list_node, &registration_list);
+ list_add_tail(&tc->active_list_node, &active_list);
spin_unlock(&translock);
printk(KERN_INFO "%s: Registered codec translator '%s' " \
@@ -117,13 +124,14 @@ int zt_transcoder_unregister(struct zt_transcoder *tc)
* that is still in use? */
spin_lock(&translock);
- if (!is_on_list(&tc->node, &trans)) {
+ if (!is_on_list(&tc->registration_list_node, &registration_list)) {
spin_unlock(&translock);
printk(KERN_WARNING "%s: Failed to unregister %s, which is " \
"not currently registerd.\n", THIS_MODULE->name, tc->name);
return -EINVAL;
}
- list_del_init(&tc->node);
+ list_del_init(&tc->registration_list_node);
+ list_del_init(&tc->active_list_node);
spin_unlock(&translock);
printk(KERN_INFO "Unregistered codec translator '%s' with %d " \
@@ -223,7 +231,7 @@ __find_free_channel(struct list_head *list, const struct zt_transcoder_formats *
struct zt_transcoder_channel *chan = NULL;
unsigned int match = 0;
- list_for_each_entry(tc, list, node) {
+ list_for_each_entry(tc, list, active_list_node) {
if ((tc->dstfmts & fmts->dstfmt) && (tc->srcfmts & fmts->srcfmt)) {
/* We found a transcoder that can handle our formats.
* Now look for an available channel. */
@@ -234,7 +242,7 @@ __find_free_channel(struct list_head *list, const struct zt_transcoder_formats *
* transcoders (when there are more than one
* transcoder in the system) we'll move tc
* to the end of the list. */
- list_move_tail(&tc->node, list);
+ list_move_tail(&tc->active_list_node, list);
return chan;
}
}
@@ -253,7 +261,7 @@ static long zt_tc_allocate(struct file *file, unsigned long data)
}
spin_lock(&translock);
- chan = __find_free_channel(&trans, &fmts);
+ chan = __find_free_channel(&active_list, &fmts);
spin_unlock(&translock);
if (IS_ERR(chan)) {
@@ -303,14 +311,15 @@ static long zt_tc_getinfo(unsigned long data)
struct zt_transcoder_info info;
struct zt_transcoder *cur;
struct zt_transcoder *tc = NULL;
+ unsigned int count = 0;
if (copy_from_user(&info, (const void *) data, sizeof(info))) {
return -EFAULT;
}
spin_lock(&translock);
- list_for_each_entry(cur, &trans, node) {
- if (cur->pos == info.tcnum) {
+ list_for_each_entry(cur, &registration_list, registration_list_node) {
+ if (info.tcnum == count++) {
tc = cur;
break;
}