diff options
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r-- | drivers/usb/host/xhci-hcd.c | 77 |
1 files changed, 68 insertions, 9 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index 4353c1c78935..1d4a1e3f9533 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c | |||
@@ -224,7 +224,7 @@ int xhci_init(struct usb_hcd *hcd) | |||
224 | xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); | 224 | xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); |
225 | xhci->quirks |= XHCI_LINK_TRB_QUIRK; | 225 | xhci->quirks |= XHCI_LINK_TRB_QUIRK; |
226 | } else { | 226 | } else { |
227 | xhci_dbg(xhci, "xHCI has no QUIRKS\n"); | 227 | xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n"); |
228 | } | 228 | } |
229 | retval = xhci_mem_init(xhci, GFP_KERNEL); | 229 | retval = xhci_mem_init(xhci, GFP_KERNEL); |
230 | xhci_dbg(xhci, "Finished xhci_init\n"); | 230 | xhci_dbg(xhci, "Finished xhci_init\n"); |
@@ -567,13 +567,22 @@ unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc) | |||
567 | return 1 << (xhci_get_endpoint_index(desc) + 1); | 567 | return 1 << (xhci_get_endpoint_index(desc) + 1); |
568 | } | 568 | } |
569 | 569 | ||
570 | /* Find the flag for this endpoint (for use in the control context). Use the | ||
571 | * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is | ||
572 | * bit 1, etc. | ||
573 | */ | ||
574 | unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index) | ||
575 | { | ||
576 | return 1 << (ep_index + 1); | ||
577 | } | ||
578 | |||
570 | /* Compute the last valid endpoint context index. Basically, this is the | 579 | /* Compute the last valid endpoint context index. Basically, this is the |
571 | * endpoint index plus one. For slot contexts with more than valid endpoint, | 580 | * endpoint index plus one. For slot contexts with more than valid endpoint, |
572 | * we find the most significant bit set in the added contexts flags. | 581 | * we find the most significant bit set in the added contexts flags. |
573 | * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 | 582 | * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 |
574 | * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. | 583 | * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. |
575 | */ | 584 | */ |
576 | static inline unsigned int xhci_last_valid_endpoint(u32 added_ctxs) | 585 | unsigned int xhci_last_valid_endpoint(u32 added_ctxs) |
577 | { | 586 | { |
578 | return fls(added_ctxs) - 1; | 587 | return fls(added_ctxs) - 1; |
579 | } | 588 | } |
@@ -1230,8 +1239,44 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1230 | xhci_zero_in_ctx(xhci, virt_dev); | 1239 | xhci_zero_in_ctx(xhci, virt_dev); |
1231 | } | 1240 | } |
1232 | 1241 | ||
1242 | void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, | ||
1243 | unsigned int slot_id, unsigned int ep_index, | ||
1244 | struct xhci_dequeue_state *deq_state) | ||
1245 | { | ||
1246 | struct xhci_container_ctx *in_ctx; | ||
1247 | struct xhci_input_control_ctx *ctrl_ctx; | ||
1248 | struct xhci_ep_ctx *ep_ctx; | ||
1249 | u32 added_ctxs; | ||
1250 | dma_addr_t addr; | ||
1251 | |||
1252 | xhci_endpoint_copy(xhci, xhci->devs[slot_id], ep_index); | ||
1253 | in_ctx = xhci->devs[slot_id]->in_ctx; | ||
1254 | ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); | ||
1255 | addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, | ||
1256 | deq_state->new_deq_ptr); | ||
1257 | if (addr == 0) { | ||
1258 | xhci_warn(xhci, "WARN Cannot submit config ep after " | ||
1259 | "reset ep command\n"); | ||
1260 | xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", | ||
1261 | deq_state->new_deq_seg, | ||
1262 | deq_state->new_deq_ptr); | ||
1263 | return; | ||
1264 | } | ||
1265 | ep_ctx->deq = addr | deq_state->new_cycle_state; | ||
1266 | |||
1267 | xhci_slot_copy(xhci, xhci->devs[slot_id]); | ||
1268 | |||
1269 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||
1270 | added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); | ||
1271 | ctrl_ctx->add_flags = added_ctxs | SLOT_FLAG; | ||
1272 | ctrl_ctx->drop_flags = added_ctxs; | ||
1273 | |||
1274 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", slot_id); | ||
1275 | xhci_dbg_ctx(xhci, in_ctx, ep_index); | ||
1276 | } | ||
1277 | |||
1233 | void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, | 1278 | void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, |
1234 | struct usb_device *udev, struct usb_host_endpoint *ep, | 1279 | struct usb_device *udev, |
1235 | unsigned int ep_index, struct xhci_ring *ep_ring) | 1280 | unsigned int ep_index, struct xhci_ring *ep_ring) |
1236 | { | 1281 | { |
1237 | struct xhci_dequeue_state deq_state; | 1282 | struct xhci_dequeue_state deq_state; |
@@ -1241,12 +1286,26 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, | |||
1241 | * or it will attempt to resend it on the next doorbell ring. | 1286 | * or it will attempt to resend it on the next doorbell ring. |
1242 | */ | 1287 | */ |
1243 | xhci_find_new_dequeue_state(xhci, udev->slot_id, | 1288 | xhci_find_new_dequeue_state(xhci, udev->slot_id, |
1244 | ep_index, ep_ring->stopped_td, &deq_state); | 1289 | ep_index, ep_ring->stopped_td, |
1290 | &deq_state); | ||
1245 | 1291 | ||
1246 | xhci_dbg(xhci, "Queueing new dequeue state\n"); | 1292 | /* HW with the reset endpoint quirk will use the saved dequeue state to |
1247 | xhci_queue_new_dequeue_state(xhci, ep_ring, | 1293 | * issue a configure endpoint command later. |
1248 | udev->slot_id, | 1294 | */ |
1249 | ep_index, &deq_state); | 1295 | if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { |
1296 | xhci_dbg(xhci, "Queueing new dequeue state\n"); | ||
1297 | xhci_queue_new_dequeue_state(xhci, ep_ring, | ||
1298 | udev->slot_id, | ||
1299 | ep_index, &deq_state); | ||
1300 | } else { | ||
1301 | /* Better hope no one uses the input context between now and the | ||
1302 | * reset endpoint completion! | ||
1303 | */ | ||
1304 | xhci_dbg(xhci, "Setting up input context for " | ||
1305 | "configure endpoint command\n"); | ||
1306 | xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, | ||
1307 | ep_index, &deq_state); | ||
1308 | } | ||
1250 | } | 1309 | } |
1251 | 1310 | ||
1252 | /* Deal with stalled endpoints. The core should have sent the control message | 1311 | /* Deal with stalled endpoints. The core should have sent the control message |
@@ -1293,7 +1352,7 @@ void xhci_endpoint_reset(struct usb_hcd *hcd, | |||
1293 | * command. Better hope that last command worked! | 1352 | * command. Better hope that last command worked! |
1294 | */ | 1353 | */ |
1295 | if (!ret) { | 1354 | if (!ret) { |
1296 | xhci_cleanup_stalled_ring(xhci, udev, ep, ep_index, ep_ring); | 1355 | xhci_cleanup_stalled_ring(xhci, udev, ep_index, ep_ring); |
1297 | kfree(ep_ring->stopped_td); | 1356 | kfree(ep_ring->stopped_td); |
1298 | xhci_ring_cmd_db(xhci); | 1357 | xhci_ring_cmd_db(xhci); |
1299 | } | 1358 | } |