Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e64b037 authored by Mathias Nyman's avatar Mathias Nyman Committed by Greg Kroah-Hartman
Browse files

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: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9ef7fbbb
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -1817,11 +1817,8 @@ 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);
}
}

void xhci_free_command(struct xhci_hcd *xhci,
		struct xhci_command *command)
+10 −10
Original line number Diff line number Diff line
@@ -2838,7 +2838,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);
@@ -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)
		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)
@@ -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],
				       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);
	}
@@ -3279,7 +3279,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)
@@ -3567,7 +3567,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;
@@ -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. */

	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);
+6 −18
Original line number Diff line number Diff line
@@ -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);
	}

+1 −1
Original line number Diff line number Diff line
@@ -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];
};

/*