summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wcte12xp
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2010-02-08 22:49:32 +0000
committerShaun Ruffell <sruffell@digium.com>2010-02-08 22:49:32 +0000
commit79a483ebbe9f7702529240ef4958209e1e2f5ed0 (patch)
tree7aa554e74ca4bf83805d382073efc91967f27f6c /drivers/dahdi/wcte12xp
parentf513583a07701753b68d9413eda5acea1edbb034 (diff)
vpmadt032,wcte12xp: Use a timeout on the read/write commands and during load.
It is possible for poorly behaving hardware (and driver bugs) to lockup the modprobe process by having it wait indefinitely for a command to complete that never will. DAHDI-451. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@8003 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wcte12xp')
-rw-r--r--drivers/dahdi/wcte12xp/base.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 43b5f5f..50aafd4 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -559,7 +559,7 @@ static inline int t1_setreg(struct t1 *wc, int addr, int val)
static int t1_getreg(struct t1 *wc, int addr)
{
struct command *cmd = NULL;
- int ret;
+ unsigned long ret;
might_sleep();
@@ -570,7 +570,15 @@ static int t1_getreg(struct t1 *wc, int addr)
cmd->data = 0x00;
cmd->flags = __CMD_RD;
submit_cmd(wc, cmd);
- wait_for_completion(&cmd->complete);
+ ret = wait_for_completion_timeout(&cmd->complete, HZ/5);
+ if (unlikely(ret)) {
+ if (printk_ratelimit()) {
+ dev_warn(&wc->vb.pdev->dev,
+ "Timeout in %s\n", __func__);
+ }
+ free_cmd(wc, cmd);
+ return -EIO;
+ }
ret = cmd->data;
free_cmd(wc, cmd);
return ret;
@@ -592,8 +600,8 @@ static void t1_setleds(struct t1 *wc, int leds)
static inline int t1_getpins(struct t1 *wc, int inisr)
{
- int ret = 0;
struct command *cmd;
+ unsigned long ret;
cmd = get_free_cmd(wc);
BUG_ON(!cmd);
@@ -602,10 +610,18 @@ static inline int t1_getpins(struct t1 *wc, int inisr)
cmd->data = 0x00;
cmd->flags = __CMD_PINS;
submit_cmd(wc, cmd);
- wait_for_completion(&cmd->complete);
+ ret = wait_for_completion_timeout(&cmd->complete, HZ/5);
+ if (unlikely(ret)) {
+ if (printk_ratelimit()) {
+ dev_warn(&wc->vb.pdev->dev,
+ "Timeout in %s\n", __func__);
+ }
+ free_cmd(wc, cmd);
+ return -EIO;
+ }
ret = cmd->data;
free_cmd(wc, cmd);
- return ret;
+ return 0;
}
static void __t1xxp_set_clear(struct t1 *wc, int channo)