Skip to content

Commit c4d25ce

Browse files
committed
Merge tag 'usb-6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "A few small USB fixes for 6.1-rc3. Include in here are: - MAINTAINERS update, including a big one for the USB gadget subsystem. Many thanks to Felipe for all of the years of hard work he has done on this codebase, it was greatly appreciated. - dwc3 driver fixes for reported problems. - xhci driver fixes for reported problems. - typec driver fixes for minor issues - uvc gadget driver change, and then revert as it wasn't relevant for 6.1-final, as it is a new feature and people are still reviewing and modifying it. All of these have been in the linux-next tree with no reported issues" * tag 'usb-6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: dwc3: gadget: Don't set IMI for no_interrupt usb: dwc3: gadget: Stop processing more requests on IMI Revert "usb: gadget: uvc: limit isoc_sg to super speed gadgets" xhci: Remove device endpoints from bandwidth list when freeing the device xhci-pci: Set runtime PM as default policy on all xHC 1.2 or later devices xhci: Add quirk to reset host back to default state at shutdown usb: xhci: add XHCI_SPURIOUS_SUCCESS to ASM1042 despite being a V0.96 controller usb: dwc3: st: Rely on child's compatible instead of name usb: gadget: uvc: limit isoc_sg to super speed gadgets usb: bdc: change state when port disconnected usb: typec: ucsi: acpi: Implement resume callback usb: typec: ucsi: Check the connection on resume usb: gadget: aspeed: Fix probe regression usb: gadget: uvc: fix sg handling during video encode usb: gadget: uvc: fix sg handling in error case usb: gadget: uvc: fix dropped frame after missed isoc usb: dwc3: gadget: Don't delay End Transfer on delayed_status usb: dwc3: Don't switch OTG -> peripheral if extcon is present MAINTAINERS: Update maintainers for broadcom USB MAINTAINERS: move USB gadget and phy entries under the main USB entry
2 parents ef3c094 + 308c316 commit c4d25ce

File tree

15 files changed

+169
-133
lines changed

15 files changed

+169
-133
lines changed

MAINTAINERS

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4101,6 +4101,7 @@ N: bcm7038
41014101
N: bcm7120
41024102

41034103
BROADCOM BDC DRIVER
4104+
M: Justin Chen <[email protected]>
41044105
M: Al Cooper <[email protected]>
41054106
41064107
R: Broadcom internal kernel review list <[email protected]>
@@ -4207,6 +4208,7 @@ F: Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml
42074208
F: drivers/tty/serial/8250/8250_bcm7271.c
42084209

42094210
BROADCOM BRCMSTB USB EHCI DRIVER
4211+
M: Justin Chen <[email protected]>
42104212
M: Al Cooper <[email protected]>
42114213
R: Broadcom internal kernel review list <[email protected]>
42124214
@@ -4223,6 +4225,7 @@ F: Documentation/devicetree/bindings/usb/brcm,usb-pinmap.yaml
42234225
F: drivers/usb/misc/brcmstb-usb-pinmap.c
42244226

42254227
BROADCOM BRCMSTB USB2 and USB3 PHY DRIVER
4228+
M: Justin Chen <[email protected]>
42264229
M: Al Cooper <[email protected]>
42274230
R: Broadcom internal kernel review list <[email protected]>
42284231
@@ -21179,15 +21182,6 @@ S: Maintained
2117921182
F: Documentation/usb/ehci.rst
2118021183
F: drivers/usb/host/ehci*
2118121184

21182-
USB GADGET/PERIPHERAL SUBSYSTEM
21183-
M: Felipe Balbi <[email protected]>
21184-
21185-
S: Maintained
21186-
W: http://www.linux-usb.org/gadget
21187-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
21188-
F: drivers/usb/gadget/
21189-
F: include/linux/usb/gadget*
21190-
2119121185
USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
2119221186
M: Jiri Kosina <[email protected]>
2119321187
M: Benjamin Tissoires <[email protected]>
@@ -21294,13 +21288,6 @@ W: https://github.com/petkan/pegasus
2129421288
T: git https://github.com/petkan/pegasus.git
2129521289
F: drivers/net/usb/pegasus.*
2129621290

21297-
USB PHY LAYER
21298-
M: Felipe Balbi <[email protected]>
21299-
21300-
S: Maintained
21301-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
21302-
F: drivers/usb/phy/
21303-
2130421291
USB PRINTER DRIVER (usblp)
2130521292
M: Pete Zaitcev <[email protected]>
2130621293

