Commit fb27bc03 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are a number of USB fixes for 5.7-rc6

  The "largest" in here is a bunch of raw-gadget fixes and api changes
  as the driver just showed up in -rc1 and work has been done to fix up
  some uapi issues found with the original submission, before it shows
  up in a -final release.

  Other than that, a bunch of other small USB gadget fixes, xhci fixes,
  some quirks, andother tiny fixes for reported issues.

  All of these have been in linux-next with no reported issues"

* tag 'usb-5.7-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (26 commits)
  USB: gadget: fix illegal array access in binding with UDC
  usb: core: hub: limit HUB_QUIRK_DISABLE_AUTOSUSPEND to USB5534B
  USB: usbfs: fix mmap dma mismatch
  usb: host: xhci-plat: keep runtime active when removing host
  usb: xhci: Fix NULL pointer dereference when enqueuing trbs from urb sg list
  usb: cdns3: gadget: make a bunch of functions static
  usb: mtu3: constify struct debugfs_reg32
  usb: gadget: udc: atmel: Make some symbols static
  usb: raw-gadget: fix null-ptr-deref when reenabling endpoints
  usb: raw-gadget: documentation updates
  usb: raw-gadget: support stalling/halting/wedging endpoints
  usb: raw-gadget: fix gadget endpoint selection
  usb: raw-gadget: improve uapi headers comments
  usb: typec: mux: intel: Fix DP_HPD_LVL bit field
  usb: raw-gadget: fix return value of ep read ioctls
  usb: dwc3: select USB_ROLE_SWITCH
  usb: gadget: legacy: fix error return code in gncm_bind()
  usb: gadget: legacy: fix error return code in cdc_bind()
  usb: gadget: legacy: fix redundant initialization warnings
  usb: gadget: tegra-xudc: Fix idle suspend/resume
  ...
parents b48397cb 15753588
Loading
Loading
Loading
Loading
+30 −7
Original line number Diff line number Diff line
@@ -27,9 +27,8 @@ differences are:
3. Raw Gadget provides a way to select a UDC device/driver to bind to,
   while GadgetFS currently binds to the first available UDC.

4. Raw Gadget uses predictable endpoint names (handles) across different
   UDCs (as long as UDCs have enough endpoints of each required transfer
   type).
4. Raw Gadget explicitly exposes information about endpoints addresses and
   capabilities allowing a user to write UDC-agnostic gadgets.

5. Raw Gadget has ioctl-based interface instead of a filesystem-based one.

@@ -50,12 +49,36 @@ The typical usage of Raw Gadget looks like:
   Raw Gadget and react to those depending on what kind of USB device
   needs to be emulated.

Note, that some UDC drivers have fixed addresses assigned to endpoints, and
therefore arbitrary endpoint addresses can't be used in the descriptors.
Nevertheles, Raw Gadget provides a UDC-agnostic way to write USB gadgets.
Once a USB_RAW_EVENT_CONNECT event is received via USB_RAW_IOCTL_EVENT_FETCH,
the USB_RAW_IOCTL_EPS_INFO ioctl can be used to find out information about
endpoints that the UDC driver has. Based on that information, the user must
chose UDC endpoints that will be used for the gadget being emulated, and
properly assign addresses in endpoint descriptors.

You can find usage examples (along with a test suite) here:

https://github.com/xairy/raw-gadget

Internal details
~~~~~~~~~~~~~~~~

Currently every endpoint read/write ioctl submits a USB request and waits until
its completion. This is the desired mode for coverage-guided fuzzing (as we'd
like all USB request processing happen during the lifetime of a syscall),
and must be kept in the implementation. (This might be slow for real world
applications, thus the O_NONBLOCK improvement suggestion below.)

Potential future improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- Implement ioctl's for setting/clearing halt status on endpoints.

- Reporting more events (suspend, resume, etc.) through
  USB_RAW_IOCTL_EVENT_FETCH.
- Report more events (suspend, resume, etc.) through USB_RAW_IOCTL_EVENT_FETCH.

- Support O_NONBLOCK I/O.

- Support USB 3 features (accept SS endpoint companion descriptor when
  enabling endpoints; allow providing stream_id for bulk transfers).

- Support ISO transfer features (expose frame_number for completed requests).
+11 −11
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ static int cdns3_ep_run_stream_transfer(struct cdns3_endpoint *priv_ep,
 * @ptr: address of device controller register to be read and changed
 * @mask: bits requested to clar
 */
void cdns3_clear_register_bit(void __iomem *ptr, u32 mask)
static void cdns3_clear_register_bit(void __iomem *ptr, u32 mask)
{
	mask = readl(ptr) & ~mask;
	writel(mask, ptr);
@@ -137,7 +137,7 @@ struct usb_request *cdns3_next_request(struct list_head *list)
 *
 * Returns buffer or NULL if no buffers in list
 */
struct cdns3_aligned_buf *cdns3_next_align_buf(struct list_head *list)
static struct cdns3_aligned_buf *cdns3_next_align_buf(struct list_head *list)
{
	return list_first_entry_or_null(list, struct cdns3_aligned_buf, list);
}
@@ -148,7 +148,7 @@ struct cdns3_aligned_buf *cdns3_next_align_buf(struct list_head *list)
 *
 * Returns request or NULL if no requests in list
 */
struct cdns3_request *cdns3_next_priv_request(struct list_head *list)
static struct cdns3_request *cdns3_next_priv_request(struct list_head *list)
{
	return list_first_entry_or_null(list, struct cdns3_request, list);
}
@@ -190,7 +190,7 @@ dma_addr_t cdns3_trb_virt_to_dma(struct cdns3_endpoint *priv_ep,
	return priv_ep->trb_pool_dma + offset;
}

int cdns3_ring_size(struct cdns3_endpoint *priv_ep)
static int cdns3_ring_size(struct cdns3_endpoint *priv_ep)
{
	switch (priv_ep->type) {
	case USB_ENDPOINT_XFER_ISOC:
@@ -345,7 +345,7 @@ static void cdns3_ep_inc_deq(struct cdns3_endpoint *priv_ep)
	cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs);
}

void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req)
static void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req)
{
	struct cdns3_endpoint *priv_ep = priv_req->priv_ep;
	int current_trb = priv_req->start_trb;
@@ -511,7 +511,7 @@ static void cdns3_wa2_descmiss_copy_data(struct cdns3_endpoint *priv_ep,
	}
}

struct usb_request *cdns3_wa2_gadget_giveback(struct cdns3_device *priv_dev,
static struct usb_request *cdns3_wa2_gadget_giveback(struct cdns3_device *priv_dev,
					      struct cdns3_endpoint *priv_ep,
					      struct cdns3_request *priv_req)
{
@@ -551,7 +551,7 @@ struct usb_request *cdns3_wa2_gadget_giveback(struct cdns3_device *priv_dev,
	return &priv_req->request;
}

int cdns3_wa2_gadget_ep_queue(struct cdns3_device *priv_dev,
static int cdns3_wa2_gadget_ep_queue(struct cdns3_device *priv_dev,
			      struct cdns3_endpoint *priv_ep,
			      struct cdns3_request *priv_req)
{
@@ -836,7 +836,7 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep,
		cdns3_gadget_ep_free_request(&priv_ep->endpoint, request);
}

void cdns3_wa1_restore_cycle_bit(struct cdns3_endpoint *priv_ep)
static void cdns3_wa1_restore_cycle_bit(struct cdns3_endpoint *priv_ep)
{
	/* Work around for stale data address in TRB*/
	if (priv_ep->wa1_set) {
@@ -1904,7 +1904,7 @@ static int cdns3_ep_onchip_buffer_reserve(struct cdns3_device *priv_dev,
	return 0;
}

void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev,
static void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev,
			      struct cdns3_endpoint *priv_ep)
{
	if (!priv_ep->use_streams || priv_dev->gadget.speed < USB_SPEED_SUPER)
@@ -1925,7 +1925,7 @@ void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev,
			       EP_CFG_TDL_CHK | EP_CFG_SID_CHK);
}

void cdns3_configure_dmult(struct cdns3_device *priv_dev,
static void cdns3_configure_dmult(struct cdns3_device *priv_dev,
			   struct cdns3_endpoint *priv_ep)
{
	struct cdns3_usb_regs __iomem *regs = priv_dev->regs;
@@ -2548,7 +2548,7 @@ found:
	link_trb = priv_req->trb;

	/* Update ring only if removed request is on pending_req_list list */
	if (req_on_hw_ring) {
	if (req_on_hw_ring && link_trb) {
		link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma +
			((priv_req->end_trb + 1) * TRB_SIZE));
		link_trb->control = (link_trb->control & TRB_CYCLE) |
+13 −3
Original line number Diff line number Diff line
@@ -251,10 +251,20 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma)
	usbm->vma_use_count = 1;
	INIT_LIST_HEAD(&usbm->memlist);

	if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) {
	if (hcd->localmem_pool || !hcd_uses_dma(hcd)) {
		if (remap_pfn_range(vma, vma->vm_start,
				    virt_to_phys(usbm->mem) >> PAGE_SHIFT,
				    size, vma->vm_page_prot) < 0) {
			dec_usb_memory_use_count(usbm, &usbm->vma_use_count);
			return -EAGAIN;
		}
	} else {
		if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle,
				      size)) {
			dec_usb_memory_use_count(usbm, &usbm->vma_use_count);
			return -EAGAIN;
		}
	}

	vma->vm_flags |= VM_IO;
	vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP);
+5 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@

#define USB_VENDOR_GENESYS_LOGIC		0x05e3
#define USB_VENDOR_SMSC				0x0424
#define USB_PRODUCT_USB5534B			0x5534
#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND	0x01
#define HUB_QUIRK_DISABLE_AUTOSUSPEND		0x02

@@ -5621,8 +5622,11 @@ out_hdev_lock:
}

static const struct usb_device_id hub_id_table[] = {
    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS,
    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
                   | USB_DEVICE_ID_MATCH_PRODUCT
                   | USB_DEVICE_ID_MATCH_INT_CLASS,
      .idVendor = USB_VENDOR_SMSC,
      .idProduct = USB_PRODUCT_USB5534B,
      .bInterfaceClass = USB_CLASS_HUB,
      .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ config USB_DWC3
	tristate "DesignWare USB3 DRD Core Support"
	depends on (USB || USB_GADGET) && HAS_DMA
	select USB_XHCI_PLATFORM if USB_XHCI_HCD
	select USB_ROLE_SWITCH if USB_DWC3_DUAL_ROLE
	help
	  Say Y or M here if your system has a Dual Role SuperSpeed
	  USB controller based on the DesignWare USB3 IP Core.
Loading