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

Commit 63a0d9ab authored by Sarah Sharp's avatar Sarah Sharp Committed by Greg Kroah-Hartman
Browse files

USB: xhci: Endpoint representation refactoring.



The xhci_ring structure contained information that is really related to an
endpoint, not a ring.  This will cause problems later when endpoint
streams are supported and there are multiple rings per endpoint.

Move the endpoint state and cancellation information into a new virtual
endpoint structure, xhci_virt_ep.  The list of TRBs to be cancelled should
be per endpoint, not per ring, for easy access.  There can be only one TRB
that the endpoint stopped on after a stop endpoint command (even with
streams enabled); move the stopped TRB information into the new virtual
endpoint structure.  Also move the 31 endpoint rings and temporary ring
storage from the virtual device structure (xhci_virt_device) into the
virtual endpoint structure (xhci_virt_ep).

Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9e221be8
Loading
Loading
Loading
Loading
+31 −28
Original line number Original line Diff line number Diff line
@@ -351,13 +351,14 @@ void xhci_event_ring_work(unsigned long arg)
	xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
	xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
	xhci_dbg_cmd_ptrs(xhci);
	xhci_dbg_cmd_ptrs(xhci);
	for (i = 0; i < MAX_HC_SLOTS; ++i) {
	for (i = 0; i < MAX_HC_SLOTS; ++i) {
		if (xhci->devs[i]) {
		if (!xhci->devs[i])
			continue;
		for (j = 0; j < 31; ++j) {
		for (j = 0; j < 31; ++j) {
				if (xhci->devs[i]->ep_rings[j]) {
			struct xhci_ring *ring = xhci->devs[i]->eps[j].ring;
			if (!ring)
				continue;
			xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
			xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
					xhci_debug_segment(xhci, xhci->devs[i]->ep_rings[j]->deq_seg);
			xhci_debug_segment(xhci, ring->deq_seg);
				}
			}
		}
		}
	}
	}


@@ -778,6 +779,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
	struct xhci_td *td;
	struct xhci_td *td;
	unsigned int ep_index;
	unsigned int ep_index;
	struct xhci_ring *ep_ring;
	struct xhci_ring *ep_ring;
	struct xhci_virt_ep *ep;


	xhci = hcd_to_xhci(hcd);
	xhci = hcd_to_xhci(hcd);
	spin_lock_irqsave(&xhci->lock, flags);
	spin_lock_irqsave(&xhci->lock, flags);
@@ -790,17 +792,18 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
	xhci_dbg(xhci, "Event ring:\n");
	xhci_dbg(xhci, "Event ring:\n");
	xhci_debug_ring(xhci, xhci->event_ring);
	xhci_debug_ring(xhci, xhci->event_ring);
	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
	ep_ring = xhci->devs[urb->dev->slot_id]->ep_rings[ep_index];
	ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
	ep_ring = ep->ring;
	xhci_dbg(xhci, "Endpoint ring:\n");
	xhci_dbg(xhci, "Endpoint ring:\n");
	xhci_debug_ring(xhci, ep_ring);
	xhci_debug_ring(xhci, ep_ring);
	td = (struct xhci_td *) urb->hcpriv;
	td = (struct xhci_td *) urb->hcpriv;


	ep_ring->cancels_pending++;
	ep->cancels_pending++;
	list_add_tail(&td->cancelled_td_list, &ep_ring->cancelled_td_list);
	list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
	/* Queue a stop endpoint command, but only if this is
	/* Queue a stop endpoint command, but only if this is
	 * the first cancellation to be handled.
	 * the first cancellation to be handled.
	 */
	 */
	if (ep_ring->cancels_pending == 1) {
	if (ep->cancels_pending == 1) {
		xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
		xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
		xhci_ring_cmd_db(xhci);
		xhci_ring_cmd_db(xhci);
	}
	}
@@ -1206,10 +1209,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
	xhci_zero_in_ctx(xhci, virt_dev);
	xhci_zero_in_ctx(xhci, virt_dev);
	/* Free any old rings */
	/* Free any old rings */
	for (i = 1; i < 31; ++i) {
	for (i = 1; i < 31; ++i) {
		if (virt_dev->new_ep_rings[i]) {
		if (virt_dev->eps[i].new_ring) {
			xhci_ring_free(xhci, virt_dev->ep_rings[i]);
			xhci_ring_free(xhci, virt_dev->eps[i].ring);
			virt_dev->ep_rings[i] = virt_dev->new_ep_rings[i];
			virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
			virt_dev->new_ep_rings[i] = NULL;
			virt_dev->eps[i].new_ring = NULL;
		}
		}
	}
	}


