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

Commit 712187a2 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

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

parents adcacd80 106c645a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2291,6 +2291,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
@@ -872,6 +872,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
+56 −0
Original line number Diff line number Diff line
@@ -5187,6 +5187,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, 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",
@@ -5252,6 +5307,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
@@ -837,6 +837,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,
+4 −0
Original line number Diff line number Diff line
@@ -416,6 +416,8 @@ struct hc_driver {
			struct usb_device *udev, struct usb_host_endpoint *ep,
			dma_addr_t *dma);
	int (*get_core_id)(struct usb_hcd *hcd);
	int (*stop_endpoint)(struct usb_hcd *hcd, struct usb_device *udev,
			struct usb_host_endpoint *ep);
};

static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
@@ -463,6 +465,8 @@ extern phys_addr_t usb_hcd_get_sec_event_ring_phys_addr(
extern phys_addr_t usb_hcd_get_xfer_ring_phys_addr(
	struct usb_device *udev, struct usb_host_endpoint *ep, dma_addr_t *dma);
extern int usb_hcd_get_controller_id(struct usb_device *udev);
extern int usb_hcd_stop_endpoint(struct usb_device *udev,
	struct usb_host_endpoint *ep);

struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
		struct device *sysdev, struct device *dev, const char *bus_name,