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.ny...@linux.intel.com>
---
 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(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index e452492..ba1853f4 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1817,10 +1817,7 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd 
*xhci,
 
 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,
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index dbbf8c2..5e51109 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2841,7 +2841,7 @@ static int prepare_transfer(struct xhci_hcd *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 *xhci, gfp_t 
mem_flags,
        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 *xhci, gfp_t 
mem_flags,
                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 *xhci, gfp_t 
mem_flags,
                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 xhci_hcd *xhci, 
gfp_t mem_flags,
                                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 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
        /* 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);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index bee6272..dde5c2d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1332,12 +1332,11 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, 
unsigned int slot_id,
 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)
@@ -1364,21 +1363,10 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb 
*urb, gfp_t mem_flags)
                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;
@@ -1526,7 +1514,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb 
*urb, int status)
                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))
@@ -1557,11 +1545,11 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb 
*urb, int status)
                                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);
        }
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index dab2719..da3eb69 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1610,7 +1610,7 @@ struct xhci_scratchpad {
 struct urb_priv {
        int     num_tds;
        int     num_tds_done;
-       struct  xhci_td *td[0];
+       struct  xhci_td td[0];
 };
 
 /*
-- 
1.9.1

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

Reply via email to