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

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

Merge "usb: Add helper API to issue stop endpoint command"

parents 4aea4225 0a1c067c
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2300,6 +2300,14 @@ int usb_hcd_get_controller_id(struct usb_device *udev)
	return hcd->driver->get_core_id(hcd);
}

int usb_hcd_stop_endpoint(struct usb_device *udev,
		struct usb_host_endpoint *ep)
{
	struct usb_hcd	*hcd = bus_to_hcd(udev->bus);

	return hcd->driver->stop_endpoint(hcd, udev, ep);
}

#ifdef	CONFIG_PM

int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
+6 −0
Original line number Diff line number Diff line
@@ -871,6 +871,12 @@ int usb_get_controller_id(struct usb_device *dev)
}
EXPORT_SYMBOL(usb_get_controller_id);

int usb_stop_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
{
	return usb_hcd_stop_endpoint(dev, ep);
}
EXPORT_SYMBOL(usb_stop_endpoint);

/*-------------------------------------------------------------------*/
/*
 * __usb_get_extra_descriptor() finds a descriptor of specific type in the
+1 −1
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,

	slot_id = 0;
	for (i = 0; i < MAX_HC_SLOTS; i++) {
		if (!xhci->devs[i])
		if (!xhci->devs[i] || !xhci->devs[i]->udev)
			continue;
		speed = xhci->devs[i]->udev->speed;
		if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3))
+56 −0
Original line number Diff line number Diff line
@@ -4986,6 +4986,61 @@ int xhci_get_core_id(struct usb_hcd *hcd)
	return xhci->core_id;
}

static int  xhci_stop_endpoint(struct usb_hcd *hcd,
	struct usb_device *udev, struct usb_host_endpoint *ep)
{
	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
	unsigned int ep_index;
	struct xhci_virt_device *virt_dev;
	struct xhci_command *cmd;
	unsigned long flags;
	int ret = 0;

	cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
	if (!cmd)
		return -ENOMEM;

	spin_lock_irqsave(&xhci->lock, flags);
	virt_dev = xhci->devs[udev->slot_id];
	if (!virt_dev) {
		ret = -ENODEV;
		goto err;
	}

	ep_index = xhci_get_endpoint_index(&ep->desc);
	if (virt_dev->eps[ep_index].ring &&
			virt_dev->eps[ep_index].ring->dequeue) {
		ret = xhci_queue_stop_endpoint(xhci, cmd, udev->slot_id,
				ep_index, 0);
		if (ret)
			goto err;

		xhci_ring_cmd_db(xhci);
		spin_unlock_irqrestore(&xhci->lock, flags);

		/* Wait for stop endpoint command to finish */
		wait_for_completion(cmd->completion);

		if (cmd->status == COMP_COMMAND_ABORTED ||
				cmd->status == COMP_STOPPED) {
			xhci_warn(xhci,
				"stop endpoint command timeout for ep%d%s\n",
				usb_endpoint_num(&ep->desc),
				usb_endpoint_dir_in(&ep->desc) ? "in" : "out");
			ret = -ETIME;
		}
		goto free_cmd;
	}

err:
	spin_unlock_irqrestore(&xhci->lock, flags);
free_cmd:
	xhci_free_command(xhci, cmd);
	return ret;
}



static const struct hc_driver xhci_hc_driver = {
	.description =		"xhci-hcd",
	.product_desc =		"xHCI Host Controller",
@@ -5050,6 +5105,7 @@ static const struct hc_driver xhci_hc_driver = {
	.get_sec_event_ring_phys_addr =	xhci_get_sec_event_ring_phys_addr,
	.get_xfer_ring_phys_addr =	xhci_get_xfer_ring_phys_addr,
	.get_core_id =			xhci_get_core_id,
	.stop_endpoint =		xhci_stop_endpoint,
};

void xhci_init_driver(struct hc_driver *drv,
+3 −0
Original line number Diff line number Diff line
@@ -826,6 +826,9 @@ extern phys_addr_t usb_get_xfer_ring_phys_addr(struct usb_device *dev,
	struct usb_host_endpoint *ep, dma_addr_t *dma);
extern int usb_get_controller_id(struct usb_device *dev);

extern int usb_stop_endpoint(struct usb_device *dev,
	struct usb_host_endpoint *ep);

/* Sets up a group of bulk endpoints to support multiple stream IDs. */
extern int usb_alloc_streams(struct usb_interface *interface,
		struct usb_host_endpoint **eps, unsigned int num_eps,
Loading