drivers/usb/dwc3/core.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/delay.h>
2424
#include <linux/dma-mapping.h>
2525
#include <linux/of.h>
26+
#include <linux/of_graph.h>
2627
#include <linux/acpi.h>
2728
#include <linux/pinctrl/consumer.h>
2829
#include <linux/reset.h>
@@ -85,7 +86,7 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
8586
* mode. If the controller supports DRD but the dr_mode is not
8687
* specified or set to OTG, then set the mode to peripheral.
8788
*/
88-
if (mode == USB_DR_MODE_OTG &&
89+
if (mode == USB_DR_MODE_OTG && !dwc->edev &&
8990
(!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
9091
!device_property_read_bool(dwc->dev, "usb-role-switch")) &&
9192
!DWC3_VER_IS_PRIOR(DWC3, 330A))
@@ -1690,6 +1691,46 @@ static void dwc3_check_params(struct dwc3 *dwc)
16901691
}
16911692
}
16921693

1694+
static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
1695+
{
1696+
struct device *dev = dwc->dev;
1697+
struct device_node *np_phy;
1698+
struct extcon_dev *edev = NULL;
1699+
const char *name;
1700+
1701+
if (device_property_read_bool(dev, "extcon"))
1702+
return extcon_get_edev_by_phandle(dev, 0);
1703+
1704+
/*
1705+
* Device tree platforms should get extcon via phandle.
1706+
* On ACPI platforms, we get the name from a device property.
1707+
* This device property is for kernel internal use only and
1708+
* is expected to be set by the glue code.
1709+
*/
1710+
if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
1711+
return extcon_get_extcon_dev(name);
1712+
1713+
/*
1714+
* Try to get an extcon device from the USB PHY controller's "port"
1715+
* node. Check if it has the "port" node first, to avoid printing the
1716+
* error message from underlying code, as it's a valid case: extcon
1717+
* device (and "port" node) may be missing in case of "usb-role-switch"
1718+
* or OTG mode.
1719+
*/
1720+
np_phy = of_parse_phandle(dev->of_node, "phys", 0);
1721+
if (of_graph_is_present(np_phy)) {
1722+
struct device_node *np_conn;
1723+
1724+
np_conn = of_graph_get_remote_node(np_phy, -1, -1);
1725+
if (np_conn)
1726+
edev = extcon_find_edev_by_node(np_conn);
1727+
of_node_put(np_conn);
1728+
}
1729+
of_node_put(np_phy);
1730+
1731+
return edev;
1732+
}
1733+
16931734
static int dwc3_probe(struct platform_device *pdev)
16941735
{
16951736
struct device *dev = &pdev->dev;
@@ -1840,6 +1881,12 @@ static int dwc3_probe(struct platform_device *pdev)
18401881
goto err2;
18411882
}
18421883

1884+
dwc->edev = dwc3_get_extcon(dwc);
1885+
if (IS_ERR(dwc->edev)) {
1886+
ret = dev_err_probe(dwc->dev, PTR_ERR(dwc->edev), "failed to get extcon\n");
1887+
goto err3;
1888+
}
1889+
18431890
ret = dwc3_get_dr_mode(dwc);
18441891
if (ret)
18451892
goto err3;

drivers/usb/dwc3/drd.c

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*/
99

1010
#include <linux/extcon.h>
11-
#include <linux/of_graph.h>
1211
#include <linux/of_platform.h>
1312
#include <linux/platform_device.h>
1413
#include <linux/property.h>
@@ -439,51 +438,6 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
439438
return NOTIFY_DONE;
440439
}
441440

442-
static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
443-
{
444-
struct device *dev = dwc->dev;
445-
struct device_node *np_phy;
446-
struct extcon_dev *edev = NULL;
447-
const char *name;
448-
449-
if (device_property_read_bool(dev, "extcon"))
450-
return extcon_get_edev_by_phandle(dev, 0);
451-
452-
/*
453-
* Device tree platforms should get extcon via phandle.
454-
* On ACPI platforms, we get the name from a device property.
455-
* This device property is for kernel internal use only and
456-
* is expected to be set by the glue code.
457-
*/
458-
if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) {
459-
edev = extcon_get_extcon_dev(name);
460-
if (!edev)
461-
return ERR_PTR(-EPROBE_DEFER);
462-
463-
return edev;
464-
}
465-
466-
/*
467-
* Try to get an extcon device from the USB PHY controller's "port"
468-
* node. Check if it has the "port" node first, to avoid printing the
469-
* error message from underlying code, as it's a valid case: extcon
470-
* device (and "port" node) may be missing in case of "usb-role-switch"
471-
* or OTG mode.
472-
*/
473-
np_phy = of_parse_phandle(dev->of_node, "phys", 0);
474-
if (of_graph_is_present(np_phy)) {
475-
struct device_node *np_conn;
476-
477-
np_conn = of_graph_get_remote_node(np_phy, -1, -1);
478-
if (np_conn)
479-
edev = extcon_find_edev_by_node(np_conn);
480-
of_node_put(np_conn);
481-
}
482-
of_node_put(np_phy);
483-
484-
return edev;
485-
}
486-
487441
#if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
488442
#define ROLE_SWITCH 1
489443
static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
@@ -588,10 +542,6 @@ int dwc3_drd_init(struct dwc3 *dwc)
588542
device_property_read_bool(dwc->dev, "usb-role-switch"))
589543
return dwc3_setup_role_switch(dwc);
590544

