diff options
-rw-r--r-- | drivers/usb/host/xhci-dbg.c | 101 | ||||
-rw-r--r-- | drivers/usb/host/xhci-hcd.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 15 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 19 |
4 files changed, 89 insertions, 53 deletions
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 6d62e4abe3c6..d77f8de11256 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c | |||
@@ -393,78 +393,103 @@ void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci) | |||
393 | upper_32_bits(val)); | 393 | upper_32_bits(val)); |
394 | } | 394 | } |
395 | 395 | ||
396 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep) | 396 | dma_addr_t xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_slot_ctx *slot, dma_addr_t dma) |
397 | { | 397 | { |
398 | int i, j; | ||
399 | int last_ep_ctx = 31; | ||
400 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | 398 | /* Fields are 32 bits wide, DMA addresses are in bytes */ |
401 | int field_size = 32 / 8; | 399 | int field_size = 32 / 8; |
402 | 400 | int i; | |
403 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n", | ||
404 | &ctx->drop_flags, (unsigned long long)dma, | ||
405 | ctx->drop_flags); | ||
406 | dma += field_size; | ||
407 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n", | ||
408 | &ctx->add_flags, (unsigned long long)dma, | ||
409 | ctx->add_flags); | ||
410 | dma += field_size; | ||
411 | for (i = 0; i < 6; ++i) { | ||
412 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", | ||
413 | &ctx->rsvd[i], (unsigned long long)dma, | ||
414 | ctx->rsvd[i], i); | ||
415 | dma += field_size; | ||
416 | } | ||
417 | 401 | ||
418 | xhci_dbg(xhci, "Slot Context:\n"); | 402 | xhci_dbg(xhci, "Slot Context:\n"); |
419 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n", | 403 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n", |
420 | &ctx->slot.dev_info, | 404 | &slot->dev_info, |
421 | (unsigned long long)dma, ctx->slot.dev_info); | 405 | (unsigned long long)dma, slot->dev_info); |
422 | dma += field_size; | 406 | dma += field_size; |
423 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n", | 407 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n", |
424 | &ctx->slot.dev_info2, | 408 | &slot->dev_info2, |
425 | (unsigned long long)dma, ctx->slot.dev_info2); | 409 | (unsigned long long)dma, slot->dev_info2); |
426 | dma += field_size; | 410 | dma += field_size; |
427 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n", | 411 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n", |
428 | &ctx->slot.tt_info, | 412 | &slot->tt_info, |
429 | (unsigned long long)dma, ctx->slot.tt_info); | 413 | (unsigned long long)dma, slot->tt_info); |
430 | dma += field_size; | 414 | dma += field_size; |
431 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n", | 415 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n", |
432 | &ctx->slot.dev_state, | 416 | &slot->dev_state, |
433 | (unsigned long long)dma, ctx->slot.dev_state); | 417 | (unsigned long long)dma, slot->dev_state); |
434 | dma += field_size; | 418 | dma += field_size; |
435 | for (i = 0; i < 4; ++i) { | 419 | for (i = 0; i < 4; ++i) { |
436 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", | 420 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", |
437 | &ctx->slot.reserved[i], (unsigned long long)dma, | 421 | &slot->reserved[i], (unsigned long long)dma, |
438 | ctx->slot.reserved[i], i); | 422 | slot->reserved[i], i); |
439 | dma += field_size; | 423 | dma += field_size; |
440 | } | 424 | } |
441 | 425 | ||
426 | return dma; | ||
427 | } | ||
428 | |||
429 | dma_addr_t xhci_dbg_ep_ctx(struct xhci_hcd *xhci, struct xhci_ep_ctx *ep, dma_addr_t dma, unsigned int last_ep) | ||
430 | { | ||
431 | int i, j; | ||
432 | int last_ep_ctx = 31; | ||
433 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | ||
434 | int field_size = 32 / 8; | ||
435 | |||
442 | if (last_ep < 31) | 436 | if (last_ep < 31) |
443 | last_ep_ctx = last_ep + 1; | 437 | last_ep_ctx = last_ep + 1; |
444 | for (i = 0; i < last_ep_ctx; ++i) { | 438 | for (i = 0; i < last_ep_ctx; ++i) { |
445 | xhci_dbg(xhci, "Endpoint %02d Context:\n", i); | 439 | xhci_dbg(xhci, "Endpoint %02d Context:\n", i); |
446 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", | 440 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", |
447 | &ctx->ep[i].ep_info, | 441 | &ep[i].ep_info, |
448 | (unsigned long long)dma, ctx->ep[i].ep_info); | 442 | (unsigned long long)dma, ep[i].ep_info); |
449 | dma += field_size; | 443 | dma += field_size; |
450 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n", | 444 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n", |
451 | &ctx->ep[i].ep_info2, | 445 | &ep[i].ep_info2, |
452 | (unsigned long long)dma, ctx->ep[i].ep_info2); | 446 | (unsigned long long)dma, ep[i].ep_info2); |
453 | dma += field_size; | 447 | dma += field_size; |
454 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n", | 448 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n", |
455 | &ctx->ep[i].deq, | 449 | &ep[i].deq, |
456 | (unsigned long long)dma, ctx->ep[i].deq); | 450 | (unsigned long long)dma, ep[i].deq); |
457 | dma += 2*field_size; | 451 | dma += 2*field_size; |
458 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n", | 452 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n", |
459 | &ctx->ep[i].tx_info, | 453 | &ep[i].tx_info, |
460 | (unsigned long long)dma, ctx->ep[i].tx_info); | 454 | (unsigned long long)dma, ep[i].tx_info); |
461 | dma += field_size; | 455 | dma += field_size; |
462 | for (j = 0; j < 3; ++j) { | 456 | for (j = 0; j < 3; ++j) { |
463 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", | 457 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", |
464 | &ctx->ep[i].reserved[j], | 458 | &ep[i].reserved[j], |
465 | (unsigned long long)dma, | 459 | (unsigned long long)dma, |
466 | ctx->ep[i].reserved[j], j); | 460 | ep[i].reserved[j], j); |
467 | dma += field_size; | 461 | dma += field_size; |
468 | } | 462 | } |
469 | } | 463 | } |
464 | return dma; | ||
465 | } | ||
466 | |||
467 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep) | ||
468 | { | ||
469 | int i; | ||
470 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | ||
471 | int field_size = 32 / 8; | ||
472 | |||
473 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n", | ||
474 | &ctx->drop_flags, (unsigned long long)dma, | ||
475 | ctx->drop_flags); | ||
476 | dma += field_size; | ||
477 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n", | ||
478 | &ctx->add_flags, (unsigned long long)dma, | ||
479 | ctx->add_flags); | ||
480 | dma += field_size; | ||
481 | for (i = 0; i < 6; ++i) { | ||
482 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", | ||
483 | &ctx->rsvd[i], (unsigned long long)dma, | ||
484 | ctx->rsvd[i], i); | ||
485 | dma += field_size; | ||
486 | } | ||
487 | dma = xhci_dbg_slot_ctx(xhci, &ctx->slot, dma); | ||
488 | dma = xhci_dbg_ep_ctx(xhci, ctx->ep, dma, last_ep); | ||
489 | } | ||
490 | |||
491 | void xhci_dbg_device_ctx(struct xhci_hcd *xhci, struct xhci_device_ctx *ctx, dma_addr_t dma, unsigned int last_ep) | ||
492 | { | ||
493 | dma = xhci_dbg_slot_ctx(xhci, &ctx->slot, dma); | ||
494 | dma = xhci_dbg_ep_ctx(xhci, ctx->ep, dma, last_ep); | ||
470 | } | 495 | } |
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index 008326d5bc52..921dd173d793 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c | |||
@@ -1013,7 +1013,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); | 1015 | xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); |
1016 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, | 1016 | xhci_dbg_device_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, |
1017 | LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info)); | 1017 | LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info)); |
1018 | 1018 | ||
1019 | xhci_zero_in_ctx(virt_dev); | 1019 | xhci_zero_in_ctx(virt_dev); |
@@ -1265,7 +1265,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
1265 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); | 1265 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); |
1266 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma, 2); | 1266 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma, 2); |
1267 | xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); | 1267 | xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); |
1268 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, 2); | 1268 | xhci_dbg_device_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, 2); |
1269 | /* | 1269 | /* |
1270 | * USB core uses address 1 for the roothubs, so we add one to the | 1270 | * USB core uses address 1 for the roothubs, so we add one to the |
1271 | * address given back to us by the HC. | 1271 | * address given back to us by the HC. |
@@ -1274,9 +1274,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
1274 | /* Zero the input context control for later use */ | 1274 | /* Zero the input context control for later use */ |
1275 | virt_dev->in_ctx->add_flags = 0; | 1275 | virt_dev->in_ctx->add_flags = 0; |
1276 | virt_dev->in_ctx->drop_flags = 0; | 1276 | virt_dev->in_ctx->drop_flags = 0; |
1277 | /* Mirror flags in the output context for future ep enable/disable */ | ||
1278 | virt_dev->out_ctx->add_flags = SLOT_FLAG | EP0_FLAG; | ||
1279 | virt_dev->out_ctx->drop_flags = 0; | ||
1280 | 1277 | ||
1281 | xhci_dbg(xhci, "Device address = %d\n", udev->devnum); | 1278 | xhci_dbg(xhci, "Device address = %d\n", udev->devnum); |
1282 | /* XXX Meh, not sure if anyone else but choose_address uses this. */ | 1279 | /* XXX Meh, not sure if anyone else but choose_address uses this. */ |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 71121d99235d..8d6bdf2f8015 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -235,7 +235,10 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | |||
235 | return 0; | 235 | return 0; |
236 | dev = xhci->devs[slot_id]; | 236 | dev = xhci->devs[slot_id]; |
237 | 237 | ||
238 | /* Allocate the (output) device context that will be used in the HC */ | 238 | /* Allocate the (output) device context that will be used in the HC. |
239 | * The structure is 32 bytes smaller than the input context, but that's | ||
240 | * fine. | ||
241 | */ | ||
239 | dev->out_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma); | 242 | dev->out_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma); |
240 | if (!dev->out_ctx) | 243 | if (!dev->out_ctx) |
241 | goto fail; | 244 | goto fail; |
@@ -260,16 +263,12 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | |||
260 | 263 | ||
261 | init_completion(&dev->cmd_completion); | 264 | init_completion(&dev->cmd_completion); |
262 | 265 | ||
263 | /* | 266 | /* Point to output device context in dcbaa. */ |
264 | * Point to output device context in dcbaa; skip the output control | 267 | xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx_dma; |
265 | * context, which is eight 32 bit fields (or 32 bytes long) | ||
266 | */ | ||
267 | xhci->dcbaa->dev_context_ptrs[slot_id] = | ||
268 | (u32) dev->out_ctx_dma + (32); | ||
269 | xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n", | 268 | xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n", |
270 | slot_id, | 269 | slot_id, |
271 | &xhci->dcbaa->dev_context_ptrs[slot_id], | 270 | &xhci->dcbaa->dev_context_ptrs[slot_id], |
272 | (unsigned long long)dev->out_ctx_dma); | 271 | (unsigned long long) xhci->dcbaa->dev_context_ptrs[slot_id]); |
273 | 272 | ||
274 | return 1; | 273 | return 1; |
275 | fail: | 274 | fail: |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 5a09b9a26e0d..d4d3c7777fb8 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -584,15 +584,29 @@ struct xhci_ep_ctx { | |||
584 | 584 | ||
585 | /** | 585 | /** |
586 | * struct xhci_device_control | 586 | * struct xhci_device_control |
587 | * Input/Output context; see section 6.2.5. | 587 | * Input context; see section 6.2.5. |
588 | * | 588 | * |
589 | * @drop_context: set the bit of the endpoint context you want to disable | 589 | * @drop_context: set the bit of the endpoint context you want to disable |
590 | * @add_context: set the bit of the endpoint context you want to enable | 590 | * @add_context: set the bit of the endpoint context you want to enable |
591 | */ | 591 | */ |
592 | struct xhci_device_control { | 592 | struct xhci_device_control { |
593 | /* Input control context */ | ||
593 | u32 drop_flags; | 594 | u32 drop_flags; |
594 | u32 add_flags; | 595 | u32 add_flags; |
595 | u32 rsvd[6]; | 596 | u32 rsvd[6]; |
597 | /* Copy of device context */ | ||
598 | struct xhci_slot_ctx slot; | ||
599 | struct xhci_ep_ctx ep[31]; | ||
600 | }; | ||
601 | |||
602 | /** | ||
603 | * struct xhci_device_ctx | ||
604 | * Device context; see section 6.2.1. | ||
605 | * | ||
606 | * @slot: slot context for the device. | ||
607 | * @ep: array of endpoint contexts for the device. | ||
608 | */ | ||
609 | struct xhci_device_ctx { | ||
596 | struct xhci_slot_ctx slot; | 610 | struct xhci_slot_ctx slot; |
597 | struct xhci_ep_ctx ep[31]; | 611 | struct xhci_ep_ctx ep[31]; |
598 | }; | 612 | }; |
@@ -612,7 +626,7 @@ struct xhci_virt_device { | |||
612 | * track of input and output contexts separately because | 626 | * track of input and output contexts separately because |
613 | * these commands might fail and we don't trust the hardware. | 627 | * these commands might fail and we don't trust the hardware. |
614 | */ | 628 | */ |
615 | struct xhci_device_control *out_ctx; | 629 | struct xhci_device_ctx *out_ctx; |
616 | dma_addr_t out_ctx_dma; | 630 | dma_addr_t out_ctx_dma; |
617 | /* Used for addressing devices and configuration changes */ | 631 | /* Used for addressing devices and configuration changes */ |
618 | struct xhci_device_control *in_ctx; | 632 | struct xhci_device_control *in_ctx; |
@@ -1126,6 +1140,7 @@ void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst); | |||
1126 | void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci); | 1140 | void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci); |
1127 | void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring); | 1141 | void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring); |
1128 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep); | 1142 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep); |
1143 | void xhci_dbg_device_ctx(struct xhci_hcd *xhci, struct xhci_device_ctx *ctx, dma_addr_t dma, unsigned int last_ep); | ||
1129 | 1144 | ||
1130 | /* xHCI memory managment */ | 1145 | /* xHCI memory managment */ |
1131 | void xhci_mem_cleanup(struct xhci_hcd *xhci); | 1146 | void xhci_mem_cleanup(struct xhci_hcd *xhci); |