Commit 35808787 authored by Tim Waugh's avatar Tim Waugh Committed by Linus Torvalds

[PATCH] 2.5.3-pre6: deadlock

This patch fixes a potential deadlock in ppdev.

	* drivers/char/ppdev.c: Watch out for errors from
	parport_claim_or_block.
	* drivers/parport/share.c: Watch out for signals.
	* drivers/parport/ChangeLog: Updated.
parent 82345017
...@@ -320,6 +320,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, ...@@ -320,6 +320,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
case PPCLAIM: case PPCLAIM:
{ {
struct ieee1284_info *info; struct ieee1284_info *info;
int ret;
if (pp->flags & PP_CLAIMED) { if (pp->flags & PP_CLAIMED) {
printk (KERN_DEBUG CHRDEV printk (KERN_DEBUG CHRDEV
...@@ -335,7 +336,10 @@ static int pp_ioctl(struct inode *inode, struct file *file, ...@@ -335,7 +336,10 @@ static int pp_ioctl(struct inode *inode, struct file *file,
} }
} }
parport_claim_or_block (pp->pdev); ret = parport_claim_or_block (pp->pdev);
if (ret < 0)
return ret;
pp->flags |= PP_CLAIMED; pp->flags |= PP_CLAIMED;
/* For interrupt-reporting to work, we need to be /* For interrupt-reporting to work, we need to be
......
2002-01-04 Tim Waugh <twaugh@redhat.com>
* share.c (parport_claim_or_block): Sleep interruptibly to prevent
a possible deadlock.
2002-01-13 Niels Kristian Bech Jensen <nkbj@image.dk> 2002-01-13 Niels Kristian Bech Jensen <nkbj@image.dk>
* parport_pc.c: Change some occurrences of frob_set_mode to * parport_pc.c: Change some occurrences of frob_set_mode to
......
...@@ -1011,7 +1011,11 @@ int parport_claim_or_block(struct pardevice *dev) ...@@ -1011,7 +1011,11 @@ int parport_claim_or_block(struct pardevice *dev)
/* If dev->waiting is clear now, an interrupt /* If dev->waiting is clear now, an interrupt
gave us the port and we would deadlock if we slept. */ gave us the port and we would deadlock if we slept. */
if (dev->waiting) { if (dev->waiting) {
sleep_on(&dev->wait_q); interruptible_sleep_on (&dev->wait_q);
if (signal_pending (current)) {
restore_flags (flags);
return -EINTR;
}
r = 1; r = 1;
} else { } else {
r = 0; r = 0;
...@@ -1084,7 +1088,7 @@ void parport_release(struct pardevice *dev) ...@@ -1084,7 +1088,7 @@ void parport_release(struct pardevice *dev)
if (pd->waiting & 2) { /* sleeping in claim_or_block */ if (pd->waiting & 2) { /* sleeping in claim_or_block */
parport_claim(pd); parport_claim(pd);
if (waitqueue_active(&pd->wait_q)) if (waitqueue_active(&pd->wait_q))
wake_up(&pd->wait_q); wake_up_interruptible(&pd->wait_q);
return; return;
} else if (pd->wakeup) { } else if (pd->wakeup) {
pd->wakeup(pd->private); pd->wakeup(pd->private);
......
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