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