From c4a17f9442a26f2d124d835e0986436837256b86 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Wed, 15 May 2013 17:36:23 -0500 Subject: [PATCH] wcte12xp: Allow non-interrupting cards to unload faster. If a card stops generating interrupts for any reason, it can take awhile to unload the driver while waiting for the commands to timeout. Now if there is a problem, immediately set a bit that the card is failed so that no new commands will be submitted. Also, do not free and commands in submit since all commands are freed in get results now. This prevents list/memory corruption when commands time out. Signed-off-by: Shaun Ruffell Signed-off-by: Russ Meyerriecks --- drivers/dahdi/wcte12xp/base.c | 14 ++++++++++++-- drivers/dahdi/wcte12xp/wcte12xp.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c index 22bd450..19ca58e 100644 --- a/drivers/dahdi/wcte12xp/base.c +++ b/drivers/dahdi/wcte12xp/base.c @@ -658,6 +658,17 @@ static int __t1_getresult(struct t1 *wc, struct command *cmd) might_sleep(); + if (test_bit(IOERROR, &wc->bit_flags)) { + spin_lock_irqsave(&wc->reglock, flags); + list_del_init(&cmd->node); + spin_unlock_irqrestore(&wc->reglock, flags); + if (printk_ratelimit()) { + dev_warn(&wc->vb.pdev->dev, + "Timeout in %s\n", __func__); + } + return -EIO; + } + ret = wait_for_completion_interruptible_timeout(&cmd->complete, HZ*10); if (unlikely(!ret)) { spin_lock_irqsave(&wc->reglock, flags); @@ -666,13 +677,13 @@ static int __t1_getresult(struct t1 *wc, struct command *cmd) * can go ahead and free it right away. */ list_del_init(&cmd->node); spin_unlock_irqrestore(&wc->reglock, flags); - free_cmd(wc, cmd); if (-ERESTARTSYS != ret) { if (printk_ratelimit()) { dev_warn(&wc->vb.pdev->dev, "Timeout in %s\n", __func__); } ret = -EIO; + set_bit(IOERROR, &wc->bit_flags); } return ret; } else { @@ -683,7 +694,6 @@ static int __t1_getresult(struct t1 *wc, struct command *cmd) ret = wait_for_completion_timeout(&cmd->complete, HZ*2); WARN_ON(!ret); ret = cmd->data; - free_cmd(wc, cmd); return ret; } } diff --git a/drivers/dahdi/wcte12xp/wcte12xp.h b/drivers/dahdi/wcte12xp/wcte12xp.h index 838f0dd..27ce597 100644 --- a/drivers/dahdi/wcte12xp/wcte12xp.h +++ b/drivers/dahdi/wcte12xp/wcte12xp.h @@ -114,6 +114,7 @@ struct t1 { #define INITIALIZED 1 #define SHUTDOWN 2 #define READY 3 +#define IOERROR 4 unsigned long bit_flags; unsigned long alarmtimer; unsigned char ledstate;