46b61d63770401cf544ba51c4b276a3c7206beb9
[openwrt.git] / target / linux / adm5120 / patches-2.6.24 / 910-usb_manage_endpoint_queues.patch
1 Index: linux-2.6.24/drivers/usb/host/adm5120-hcd.c
2 ===================================================================
3 --- linux-2.6.24.orig/drivers/usb/host/adm5120-hcd.c
4 +++ linux-2.6.24/drivers/usb/host/adm5120-hcd.c
5 @@ -83,8 +83,8 @@ static void admhc_stop(struct usb_hcd *h
6  /*
7   * queue up an urb for anything except the root hub
8   */
9 -static int admhc_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
10 -       struct urb *urb, gfp_t mem_flags)
11 +static int admhc_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
12 +               gfp_t mem_flags)
13  {
14         struct admhcd   *ahcd = hcd_to_admhcd(hcd);
15         struct ed       *ed;
16 @@ -101,7 +101,7 @@ static int admhc_urb_enqueue(struct usb_
17  #endif
18  
19         /* every endpoint has an ed, locate and maybe (re)initialize it */
20 -       ed = ed_get(ahcd, ep, urb->dev, pipe, urb->interval);
21 +       ed = ed_get(ahcd, urb->ep, urb->dev, pipe, urb->interval);
22         if (!ed)
23                 return -ENOMEM;
24  
25 @@ -161,22 +161,17 @@ static int admhc_urb_enqueue(struct usb_
26                 goto fail;
27         }
28  
29 -       /* in case of unlink-during-submit */
30 -       spin_lock(&urb->lock);
31 -       if (urb->status != -EINPROGRESS) {
32 -               spin_unlock(&urb->lock);
33 -               urb->hcpriv = urb_priv;
34 -               finish_urb(ahcd, urb);
35 -               ret = 0;
36 +       ret = usb_hcd_link_urb_to_ep(hcd, urb);
37 +       if (ret)
38                 goto fail;
39 -       }
40  
41         /* schedule the ed if needed */
42         if (ed->state == ED_IDLE) {
43                 ret = ed_schedule(ahcd, ed);
44 -               if (ret < 0)
45 -                       goto fail0;
46 -
47 +               if (ret < 0) {
48 +                       usb_hcd_unlink_urb_from_ep(hcd, urb);
49 +                       goto fail;
50 +               }
51                 if (ed->type == PIPE_ISOCHRONOUS) {
52                         u16     frame = admhc_frame_no(ahcd);
53  
54 @@ -204,8 +199,6 @@ static int admhc_urb_enqueue(struct usb_
55         admhc_dump_ed(ahcd, "admhc_urb_enqueue", urb_priv->ed, 1);
56  #endif
57  
58 -fail0:
59 -       spin_unlock(&urb->lock);
60  fail:
61         if (ret)
62                 urb_priv_free(ahcd, urb_priv);
63 @@ -220,18 +213,23 @@ fail:
64   * asynchronously, and we might be dealing with an urb that's
65   * partially transferred, or an ED with other urbs being unlinked.
66   */
67 -static int admhc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
68 +static int admhc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
69 +               int status)
70  {
71         struct admhcd *ahcd = hcd_to_admhcd(hcd);
72         unsigned long flags;
73 +       int ret;
74  
75         spin_lock_irqsave(&ahcd->lock, flags);
76  
77  #ifdef ADMHC_VERBOSE_DEBUG
78         urb_print(ahcd, urb, "DEQUEUE", 1);
79  #endif
80 -
81 -       if (HC_IS_RUNNING(hcd->state)) {
82 +       ret = usb_hcd_check_unlink_urb(hcd, urb, status);
83 +       if (ret) {
84 +               /* Do nothing */
85 +               ;
86 +       } else if (HC_IS_RUNNING(hcd->state)) {
87                 struct urb_priv *urb_priv;
88  
89                 /* Unless an IRQ completed the unlink while it was being
90 @@ -253,7 +251,7 @@ static int admhc_urb_dequeue(struct usb_
91         }
92         spin_unlock_irqrestore(&ahcd->lock, flags);
93  
94 -       return 0;
95 +       return ret;
96  }
97  
98  /*-------------------------------------------------------------------------*/
99 Index: linux-2.6.24/drivers/usb/host/adm5120-q.c
100 ===================================================================
101 --- linux-2.6.24.orig/drivers/usb/host/adm5120-q.c
102 +++ linux-2.6.24/drivers/usb/host/adm5120-q.c
103 @@ -63,6 +63,7 @@ __acquires(ahcd->lock)
104  #endif
105  
106         /* urb->complete() can reenter this HCD */
107 +       usb_hcd_unlink_urb_from_ep(admhcd_to_hcd(ahcd), urb);
108         spin_unlock(&ahcd->lock);
109         usb_hcd_giveback_urb(admhcd_to_hcd(ahcd), urb);
110         spin_lock(&ahcd->lock);