@@ -1236,9 +1239,9 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
	virt_dev = xhci->devs[udev->slot_id];
	virt_dev = xhci->devs[udev->slot_id];
	/* Free any rings allocated for added endpoints */
	/* Free any rings allocated for added endpoints */
	for (i = 0; i < 31; ++i) {
	for (i = 0; i < 31; ++i) {
		if (virt_dev->new_ep_rings[i]) {
		if (virt_dev->eps[i].new_ring) {
			xhci_ring_free(xhci, virt_dev->new_ep_rings[i]);
			xhci_ring_free(xhci, virt_dev->eps[i].new_ring);
			virt_dev->new_ep_rings[i] = NULL;
			virt_dev->eps[i].new_ring = NULL;
		}
		}
	}
	}
	xhci_zero_in_ctx(xhci, virt_dev);
	xhci_zero_in_ctx(xhci, virt_dev);
@@ -1281,17 +1284,18 @@ void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
}
}


void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
		struct usb_device *udev,
		struct usb_device *udev, unsigned int ep_index)
		unsigned int ep_index, struct xhci_ring *ep_ring)
{
{
	struct xhci_dequeue_state deq_state;
	struct xhci_dequeue_state deq_state;
	struct xhci_virt_ep *ep;


	xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
	xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
	ep = &xhci->devs[udev->slot_id]->eps[ep_index];
	/* We need to move the HW's dequeue pointer past this TD,
	/* We need to move the HW's dequeue pointer past this TD,
	 * or it will attempt to resend it on the next doorbell ring.
	 * or it will attempt to resend it on the next doorbell ring.
	 */
	 */
	xhci_find_new_dequeue_state(xhci, udev->slot_id,
	xhci_find_new_dequeue_state(xhci, udev->slot_id,
			ep_index, ep_ring->stopped_td,
			ep_index, ep->stopped_td,
			&deq_state);
			&deq_state);


	/* HW with the reset endpoint quirk will use the saved dequeue state to
	/* HW with the reset endpoint quirk will use the saved dequeue state to
@@ -1299,8 +1303,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
	 */
	 */
	if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
	if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
		xhci_dbg(xhci, "Queueing new dequeue state\n");
		xhci_dbg(xhci, "Queueing new dequeue state\n");
		xhci_queue_new_dequeue_state(xhci, ep_ring,
		xhci_queue_new_dequeue_state(xhci, udev->slot_id,
				udev->slot_id,
				ep_index, &deq_state);
				ep_index, &deq_state);
	} else {
	} else {
		/* Better hope no one uses the input context between now and the
		/* Better hope no one uses the input context between now and the
@@ -1327,7 +1330,7 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
	unsigned int ep_index;
	unsigned int ep_index;
	unsigned long flags;
	unsigned long flags;
	int ret;
	int ret;
	struct xhci_ring *ep_ring;
	struct xhci_virt_ep *virt_ep;


	xhci = hcd_to_xhci(hcd);
	xhci = hcd_to_xhci(hcd);
	udev = (struct usb_device *) ep->hcpriv;
	udev = (struct usb_device *) ep->hcpriv;
@@ -1337,8 +1340,8 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
	if (!ep->hcpriv)
	if (!ep->hcpriv)
		return;
		return;
	ep_index = xhci_get_endpoint_index(&ep->desc);
	ep_index = xhci_get_endpoint_index(&ep->desc);
	ep_ring = xhci->devs[udev->slot_id]->ep_rings[ep_index];
	virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index];
	if (!ep_ring->stopped_td) {
	if (!virt_ep->stopped_td) {
		xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n",
		xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n",
				ep->desc.bEndpointAddress);
				ep->desc.bEndpointAddress);
		return;
		return;
@@ -1357,8 +1360,8 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
	 * command.  Better hope that last command worked!
	 * command.  Better hope that last command worked!
	 */
	 */
	if (!ret) {
	if (!ret) {
		xhci_cleanup_stalled_ring(xhci, udev, ep_index, ep_ring);
		xhci_cleanup_stalled_ring(xhci, udev, ep_index);
		kfree(ep_ring->stopped_td);
		kfree(virt_ep->stopped_td);
		xhci_ring_cmd_db(xhci);
		xhci_ring_cmd_db(xhci);
	}
	}
	spin_unlock_irqrestore(&xhci->lock, flags);
	spin_unlock_irqrestore(&xhci->lock, flags);
+15 −10
Original line number Original line Diff line number Diff line
@@ -144,7 +144,6 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
		return 0;
		return 0;


	INIT_LIST_HEAD(&ring->td_list);
	INIT_LIST_HEAD(&ring->td_list);
	INIT_LIST_HEAD(&ring->cancelled_td_list);
	if (num_segs == 0)
	if (num_segs == 0)
		return ring;
		return ring;


@@ -265,8 +264,8 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
		return;
		return;


	for (i = 0; i < 31; ++i)
	for (i = 0; i < 31; ++i)
		if (dev->ep_rings[i])
		if (dev->eps[i].ring)
			xhci_ring_free(xhci, dev->ep_rings[i]);
			xhci_ring_free(xhci, dev->eps[i].ring);


	if (dev->in_ctx)
	if (dev->in_ctx)
		xhci_free_container_ctx(xhci, dev->in_ctx);
		xhci_free_container_ctx(xhci, dev->in_ctx);
@@ -281,6 +280,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
		struct usb_device *udev, gfp_t flags)
		struct usb_device *udev, gfp_t flags)
{
{
	struct xhci_virt_device *dev;
	struct xhci_virt_device *dev;
	int i;


	/* Slot ID 0 is reserved */
	/* Slot ID 0 is reserved */
	if (slot_id == 0 || xhci->devs[slot_id]) {
	if (slot_id == 0 || xhci->devs[slot_id]) {
@@ -309,9 +309,13 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
	xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id,
	xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id,
			(unsigned long long)dev->in_ctx->dma);
			(unsigned long long)dev->in_ctx->dma);


	/* Initialize the cancellation list for each endpoint */
	for (i = 0; i < 31; i++)
		INIT_LIST_HEAD(&dev->eps[i].cancelled_td_list);

	/* Allocate endpoint 0 ring */
	/* Allocate endpoint 0 ring */
	dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags);
	dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, flags);
	if (!dev->ep_rings[0])
	if (!dev->eps[0].ring)
		goto fail;
		goto fail;


	init_completion(&dev->cmd_completion);
	init_completion(&dev->cmd_completion);
