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

Commit 80d566db authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "xhci: Ensure a command structure points to the correct trb on the command ring"

parents fab1a9d4 39e258eb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
		if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue)
			xhci_queue_stop_endpoint(xhci, slot_id, i, suspend);
	}
	cmd->command_trb = xhci->cmd_ring->enqueue;
	cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring);
	list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list);
	xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend);
	xhci_ring_cmd_db(xhci);
+10 −0
Original line number Diff line number Diff line
@@ -122,6 +122,16 @@ static int enqueue_is_link_trb(struct xhci_ring *ring)
	return TRB_TYPE_LINK_LE32(link->control);
}

union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring)
{
	/* Enqueue pointer can be left pointing to the link TRB,
	 * we must handle that
	 */
	if (TRB_TYPE_LINK_LE32(ring->enqueue->link.control))
		return ring->enq_seg->next->trbs;
	return ring->enqueue;
}

/* Updates trb to point to the next TRB in the ring, and updates seg if the next
 * TRB is in a new segment.  This does not skip over link TRBs, and it does not
 * effect the ring dequeue or enqueue pointers.
+5 −20
Original line number Diff line number Diff line
@@ -2597,15 +2597,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
	if (command) {
		cmd_completion = command->completion;
		cmd_status = &command->status;
		command->command_trb = xhci->cmd_ring->enqueue;

		/* Enqueue pointer can be left pointing to the link TRB,
		 * we must handle that
		 */
		if (TRB_TYPE_LINK_LE32(command->command_trb->link.control))
			command->command_trb =
				xhci->cmd_ring->enq_seg->next->trbs;

		command->command_trb = xhci_find_next_enqueue(xhci->cmd_ring);
		list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
	} else {
		cmd_completion = &virt_dev->cmd_completion;
@@ -2613,7 +2605,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
	}
	init_completion(cmd_completion);

	cmd_trb = xhci->cmd_ring->dequeue;
	cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring);
	if (!ctx_change)
		ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
				udev->slot_id, must_succeed);
@@ -3398,14 +3390,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)

	/* Attempt to submit the Reset Device command to the command ring */
	spin_lock_irqsave(&xhci->lock, flags);
	reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;

	/* Enqueue pointer can be left pointing to the link TRB,
	 * we must handle that
	 */
	if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control))
		reset_device_cmd->command_trb =
			xhci->cmd_ring->enq_seg->next->trbs;
	reset_device_cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring);

	list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
	ret = xhci_queue_reset_device(xhci, slot_id);
@@ -3597,7 +3582,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
	union xhci_trb *cmd_trb;

	spin_lock_irqsave(&xhci->lock, flags);
	cmd_trb = xhci->cmd_ring->dequeue;
	cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring);
	ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0);
	if (ret) {
		spin_unlock_irqrestore(&xhci->lock, flags);
@@ -3714,7 +3699,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);

	spin_lock_irqsave(&xhci->lock, flags);
	cmd_trb = xhci->cmd_ring->dequeue;
	cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring);
	ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
					udev->slot_id);
	if (ret) {
+1 −0
Original line number Diff line number Diff line
@@ -1861,6 +1861,7 @@ int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command,
		union xhci_trb *cmd_trb);
void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id,
		unsigned int ep_index, unsigned int stream_id);
union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring);

/* xHCI roothub code */
void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,