aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hcd.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-07-27 15:03:31 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-07-28 17:31:12 -0400
commit8e595a5d30a5ee4bb745d4da6439d73ed7d91054 (patch)
tree0050cb2c24643b602a8b3c40adef3e7b73fe81fc /drivers/usb/host/xhci-hcd.c
parentb11069f5f6ce6e359f853e908b0917303fcdec8f (diff)
USB: xhci: Represent 64-bit addresses with one u64.
There are several xHCI data structures that use two 32-bit fields to represent a 64-bit address. Since some architectures don't support 64-bit PCI writes, the fields need to be written in two 32-bit writes. The xHCI specification says that if a platform is incapable of generating 64-bit writes, software must write the low 32-bits first, then the high 32-bits. Hardware that supports 64-bit addressing will wait for the high 32-bit write before reading the revised value, and hardware that only supports 32-bit writes will ignore the high 32-bit write. Previous xHCI code represented 64-bit addresses with two u32 values. This lead to buggy code that would write the 32-bits in the wrong order, or forget to write the upper 32-bits. Change the two u32s to one u64 and create a function call to write all 64-bit addresses in the proper order. This new function could be modified in the future if all platforms support 64-bit writes. 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/host/xhci-hcd.c')
-rw-r--r--drivers/usb/host/xhci-hcd.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index ff99365cae42..e15773598e4e 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -226,6 +226,7 @@ int xhci_init(struct usb_hcd *hcd)
226static void xhci_work(struct xhci_hcd *xhci) 226static void xhci_work(struct xhci_hcd *xhci)
227{ 227{
228 u32 temp; 228 u32 temp;
229 u64 temp_64;
229 230
230 /* 231 /*
231 * Clear the op reg interrupt status first, 232 * Clear the op reg interrupt status first,
@@ -249,8 +250,8 @@ static void xhci_work(struct xhci_hcd *xhci)
249 xhci_handle_event(xhci); 250 xhci_handle_event(xhci);
250 251
251 /* Clear the event handler busy flag; the event ring should be empty. */ 252 /* Clear the event handler busy flag; the event ring should be empty. */
252 temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); 253 temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
253 xhci_writel(xhci, temp & ~ERST_EHB, &xhci->ir_set->erst_dequeue[0]); 254 xhci_write_64(xhci, temp_64 & ~ERST_EHB, &xhci->ir_set->erst_dequeue);
254 /* Flush posted writes -- FIXME is this necessary? */ 255 /* Flush posted writes -- FIXME is this necessary? */
255 xhci_readl(xhci, &xhci->ir_set->irq_pending); 256 xhci_readl(xhci, &xhci->ir_set->irq_pending);
256} 257}
@@ -295,6 +296,7 @@ void xhci_event_ring_work(unsigned long arg)
295{ 296{
296 unsigned long flags; 297 unsigned long flags;
297 int temp; 298 int temp;
299 u64 temp_64;
298 struct xhci_hcd *xhci = (struct xhci_hcd *) arg; 300 struct xhci_hcd *xhci = (struct xhci_hcd *) arg;
299 int i, j; 301 int i, j;
300 302
@@ -311,9 +313,9 @@ void xhci_event_ring_work(unsigned long arg)
311 xhci_dbg(xhci, "Event ring:\n"); 313 xhci_dbg(xhci, "Event ring:\n");
312 xhci_debug_segment(xhci, xhci->event_ring->deq_seg); 314 xhci_debug_segment(xhci, xhci->event_ring->deq_seg);
313 xhci_dbg_ring_ptrs(xhci, xhci->event_ring); 315 xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
314 temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); 316 temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
315 temp &= ERST_PTR_MASK; 317 temp_64 &= ~ERST_PTR_MASK;
316 xhci_dbg(xhci, "ERST deq = 0x%x\n", temp); 318 xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
317 xhci_dbg(xhci, "Command ring:\n"); 319 xhci_dbg(xhci, "Command ring:\n");
318 xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); 320 xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg);
319 xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); 321 xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
@@ -356,6 +358,7 @@ void xhci_event_ring_work(unsigned long arg)
356int xhci_run(struct usb_hcd *hcd) 358int xhci_run(struct usb_hcd *hcd)
357{ 359{
358 u32 temp; 360 u32 temp;
361 u64 temp_64;
359 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 362 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
360 void (*doorbell)(struct xhci_hcd *) = NULL; 363 void (*doorbell)(struct xhci_hcd *) = NULL;
361 364
@@ -416,11 +419,9 @@ int xhci_run(struct usb_hcd *hcd)
416 xhci_dbg(xhci, "Event ring:\n"); 419 xhci_dbg(xhci, "Event ring:\n");
417 xhci_debug_ring(xhci, xhci->event_ring); 420 xhci_debug_ring(xhci, xhci->event_ring);
418 xhci_dbg_ring_ptrs(xhci, xhci->event_ring); 421 xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
419 temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); 422 temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
420 temp &= ERST_PTR_MASK; 423 temp_64 &= ~ERST_PTR_MASK;
421 xhci_dbg(xhci, "ERST deq = 0x%x\n", temp); 424 xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
422 temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[1]);
423 xhci_dbg(xhci, "ERST deq upper = 0x%x\n", temp);
424 425
425 temp = xhci_readl(xhci, &xhci->op_regs->command); 426 temp = xhci_readl(xhci, &xhci->op_regs->command);
426 temp |= (CMD_RUN); 427 temp |= (CMD_RUN);
@@ -888,8 +889,7 @@ static void xhci_zero_in_ctx(struct xhci_virt_device *virt_dev)
888 ep_ctx = &virt_dev->in_ctx->ep[i]; 889 ep_ctx = &virt_dev->in_ctx->ep[i];
889 ep_ctx->ep_info = 0; 890 ep_ctx->ep_info = 0;
890 ep_ctx->ep_info2 = 0; 891 ep_ctx->ep_info2 = 0;
891 ep_ctx->deq[0] = 0; 892 ep_ctx->deq = 0;
892 ep_ctx->deq[1] = 0;
893 ep_ctx->tx_info = 0; 893 ep_ctx->tx_info = 0;
894 } 894 }
895} 895}
@@ -1165,7 +1165,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
1165 struct xhci_virt_device *virt_dev; 1165 struct xhci_virt_device *virt_dev;
1166 int ret = 0; 1166 int ret = 0;
1167 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 1167 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
1168 u32 temp; 1168 u64 temp_64;
1169 1169
1170 if (!udev->slot_id) { 1170 if (!udev->slot_id) {
1171 xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); 1171 xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id);
@@ -1227,18 +1227,13 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
1227 if (ret) { 1227 if (ret) {
1228 return ret; 1228 return ret;
1229 } 1229 }
1230 temp = xhci_readl(xhci, &xhci->op_regs->dcbaa_ptr[0]); 1230 temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
1231 xhci_dbg(xhci, "Op regs DCBAA ptr[0] = %#08x\n", temp); 1231 xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64);
1232 temp = xhci_readl(xhci, &xhci->op_regs->dcbaa_ptr[1]); 1232 xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n",
1233 xhci_dbg(xhci, "Op regs DCBAA ptr[1] = %#08x\n", temp);
1234 xhci_dbg(xhci, "Slot ID %d dcbaa entry[0] @%p = %#08x\n",
1235 udev->slot_id,
1236 &xhci->dcbaa->dev_context_ptrs[2*udev->slot_id],
1237 xhci->dcbaa->dev_context_ptrs[2*udev->slot_id]);
1238 xhci_dbg(xhci, "Slot ID %d dcbaa entry[1] @%p = %#08x\n",
1239 udev->slot_id, 1233 udev->slot_id,
1240 &xhci->dcbaa->dev_context_ptrs[2*udev->slot_id+1], 1234 &xhci->dcbaa->dev_context_ptrs[udev->slot_id],
1241 xhci->dcbaa->dev_context_ptrs[2*udev->slot_id+1]); 1235 (unsigned long long)
1236 xhci->dcbaa->dev_context_ptrs[udev->slot_id]);
1242 xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", 1237 xhci_dbg(xhci, "Output Context DMA address = %#08llx\n",
1243 (unsigned long long)virt_dev->out_ctx_dma); 1238 (unsigned long long)virt_dev->out_ctx_dma);
1244 xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); 1239 xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);