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); |
