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

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
...@@ -1083,11 +1083,6 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, ...@@ -1083,11 +1083,6 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
else else
packets = 1; /* send one packet if length is zero. */ 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 (dir_in && index != 0)
if (hs_ep->isochronous) if (hs_ep->isochronous)
epsize = DXEPTSIZ_MC(packets); epsize = DXEPTSIZ_MC(packets);
...@@ -1391,6 +1386,13 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, ...@@ -1391,6 +1386,13 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
req->actual = 0; req->actual = 0;
req->status = -EINPROGRESS; 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 /* In DDMA mode for ISOC's don't queue request if length greater
* than descriptor limits. * than descriptor limits.
*/ */
...@@ -1632,6 +1634,7 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg, ...@@ -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 *ep0 = hsotg->eps_out[0];
struct dwc2_hsotg_ep *ep; struct dwc2_hsotg_ep *ep;
__le16 reply; __le16 reply;
u16 status;
int ret; int ret;
dev_dbg(hsotg->dev, "%s: USB_REQ_GET_STATUS\n", __func__); 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, ...@@ -1643,11 +1646,10 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
switch (ctrl->bRequestType & USB_RECIP_MASK) { switch (ctrl->bRequestType & USB_RECIP_MASK) {
case USB_RECIP_DEVICE: case USB_RECIP_DEVICE:
/* status = 1 << USB_DEVICE_SELF_POWERED;
* bit 0 => self powered status |= hsotg->remote_wakeup_allowed <<
* bit 1 => remote wakeup USB_DEVICE_REMOTE_WAKEUP;
*/ reply = cpu_to_le16(status);
reply = cpu_to_le16(0);
break; break;
case USB_RECIP_INTERFACE: case USB_RECIP_INTERFACE:
...@@ -1758,7 +1760,10 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, ...@@ -1758,7 +1760,10 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
case USB_RECIP_DEVICE: case USB_RECIP_DEVICE:
switch (wValue) { switch (wValue) {
case USB_DEVICE_REMOTE_WAKEUP: case USB_DEVICE_REMOTE_WAKEUP:
hsotg->remote_wakeup_allowed = 1; if (set)
hsotg->remote_wakeup_allowed = 1;
else
hsotg->remote_wakeup_allowed = 0;
break; break;
case USB_DEVICE_TEST_MODE: case USB_DEVICE_TEST_MODE:
...@@ -1768,16 +1773,17 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, ...@@ -1768,16 +1773,17 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
return -EINVAL; return -EINVAL;
hsotg->test_mode = wIndex >> 8; hsotg->test_mode = wIndex >> 8;
ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
if (ret) {
dev_err(hsotg->dev,
"%s: failed to send reply\n", __func__);
return ret;
}
break; break;
default: default:
return -ENOENT; return -ENOENT;
} }
ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
if (ret) {
dev_err(hsotg->dev,
"%s: failed to send reply\n", __func__);
return ret;
}
break; break;
case USB_RECIP_ENDPOINT: case USB_RECIP_ENDPOINT:
......
...@@ -2429,7 +2429,8 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep, ...@@ -2429,7 +2429,8 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
if (event->status & DEPEVT_STATUS_SHORT && !chain) if (event->status & DEPEVT_STATUS_SHORT && !chain)
return 1; return 1;
if (event->status & DEPEVT_STATUS_IOC) if ((trb->ctrl & DWC3_TRB_CTRL_IOC) ||
(trb->ctrl & DWC3_TRB_CTRL_LST))
return 1; return 1;
return 0; return 0;
......
...@@ -437,12 +437,14 @@ static u8 encode_bMaxPower(enum usb_device_speed speed, ...@@ -437,12 +437,14 @@ static u8 encode_bMaxPower(enum usb_device_speed speed,
val = CONFIG_USB_GADGET_VBUS_DRAW; val = CONFIG_USB_GADGET_VBUS_DRAW;
if (!val) if (!val)
return 0; return 0;
switch (speed) { if (speed < USB_SPEED_SUPER)
case USB_SPEED_SUPER: return min(val, 500U) / 2;
return DIV_ROUND_UP(val, 8); else
default: /*
return DIV_ROUND_UP(val, 2); * 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, static int config_buf(struct usb_configuration *config,
...@@ -854,6 +856,10 @@ static int set_config(struct usb_composite_dev *cdev, ...@@ -854,6 +856,10 @@ static int set_config(struct usb_composite_dev *cdev,
/* when we return, be sure our power usage is valid */ /* when we return, be sure our power usage is valid */
power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; 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: done:
usb_gadget_vbus_draw(gadget, power); usb_gadget_vbus_draw(gadget, power);
if (result >= 0 && cdev->delayed_status) if (result >= 0 && cdev->delayed_status)
...@@ -2280,7 +2286,7 @@ void composite_resume(struct usb_gadget *gadget) ...@@ -2280,7 +2286,7 @@ void composite_resume(struct usb_gadget *gadget)
{ {
struct usb_composite_dev *cdev = get_gadget_data(gadget); struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_function *f; struct usb_function *f;
u16 maxpower; unsigned maxpower;
/* REVISIT: should we have config level /* REVISIT: should we have config level
* suspend/resume callbacks? * suspend/resume callbacks?
...@@ -2294,10 +2300,14 @@ void composite_resume(struct usb_gadget *gadget) ...@@ -2294,10 +2300,14 @@ void composite_resume(struct usb_gadget *gadget)
f->resume(f); 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 ? usb_gadget_vbus_draw(gadget, maxpower);
maxpower : CONFIG_USB_GADGET_VBUS_DRAW);
} }
cdev->suspended = 0; cdev->suspended = 0;
......
...@@ -1162,18 +1162,19 @@ static int ffs_aio_cancel(struct kiocb *kiocb) ...@@ -1162,18 +1162,19 @@ static int ffs_aio_cancel(struct kiocb *kiocb)
{ {
struct ffs_io_data *io_data = kiocb->private; struct ffs_io_data *io_data = kiocb->private;
struct ffs_epfile *epfile = kiocb->ki_filp->private_data; struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
unsigned long flags;
int value; int value;
ENTER(); 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)) if (likely(io_data && io_data->ep && io_data->req))
value = usb_ep_dequeue(io_data->ep, io_data->req); value = usb_ep_dequeue(io_data->ep, io_data->req);
else else
value = -EINVAL; value = -EINVAL;
spin_unlock_irq(&epfile->ffs->eps_lock); spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);
return value; return value;
} }
......
...@@ -361,7 +361,7 @@ int u_audio_start_capture(struct g_audio *audio_dev) ...@@ -361,7 +361,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
ep = audio_dev->out_ep; ep = audio_dev->out_ep;
prm = &uac->c_prm; prm = &uac->c_prm;
config_ep_by_speed(gadget, &audio_dev->func, ep); config_ep_by_speed(gadget, &audio_dev->func, ep);
req_len = prm->max_psize; req_len = ep->maxpacket;
prm->ep_enabled = true; prm->ep_enabled = true;
usb_ep_enable(ep); usb_ep_enable(ep);
...@@ -379,7 +379,7 @@ int u_audio_start_capture(struct g_audio *audio_dev) ...@@ -379,7 +379,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
req->context = &prm->ureq[i]; req->context = &prm->ureq[i];
req->length = req_len; req->length = req_len;
req->complete = u_audio_iso_complete; 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)) 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) ...@@ -430,9 +430,9 @@ int u_audio_start_playback(struct g_audio *audio_dev)
uac->p_pktsize = min_t(unsigned int, uac->p_pktsize = min_t(unsigned int,
uac->p_framesize * uac->p_framesize *
(params->p_srate / uac->p_interval), (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 * uac->p_pktsize_residue = uac->p_framesize *
(params->p_srate % uac->p_interval); (params->p_srate % uac->p_interval);
else else
...@@ -457,7 +457,7 @@ int u_audio_start_playback(struct g_audio *audio_dev) ...@@ -457,7 +457,7 @@ int u_audio_start_playback(struct g_audio *audio_dev)
req->context = &prm->ureq[i]; req->context = &prm->ureq[i];
req->length = req_len; req->length = req_len;
req->complete = u_audio_iso_complete; 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)) if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
......
...@@ -561,8 +561,10 @@ static int gs_start_io(struct gs_port *port) ...@@ -561,8 +561,10 @@ static int gs_start_io(struct gs_port *port)
port->n_read = 0; port->n_read = 0;
started = gs_start_rx(port); started = gs_start_rx(port);
/* unblock any pending writes into our circular buffer */
if (started) { if (started) {
gs_start_tx(port);
/* Unblock any pending writes into our circular buffer, in case
* we didn't in gs_start_tx() */
tty_wakeup(port->port.tty); tty_wakeup(port->port.tty);
} else { } else {
gs_free_requests(ep, head, &port->read_allocated); gs_free_requests(ep, head, &port->read_allocated);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment