aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Youn <johnyoun@synopsys.com>2009-07-27 15:05:03 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-07-28 17:31:13 -0400
commit254c80a3a0eb811489f7410c3291f01a60e8e42f (patch)
tree2556e997876bc3e02f49bad8feb2a269103a5440
parent9f8e443816976edd68f415ea25c0223ea921e88c (diff)
USB: xhci: Scratchpad buffer allocation
Allocates and initializes the scratchpad buffer array (XHCI 4.20). This is an array of 64-bit DMA addresses to scratch pages that the controller may use during operation. The number of pages is specified in the "Max Scratchpad Buffers" field of HCSPARAMS2. The DMA address of this array is written into slot 0 of the DCBAA. Signed-off-by: John Youn <johnyoun@synopsys.com> Acked-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/xhci-mem.c102
-rw-r--r--drivers/usb/host/xhci.h11
2 files changed, 113 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 41aca003ee82..71121d99235d 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -545,6 +545,103 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci,
545 */ 545 */
546} 546}
547 547
548/* Set up the scratchpad buffer array and scratchpad buffers, if needed. */
549static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
550{
551 int i;
552 struct device *dev = xhci_to_hcd(xhci)->self.controller;
553 int num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);
554
555 xhci_dbg(xhci, "Allocating %d scratchpad buffers\n", num_sp);
556
557 if (!num_sp)
558 return 0;
559
560 xhci->scratchpad = kzalloc(sizeof(*xhci->scratchpad), flags);
561 if (!xhci->scratchpad)
562 goto fail_sp;
563
564 xhci->scratchpad->sp_array =
565 pci_alloc_consistent(to_pci_dev(dev),
566 num_sp * sizeof(u64),
567 &xhci->scratchpad->sp_dma);
568 if (!xhci->scratchpad->sp_array)
569 goto fail_sp2;
570
571 xhci->scratchpad->sp_buffers = kzalloc(sizeof(void *) * num_sp, flags);
572 if (!xhci->scratchpad->sp_buffers)
573 goto fail_sp3;
574
575 xhci->scratchpad->sp_dma_buffers =
576 kzalloc(sizeof(dma_addr_t) * num_sp, flags);
577
578 if (!xhci->scratchpad->sp_dma_buffers)
579 goto fail_sp4;
580
581 xhci->dcbaa->dev_context_ptrs[0] = xhci->scratchpad->sp_dma;
582 for (i = 0; i < num_sp; i++) {
583 dma_addr_t dma;
584 void *buf = pci_alloc_consistent(to_pci_dev(dev),
585 xhci->page_size, &dma);
586 if (!buf)
587 goto fail_sp5;
588
589 xhci->scratchpad->sp_array[i] = dma;
590 xhci->scratchpad->sp_buffers[i] = buf;
591 xhci->scratchpad->sp_dma_buffers[i] = dma;
592 }
593
594 return 0;
595
596 fail_sp5:
597 for (i = i - 1; i >= 0; i--) {
598 pci_free_consistent(to_pci_dev(dev), xhci->page_size,
599 xhci->scratchpad->sp_buffers[i],
600 xhci->scratchpad->sp_dma_buffers[i]);
601 }
602 kfree(xhci->scratchpad->sp_dma_buffers);
603
604 fail_sp4:
605 kfree(xhci->scratchpad->sp_buffers);
606
607 fail_sp3:
608 pci_free_consistent(to_pci_dev(dev), num_sp * sizeof(u64),
609 xhci->scratchpad->sp_array,
610 xhci->scratchpad->sp_dma);
611
612 fail_sp2:
613 kfree(xhci->scratchpad);
614 xhci->scratchpad = NULL;
615
616 fail_sp:
617 return -ENOMEM;
618}
619
620static void scratchpad_free(struct xhci_hcd *xhci)
621{
622 int num_sp;
623 int i;
624 struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
625
626 if (!xhci->scratchpad)
627 return;
628
629 num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);
630
631 for (i = 0; i < num_sp; i++) {
632 pci_free_consistent(pdev, xhci->page_size,
633 xhci->scratchpad->sp_buffers[i],
634 xhci->scratchpad->sp_dma_buffers[i]);
635 }
636 kfree(xhci->scratchpad->sp_dma_buffers);
637 kfree(xhci->scratchpad->sp_buffers);
638 pci_free_consistent(pdev, num_sp * sizeof(u64),
639 xhci->scratchpad->sp_array,
640 xhci->scratchpad->sp_dma);
641 kfree(xhci->scratchpad);
642 xhci->scratchpad = NULL;
643}
644
548void xhci_mem_cleanup(struct xhci_hcd *xhci) 645void xhci_mem_cleanup(struct xhci_hcd *xhci)
549{ 646{
550 struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); 647 struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
@@ -593,6 +690,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
593 690
594 xhci->page_size = 0; 691 xhci->page_size = 0;
595 xhci->page_shift = 0; 692 xhci->page_shift = 0;
693 scratchpad_free(xhci);
596} 694}
597 695
598int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) 696int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
@@ -755,7 +853,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
755 for (i = 0; i < MAX_HC_SLOTS; ++i) 853 for (i = 0; i < MAX_HC_SLOTS; ++i)
756 xhci->devs[i] = 0; 854 xhci->devs[i] = 0;
757 855
856 if (scratchpad_alloc(xhci, flags))
857 goto fail;
858
758 return 0; 859 return 0;
860
759fail: 861fail:
760 xhci_warn(xhci, "Couldn't initialize memory\n"); 862 xhci_warn(xhci, "Couldn't initialize memory\n");
761 xhci_mem_cleanup(xhci); 863 xhci_mem_cleanup(xhci);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 074728e10225..5a09b9a26e0d 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -89,6 +89,7 @@ struct xhci_cap_regs {
89#define HCS_ERST_MAX(p) (((p) >> 4) & 0xf) 89#define HCS_ERST_MAX(p) (((p) >> 4) & 0xf)
90/* bit 26 Scratchpad restore - for save/restore HW state - not used yet */ 90/* bit 26 Scratchpad restore - for save/restore HW state - not used yet */
91/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */ 91/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */
92#define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f)
92 93
93/* HCSPARAMS3 - hcs_params3 - bitmasks */ 94/* HCSPARAMS3 - hcs_params3 - bitmasks */
94/* bits 0:7, Max U1 to U0 latency for the roothub ports */ 95/* bits 0:7, Max U1 to U0 latency for the roothub ports */
@@ -951,6 +952,13 @@ struct xhci_erst {
951 unsigned int erst_size; 952 unsigned int erst_size;
952}; 953};
953 954
955struct xhci_scratchpad {
956 u64 *sp_array;
957 dma_addr_t sp_dma;
958 void **sp_buffers;
959 dma_addr_t *sp_dma_buffers;
960};
961
954/* 962/*
955 * Each segment table entry is 4*32bits long. 1K seems like an ok size: 963 * Each segment table entry is 4*32bits long. 1K seems like an ok size:
956 * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table, 964 * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
@@ -1005,6 +1013,9 @@ struct xhci_hcd {
1005 struct xhci_ring *cmd_ring; 1013 struct xhci_ring *cmd_ring;
1006 struct xhci_ring *event_ring; 1014 struct xhci_ring *event_ring;
1007 struct xhci_erst erst; 1015 struct xhci_erst erst;
1016 /* Scratchpad */
1017 struct xhci_scratchpad *scratchpad;
1018
1008 /* slot enabling and address device helpers */ 1019 /* slot enabling and address device helpers */
1009 struct completion addr_dev; 1020 struct completion addr_dev;
1010 int slot_id; 1021 int slot_id;