| From 16082b87853b93a25922e59440045f57fb5df292 Mon Sep 17 00:00:00 2001 |
| From: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Date: Mon, 23 Jan 2017 14:20:26 +0200 |
| Subject: [PATCH 212/255] xhci: simplify how we store TDs in urb private data |
| |
| Instead of storing a zero length array of td pointers, and then |
| allocate memory both for the td pointer array and the td's, just |
| use a zero length array of actual td's in urb private data. |
| |
| old: |
| |
| struct urb_priv { |
| struct xhci_td *td[0] |
| } |
| |
| new: |
| |
| struct urb_priv { |
| struct xhci_td td[0] |
| } |
| |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| (cherry picked from commit 7e64b0373af50fa46d3bf441f1c079615bbdf77f) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/usb/host/xhci-mem.c | 5 +---- |
| drivers/usb/host/xhci-ring.c | 20 ++++++++++---------- |
| drivers/usb/host/xhci.c | 24 ++++++------------------ |
| drivers/usb/host/xhci.h | 2 +- |
| 4 files changed, 18 insertions(+), 33 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-mem.c |
| +++ b/drivers/usb/host/xhci-mem.c |
| @@ -1845,10 +1845,7 @@ struct xhci_command *xhci_alloc_command( |
| |
| void xhci_urb_free_priv(struct urb_priv *urb_priv) |
| { |
| - if (urb_priv) { |
| - kfree(urb_priv->td[0]); |
| - kfree(urb_priv); |
| - } |
| + kfree(urb_priv); |
| } |
| |
| void xhci_free_command(struct xhci_hcd *xhci, |
| --- a/drivers/usb/host/xhci-ring.c |
| +++ b/drivers/usb/host/xhci-ring.c |
| @@ -2841,7 +2841,7 @@ static int prepare_transfer(struct xhci_ |
| return ret; |
| |
| urb_priv = urb->hcpriv; |
| - td = urb_priv->td[td_index]; |
| + td = &urb_priv->td[td_index]; |
| |
| INIT_LIST_HEAD(&td->td_list); |
| INIT_LIST_HEAD(&td->cancelled_td_list); |
| @@ -3137,7 +3137,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd * |
| if (urb->transfer_flags & URB_ZERO_PACKET && urb_priv->num_tds > 1) |
| need_zero_pkt = true; |
| |
| - td = urb_priv->td[0]; |
| + td = &urb_priv->td[0]; |
| |
| /* |
| * Don't give the first TRB to the hardware (by toggling the cycle bit) |
| @@ -3230,7 +3230,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd * |
| ret = prepare_transfer(xhci, xhci->devs[slot_id], |
| ep_index, urb->stream_id, |
| 1, urb, 1, mem_flags); |
| - urb_priv->td[1]->last_trb = ring->enqueue; |
| + urb_priv->td[1].last_trb = ring->enqueue; |
| field = TRB_TYPE(TRB_NORMAL) | ring->cycle_state | TRB_IOC; |
| queue_trb(xhci, ring, 0, 0, 0, TRB_INTR_TARGET(0), field); |
| } |
| @@ -3282,7 +3282,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * |
| return ret; |
| |
| urb_priv = urb->hcpriv; |
| - td = urb_priv->td[0]; |
| + td = &urb_priv->td[0]; |
| |
| /* |
| * Don't give the first TRB to the hardware (by toggling the cycle bit) |
| @@ -3570,7 +3570,7 @@ static int xhci_queue_isoc_tx(struct xhc |
| return ret; |
| goto cleanup; |
| } |
| - td = urb_priv->td[i]; |
| + td = &urb_priv->td[i]; |
| |
| /* use SIA as default, if frame id is used overwrite it */ |
| sia_frame_id = TRB_SIA; |
| @@ -3677,20 +3677,20 @@ cleanup: |
| /* Clean up a partially enqueued isoc transfer. */ |
| |
| for (i--; i >= 0; i--) |
| - list_del_init(&urb_priv->td[i]->td_list); |
| + list_del_init(&urb_priv->td[i].td_list); |
| |
| /* Use the first TD as a temporary variable to turn the TDs we've queued |
| * into No-ops with a software-owned cycle bit. That way the hardware |
| * won't accidentally start executing bogus TDs when we partially |
| * overwrite them. td->first_trb and td->start_seg are already set. |
| */ |
| - urb_priv->td[0]->last_trb = ep_ring->enqueue; |
| + urb_priv->td[0].last_trb = ep_ring->enqueue; |
| /* Every TRB except the first & last will have its cycle bit flipped. */ |
| - td_to_noop(xhci, ep_ring, urb_priv->td[0], true); |
| + td_to_noop(xhci, ep_ring, &urb_priv->td[0], true); |
| |
| /* Reset the ring enqueue back to the first TRB and its cycle bit. */ |
| - ep_ring->enqueue = urb_priv->td[0]->first_trb; |
| - ep_ring->enq_seg = urb_priv->td[0]->start_seg; |
| + ep_ring->enqueue = urb_priv->td[0].first_trb; |
| + ep_ring->enq_seg = urb_priv->td[0].start_seg; |
| ep_ring->cycle_state = start_cycle; |
| ep_ring->num_trbs_free = ep_ring->num_trbs_free_temp; |
| usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
| --- a/drivers/usb/host/xhci.c |
| +++ b/drivers/usb/host/xhci.c |
| @@ -1377,12 +1377,11 @@ command_cleanup: |
| int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) |
| { |
| struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
| - struct xhci_td *buffer; |
| unsigned long flags; |
| int ret = 0; |
| unsigned int slot_id, ep_index; |
| struct urb_priv *urb_priv; |
| - int num_tds, i; |
| + int num_tds; |
| |
| if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, |
| true, true, __func__) <= 0) |
| @@ -1409,21 +1408,10 @@ int xhci_urb_enqueue(struct usb_hcd *hcd |
| num_tds = 1; |
| |
| urb_priv = kzalloc(sizeof(struct urb_priv) + |
| - num_tds * sizeof(struct xhci_td *), mem_flags); |
| + num_tds * sizeof(struct xhci_td), mem_flags); |
| if (!urb_priv) |
| return -ENOMEM; |
| |
| - buffer = kzalloc(num_tds * sizeof(struct xhci_td), mem_flags); |
| - if (!buffer) { |
| - kfree(urb_priv); |
| - return -ENOMEM; |
| - } |
| - |
| - for (i = 0; i < num_tds; i++) { |
| - urb_priv->td[i] = buffer; |
| - buffer++; |
| - } |
| - |
| urb_priv->num_tds = num_tds; |
| urb_priv->num_tds_done = 0; |
| urb->hcpriv = urb_priv; |
| @@ -1571,7 +1559,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd |
| for (i = urb_priv->num_tds_done; |
| i < urb_priv->num_tds && xhci->devs[urb->dev->slot_id]; |
| i++) { |
| - td = urb_priv->td[i]; |
| + td = &urb_priv->td[i]; |
| if (!list_empty(&td->td_list)) |
| list_del_init(&td->td_list); |
| if (!list_empty(&td->cancelled_td_list)) |
| @@ -1602,11 +1590,11 @@ int xhci_urb_dequeue(struct usb_hcd *hcd |
| urb, urb->dev->devpath, |
| urb->ep->desc.bEndpointAddress, |
| (unsigned long long) xhci_trb_virt_to_dma( |
| - urb_priv->td[i]->start_seg, |
| - urb_priv->td[i]->first_trb)); |
| + urb_priv->td[i].start_seg, |
| + urb_priv->td[i].first_trb)); |
| |
| for (; i < urb_priv->num_tds; i++) { |
| - td = urb_priv->td[i]; |
| + td = &urb_priv->td[i]; |
| list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); |
| } |
| |
| --- a/drivers/usb/host/xhci.h |
| +++ b/drivers/usb/host/xhci.h |
| @@ -1614,7 +1614,7 @@ struct xhci_scratchpad { |
| struct urb_priv { |
| int num_tds; |
| int num_tds_done; |
| - struct xhci_td *td[0]; |
| + struct xhci_td td[0]; |
| }; |
| |
| /* |