Commit 1f604c4b authored by Amol Lad's avatar Amol Lad Committed by Linus Torvalds

[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: default avatarAmol Lad <amol@verismonetworks.com>
Signed-off-by: default avatarKarsten Keil <kkeil@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 43530d2b
...@@ -155,21 +155,17 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) ...@@ -155,21 +155,17 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan)
if (card->debug_flags & LOG_SCHED_ASYN) if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); 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) { while (card->async_busy) {
sti();
if (card->debug_flags & LOG_SCHED_ASYN) if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg delayed"); hysdn_addlog(card, "async tx-cfg delayed");
msleep_interruptible(20); /* Timeout 20ms */ msleep_interruptible(20); /* Timeout 20ms */
if (!--cnt) { if (!--cnt)
spin_unlock_irqrestore(&card->hysdn_lock, flags);
return (-ERR_ASYNC_TIME); /* timed out */ return (-ERR_ASYNC_TIME); /* timed out */
}
cli();
} /* wait for buffer to become free */ } /* wait for buffer to become free */
spin_lock_irqsave(&card->hysdn_lock, flags);
strcpy(card->async_data, line); strcpy(card->async_data, line);
card->async_len = strlen(line) + 1; card->async_len = strlen(line) + 1;
card->async_channel = chan; card->async_channel = chan;
...@@ -177,30 +173,23 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) ...@@ -177,30 +173,23 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan)
/* now queue the task */ /* now queue the task */
schedule_work(&card->irq_queue); schedule_work(&card->irq_queue);
sti(); spin_unlock_irqrestore(&card->hysdn_lock, flags);
if (card->debug_flags & LOG_SCHED_ASYN) if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg data queued"); hysdn_addlog(card, "async tx-cfg data queued");
cnt++; /* short delay */ cnt++; /* short delay */
cli();
while (card->async_busy) { while (card->async_busy) {
sti();
if (card->debug_flags & LOG_SCHED_ASYN) if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); hysdn_addlog(card, "async tx-cfg waiting for tx-ready");
msleep_interruptible(20); /* Timeout 20ms */ msleep_interruptible(20); /* Timeout 20ms */
if (!--cnt) { if (!--cnt)
spin_unlock_irqrestore(&card->hysdn_lock, flags);
return (-ERR_ASYNC_TIME); /* timed out */ return (-ERR_ASYNC_TIME); /* timed out */
}
cli();
} /* wait for buffer to become free again */ } /* wait for buffer to become free again */
spin_unlock_irqrestore(&card->hysdn_lock, flags);
if (card->debug_flags & LOG_SCHED_ASYN) if (card->debug_flags & LOG_SCHED_ASYN)
hysdn_addlog(card, "async tx-cfg data send"); hysdn_addlog(card, "async tx-cfg data send");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment