From 836880de628eb12634aa93930831b0ab4715ab8e Mon Sep 17 00:00:00 2001 From: tzafrir Date: Fri, 1 Dec 2006 00:07:25 +0000 Subject: 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 --- xpp/xbus-core.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'xpp/xbus-core.c') 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 #endif #include -#include /* for mdelay() to debug */ +#include /* 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) { -- cgit v1.2.3