summaryrefslogtreecommitdiff
path: root/xpp/xbus-core.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-12-01 00:07:25 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-12-01 00:07:25 +0000
commit836880de628eb12634aa93930831b0ab4715ab8e (patch)
tree0002b7cb1aa2339ce006920a38e40dbdd35b7791 /xpp/xbus-core.c
parent6c5117b69b53580b9eac7e9c9025af751450939f (diff)
r1666@boole: tzafrir | 2006-11-30 23:46:11 +0200
r2817@boole: oron | 2006-11-28 13:39:47 +0200 Maintenance branch for asterisk-1.2.x git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@1674 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/xbus-core.c')
-rw-r--r--xpp/xbus-core.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/xpp/xbus-core.c b/xpp/xbus-core.c
index 9f73a86..59db079 100644
--- a/xpp/xbus-core.c
+++ b/xpp/xbus-core.c
@@ -33,7 +33,7 @@
#include <linux/ctype.h>
#endif
#include <linux/device.h>
-#include <linux/delay.h> /* for mdelay() to debug */
+#include <linux/delay.h> /* for msleep() to debug */
#include "xpd.h"
#include "xpp_zap.h"
#include "xbus-core.h"
@@ -42,7 +42,7 @@
static const char rcsid[] = "$Id$";
/* Defines */
-#define POLL_TIMEOUT (MAX_XPDS) /* in jiffies */
+#define POLL_TIMEOUT (2*MAX_XPDS) /* in jiffies */
#define INITIALIZATION_TIMEOUT (40*HZ) /* in jiffies */
#define PROC_XBUSES "xbuses"
#define PROC_XBUS_SUMMARY "summary"
@@ -55,6 +55,7 @@ static int proc_xbus_command_write(struct file *file, const char __user *buffer,
/* Command line parameters */
extern int print_dbg;
+DEF_PARM(uint, poll_timeout, POLL_TIMEOUT,"Timeout (in jiffies) waiting for units to reply (default " __stringify(POLL_TIMEOUT) ")");
/* Forward declarations */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
@@ -226,7 +227,7 @@ static int xbus_poll(void *data)
ERR("%s is being removed...\n", xbus->busname);
return -EBUSY;
}
- mdelay(2); /* roundtrip for older polls */
+ msleep(2); /* roundtrip for older polls */
spin_lock_irqsave(&xbus->lock, flags);
DBG("%s\n", xbus->busname);
@@ -250,16 +251,18 @@ static int xbus_poll(void *data)
/*
* Wait for replies
*/
- DBG("%s: Polled %d XPD's. Waiting for replies max %d jiffies\n", xbus->busname, MAX_XPDS, POLL_TIMEOUT);
- ret = wait_event_interruptible_timeout(xbus->wait_for_polls, atomic_read(&xbus->count_poll_answers) >= MAX_XPDS, POLL_TIMEOUT);
+ DBG("%s: Polled %d XPD's. Waiting for replies max %d jiffies\n", xbus->busname, MAX_XPDS, poll_timeout);
+ ret = wait_event_interruptible_timeout(xbus->wait_for_polls, atomic_read(&xbus->count_poll_answers) >= MAX_XPDS, poll_timeout);
if(ret == 0) {
- ERR("%s: Poll timeout\n", xbus->busname);
- goto out;
+ ERR("%s: Poll timeout. Continuing anyway.\n", xbus->busname);
+ /*
+ * Continue processing. Maybe some units did reply.
+ */
} else if(ret < 0) {
ERR("%s: Poll interrupted %d\n", xbus->busname, ret);
goto out;
- }
- DBG("%s: Poll finished in %d jiffies. Start processing.\n", xbus->busname, POLL_TIMEOUT - ret);
+ } else
+ DBG("%s: Poll finished in %d jiffies.\n", xbus->busname, poll_timeout - ret);
/*
* Build removals/additions lists
*/
@@ -288,6 +291,10 @@ static int xbus_poll(void *data)
kfree(card_desc);
}
}
+ /*
+ * We set this *after* poll is finished, so wait_for_xpd_initialization can
+ * tell we already know how many units we have.
+ */
atomic_set(&xbus->count_xpds_to_initialize, count_added);
spin_unlock_irqrestore(&xbus->lock, flags);
INFO("%s: Poll results: removals=%d additions=%d\n", xbus->busname, count_removed, count_added);
@@ -659,7 +666,14 @@ static int xbus_read_waitfor_xpds(char *page, char **start, off_t off, int count
if(!xbus)
goto out;
DBG("%s: Waiting for card initialization of %d XPD's max %d seconds\n", xbus->busname, MAX_XPDS, INITIALIZATION_TIMEOUT/HZ);
+ /*
+ * xbus_poll sets count_xpds_to_initialize only when polling is finished.
+ * To prevent race conditions we test both:
+ * - It is none zero -- meaning we already have the poll results.
+ * - And all units have finished initialization.
+ */
ret = wait_event_interruptible_timeout(xbus->wait_for_xpd_initialization,
+ atomic_read(&xbus->count_xpds_to_initialize) &&
atomic_read(&xbus->count_xpds_initialized) >= atomic_read(&xbus->count_xpds_to_initialize),
INITIALIZATION_TIMEOUT);
if(ret == 0) {