diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-12-09 18:59:01 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-02 17:53:08 -0500 |
commit | 412566bd716397e28e81fc9b20804bc6a6daf14d (patch) | |
tree | 4013aaa1eda796f8dedea243167f3f4811d211b4 /drivers/usb/host | |
parent | c01591bd6ece72e1c099cbc25ed812e1add579dc (diff) |
USB: xhci: Refactor code to free or cache endpoint rings.
Refactor out the code to cache or free endpoint rings from recently
dropped or disabled endpoints. This code will be used by a new function
to reset a device and disable all endpoints except control endpoint 0.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/xhci-hcd.c | 19 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 25 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 3 |
3 files changed, 29 insertions, 18 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index 0c5c1b2f3263..451f53eec6d7 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c | |||
@@ -1266,30 +1266,13 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1266 | xhci_zero_in_ctx(xhci, virt_dev); | 1266 | xhci_zero_in_ctx(xhci, virt_dev); |
1267 | /* Install new rings and free or cache any old rings */ | 1267 | /* Install new rings and free or cache any old rings */ |
1268 | for (i = 1; i < 31; ++i) { | 1268 | for (i = 1; i < 31; ++i) { |
1269 | int rings_cached; | ||
1270 | |||
1271 | if (!virt_dev->eps[i].new_ring) | 1269 | if (!virt_dev->eps[i].new_ring) |
1272 | continue; | 1270 | continue; |
1273 | /* Only cache or free the old ring if it exists. | 1271 | /* Only cache or free the old ring if it exists. |
1274 | * It may not if this is the first add of an endpoint. | 1272 | * It may not if this is the first add of an endpoint. |
1275 | */ | 1273 | */ |
1276 | if (virt_dev->eps[i].ring) { | 1274 | if (virt_dev->eps[i].ring) { |
1277 | rings_cached = virt_dev->num_rings_cached; | 1275 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); |
1278 | if (rings_cached < XHCI_MAX_RINGS_CACHED) { | ||
1279 | virt_dev->num_rings_cached++; | ||
1280 | rings_cached = virt_dev->num_rings_cached; | ||
1281 | virt_dev->ring_cache[rings_cached] = | ||
1282 | virt_dev->eps[i].ring; | ||
1283 | xhci_dbg(xhci, "Cached old ring, " | ||
1284 | "%d ring%s cached\n", | ||
1285 | rings_cached, | ||
1286 | (rings_cached > 1) ? "s" : ""); | ||
1287 | } else { | ||
1288 | xhci_ring_free(xhci, virt_dev->eps[i].ring); | ||
1289 | xhci_dbg(xhci, "Ring cache full (%d rings), " | ||
1290 | "freeing ring\n", | ||
1291 | virt_dev->num_rings_cached); | ||
1292 | } | ||
1293 | } | 1276 | } |
1294 | virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; | 1277 | virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; |
1295 | virt_dev->eps[i].new_ring = NULL; | 1278 | virt_dev->eps[i].new_ring = NULL; |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index bffcef7a5545..1f1f8a0f2e66 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -198,6 +198,31 @@ fail: | |||
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
200 | 200 | ||
201 | void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci, | ||
202 | struct xhci_virt_device *virt_dev, | ||
203 | unsigned int ep_index) | ||
204 | { | ||
205 | int rings_cached; | ||
206 | |||
207 | rings_cached = virt_dev->num_rings_cached; | ||
208 | if (rings_cached < XHCI_MAX_RINGS_CACHED) { | ||
209 | virt_dev->num_rings_cached++; | ||
210 | rings_cached = virt_dev->num_rings_cached; | ||
211 | virt_dev->ring_cache[rings_cached] = | ||
212 | virt_dev->eps[ep_index].ring; | ||
213 | xhci_dbg(xhci, "Cached old ring, " | ||
214 | "%d ring%s cached\n", | ||
215 | rings_cached, | ||
216 | (rings_cached > 1) ? "s" : ""); | ||
217 | } else { | ||
218 | xhci_ring_free(xhci, virt_dev->eps[ep_index].ring); | ||
219 | xhci_dbg(xhci, "Ring cache full (%d rings), " | ||
220 | "freeing ring\n", | ||
221 | virt_dev->num_rings_cached); | ||
222 | } | ||
223 | virt_dev->eps[ep_index].ring = NULL; | ||
224 | } | ||
225 | |||
201 | /* Zero an endpoint ring (except for link TRBs) and move the enqueue and dequeue | 226 | /* Zero an endpoint ring (except for link TRBs) and move the enqueue and dequeue |
202 | * pointers to the beginning of the ring. | 227 | * pointers to the beginning of the ring. |
203 | */ | 228 | */ |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 877813505ef2..61747f3c5c8f 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1233,6 +1233,9 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, | |||
1233 | struct usb_device *udev, struct usb_host_endpoint *ep, | 1233 | struct usb_device *udev, struct usb_host_endpoint *ep, |
1234 | gfp_t mem_flags); | 1234 | gfp_t mem_flags); |
1235 | void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); | 1235 | void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); |
1236 | void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci, | ||
1237 | struct xhci_virt_device *virt_dev, | ||
1238 | unsigned int ep_index); | ||
1236 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, | 1239 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, |
1237 | bool allocate_completion, gfp_t mem_flags); | 1240 | bool allocate_completion, gfp_t mem_flags); |
1238 | void xhci_free_command(struct xhci_hcd *xhci, | 1241 | void xhci_free_command(struct xhci_hcd *xhci, |