[PATCH] drivers/isdn/hysdn/hysdn_sched.c: sleep after taking spinlock fix
authorAmol Lad <amol@verismonetworks.com>
Fri, 3 Nov 2006 06:07:25 +0000 (22:07 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 3 Nov 2006 20:27:59 +0000 (12:27 -0800)
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>
drivers/isdn/hysdn/hysdn_sched.c

index 1fadf01..1875877 100644 (file)
@@ -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");