@@ -428,8 +432,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
	ep0_ctx->ep_info2 |= ERROR_COUNT(3);
	ep0_ctx->ep_info2 |= ERROR_COUNT(3);


	ep0_ctx->deq =
	ep0_ctx->deq =
		dev->ep_rings[0]->first_seg->dma;
		dev->eps[0].ring->first_seg->dma;
	ep0_ctx->deq |= dev->ep_rings[0]->cycle_state;
	ep0_ctx->deq |= dev->eps[0].ring->cycle_state;


	/* Steps 7 and 8 were done in xhci_alloc_virt_device() */
	/* Steps 7 and 8 were done in xhci_alloc_virt_device() */


@@ -539,10 +543,11 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);


	/* Set up the endpoint ring */
	/* Set up the endpoint ring */
	virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, mem_flags);
	virt_dev->eps[ep_index].new_ring =
	if (!virt_dev->new_ep_rings[ep_index])
		xhci_ring_alloc(xhci, 1, true, mem_flags);
	if (!virt_dev->eps[ep_index].new_ring)
		return -ENOMEM;
		return -ENOMEM;
	ep_ring = virt_dev->new_ep_rings[ep_index];
	ep_ring = virt_dev->eps[ep_index].new_ring;
	ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
	ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;


	ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
	ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
+48 −42
Original line number Original line Diff line number Diff line
@@ -296,16 +296,18 @@ static void ring_ep_doorbell(struct xhci_hcd *xhci,
		unsigned int slot_id,
		unsigned int slot_id,
		unsigned int ep_index)
		unsigned int ep_index)
{
{
	struct xhci_ring *ep_ring;
	struct xhci_virt_ep *ep;
	unsigned int ep_state;
	u32 field;
	u32 field;
	__u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id];
	__u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id];


	ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
	ep = &xhci->devs[slot_id]->eps[ep_index];
	ep_state = ep->ep_state;
	/* Don't ring the doorbell for this endpoint if there are pending
	/* Don't ring the doorbell for this endpoint if there are pending
	 * cancellations because the we don't want to interrupt processing.
	 * cancellations because the we don't want to interrupt processing.
	 */
	 */
	if (!ep_ring->cancels_pending && !(ep_ring->state & SET_DEQ_PENDING)
	if (!ep->cancels_pending && !(ep_state & SET_DEQ_PENDING)
			&& !(ep_ring->state & EP_HALTED)) {
			&& !(ep_state & EP_HALTED)) {
		field = xhci_readl(xhci, db_addr) & DB_MASK;
		field = xhci_readl(xhci, db_addr) & DB_MASK;
		xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr);
		xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr);
		/* Flush PCI posted writes - FIXME Matthew Wilcox says this
		/* Flush PCI posted writes - FIXME Matthew Wilcox says this
@@ -361,7 +363,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
		struct xhci_td *cur_td, struct xhci_dequeue_state *state)
		struct xhci_td *cur_td, struct xhci_dequeue_state *state)
{
{
	struct xhci_virt_device *dev = xhci->devs[slot_id];
	struct xhci_virt_device *dev = xhci->devs[slot_id];
	struct xhci_ring *ep_ring = dev->ep_rings[ep_index];
	struct xhci_ring *ep_ring = dev->eps[ep_index].ring;
	struct xhci_generic_trb *trb;
	struct xhci_generic_trb *trb;
	struct xhci_ep_ctx *ep_ctx;
	struct xhci_ep_ctx *ep_ctx;
	dma_addr_t addr;
	dma_addr_t addr;
@@ -369,7 +371,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
	state->new_cycle_state = 0;
	state->new_cycle_state = 0;
	xhci_dbg(xhci, "Finding segment containing stopped TRB.\n");
	xhci_dbg(xhci, "Finding segment containing stopped TRB.\n");
	state->new_deq_seg = find_trb_seg(cur_td->start_seg,
	state->new_deq_seg = find_trb_seg(cur_td->start_seg,
			ep_ring->stopped_trb,
			dev->eps[ep_index].stopped_trb,
			&state->new_cycle_state);
			&state->new_cycle_state);
	if (!state->new_deq_seg)
	if (!state->new_deq_seg)
		BUG();
		BUG();
@@ -449,9 +451,11 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,
		union xhci_trb *deq_ptr, u32 cycle_state);
		union xhci_trb *deq_ptr, u32 cycle_state);


void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
		struct xhci_ring *ep_ring, unsigned int slot_id,
		unsigned int slot_id, unsigned int ep_index,
		unsigned int ep_index, struct xhci_dequeue_state *deq_state)
		struct xhci_dequeue_state *deq_state)
{
{
	struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];

	xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), "
	xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), "
			"new deq ptr = %p (0x%llx dma), new cycle = %u\n",
			"new deq ptr = %p (0x%llx dma), new cycle = %u\n",
			deq_state->new_deq_seg,
			deq_state->new_deq_seg,
@@ -468,7 +472,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
	 * if the ring is running, and ringing the doorbell starts the
	 * if the ring is running, and ringing the doorbell starts the
	 * ring running.
	 * ring running.
	 */
	 */
	ep_ring->state |= SET_DEQ_PENDING;
	ep->ep_state |= SET_DEQ_PENDING;
}
}


