diff options
| author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2009-03-27 15:56:26 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:40 -0400 |
| commit | 22a0d6f1383c85a7a9759cb805fd06c848c9c4d3 (patch) | |
| tree | afb1ea26aeb23ed0cc570325f4db2aaf2441c2bb /drivers/usb/musb | |
| parent | 3e5c6dc71146c2c3f21d60d3b4b25dc7755d5339 (diff) | |
musb_host: simplify check for active URB
The existance of the scheduling list shouldn't matter in
determining whether there's currectly an URB executing on a
hardware endpoint. What should actually matter is the 'in_qh'
or 'out_qh' fields of the 'struct musb_hw_ep' -- those are
set in musb_start_urb() and cleared in musb_giveback() when
the endpoint's URB list drains. Hence we should be able to
replace the big *switch* statements in musb_urb_dequeue()
and musb_h_disable() with mere musb_ep_get_qh() calls...
While at it, do some more changes:
- add 'is_in' variable to musb_urb_dequeue();
- remove the unnecessary 'epnum' variable from musb_h_disable();
- fix the comment style in the vicinity.
This is a minor shrink of source and object code.
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/musb')
| -rw-r--r-- | drivers/usb/musb/musb_host.c | 72 |
1 files changed, 14 insertions, 58 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 17d14f26bd6c..e0dacbb336d0 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -2089,14 +2089,14 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 2089 | { | 2089 | { |
| 2090 | struct musb *musb = hcd_to_musb(hcd); | 2090 | struct musb *musb = hcd_to_musb(hcd); |
| 2091 | struct musb_qh *qh; | 2091 | struct musb_qh *qh; |
| 2092 | struct list_head *sched; | ||
| 2093 | unsigned long flags; | 2092 | unsigned long flags; |
| 2093 | int is_in = usb_pipein(urb->pipe); | ||
| 2094 | int ret; | 2094 | int ret; |
| 2095 | 2095 | ||
| 2096 | DBG(4, "urb=%p, dev%d ep%d%s\n", urb, | 2096 | DBG(4, "urb=%p, dev%d ep%d%s\n", urb, |
| 2097 | usb_pipedevice(urb->pipe), | 2097 | usb_pipedevice(urb->pipe), |
| 2098 | usb_pipeendpoint(urb->pipe), | 2098 | usb_pipeendpoint(urb->pipe), |
| 2099 | usb_pipein(urb->pipe) ? "in" : "out"); | 2099 | is_in ? "in" : "out"); |
| 2100 | 2100 | ||
| 2101 | spin_lock_irqsave(&musb->lock, flags); | 2101 | spin_lock_irqsave(&musb->lock, flags); |
| 2102 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); | 2102 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); |
| @@ -2107,45 +2107,23 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 2107 | if (!qh) | 2107 | if (!qh) |
| 2108 | goto done; | 2108 | goto done; |
| 2109 | 2109 | ||
| 2110 | /* Any URB not actively programmed into endpoint hardware can be | 2110 | /* |
| 2111 | * Any URB not actively programmed into endpoint hardware can be | ||
| 2111 | * immediately given back; that's any URB not at the head of an | 2112 | * immediately given back; that's any URB not at the head of an |
| 2112 | * endpoint queue, unless someday we get real DMA queues. And even | 2113 | * endpoint queue, unless someday we get real DMA queues. And even |
| 2113 | * if it's at the head, it might not be known to the hardware... | 2114 | * if it's at the head, it might not be known to the hardware... |
| 2114 | * | 2115 | * |
| 2115 | * Otherwise abort current transfer, pending dma, etc.; urb->status | 2116 | * Otherwise abort current transfer, pending DMA, etc.; urb->status |
| 2116 | * has already been updated. This is a synchronous abort; it'd be | 2117 | * has already been updated. This is a synchronous abort; it'd be |
| 2117 | * OK to hold off until after some IRQ, though. | 2118 | * OK to hold off until after some IRQ, though. |
| 2119 | * | ||
| 2120 | * NOTE: qh is invalid unless !list_empty(&hep->urb_list) | ||
| 2118 | */ | 2121 | */ |
| 2119 | if (!qh->is_ready || urb->urb_list.prev != &qh->hep->urb_list) | 2122 | if (!qh->is_ready |
| 2120 | ret = -EINPROGRESS; | 2123 | || urb->urb_list.prev != &qh->hep->urb_list |
| 2121 | else { | 2124 | || musb_ep_get_qh(qh->hw_ep, is_in) != qh) { |
| 2122 | switch (qh->type) { | ||
| 2123 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 2124 | sched = &musb->control; | ||
| 2125 | break; | ||
| 2126 | case USB_ENDPOINT_XFER_BULK: | ||
| 2127 | if (qh->mux == 1) { | ||
| 2128 | if (usb_pipein(urb->pipe)) | ||
| 2129 | sched = &musb->in_bulk; | ||
| 2130 | else | ||
| 2131 | sched = &musb->out_bulk; | ||
| 2132 | break; | ||
| 2133 | } | ||
| 2134 | default: | ||
| 2135 | /* REVISIT when we get a schedule tree, periodic | ||
| 2136 | * transfers won't always be at the head of a | ||
| 2137 | * singleton queue... | ||
| 2138 | */ | ||
| 2139 | sched = NULL; | ||
| 2140 | break; | ||
| 2141 | } | ||
| 2142 | } | ||
| 2143 | |||
| 2144 | /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ | ||
| 2145 | if (ret < 0 || (sched && qh != first_qh(sched))) { | ||
| 2146 | int ready = qh->is_ready; | 2125 | int ready = qh->is_ready; |
| 2147 | 2126 | ||
| 2148 | ret = 0; | ||
| 2149 | qh->is_ready = 0; | 2127 | qh->is_ready = 0; |
| 2150 | __musb_giveback(musb, urb, 0); | 2128 | __musb_giveback(musb, urb, 0); |
| 2151 | qh->is_ready = ready; | 2129 | qh->is_ready = ready; |
| @@ -2169,13 +2147,11 @@ done: | |||
| 2169 | static void | 2147 | static void |
| 2170 | musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) | 2148 | musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) |
| 2171 | { | 2149 | { |
| 2172 | u8 epnum = hep->desc.bEndpointAddress; | 2150 | u8 is_in = hep->desc.bEndpointAddress & USB_DIR_IN; |
| 2173 | unsigned long flags; | 2151 | unsigned long flags; |
| 2174 | struct musb *musb = hcd_to_musb(hcd); | 2152 | struct musb *musb = hcd_to_musb(hcd); |
| 2175 | u8 is_in = epnum & USB_DIR_IN; | ||
| 2176 | struct musb_qh *qh; | 2153 | struct musb_qh *qh; |
| 2177 | struct urb *urb; | 2154 | struct urb *urb; |
| 2178 | struct list_head *sched; | ||
| 2179 | 2155 | ||
| 2180 | spin_lock_irqsave(&musb->lock, flags); | 2156 | spin_lock_irqsave(&musb->lock, flags); |
| 2181 | 2157 | ||
| @@ -2183,31 +2159,11 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) | |||
| 2183 | if (qh == NULL) | 2159 | if (qh == NULL) |
| 2184 | goto exit; | 2160 | goto exit; |
| 2185 | 2161 | ||
| 2186 | switch (qh->type) { | 2162 | /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ |
| 2187 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 2188 | sched = &musb->control; | ||
| 2189 | break; | ||
| 2190 | case USB_ENDPOINT_XFER_BULK: | ||
| 2191 | if (qh->mux == 1) { | ||
| 2192 | if (is_in) | ||
| 2193 | sched = &musb->in_bulk; | ||
| 2194 | else | ||
| 2195 | sched = &musb->out_bulk; | ||
| 2196 | break; | ||
| 2197 | } | ||
| 2198 | default: | ||
| 2199 | /* REVISIT when we get a schedule tree, periodic transfers | ||
| 2200 | * won't always be at the head of a singleton queue... | ||
| 2201 | */ | ||
| 2202 | sched = NULL; | ||
| 2203 | break; | ||
| 2204 | } | ||
| 2205 | |||
| 2206 | /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ | ||
| 2207 | 2163 | ||
| 2208 | /* kick first urb off the hardware, if needed */ | 2164 | /* Kick the first URB off the hardware, if needed */ |
| 2209 | qh->is_ready = 0; | 2165 | qh->is_ready = 0; |
| 2210 | if (!sched || qh == first_qh(sched)) { | 2166 | if (musb_ep_get_qh(qh->hw_ep, is_in) == qh) { |
| 2211 | urb = next_urb(qh); | 2167 | urb = next_urb(qh); |
| 2212 | 2168 | ||
| 2213 | /* make software (then hardware) stop ASAP */ | 2169 | /* make software (then hardware) stop ASAP */ |
