[svn-commits] sruffell: linux/trunk r6114 - in /linux/trunk: drivers/dahdi/ include/dahdi/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed Mar 11 09:50:10 CDT 2009
Author: sruffell
Date: Wed Mar 11 09:50:06 2009
New Revision: 6114
URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6114
Log:
Keep transcoders on a list in registration order.
This fixes a bug where it was possible for there to be a transcoder in position
"1" but not in position "0" if a transcoder hardware driver was loaded,
unloaded, and reloaded again without also reloading dahdi_transcode. The result
is that codec_dahdi fails to enumerate all the transcoders in the system.
(closes issue #14627)
Reported by: xblurone
Modified:
linux/trunk/drivers/dahdi/dahdi_transcode.c
linux/trunk/include/dahdi/kernel.h
Modified: linux/trunk/drivers/dahdi/dahdi_transcode.c
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/drivers/dahdi/dahdi_transcode.c?view=diff&rev=6114&r1=6113&r2=6114
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_transcode.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_transcode.c Wed Mar 11 09:50:06 2009
@@ -39,7 +39,13 @@
#include <dahdi/kernel.h>
static int debug;
-static 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(dahdi_transcoder_register);
@@ -59,7 +65,8 @@
memset(tc, 0, size);
strcpy(tc->name, "<unspecified>");
- INIT_LIST_HEAD(&tc->node);
+ INIT_LIST_HEAD(&tc->registration_list_node);
+ INIT_LIST_HEAD(&tc->active_list_node);
tc->numchannels = numchans;
for (x=0; x < tc->numchannels; x++) {
init_waitqueue_head(&tc->channels[x].ready);
@@ -93,11 +100,10 @@
/* Register a transcoder */
int dahdi_transcoder_register(struct dahdi_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, ®istration_list));
+ list_add_tail(&tc->registration_list_node, ®istration_list);
+ list_add_tail(&tc->active_list_node, &active_list);
spin_unlock(&translock);
printk(KERN_INFO "%s: Registered codec translator '%s' " \
@@ -117,13 +123,14 @@
* that is still in use? */
spin_lock(&translock);
- if (!is_on_list(&tc->node, &trans)) {
+ if (!is_on_list(&tc->registration_list_node, ®istration_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 +230,7 @@
struct dahdi_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 +241,7 @@
* 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;
}
}
@@ -252,7 +259,7 @@
}
spin_lock(&translock);
- chan = __find_free_channel(&trans, &fmts);
+ chan = __find_free_channel(&active_list, &fmts);
spin_unlock(&translock);
if (IS_ERR(chan)) {
@@ -302,14 +309,15 @@
struct dahdi_transcoder_info info;
struct dahdi_transcoder *cur;
struct dahdi_transcoder *tc = NULL;
-
+ unsigned int count = 0;
+
if (copy_from_user(&info, (__user 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, ®istration_list, registration_list_node) {
+ if (info.tcnum == count++) {
tc = cur;
break;
}
Modified: linux/trunk/include/dahdi/kernel.h
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/include/dahdi/kernel.h?view=diff&rev=6114&r1=6113&r2=6114
==============================================================================
--- linux/trunk/include/dahdi/kernel.h (original)
+++ linux/trunk/include/dahdi/kernel.h Wed Mar 11 09:50:06 2009
@@ -690,8 +690,8 @@
}
struct dahdi_transcoder {
- struct list_head node;
- int pos;
+ struct list_head active_list_node;
+ struct list_head registration_list_node;
char name[80];
int numchannels;
unsigned int srcfmts;
More information about the svn-commits
mailing list