Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 304003
b: refs/heads/master
c: 4e09dcf
h: refs/heads/master
i:
  304001: 6d58d5a
  303999: fb42631
v: v3
  • Loading branch information
Huajun Li authored and Greg Kroah-Hartman committed May 18, 2012
1 parent 298004d commit 80ea3bf
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8377c94f627f7943da9a7eefdb21fd2e9e7ec629
refs/heads/master: 4e09dcf20f7b5358615514c2ec8584b248ab8874
33 changes: 25 additions & 8 deletions trunk/drivers/usb/core/devio.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,17 +333,14 @@ static struct async *async_getcompleted(struct dev_state *ps)
static struct async *async_getpending(struct dev_state *ps,
void __user *userurb)
{
unsigned long flags;
struct async *as;

spin_lock_irqsave(&ps->lock, flags);
list_for_each_entry(as, &ps->async_pending, asynclist)
if (as->userurb == userurb) {
list_del_init(&as->asynclist);
spin_unlock_irqrestore(&ps->lock, flags);
return as;
}
spin_unlock_irqrestore(&ps->lock, flags);

return NULL;
}

Expand Down Expand Up @@ -398,6 +395,7 @@ static void cancel_bulk_urbs(struct dev_state *ps, unsigned bulk_addr)
__releases(ps->lock)
__acquires(ps->lock)
{
struct urb *urb;
struct async *as;

/* Mark all the pending URBs that match bulk_addr, up to but not
Expand All @@ -420,8 +418,11 @@ __acquires(ps->lock)
list_for_each_entry(as, &ps->async_pending, asynclist) {
if (as->bulk_status == AS_UNLINK) {
as->bulk_status = 0; /* Only once */
urb = as->urb;
usb_get_urb(urb);
spin_unlock(&ps->lock); /* Allow completions */
usb_unlink_urb(as->urb);
usb_unlink_urb(urb);
usb_put_urb(urb);
spin_lock(&ps->lock);
goto rescan;
}
Expand Down Expand Up @@ -472,17 +473,21 @@ static void async_completed(struct urb *urb)

static void destroy_async(struct dev_state *ps, struct list_head *list)
{
struct urb *urb;
struct async *as;
unsigned long flags;

spin_lock_irqsave(&ps->lock, flags);
while (!list_empty(list)) {
as = list_entry(list->next, struct async, asynclist);
list_del_init(&as->asynclist);
urb = as->urb;
usb_get_urb(urb);

/* drop the spinlock so the completion handler can run */
spin_unlock_irqrestore(&ps->lock, flags);
usb_kill_urb(as->urb);
usb_kill_urb(urb);
usb_put_urb(urb);
spin_lock_irqsave(&ps->lock, flags);
}
spin_unlock_irqrestore(&ps->lock, flags);
Expand Down Expand Up @@ -1399,12 +1404,24 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg)

static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
{
struct urb *urb;
struct async *as;
unsigned long flags;

spin_lock_irqsave(&ps->lock, flags);
as = async_getpending(ps, arg);
if (!as)
if (!as) {
spin_unlock_irqrestore(&ps->lock, flags);
return -EINVAL;
usb_kill_urb(as->urb);
}

urb = as->urb;
usb_get_urb(urb);
spin_unlock_irqrestore(&ps->lock, flags);

usb_kill_urb(urb);
usb_put_urb(urb);

return 0;
}

Expand Down

0 comments on commit 80ea3bf

Please sign in to comment.