提交 7e64b037 编写于 作者: M Mathias Nyman 提交者: Greg Kroah-Hartman

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: NMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 9ef7fbbb
...@@ -1817,10 +1817,7 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, ...@@ -1817,10 +1817,7 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
void xhci_urb_free_priv(struct urb_priv *urb_priv) void xhci_urb_free_priv(struct urb_priv *urb_priv)
{ {
if (urb_priv) { kfree(urb_priv);
kfree(urb_priv->td[0]);
kfree(urb_priv);
}
} }
void xhci_free_command(struct xhci_hcd *xhci, void xhci_free_command(struct xhci_hcd *xhci,
......
...@@ -2838,7 +2838,7 @@ static int prepare_transfer(struct xhci_hcd *xhci, ...@@ -2838,7 +2838,7 @@ static int prepare_transfer(struct xhci_hcd *xhci,
return ret; return ret;
urb_priv = urb->hcpriv; 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->td_list);
INIT_LIST_HEAD(&td->cancelled_td_list); INIT_LIST_HEAD(&td->cancelled_td_list);
...@@ -3134,7 +3134,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3134,7 +3134,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) if (urb->transfer_flags & URB_ZERO_PACKET && urb_priv->num_tds > 1)
need_zero_pkt = true; 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) * Don't give the first TRB to the hardware (by toggling the cycle bit)
...@@ -3227,7 +3227,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3227,7 +3227,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
ret = prepare_transfer(xhci, xhci->devs[slot_id], ret = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id, ep_index, urb->stream_id,
1, urb, 1, mem_flags); 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; field = TRB_TYPE(TRB_NORMAL) | ring->cycle_state | TRB_IOC;
queue_trb(xhci, ring, 0, 0, 0, TRB_INTR_TARGET(0), field); queue_trb(xhci, ring, 0, 0, 0, TRB_INTR_TARGET(0), field);
} }
...@@ -3279,7 +3279,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3279,7 +3279,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
return ret; return ret;
urb_priv = urb->hcpriv; 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) * Don't give the first TRB to the hardware (by toggling the cycle bit)
...@@ -3567,7 +3567,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3567,7 +3567,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
return ret; return ret;
goto cleanup; goto cleanup;
} }
td = urb_priv->td[i]; td = &urb_priv->td[i];
/* use SIA as default, if frame id is used overwrite it */ /* use SIA as default, if frame id is used overwrite it */
sia_frame_id = TRB_SIA; sia_frame_id = TRB_SIA;
...@@ -3674,20 +3674,20 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3674,20 +3674,20 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* Clean up a partially enqueued isoc transfer. */ /* Clean up a partially enqueued isoc transfer. */
for (i--; i >= 0; i--) 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 /* 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 * into No-ops with a software-owned cycle bit. That way the hardware
* won't accidentally start executing bogus TDs when we partially * won't accidentally start executing bogus TDs when we partially
* overwrite them. td->first_trb and td->start_seg are already set. * 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. */ /* 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. */ /* Reset the ring enqueue back to the first TRB and its cycle bit. */
ep_ring->enqueue = urb_priv->td[0]->first_trb; ep_ring->enqueue = urb_priv->td[0].first_trb;
ep_ring->enq_seg = urb_priv->td[0]->start_seg; ep_ring->enq_seg = urb_priv->td[0].start_seg;
ep_ring->cycle_state = start_cycle; ep_ring->cycle_state = start_cycle;
ep_ring->num_trbs_free = ep_ring->num_trbs_free_temp; ep_ring->num_trbs_free = ep_ring->num_trbs_free_temp;
usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
......
...@@ -1332,12 +1332,11 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, ...@@ -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) 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_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_td *buffer;
unsigned long flags; unsigned long flags;
int ret = 0; int ret = 0;
unsigned int slot_id, ep_index; unsigned int slot_id, ep_index;
struct urb_priv *urb_priv; struct urb_priv *urb_priv;
int num_tds, i; int num_tds;
if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, if (!urb || xhci_check_args(hcd, urb->dev, urb->ep,
true, true, __func__) <= 0) true, true, __func__) <= 0)
...@@ -1364,21 +1363,10 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1364,21 +1363,10 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
num_tds = 1; num_tds = 1;
urb_priv = kzalloc(sizeof(struct urb_priv) + 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) if (!urb_priv)
return -ENOMEM; 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 = num_tds;
urb_priv->num_tds_done = 0; urb_priv->num_tds_done = 0;
urb->hcpriv = urb_priv; urb->hcpriv = urb_priv;
...@@ -1526,7 +1514,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) ...@@ -1526,7 +1514,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
for (i = urb_priv->num_tds_done; for (i = urb_priv->num_tds_done;
i < urb_priv->num_tds && xhci->devs[urb->dev->slot_id]; i < urb_priv->num_tds && xhci->devs[urb->dev->slot_id];
i++) { i++) {
td = urb_priv->td[i]; td = &urb_priv->td[i];
if (!list_empty(&td->td_list)) if (!list_empty(&td->td_list))
list_del_init(&td->td_list); list_del_init(&td->td_list);
if (!list_empty(&td->cancelled_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) ...@@ -1557,11 +1545,11 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
urb, urb->dev->devpath, urb, urb->dev->devpath,
urb->ep->desc.bEndpointAddress, urb->ep->desc.bEndpointAddress,
(unsigned long long) xhci_trb_virt_to_dma( (unsigned long long) xhci_trb_virt_to_dma(
urb_priv->td[i]->start_seg, urb_priv->td[i].start_seg,
urb_priv->td[i]->first_trb)); urb_priv->td[i].first_trb));
for (; i < urb_priv->num_tds; i++) { 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); list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
} }
......
...@@ -1610,7 +1610,7 @@ struct xhci_scratchpad { ...@@ -1610,7 +1610,7 @@ struct xhci_scratchpad {
struct urb_priv { struct urb_priv {
int num_tds; int num_tds;
int num_tds_done; int num_tds_done;
struct xhci_td *td[0]; struct xhci_td td[0];
}; };
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册