Commit 450c52c7 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'fixes-for-v5.6-rc1' of...

Merge tag 'fixes-for-v5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus

Felipe writes:

USB: fixes for v5.6-rc1

DWC3 learned that we can't always depend on Event Status bits. A
problem was solved which would only surface with scatter list on IN
endpoints.

DWC2 got a fix for feature requests (both set and clear) and GetStatus
request.

The serial gadget got a fix for a TX stall bug.

Composite framework now works better for SSP devices.

* tag 'fixes-for-v5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb:
  usb: dwc3: debug: fix string position formatting mixup with ret and len
  usb: gadget: serial: fix Tx stall after buffer overflow
  usb: gadget: ffs: ffs_aio_cancel(): Save/restore IRQ flags
  usb: dwc2: Fix SET/CLEAR_FEATURE and GET_STATUS flows
  usb: dwc2: Fix in ISOC request length checking
  usb: gadget: composite: Support more than 500mA MaxPower
  usb: gadget: composite: Fix bMaxPower for SuperSpeedPlus
  usb: gadget: u_audio: Fix high-speed max packet size
  usb: dwc3: gadget: Check for IOC/LST bit in TRB->ctrl fields
parents 03cd45d2 42cd5ffe
Loading
Loading
Loading
Loading
+23 −17
Original line number Diff line number Diff line
@@ -1083,11 +1083,6 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
	else
		packets = 1;	/* send one packet if length is zero. */

	if (hs_ep->isochronous && length > (hs_ep->mc * hs_ep->ep.maxpacket)) {
		dev_err(hsotg->dev, "req length > maxpacket*mc\n");
		return;
	}

	if (dir_in && index != 0)
		if (hs_ep->isochronous)
			epsize = DXEPTSIZ_MC(packets);
@@ -1391,6 +1386,13 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
	req->actual = 0;
	req->status = -EINPROGRESS;

	/* Don't queue ISOC request if length greater than mps*mc */
	if (hs_ep->isochronous &&
	    req->length > (hs_ep->mc * hs_ep->ep.maxpacket)) {
		dev_err(hs->dev, "req length > maxpacket*mc\n");
		return -EINVAL;
	}

	/* In DDMA mode for ISOC's don't queue request if length greater
	 * than descriptor limits.
	 */
@@ -1632,6 +1634,7 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
	struct dwc2_hsotg_ep *ep;
	__le16 reply;
	u16 status;
	int ret;

	dev_dbg(hsotg->dev, "%s: USB_REQ_GET_STATUS\n", __func__);