/*
/*
@@ -487,6 +491,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
	unsigned int slot_id;
	unsigned int slot_id;
	unsigned int ep_index;
	unsigned int ep_index;
	struct xhci_ring *ep_ring;
	struct xhci_ring *ep_ring;
	struct xhci_virt_ep *ep;
	struct list_head *entry;
	struct list_head *entry;
	struct xhci_td *cur_td = 0;
	struct xhci_td *cur_td = 0;
	struct xhci_td *last_unlinked_td;
	struct xhci_td *last_unlinked_td;
@@ -499,9 +504,10 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
	memset(&deq_state, 0, sizeof(deq_state));
	memset(&deq_state, 0, sizeof(deq_state));
	slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
	slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
	ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
	ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
	ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
	ep = &xhci->devs[slot_id]->eps[ep_index];
	ep_ring = ep->ring;


	if (list_empty(&ep_ring->cancelled_td_list))
	if (list_empty(&ep->cancelled_td_list))
		return;
		return;


	/* Fix up the ep ring first, so HW stops executing cancelled TDs.
	/* Fix up the ep ring first, so HW stops executing cancelled TDs.
@@ -509,7 +515,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
	 * it.  We're also in the event handler, so we can't get re-interrupted
	 * it.  We're also in the event handler, so we can't get re-interrupted
	 * if another Stop Endpoint command completes
	 * if another Stop Endpoint command completes
	 */
	 */
	list_for_each(entry, &ep_ring->cancelled_td_list) {
	list_for_each(entry, &ep->cancelled_td_list) {
		cur_td = list_entry(entry, struct xhci_td, cancelled_td_list);
		cur_td = list_entry(entry, struct xhci_td, cancelled_td_list);
		xhci_dbg(xhci, "Cancelling TD starting at %p, 0x%llx (dma).\n",
		xhci_dbg(xhci, "Cancelling TD starting at %p, 0x%llx (dma).\n",
				cur_td->first_trb,
				cur_td->first_trb,
@@ -518,7 +524,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
		 * If we stopped on the TD we need to cancel, then we have to
		 * If we stopped on the TD we need to cancel, then we have to
		 * move the xHC endpoint ring dequeue pointer past this TD.
		 * move the xHC endpoint ring dequeue pointer past this TD.
		 */
		 */
		if (cur_td == ep_ring->stopped_td)
		if (cur_td == ep->stopped_td)
			xhci_find_new_dequeue_state(xhci, slot_id, ep_index, cur_td,
			xhci_find_new_dequeue_state(xhci, slot_id, ep_index, cur_td,
					&deq_state);
					&deq_state);
		else
		else
@@ -529,13 +535,13 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
		 * the cancelled TD list for URB completion later.
		 * the cancelled TD list for URB completion later.
		 */
		 */
		list_del(&cur_td->td_list);
		list_del(&cur_td->td_list);
		ep_ring->cancels_pending--;
		ep->cancels_pending--;
	}
	}
	last_unlinked_td = cur_td;
	last_unlinked_td = cur_td;


	/* If necessary, queue a Set Transfer Ring Dequeue Pointer command */
	/* If necessary, queue a Set Transfer Ring Dequeue Pointer command */
	if (deq_state.new_deq_ptr && deq_state.new_deq_seg) {
	if (deq_state.new_deq_ptr && deq_state.new_deq_seg) {
		xhci_queue_new_dequeue_state(xhci, ep_ring,
		xhci_queue_new_dequeue_state(xhci,
				slot_id, ep_index, &deq_state);
				slot_id, ep_index, &deq_state);
		xhci_ring_cmd_db(xhci);
		xhci_ring_cmd_db(xhci);
	} else {
	} else {
@@ -550,7 +556,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
	 * So stop when we've completed the URB for the last TD we unlinked.
	 * So stop when we've completed the URB for the last TD we unlinked.
	 */
	 */
	do {
	do {
		cur_td = list_entry(ep_ring->cancelled_td_list.next,
		cur_td = list_entry(ep->cancelled_td_list.next,
				struct xhci_td, cancelled_td_list);
				struct xhci_td, cancelled_td_list);
		list_del(&cur_td->cancelled_td_list);
		list_del(&cur_td->cancelled_td_list);


@@ -597,7 +603,7 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
	slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
	slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
	ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
	ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
	dev = xhci->devs[slot_id];
	dev = xhci->devs[slot_id];
	ep_ring = dev->ep_rings[ep_index];
	ep_ring = dev->eps[ep_index].ring;
	ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
	ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
	slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
	slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);


@@ -641,7 +647,7 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
				ep_ctx->deq);
				ep_ctx->deq);
	}
	}


	ep_ring->state &= ~SET_DEQ_PENDING;
	dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING;
	ring_ep_doorbell(xhci, slot_id, ep_index);
	ring_ep_doorbell(xhci, slot_id, ep_index);
}
}


