Commit 90d9fbc1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are some small USB fixes for 5.16-rc5.  They include:

   - gadget driver fixes for reported issues

   - xhci fixes for reported problems.

   - config endpoint parsing fixes for where we got bitfields wrong

  Most of these have been in linux-next, the remaining few were not, but
  got lots of local testing in my systems and in some cloud testing
  infrastructures"

* tag 'usb-5.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: core: config: using bit mask instead of individual bits
  usb: core: config: fix validation of wMaxPacketValue entries
  USB: gadget: zero allocate endpoint 0 buffers
  USB: gadget: detect too-big endpoint 0 requests
  xhci: avoid race between disable slot command and host runtime suspend
  xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime suspending
  Revert "usb: dwc3: dwc3-qcom: Enable tx-fifo-resize property by default"
parents 8d7ed104 ca573739
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -406,7 +406,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
	 * the USB-2 spec requires such endpoints to have wMaxPacketSize = 0
	 * (see the end of section 5.6.3), so don't warn about them.
	 */
	maxp = usb_endpoint_maxp(&endpoint->desc);
	maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize);
	if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) {
		dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n",
		    cfgno, inum, asnum, d->bEndpointAddress);
@@ -422,9 +422,9 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
		maxpacket_maxes = full_speed_maxpacket_maxes;
		break;
	case USB_SPEED_HIGH:
		/* Bits 12..11 are allowed only for HS periodic endpoints */
		/* Multiple-transactions bits are allowed only for HS periodic endpoints */
		if (usb_endpoint_xfer_int(d) || usb_endpoint_xfer_isoc(d)) {
			i = maxp & (BIT(12) | BIT(11));
			i = maxp & USB_EP_MAXP_MULT_MASK;
			maxp &= ~i;
		}
		fallthrough;
+0 −15
Original line number Diff line number Diff line
@@ -649,7 +649,6 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev)
	struct dwc3_qcom	*qcom = platform_get_drvdata(pdev);
	struct device_node	*np = pdev->dev.of_node, *dwc3_np;
	struct device		*dev = &pdev->dev;
	struct property		*prop;
	int			ret;

	dwc3_np = of_get_compatible_child(np, "snps,dwc3");
@@ -658,20 +657,6 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev)
		return -ENODEV;
	}

	prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL);
	if (!prop) {
		ret = -ENOMEM;
		dev_err(dev, "unable to allocate memory for property\n");
		goto node_put;
	}

	prop->name = "tx-fifo-resize";
	ret = of_add_property(dwc3_np, prop);
	if (ret) {
		dev_err(dev, "unable to add property\n");
		goto node_put;
	}

	ret = of_platform_populate(np, NULL, NULL, dev);
	if (ret) {
		dev_err(dev, "failed to register dwc3 core - %d\n", ret);
+13 −1
Original line number Diff line number Diff line
@@ -1679,6 +1679,18 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
	struct usb_function		*f = NULL;
	u8				endp;

	if (w_length > USB_COMP_EP0_BUFSIZ) {
		if (ctrl->bRequestType == USB_DIR_OUT) {
			goto done;
		} else {
			/* Cast away the const, we are going to overwrite on purpose. */
			__le16 *temp = (__le16 *)&ctrl->wLength;

			*temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ);
			w_length = USB_COMP_EP0_BUFSIZ;
		}
	}

	/* partial re-init of the response message; the function or the
	 * gadget might need to intercept e.g. a control-OUT completion
	 * when we delegate to it.
@@ -2209,7 +2221,7 @@ int composite_dev_prepare(struct usb_composite_driver *composite,
	if (!cdev->req)
		return -ENOMEM;

	cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL);
	cdev->req->buf = kzalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL);
	if (!cdev->req->buf)
		goto fail;

+14 −1
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ static int dbgp_enable_ep_req(struct usb_ep *ep)
		goto fail_1;
	}

	req->buf = kmalloc(DBGP_REQ_LEN, GFP_KERNEL);
	req->buf = kzalloc(DBGP_REQ_LEN, GFP_KERNEL);
	if (!req->buf) {
		err = -ENOMEM;
		stp = 2;
@@ -345,6 +345,19 @@ static int dbgp_setup(struct usb_gadget *gadget,
	void *data = NULL;
	u16 len = 0;

	if (length > DBGP_REQ_LEN) {
		if (ctrl->bRequestType == USB_DIR_OUT) {
			return err;
		} else {
			/* Cast away the const, we are going to overwrite on purpose. */
			__le16 *temp = (__le16 *)&ctrl->wLength;

			*temp = cpu_to_le16(DBGP_REQ_LEN);
			length = DBGP_REQ_LEN;
		}
	}


	if (request == USB_REQ_GET_DESCRIPTOR) {
		switch (value>>8) {
		case USB_DT_DEVICE:
+15 −1
Original line number Diff line number Diff line
@@ -110,6 +110,8 @@ enum ep0_state {
/* enough for the whole queue: most events invalidate others */
#define	N_EVENT			5

#define RBUF_SIZE		256

struct dev_data {
	spinlock_t			lock;
	refcount_t			count;
@@ -144,7 +146,7 @@ struct dev_data {
	struct dentry			*dentry;

	/* except this scratch i/o buffer for ep0 */
	u8				rbuf [256];
	u8				rbuf[RBUF_SIZE];
};

static inline void get_dev (struct dev_data *data)
@@ -1331,6 +1333,18 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
	u16				w_value = le16_to_cpu(ctrl->wValue);
	u16				w_length = le16_to_cpu(ctrl->wLength);

	if (w_length > RBUF_SIZE) {
		if (ctrl->bRequestType == USB_DIR_OUT) {
			return value;
		} else {
			/* Cast away the const, we are going to overwrite on purpose. */
			__le16 *temp = (__le16 *)&ctrl->wLength;

			*temp = cpu_to_le16(RBUF_SIZE);
			w_length = RBUF_SIZE;
		}
	}

	spin_lock (&dev->lock);
	dev->setup_abort = 0;
	if (dev->state == STATE_DEV_UNCONNECTED) {
Loading