591-
dwc->edev = dwc3_get_extcon(dwc);
592-
if (IS_ERR(dwc->edev))
593-
return PTR_ERR(dwc->edev);
594-
595545
if (dwc->edev) {
596546
dwc->edev_nb.notifier_call = dwc3_drd_notifier;
597547
ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,

drivers/usb/dwc3/dwc3-st.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
251251
/* Manage SoftReset */
252252
reset_control_deassert(dwc3_data->rstc_rst);
253253

254-
child = of_get_child_by_name(node, "usb");
254+
child = of_get_compatible_child(node, "snps,dwc3");
255255
if (!child) {
256256
dev_err(&pdev->dev, "failed to find dwc3 core node\n");
257257
ret = -ENODEV;

drivers/usb/dwc3/gadget.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,8 +1292,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
12921292
trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
12931293
}
12941294

1295-
/* always enable Interrupt on Missed ISOC */
1296-
trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
1295+
if (!no_interrupt && !chain)
1296+
trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
12971297
break;
12981298

12991299
case USB_ENDPOINT_XFER_BULK:
@@ -1698,6 +1698,16 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
16981698
cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
16991699
memset(&params, 0, sizeof(params));
17001700
ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
1701+
/*
1702+
* If the End Transfer command was timed out while the device is
1703+
* not in SETUP phase, it's possible that an incoming Setup packet
1704+
* may prevent the command's completion. Let's retry when the
1705+
* ep0state returns to EP0_SETUP_PHASE.
1706+
*/
1707+
if (ret == -ETIMEDOUT && dep->dwc->ep0state != EP0_SETUP_PHASE) {
1708+
dep->flags |= DWC3_EP_DELAY_STOP;
1709+
return 0;
1710+
}
17011711
WARN_ON_ONCE(ret);
17021712
dep->resource_index = 0;
17031713

@@ -3238,6 +3248,10 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
32383248
if (event->status & DEPEVT_STATUS_SHORT && !chain)
32393249
return 1;
32403250

3251+
if ((trb->ctrl & DWC3_TRB_CTRL_ISP_IMI) &&
3252+
DWC3_TRB_SIZE_TRBSTS(trb->size) == DWC3_TRBSTS_MISSED_ISOC)
3253+
return 1;
3254+
32413255
if ((trb->ctrl & DWC3_TRB_CTRL_IOC) ||
32423256
(trb->ctrl & DWC3_TRB_CTRL_LST))
32433257
return 1;
@@ -3719,7 +3733,7 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
37193733
* timeout. Delay issuing the End Transfer command until the Setup TRB is
37203734
* prepared.
37213735
*/
3722-
if (dwc->ep0state != EP0_SETUP_PHASE) {
3736+
if (dwc->ep0state != EP0_SETUP_PHASE && !dwc->delayed_status) {
37233737
dep->flags |= DWC3_EP_DELAY_STOP;
37243738
return;
37253739
}

drivers/usb/gadget/function/uvc_queue.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
304304

305305
queue->sequence = 0;
306306
queue->buf_used = 0;
307+
queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
307308
} else {
308309
ret = vb2_streamoff(&queue->queue, queue->queue.type);
309310
if (ret < 0)
@@ -329,10 +330,11 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
329330
void uvcg_complete_buffer(struct uvc_video_queue *queue,
330331
struct uvc_buffer *buf)
331332
{
332-
if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
333-
buf->length != buf->bytesused) {
334-
buf->state = UVC_BUF_STATE_QUEUED;
333+
if (queue->flags & UVC_QUEUE_DROP_INCOMPLETE) {
334+
queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
335+
buf->state = UVC_BUF_STATE_ERROR;
335336
vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0);
337+
vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR);
336338
return;
337339
}
338340

drivers/usb/gadget/function/uvc_video.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
8888
struct uvc_buffer *buf)
8989
{
9090
void *mem = req->buf;
91+
struct uvc_request *ureq = req->context;
9192
int len = video->req_size;
9293
int ret;
9394

@@ -113,13 +114,14 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
113114
video->queue.buf_used = 0;
114115
buf->state = UVC_BUF_STATE_DONE;
115116
list_del(&buf->queue);
116-
uvcg_complete_buffer(&video->queue, buf);
117117
video->fid ^= UVC_STREAM_FID;
118+
ureq->last_buf = buf;
118119

119120
video->payload_size = 0;
120121
}
121122

