From c3fa4e0467ac533285f6111c426ef8785ea3becc Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Jul 2020 18:41:32 +0100 Subject: usb: host: xhci-mem: Demote obvious misuse of kerneldoc to standard comment block No attempt has been made to document the demoted function here. Fixes the following W=1 kernel build warning(s): drivers/usb/host/xhci-mem.c:365: warning: Function parameter or member 'xhci' not described in 'xhci_ring_alloc' drivers/usb/host/xhci-mem.c:365: warning: Function parameter or member 'num_segs' not described in 'xhci_ring_alloc' drivers/usb/host/xhci-mem.c:365: warning: Function parameter or member 'cycle_state' not described in 'xhci_ring_alloc' drivers/usb/host/xhci-mem.c:365: warning: Function parameter or member 'type' not described in 'xhci_ring_alloc' drivers/usb/host/xhci-mem.c:365: warning: Function parameter or member 'max_packet' not described in 'xhci_ring_alloc' drivers/usb/host/xhci-mem.c:365: warning: Function parameter or member 'flags' not described in 'xhci_ring_alloc' Cc: Mathias Nyman Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200703174148.2749969-15-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/host/xhci-mem.c') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 9764122c9cdf..fb221c091478 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -352,7 +352,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, return 0; } -/** +/* * Create a new ring with zero or more segments. * * Link each segment together into a ring. -- cgit v1.2.3 From e3bc8004bde77e899e8d19487440f27b55e216b2 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 23 Jul 2020 17:45:06 +0300 Subject: xhci: Don't pass struct xhci_hcd pointer to xhci_link_seg() It's only used to dig out if we need to set a chain flag for specific hosts. Pass the flag directly as a parameter instead. No functional changes. xhci_link_seg() is also used by DbC code, this change helps decoupling xhci and DbC. Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20200723144530.9992-4-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'drivers/usb/host/xhci-mem.c') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index fb221c091478..d38779e2fc84 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -96,8 +96,9 @@ static void xhci_free_segments_for_ring(struct xhci_hcd *xhci, * DMA address of the next segment. The caller needs to set any Link TRB * related flags, such as End TRB, Toggle Cycle, and no snoop. */ -static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, - struct xhci_segment *next, enum xhci_ring_type type) +static void xhci_link_segments(struct xhci_segment *prev, + struct xhci_segment *next, + enum xhci_ring_type type, bool chain_links) { u32 val; @@ -112,11 +113,7 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, val = le32_to_cpu(prev->trbs[TRBS_PER_SEGMENT-1].link.control); val &= ~TRB_TYPE_BITMASK; val |= TRB_TYPE(TRB_LINK); - /* Always set the chain bit with 0.95 hardware */ - /* Set chain bit for isoc rings on AMD 0.96 host */ - if (xhci_link_trb_quirk(xhci) || - (type == TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST))) + if (chain_links) val |= TRB_CHAIN; prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); } @@ -131,13 +128,19 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, unsigned int num_segs) { struct xhci_segment *next; + bool chain_links; if (!ring || !first || !last) return; + /* Set chain bit for 0.95 hosts, and for isoc rings on AMD 0.96 host */ + chain_links = !!(xhci_link_trb_quirk(xhci) || + (ring->type == TYPE_ISOC && + (xhci->quirks & XHCI_AMD_0x96_HOST))); + next = ring->enq_seg->next; - xhci_link_segments(xhci, ring->enq_seg, first, ring->type); - xhci_link_segments(xhci, last, next, ring->type); + xhci_link_segments(ring->enq_seg, first, ring->type, chain_links); + xhci_link_segments(last, next, ring->type, chain_links); ring->num_segs += num_segs; ring->num_trbs_free += (TRBS_PER_SEGMENT - 1) * num_segs; @@ -321,6 +324,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) { struct xhci_segment *prev; + bool chain_links; + + /* Set chain bit for 0.95 hosts, and for isoc rings on AMD 0.96 host */ + chain_links = !!(xhci_link_trb_quirk(xhci) || + (type == TYPE_ISOC && + (xhci->quirks & XHCI_AMD_0x96_HOST))); prev = xhci_segment_alloc(xhci, cycle_state, max_packet, flags); if (!prev) @@ -341,12 +350,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, } return -ENOMEM; } - xhci_link_segments(xhci, prev, next, type); + xhci_link_segments(prev, next, type, chain_links); prev = next; num_segs--; } - xhci_link_segments(xhci, prev, *first, type); + xhci_link_segments(prev, *first, type, chain_links); *last = prev; return 0; -- cgit v1.2.3 From ac286428c69fb3dc2924ce0ad5a11b5577b2f5da Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 23 Jul 2020 17:45:22 +0300 Subject: xhci: dbc: don't use generic xhci ring allocation functions for dbc. The generic xhci ring allocations code needs struct xhci_hcd pointer, and it allocates memory for the rings from dma pools created for the xhci device. In order to decouple xhci and DbC we have to create our own ring allocation and free routines for DbC Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20200723144530.9992-20-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-dbgcap.c | 80 ++++++++++++++++++++++++++++++++++++------ drivers/usb/host/xhci-mem.c | 4 +-- drivers/usb/host/xhci.h | 2 ++ 3 files changed, 74 insertions(+), 12 deletions(-) (limited to 'drivers/usb/host/xhci-mem.c') diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c index fb56198d3aff..b00cbff5e2ca 100644 --- a/drivers/usb/host/xhci-dbgcap.c +++ b/drivers/usb/host/xhci-dbgcap.c @@ -22,6 +22,21 @@ static void dbc_free_ctx(struct device *dev, struct xhci_container_ctx *ctx) kfree(ctx); } +/* we use only one segment for DbC rings */ +static void dbc_ring_free(struct device *dev, struct xhci_ring *ring) +{ + if (!ring) + return; + + if (ring->first_seg && ring->first_seg->trbs) { + dma_free_coherent(dev, TRB_SEGMENT_SIZE, + ring->first_seg->trbs, + ring->first_seg->dma); + kfree(ring->first_seg); + } + kfree(ring); +} + static u32 xhci_dbc_populate_strings(struct dbc_str_descs *strings) { struct usb_string_descriptor *s_desc; @@ -391,6 +406,51 @@ dbc_alloc_ctx(struct device *dev, gfp_t flags) return ctx; } +struct xhci_ring * +xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags) +{ + struct xhci_ring *ring; + struct xhci_segment *seg; + dma_addr_t dma; + + ring = kzalloc(sizeof(*ring), flags); + if (!ring) + return NULL; + + ring->num_segs = 1; + ring->type = type; + + seg = kzalloc(sizeof(*seg), flags); + if (!seg) + goto seg_fail; + + ring->first_seg = seg; + ring->last_seg = seg; + seg->next = seg; + + seg->trbs = dma_alloc_coherent(dev, TRB_SEGMENT_SIZE, &dma, flags); + if (!seg->trbs) + goto dma_fail; + + seg->dma = dma; + + /* Only event ring does not use link TRB */ + if (type != TYPE_EVENT) { + union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1]; + + trb->link.segment_ptr = cpu_to_le64(dma); + trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK)); + } + INIT_LIST_HEAD(&ring->td_list); + xhci_initialize_ring_info(ring, 1); + return ring; +dma_fail: + kfree(seg); +seg_fail: + kfree(ring); + return NULL; +} + static int xhci_dbc_mem_init(struct xhci_hcd *xhci, gfp_t flags) { int ret; @@ -400,15 +460,15 @@ static int xhci_dbc_mem_init(struct xhci_hcd *xhci, gfp_t flags) struct device *dev = xhci_to_hcd(xhci)->self.controller; /* Allocate various rings for events and transfers: */ - dbc->ring_evt = xhci_ring_alloc(xhci, 1, 1, TYPE_EVENT, 0, flags); + dbc->ring_evt = xhci_dbc_ring_alloc(dev, TYPE_EVENT, flags); if (!dbc->ring_evt) goto evt_fail; - dbc->ring_in = xhci_ring_alloc(xhci, 1, 1, TYPE_BULK, 0, flags); + dbc->ring_in = xhci_dbc_ring_alloc(dev, TYPE_BULK, flags); if (!dbc->ring_in) goto in_fail; - dbc->ring_out = xhci_ring_alloc(xhci, 1, 1, TYPE_BULK, 0, flags); + dbc->ring_out = xhci_dbc_ring_alloc(dev, TYPE_BULK, flags); if (!dbc->ring_out) goto out_fail; @@ -452,13 +512,13 @@ string_fail: ctx_fail: dbc_erst_free(dev, &dbc->erst); erst_fail: - xhci_ring_free(xhci, dbc->ring_out); + dbc_ring_free(dev, dbc->ring_out); dbc->ring_out = NULL; out_fail: - xhci_ring_free(xhci, dbc->ring_in); + dbc_ring_free(dev, dbc->ring_in); dbc->ring_in = NULL; in_fail: - xhci_ring_free(xhci, dbc->ring_evt); + dbc_ring_free(dev, dbc->ring_evt); dbc->ring_evt = NULL; evt_fail: return -ENOMEM; @@ -483,10 +543,10 @@ static void xhci_dbc_mem_cleanup(struct xhci_hcd *xhci) dbc_free_ctx(dbc->dev, dbc->ctx); dbc->ctx = NULL; - dbc_erst_free(dev, &dbc->erst); - xhci_ring_free(xhci, dbc->ring_out); - xhci_ring_free(xhci, dbc->ring_in); - xhci_ring_free(xhci, dbc->ring_evt); + dbc_erst_free(dbc->dev, &dbc->erst); + dbc_ring_free(dbc->dev, dbc->ring_out); + dbc_ring_free(dbc->dev, dbc->ring_in); + dbc_ring_free(dbc->dev, dbc->ring_evt); dbc->ring_in = NULL; dbc->ring_out = NULL; dbc->ring_evt = NULL; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index d38779e2fc84..696fad50b478 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -293,8 +293,8 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) kfree(ring); } -static void xhci_initialize_ring_info(struct xhci_ring *ring, - unsigned int cycle_state) +void xhci_initialize_ring_info(struct xhci_ring *ring, + unsigned int cycle_state) { /* The ring is empty, so the enqueue pointer == dequeue pointer */ ring->enqueue = ring->first_seg->trbs; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c295e8a7f5ae..ea1754f185a2 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2015,6 +2015,8 @@ int xhci_alloc_erst(struct xhci_hcd *xhci, struct xhci_ring *evt_ring, struct xhci_erst *erst, gfp_t flags); +void xhci_initialize_ring_info(struct xhci_ring *ring, + unsigned int cycle_state); void xhci_free_erst(struct xhci_hcd *xhci, struct xhci_erst *erst); void xhci_free_endpoint_ring(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, -- cgit v1.2.3