Loading drivers/usb/core/hcd.c +8 −0 Original line number Diff line number Diff line Loading @@ -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) Loading drivers/usb/core/usb.c +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading drivers/usb/host/xhci.c +56 −0 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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, Loading include/linux/usb.h +3 −0 Original line number Diff line number Diff line Loading @@ -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, Loading include/linux/usb/hcd.h +4 −0 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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, Loading Loading
drivers/usb/core/hcd.c +8 −0 Original line number Diff line number Diff line Loading @@ -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) Loading
drivers/usb/core/usb.c +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/usb/host/xhci.c +56 −0 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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, Loading
include/linux/usb.h +3 −0 Original line number Diff line number Diff line Loading @@ -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, Loading
include/linux/usb/hcd.h +4 −0 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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, Loading