122123
if (video->payload_size == video->max_payload_size ||
124+
video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE ||
123125
buf->bytesused == video->queue.buf_used)
124126
video->payload_size = 0;
125127
}
@@ -155,10 +157,10 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
155157
sg = sg_next(sg);
156158

157159
for_each_sg(sg, iter, ureq->sgt.nents - 1, i) {
158-
if (!len || !buf->sg || !sg_dma_len(buf->sg))
160+
if (!len || !buf->sg || !buf->sg->length)
159161
break;
160162

161-
sg_left = sg_dma_len(buf->sg) - buf->offset;
163+
sg_left = buf->sg->length - buf->offset;
162164
part = min_t(unsigned int, len, sg_left);
163165

164166
sg_set_page(iter, sg_page(buf->sg), part, buf->offset);
@@ -180,7 +182,8 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
180182
req->length -= len;
181183
video->queue.buf_used += req->length - header_len;
182184

183-
if (buf->bytesused == video->queue.buf_used || !buf->sg) {
185+
if (buf->bytesused == video->queue.buf_used || !buf->sg ||
186+
video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) {
184187
video->queue.buf_used = 0;
185188
buf->state = UVC_BUF_STATE_DONE;
186189
buf->offset = 0;
@@ -195,6 +198,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
195198
struct uvc_buffer *buf)
196199
{
197200
void *mem = req->buf;
201+
struct uvc_request *ureq = req->context;
198202
int len = video->req_size;
199203
int ret;
200204

@@ -209,12 +213,13 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
209213

210214
req->length = video->req_size - len;
211215

212-
if (buf->bytesused == video->queue.buf_used) {
216+
if (buf->bytesused == video->queue.buf_used ||
217+
video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) {
213218
video->queue.buf_used = 0;
214219
buf->state = UVC_BUF_STATE_DONE;
215220
list_del(&buf->queue);
216-
uvcg_complete_buffer(&video->queue, buf);
217221
video->fid ^= UVC_STREAM_FID;
222+
ureq->last_buf = buf;
218223
}
219224
}
220225

@@ -255,6 +260,11 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
255260
case 0:
256261
break;
257262

263+
case -EXDEV:
264+
uvcg_dbg(&video->uvc->func, "VS request missed xfer.\n");
265+
queue->flags |= UVC_QUEUE_DROP_INCOMPLETE;
266+
break;
267+
258268
case -ESHUTDOWN: /* disconnect from host. */
259269
uvcg_dbg(&video->uvc->func, "VS request cancelled.\n");
260270
uvcg_queue_cancel(queue, 1);
@@ -431,7 +441,8 @@ static void uvcg_video_pump(struct work_struct *work)
431441

432442
/* Endpoint now owns the request */
433443
req = NULL;
434-
video->req_int_count++;
444+
if (buf->state != UVC_BUF_STATE_DONE)
445+
video->req_int_count++;
435446
}
436447

437448
if (!req)

drivers/usb/gadget/udc/aspeed-vhub/dev.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
591591
d->gadget.max_speed = USB_SPEED_HIGH;
592592
d->gadget.speed = USB_SPEED_UNKNOWN;
593593
d->gadget.dev.of_node = vhub->pdev->dev.of_node;
594+
d->gadget.dev.of_node_reused = true;
594595

595596
rc = usb_add_gadget_udc(d->port_dev, &d->gadget);
596597
if (rc != 0)

drivers/usb/gadget/udc/bdc/bdc_udc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ static void bdc_uspc_disconnected(struct bdc *bdc, bool reinit)
151151
bdc->delayed_status = false;
152152
bdc->reinit = reinit;
153153
bdc->test_mode = false;
154+
usb_gadget_set_state(&bdc->gadget, USB_STATE_NOTATTACHED);
154155
}
155156

156157
/* TNotify wkaeup timer */

0 commit comments

Comments
 (0)