@@ -655,7 +661,7 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,


	slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
	slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
	ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
	ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
	ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
	ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
	/* This command will only fail if the endpoint wasn't halted,
	/* This command will only fail if the endpoint wasn't halted,
	 * but we don't care.
	 * but we don't care.
	 */
	 */
@@ -673,7 +679,7 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,
		xhci_ring_cmd_db(xhci);
		xhci_ring_cmd_db(xhci);
	} else {
	} else {
		/* Clear our internal halted state and restart the ring */
		/* Clear our internal halted state and restart the ring */
		ep_ring->state &= ~EP_HALTED;
		xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED;
		ring_ep_doorbell(xhci, slot_id, ep_index);
		ring_ep_doorbell(xhci, slot_id, ep_index);
	}
	}
}
}
@@ -726,7 +732,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
				xhci->devs[slot_id]->in_ctx);
				xhci->devs[slot_id]->in_ctx);
		/* Input ctx add_flags are the endpoint index plus one */
		/* Input ctx add_flags are the endpoint index plus one */
		ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1;
		ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1;
		ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
		ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
		if (!ep_ring) {
		if (!ep_ring) {
			/* This must have been an initial configure endpoint */
			/* This must have been an initial configure endpoint */
			xhci->devs[slot_id]->cmd_status =
			xhci->devs[slot_id]->cmd_status =
@@ -734,13 +740,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
			complete(&xhci->devs[slot_id]->cmd_completion);
			complete(&xhci->devs[slot_id]->cmd_completion);
			break;
			break;
		}
		}
		ep_state = ep_ring->state;
		ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state;
		xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, "
		xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, "
				"state = %d\n", ep_index, ep_state);
				"state = %d\n", ep_index, ep_state);
		if (xhci->quirks & XHCI_RESET_EP_QUIRK &&
		if (xhci->quirks & XHCI_RESET_EP_QUIRK &&
				ep_state & EP_HALTED) {
				ep_state & EP_HALTED) {
			/* Clear our internal halted state and restart ring */
			/* Clear our internal halted state and restart ring */
			xhci->devs[slot_id]->ep_rings[ep_index]->state &=
			xhci->devs[slot_id]->eps[ep_index].ep_state &=
				~EP_HALTED;
				~EP_HALTED;
			ring_ep_doorbell(xhci, slot_id, ep_index);
			ring_ep_doorbell(xhci, slot_id, ep_index);
		} else {
		} else {
@@ -864,6 +870,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
		struct xhci_transfer_event *event)
		struct xhci_transfer_event *event)
{
{
	struct xhci_virt_device *xdev;
	struct xhci_virt_device *xdev;
	struct xhci_virt_ep *ep;
	struct xhci_ring *ep_ring;
	struct xhci_ring *ep_ring;
	unsigned int slot_id;
	unsigned int slot_id;
	int ep_index;
	int ep_index;
@@ -887,7 +894,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
	/* Endpoint ID is 1 based, our index is zero based */
	/* Endpoint ID is 1 based, our index is zero based */
	ep_index = TRB_TO_EP_ID(event->flags) - 1;
	ep_index = TRB_TO_EP_ID(event->flags) - 1;
	xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index);
	xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index);
	ep_ring = xdev->ep_rings[ep_index];
	ep = &xdev->eps[ep_index];
	ep_ring = ep->ring;
	ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
	ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
	if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
	if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
		xhci_err(xhci, "ERROR Transfer event pointed to disabled endpoint\n");
		xhci_err(xhci, "ERROR Transfer event pointed to disabled endpoint\n");
