[RFC 1/4] xHCI: make xhci->erst a pointer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch changes xhci->erst to a pointer, because in the following
interrupters implementation, xhci will have multiple erst and event rings.
xhci->erst will be extended to a pointer array and allocate memory when
needed will prevent unnecessary memory cost.

Signed-off-by: Andiry Xu <andiry.xu@xxxxxxx>
---
 drivers/usb/host/xhci-mem.c |   36 +++++++++++++++++++++---------------
 drivers/usb/host/xhci.c     |    2 +-
 drivers/usb/host/xhci.h     |    2 +-
 3 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1d0f45f..ad098dd 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1396,11 +1396,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 		xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
 		xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
 	}
-	size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
-	if (xhci->erst.entries)
+	size = sizeof(struct xhci_erst_entry)*(xhci->erst->num_entries);
+	if (xhci->erst->entries)
 		pci_free_consistent(pdev, size,
-				xhci->erst.entries, xhci->erst.erst_dma_addr);
-	xhci->erst.entries = NULL;
+				xhci->erst->entries, xhci->erst->erst_dma_addr);
+	xhci->erst->entries = NULL;
+	if (xhci->erst)
+		kfree(xhci->erst);
 	xhci_dbg(xhci, "Freed ERST\n");
 	if (xhci->event_ring)
 		xhci_ring_free(xhci, xhci->event_ring);
@@ -1910,6 +1912,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 	 * Event ring setup: Allocate a normal ring, but also setup
 	 * the event ring segment table (ERST).  Section 4.9.3.
 	 */
+	xhci_dbg(xhci, "// Allocating erst\n");
+	xhci->erst = kzalloc(sizeof(struct xhci_erst), flags);
+	if (!xhci->erst)
+		goto fail;
 	xhci_dbg(xhci, "// Allocating event ring\n");
 	xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, flags);
 	if (!xhci->event_ring)
@@ -1917,24 +1923,24 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 	if (xhci_check_trb_in_td_math(xhci, flags) < 0)
 		goto fail;
 
-	xhci->erst.entries = pci_alloc_consistent(to_pci_dev(dev),
+	xhci->erst->entries = pci_alloc_consistent(to_pci_dev(dev),
 			sizeof(struct xhci_erst_entry)*ERST_NUM_SEGS, &dma);
-	if (!xhci->erst.entries)
+	if (!xhci->erst->entries)
 		goto fail;
 	xhci_dbg(xhci, "// Allocated event ring segment table at 0x%llx\n",
 			(unsigned long long)dma);
 
-	memset(xhci->erst.entries, 0, sizeof(struct xhci_erst_entry)*ERST_NUM_SEGS);
-	xhci->erst.num_entries = ERST_NUM_SEGS;
-	xhci->erst.erst_dma_addr = dma;
+	memset(xhci->erst->entries, 0, sizeof(struct xhci_erst_entry)*ERST_NUM_SEGS);
+	xhci->erst->num_entries = ERST_NUM_SEGS;
+	xhci->erst->erst_dma_addr = dma;
 	xhci_dbg(xhci, "Set ERST to 0; private num segs = %i, virt addr = %p, dma addr = 0x%llx\n",
-			xhci->erst.num_entries,
-			xhci->erst.entries,
-			(unsigned long long)xhci->erst.erst_dma_addr);
+			xhci->erst->num_entries,
+			xhci->erst->entries,
+			(unsigned long long)xhci->erst->erst_dma_addr);
 
 	/* set ring base address and size for each segment table entry */
 	for (val = 0, seg = xhci->event_ring->first_seg; val < ERST_NUM_SEGS; val++) {
-		struct xhci_erst_entry *entry = &xhci->erst.entries[val];
+		struct xhci_erst_entry *entry = &xhci->erst->entries[val];
 		entry->seg_addr = seg->dma;
 		entry->seg_size = TRBS_PER_SEGMENT;
 		entry->rsvd = 0;
@@ -1952,10 +1958,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 	xhci_dbg(xhci, "// Set ERST entries to point to event ring.\n");
 	/* set the segment table base address */
 	xhci_dbg(xhci, "// Set ERST base address for ir_set 0 = 0x%llx\n",
-			(unsigned long long)xhci->erst.erst_dma_addr);
+			(unsigned long long)xhci->erst->erst_dma_addr);
 	val_64 = xhci_read_64(xhci, &xhci->ir_set->erst_base);
 	val_64 &= ERST_PTR_MASK;
-	val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK);
+	val_64 |= (xhci->erst->erst_dma_addr & (u64) ~ERST_PTR_MASK);
 	xhci_write_64(xhci, val_64, &xhci->ir_set->erst_base);
 
 	/* Set the event ring dequeue address */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 34cf4e1..d77b1b0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -446,7 +446,7 @@ int xhci_run(struct usb_hcd *hcd)
 	xhci_dbg_cmd_ptrs(xhci);
 
 	xhci_dbg(xhci, "ERST memory map follows:\n");
-	xhci_dbg_erst(xhci, &xhci->erst);
+	xhci_dbg_erst(xhci, xhci->erst);
 	xhci_dbg(xhci, "Event ring:\n");
 	xhci_debug_ring(xhci, xhci->event_ring);
 	xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 7f236fd..8883ce0 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1200,7 +1200,7 @@ struct xhci_hcd {
 	struct xhci_ring	*cmd_ring;
 	unsigned int		cmd_ring_reserved_trbs;
 	struct xhci_ring	*event_ring;
-	struct xhci_erst	erst;
+	struct xhci_erst	*erst;
 	/* Scratchpad */
 	struct xhci_scratchpad  *scratchpad;
 
-- 
1.7.0.4



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux