aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-07-27 15:05:08 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-07-28 17:31:13 -0400
commit28c2d2efb48dec2f0b050affae6d5787d6449e47 (patch)
treeaaa5d3617857f0a40b964f85e371207ce761c373 /drivers/usb
parent254c80a3a0eb811489f7410c3291f01a60e8e42f (diff)
USB: xhci: Always align output device contexts to 64 bytes.
Make sure the xHCI output device context is 64-byte aligned. Previous code was using the same structure for both the output device context and the input control context. Since the structure had 32 bytes of flags before the device context, the output device context wouldn't be 64-byte aligned. Define a new structure to use for the output device context and clean up the debugging for these two structures. The copy of the device context in the input control context does *not* need to be 64-byte aligned. 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')
-rw-r--r--drivers/usb/host/xhci-dbg.c101
-rw-r--r--drivers/usb/host/xhci-hcd.c7
-rw-r--r--drivers/usb/host/xhci-mem.c15
-rw-r--r--drivers/usb/host/xhci.h19
4 files changed, 89 insertions, 53 deletions
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 6d62e4abe3c..d77f8de1125 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
396void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep) 396dma_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
429dma_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
467void 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
491void 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 008326d5bc5..921dd173d79 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 71121d99235..8d6bdf2f801 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;
275fail: 274fail:
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 5a09b9a26e0..d4d3c7777fb 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 */
592struct xhci_device_control { 592struct 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 */
609struct 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);
1126void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci); 1140void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
1127void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring); 1141void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
1128void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep); 1142void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep);
1143void 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 */
1131void xhci_mem_cleanup(struct xhci_hcd *xhci); 1146void xhci_mem_cleanup(struct xhci_hcd *xhci);