summaryrefslogtreecommitdiff
path: root/drivers/isdn
diff options
context:
space:
mode:
authorAmol Lad <amol@verismonetworks.com>2006-11-02 22:07:25 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-11-03 12:27:59 -0800
commit1f604c4bc078213aa1c4576efa0e8dad98522fa7 (patch)
treeace4a7db5da33a894009877e2b327bf56624efaa /drivers/isdn
parent43530d2b04b63ac4bb4ac25deee5f1180ccedc2e (diff)
downloadlinux-3.10-1f604c4bc078213aa1c4576efa0e8dad98522fa7.tar.gz
linux-3.10-1f604c4bc078213aa1c4576efa0e8dad98522fa7.tar.bz2
linux-3.10-1f604c4bc078213aa1c4576efa0e8dad98522fa7.zip
[PATCH] drivers/isdn/hysdn/hysdn_sched.c: sleep after taking spinlock fix
spin_lock_irq{save,restore} is incorrectly called here (the function can sleep after acquring the lock). done the necessary corrections and removed unwanted cli/sti. Signed-off-by: Amol Lad <amol@verismonetworks.com> Signed-off-by: Karsten Keil <kkeil@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/hysdn/hysdn_sched.c19
1 files changed, 4 insertions, 15 deletions
diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c
index 1fadf0133e9..18758772b74 100644
--- a/drivers/isdn/hysdn/hysdn_sched.c
+++ b/drivers/isdn/hysdn/hysdn_sched.c
@@ -155,21 +155,17 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan)
if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1);
- spin_lock_irqsave(&card->hysdn_lock, flags);
while (card->async_busy) {
- sti();
if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg delayed");
msleep_interruptible(20); /* Timeout 20ms */
- if (!--cnt) {
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
+ if (!--cnt)
return (-ERR_ASYNC_TIME); /* timed out */
- }
- cli();
} /* wait for buffer to become free */
+ spin_lock_irqsave(&card->hysdn_lock, flags);
strcpy(card->async_data, line);
card->async_len = strlen(line) + 1;
card->async_channel = chan;
@@ -177,30 +173,23 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan)
/* now queue the task */
schedule_work(&card->irq_queue);
- sti();
+ spin_unlock_irqrestore(&card->hysdn_lock, flags);
if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg data queued");
cnt++; /* short delay */
- cli();
while (card->async_busy) {
- sti();
if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg waiting for tx-ready");
msleep_interruptible(20); /* Timeout 20ms */
- if (!--cnt) {
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
+ if (!--cnt)
return (-ERR_ASYNC_TIME); /* timed out */
- }
- cli();
} /* wait for buffer to become free again */
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
-
if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg data send");