@@ -948,7 +956,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
		break;
		break;
	case COMP_STALL:
	case COMP_STALL:
		xhci_warn(xhci, "WARN: Stalled endpoint\n");
		xhci_warn(xhci, "WARN: Stalled endpoint\n");
		ep_ring->state |= EP_HALTED;
		ep->ep_state |= EP_HALTED;
		status = -EPIPE;
		status = -EPIPE;
		break;
		break;
	case COMP_TRB_ERR:
	case COMP_TRB_ERR:
@@ -1016,12 +1024,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
			else
			else
				td->urb->actual_length = 0;
				td->urb->actual_length = 0;


			ep_ring->stopped_td = td;
			ep->stopped_td = td;
			ep_ring->stopped_trb = event_trb;
			ep->stopped_trb = event_trb;
			xhci_queue_reset_ep(xhci, slot_id, ep_index);
			xhci_queue_reset_ep(xhci, slot_id, ep_index);
			xhci_cleanup_stalled_ring(xhci,
			xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);
					td->urb->dev,
					ep_index, ep_ring);
			xhci_ring_cmd_db(xhci);
			xhci_ring_cmd_db(xhci);
			goto td_cleanup;
			goto td_cleanup;
		default:
		default:
@@ -1161,8 +1167,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
		 * stopped TDs.  A stopped TD may be restarted, so don't update
		 * stopped TDs.  A stopped TD may be restarted, so don't update
		 * the ring dequeue pointer or take this TD off any lists yet.
		 * the ring dequeue pointer or take this TD off any lists yet.
		 */
		 */
		ep_ring->stopped_td = td;
		ep->stopped_td = td;
		ep_ring->stopped_trb = event_trb;
		ep->stopped_trb = event_trb;
	} else {
	} else {
		if (trb_comp_code == COMP_STALL ||
		if (trb_comp_code == COMP_STALL ||
				trb_comp_code == COMP_BABBLE) {
				trb_comp_code == COMP_BABBLE) {
@@ -1172,8 +1178,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
			 * pointer past the TD.  We can't do that here because
			 * pointer past the TD.  We can't do that here because
			 * the halt condition must be cleared first.
			 * the halt condition must be cleared first.
			 */
			 */
			ep_ring->stopped_td = td;
			ep->stopped_td = td;
			ep_ring->stopped_trb = event_trb;
			ep->stopped_trb = event_trb;
		} else {
		} else {
			/* Update ring dequeue pointer */
			/* Update ring dequeue pointer */
			while (ep_ring->dequeue != td->last_trb)
			while (ep_ring->dequeue != td->last_trb)
@@ -1206,7 +1212,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
		/* Was this TD slated to be cancelled but completed anyway? */
		/* Was this TD slated to be cancelled but completed anyway? */
		if (!list_empty(&td->cancelled_td_list)) {
		if (!list_empty(&td->cancelled_td_list)) {
			list_del(&td->cancelled_td_list);
			list_del(&td->cancelled_td_list);
			ep_ring->cancels_pending--;
			ep->cancels_pending--;
		}
		}
		/* Leave the TD around for the reset endpoint function to use
		/* Leave the TD around for the reset endpoint function to use
		 * (but only if it's not a control endpoint, since we already
		 * (but only if it's not a control endpoint, since we already
@@ -1369,7 +1375,7 @@ static int prepare_transfer(struct xhci_hcd *xhci,
{
{
	int ret;
	int ret;
	struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
	struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
	ret = prepare_ring(xhci, xdev->ep_rings[ep_index],
	ret = prepare_ring(xhci, xdev->eps[ep_index].ring,
			ep_ctx->ep_info & EP_STATE_MASK,
			ep_ctx->ep_info & EP_STATE_MASK,
			num_trbs, mem_flags);
			num_trbs, mem_flags);
	if (ret)
	if (ret)
@@ -1389,9 +1395,9 @@ static int prepare_transfer(struct xhci_hcd *xhci,
	(*td)->urb = urb;
	(*td)->urb = urb;
	urb->hcpriv = (void *) (*td);
	urb->hcpriv = (void *) (*td);
	/* Add this TD to the tail of the endpoint ring's TD list */
	/* Add this TD to the tail of the endpoint ring's TD list */
	list_add_tail(&(*td)->td_list, &xdev->ep_rings[ep_index]->td_list);
	list_add_tail(&(*td)->td_list, &xdev->eps[ep_index].ring->td_list);
	(*td)->start_seg = xdev->ep_rings[ep_index]->enq_seg;
	(*td)->start_seg = xdev->eps[ep_index].ring->enq_seg;
	(*td)->first_trb = xdev->ep_rings[ep_index]->enqueue;
	(*td)->first_trb = xdev->eps[ep_index].ring->enqueue;


	return 0;
	return 0;
}
}
@@ -1525,7 +1531,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
	struct xhci_generic_trb *start_trb;
	struct xhci_generic_trb *start_trb;
	int start_cycle;
	int start_cycle;


	ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
	ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
	num_trbs = count_sg_trbs_needed(xhci, urb);
	num_trbs = count_sg_trbs_needed(xhci, urb);
	num_sgs = urb->num_sgs;
	num_sgs = urb->num_sgs;


@@ -1658,7 +1664,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
	if (urb->sg)
	if (urb->sg)
		return queue_bulk_sg_tx(xhci, mem_flags, urb, slot_id, ep_index);
		return queue_bulk_sg_tx(xhci, mem_flags, urb, slot_id, ep_index);


	ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
	ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;


	num_trbs = 0;
	num_trbs = 0;
	/* How much data is (potentially) left before the 64KB boundary? */
	/* How much data is (potentially) left before the 64KB boundary? */
@@ -1769,7 +1775,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
	u32 field, length_field;
	u32 field, length_field;
	struct xhci_td *td;
	struct xhci_td *td;


	ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
	ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;


	/*
	/*
	 * Need to copy setup packet into setup TRB, so we can't use the setup
	 * Need to copy setup packet into setup TRB, so we can't use the setup
+21 −20
Original line number Original line Diff line number Diff line
@@ -625,6 +625,23 @@ struct xhci_input_control_ctx {
/* add context bitmasks */
/* add context bitmasks */
#define	ADD_EP(x)	(0x1 << x)
#define	ADD_EP(x)	(0x1 << x)


struct xhci_virt_ep {
	struct xhci_ring		*ring;
	/* Temporary storage in case the configure endpoint command fails and we
	 * have to restore the device state to the previous state
	 */
	struct xhci_ring		*new_ring;
	unsigned int			ep_state;
#define SET_DEQ_PENDING		(1 << 0)
#define EP_HALTED		(1 << 1)
	/* ----  Related to URB cancellation ---- */
	struct list_head	cancelled_td_list;
	unsigned int		cancels_pending;
	/* The TRB that was last reported in a stopped endpoint ring */
	union xhci_trb		*stopped_trb;
	struct xhci_td		*stopped_td;
};

struct xhci_virt_device {
struct xhci_virt_device {
	/*
	/*
	 * Commands to the hardware are passed an "input context" that
	 * Commands to the hardware are passed an "input context" that
@@ -637,13 +654,7 @@ struct xhci_virt_device {
	struct xhci_container_ctx       *out_ctx;
	struct xhci_container_ctx       *out_ctx;
	/* Used for addressing devices and configuration changes */
	/* Used for addressing devices and configuration changes */
	struct xhci_container_ctx       *in_ctx;
	struct xhci_container_ctx       *in_ctx;

	struct xhci_virt_ep		eps[31];
	/* FIXME when stream support is added */
	struct xhci_ring		*ep_rings[31];
	/* Temporary storage in case the configure endpoint command fails and we
	 * have to restore the device state to the previous state
	 */
	struct xhci_ring		*new_ep_rings[31];
	struct completion		cmd_completion;
	struct completion		cmd_completion;
	/* Status of the last command issued for this device */
	/* Status of the last command issued for this device */
	u32				cmd_status;
	u32				cmd_status;
@@ -945,15 +956,6 @@ struct xhci_ring {
	struct xhci_segment	*deq_seg;
	struct xhci_segment	*deq_seg;
	unsigned int		deq_updates;
	unsigned int		deq_updates;
	struct list_head	td_list;
	struct list_head	td_list;
	/* ----  Related to URB cancellation ---- */
	struct list_head	cancelled_td_list;
	unsigned int		cancels_pending;
	unsigned int		state;
#define SET_DEQ_PENDING		(1 << 0)
#define EP_HALTED		(1 << 1)
	/* The TRB that was last reported in a stopped endpoint ring */
	union xhci_trb		*stopped_trb;
	struct xhci_td		*stopped_td;
	/*
	/*
	 * Write the cycle state into the TRB cycle field to give ownership of
	 * Write the cycle state into the TRB cycle field to give ownership of
	 * the TRB to the host controller (if we are the producer), or to check
	 * the TRB to the host controller (if we are the producer), or to check
@@ -1236,11 +1238,10 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
		unsigned int slot_id, unsigned int ep_index,
		unsigned int slot_id, unsigned int ep_index,
		struct xhci_td *cur_td, struct xhci_dequeue_state *state);
		struct xhci_td *cur_td, struct xhci_dequeue_state *state);
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
		struct xhci_ring *ep_ring, unsigned int slot_id,
		unsigned int slot_id, unsigned int ep_index,
		unsigned int ep_index, struct xhci_dequeue_state *deq_state);
		struct xhci_dequeue_state *deq_state);
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
		struct usb_device *udev,
		struct usb_device *udev, unsigned int ep_index);
		unsigned int ep_index, struct xhci_ring *ep_ring);
void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
		unsigned int slot_id, unsigned int ep_index,
		unsigned int slot_id, unsigned int ep_index,
		struct xhci_dequeue_state *deq_state);
		struct xhci_dequeue_state *deq_state);