blob: 058c691b7291def2acd4131a80f5de96675d4c63 [file] [log] [blame]
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];
};
/*