diff options
author | Shaun Ruffell <sruffell@digium.com> | 2010-02-08 22:49:32 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2010-02-08 22:49:32 +0000 |
commit | 79a483ebbe9f7702529240ef4958209e1e2f5ed0 (patch) | |
tree | 7aa554e74ca4bf83805d382073efc91967f27f6c /drivers/dahdi/wcte12xp | |
parent | f513583a07701753b68d9413eda5acea1edbb034 (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.c | 26 |
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) |