mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
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>
This commit is contained in:
parent
9ef7fbbb4f
commit
7e64b0373a
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 @@ cleanup:
|
|||||||
/* 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 @@ command_cleanup:
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user