aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r--drivers/usb/host/xhci-hcd.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 0d5a8564ed17..5e92c72df642 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -1262,13 +1262,35 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
1262 LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); 1262 LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
1263 1263
1264 xhci_zero_in_ctx(xhci, virt_dev); 1264 xhci_zero_in_ctx(xhci, virt_dev);
1265 /* Free any old rings */ 1265 /* Install new rings and free or cache any old rings */
1266 for (i = 1; i < 31; ++i) { 1266 for (i = 1; i < 31; ++i) {
1267 if (virt_dev->eps[i].new_ring) { 1267 int rings_cached;
1268 xhci_ring_free(xhci, virt_dev->eps[i].ring); 1268
1269 virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; 1269 if (!virt_dev->eps[i].new_ring)
1270 virt_dev->eps[i].new_ring = NULL; 1270 continue;
1271 /* Only cache or free the old ring if it exists.
1272 * It may not if this is the first add of an endpoint.
1273 */
1274 if (virt_dev->eps[i].ring) {
1275 rings_cached = virt_dev->num_rings_cached;
1276 if (rings_cached < XHCI_MAX_RINGS_CACHED) {
1277 virt_dev->num_rings_cached++;
1278 rings_cached = virt_dev->num_rings_cached;
1279 virt_dev->ring_cache[rings_cached] =
1280 virt_dev->eps[i].ring;
1281 xhci_dbg(xhci, "Cached old ring, "
1282 "%d ring%s cached\n",
1283 rings_cached,
1284 (rings_cached > 1) ? "s" : "");
1285 } else {
1286 xhci_ring_free(xhci, virt_dev->eps[i].ring);
1287 xhci_dbg(xhci, "Ring cache full (%d rings), "
1288 "freeing ring\n",
1289 virt_dev->num_rings_cached);
1290 }
1271 } 1291 }
1292 virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
1293 virt_dev->eps[i].new_ring = NULL;
1272 } 1294 }
1273 1295
1274 return ret; 1296 return ret;