Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+4 −15
Original line number Diff line number Diff line
@@ -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");