@@ -1643,11 +1646,10 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,

	switch (ctrl->bRequestType & USB_RECIP_MASK) {
	case USB_RECIP_DEVICE:
		/*
		 * bit 0 => self powered
		 * bit 1 => remote wakeup
		 */
		reply = cpu_to_le16(0);
		status = 1 << USB_DEVICE_SELF_POWERED;
		status |= hsotg->remote_wakeup_allowed <<
			  USB_DEVICE_REMOTE_WAKEUP;
		reply = cpu_to_le16(status);
		break;

	case USB_RECIP_INTERFACE:
@@ -1758,7 +1760,10 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
	case USB_RECIP_DEVICE:
		switch (wValue) {
		case USB_DEVICE_REMOTE_WAKEUP:
			if (set)
				hsotg->remote_wakeup_allowed = 1;
			else
				hsotg->remote_wakeup_allowed = 0;
			break;

		case USB_DEVICE_TEST_MODE:
@@ -1768,6 +1773,11 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
				return -EINVAL;

			hsotg->test_mode = wIndex >> 8;
			break;
		default:
			return -ENOENT;
		}

		ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
		if (ret) {
			dev_err(hsotg->dev,
@@ -1775,10 +1785,6 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
			return ret;
		}
		break;
		default:
			return -ENOENT;
		}
		break;

	case USB_RECIP_ENDPOINT:
		ep = ep_from_windex(hsotg, wIndex);
+2 −1
Original line number Diff line number Diff line
@@ -2429,7 +2429,8 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
	if (event->status & DEPEVT_STATUS_SHORT && !chain)
		return 1;

	if (event->status & DEPEVT_STATUS_IOC)
	if ((trb->ctrl & DWC3_TRB_CTRL_IOC) ||
	    (trb->ctrl & DWC3_TRB_CTRL_LST))
		return 1;

	return 0;
+20 −10
Original line number Diff line number Diff line
@@ -437,12 +437,14 @@ static u8 encode_bMaxPower(enum usb_device_speed speed,
		val = CONFIG_USB_GADGET_VBUS_DRAW;
	if (!val)
		return 0;
	switch (speed) {
	case USB_SPEED_SUPER:
		return DIV_ROUND_UP(val, 8);
	default:
		return DIV_ROUND_UP(val, 2);
	}
	if (speed < USB_SPEED_SUPER)
		return min(val, 500U) / 2;
	else
		/*
		 * USB 3.x supports up to 900mA, but since 900 isn't divisible
		 * by 8 the integral division will effectively cap to 896mA.
		 */
		return min(val, 900U) / 8;
}

static int config_buf(struct usb_configuration *config,
@@ -854,6 +856,10 @@ static int set_config(struct usb_composite_dev *cdev,

	/* when we return, be sure our power usage is valid */
	power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW;
	if (gadget->speed < USB_SPEED_SUPER)
		power = min(power, 500U);
	else
		power = min(power, 900U);
done:
	usb_gadget_vbus_draw(gadget, power);
	if (result >= 0 && cdev->delayed_status)
@@ -2280,7 +2286,7 @@ void composite_resume(struct usb_gadget *gadget)
{
	struct usb_composite_dev	*cdev = get_gadget_data(gadget);
	struct usb_function		*f;
	u16				maxpower;
	unsigned			maxpower;

	/* REVISIT:  should we have config level
	 * suspend/resume callbacks?
@@ -2294,10 +2300,14 @@ void composite_resume(struct usb_gadget *gadget)
				f->resume(f);
		}

		maxpower = cdev->config->MaxPower;
		maxpower = cdev->config->MaxPower ?
			cdev->config->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW;
		if (gadget->speed < USB_SPEED_SUPER)
			maxpower = min(maxpower, 500U);
		else
			maxpower = min(maxpower, 900U);

		usb_gadget_vbus_draw(gadget, maxpower ?
			maxpower : CONFIG_USB_GADGET_VBUS_DRAW);
		usb_gadget_vbus_draw(gadget, maxpower);
	}

	cdev->suspended = 0;
+3 −2
Original line number Diff line number Diff line
@@ -1162,18 +1162,19 @@ static int ffs_aio_cancel(struct kiocb *kiocb)
{
	struct ffs_io_data *io_data = kiocb->private;
	struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
	unsigned long flags;
	int value;

	ENTER();

	spin_lock_irq(&epfile->ffs->eps_lock);
	spin_lock_irqsave(&epfile->ffs->eps_lock, flags);

	if (likely(io_data && io_data->ep && io_data->req))
		value = usb_ep_dequeue(io_data->ep, io_data->req);
	else
		value = -EINVAL;

	spin_unlock_irq(&epfile->ffs->eps_lock);
	spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);

	return value;
}
+5 −5
Original line number Diff line number Diff line
@@ -361,7 +361,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
	ep = audio_dev->out_ep;
	prm = &uac->c_prm;
	config_ep_by_speed(gadget, &audio_dev->func, ep);
	req_len = prm->max_psize;
	req_len = ep->maxpacket;

	prm->ep_enabled = true;
	usb_ep_enable(ep);
@@ -379,7 +379,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
			req->context = &prm->ureq[i];
			req->length = req_len;
			req->complete = u_audio_iso_complete;
			req->buf = prm->rbuf + i * prm->max_psize;
			req->buf = prm->rbuf + i * ep->maxpacket;
		}

		if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
@@ -430,9 +430,9 @@ int u_audio_start_playback(struct g_audio *audio_dev)
	uac->p_pktsize = min_t(unsigned int,
				uac->p_framesize *
					(params->p_srate / uac->p_interval),
				prm->max_psize);
				ep->maxpacket);

	if (uac->p_pktsize < prm->max_psize)
	if (uac->p_pktsize < ep->maxpacket)
		uac->p_pktsize_residue = uac->p_framesize *
			(params->p_srate % uac->p_interval);
	else
@@ -457,7 +457,7 @@ int u_audio_start_playback(struct g_audio *audio_dev)
			req->context = &prm->ureq[i];
			req->length = req_len;
			req->complete = u_audio_iso_complete;
			req->buf = prm->rbuf + i * prm->max_psize;
			req->buf = prm->rbuf + i * ep->maxpacket;
		}

		if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
Loading