Skip to content

Commit 3c15237

Browse files
committed
Merge tag 'usb-6.9-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB driver fixes from Greg KH: "Here are some small USB driver fixes for reported problems for 6.9-rc7. Included in here are: - usb core fixes for found issues - typec driver fixes for reported problems - usb gadget driver fixes for reported problems - xhci build fixes - dwc3 driver fixes for reported issues All of these have been in linux-next this past week with no reported problems" * tag 'usb-6.9-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: typec: tcpm: Check for port partner validity before consuming it usb: typec: tcpm: enforce ready state when queueing alt mode vdm usb: typec: tcpm: unregister existing source caps before re-registration usb: typec: tcpm: clear pd_event queue in PORT_RESET usb: typec: tcpm: queue correct sop type in tcpm_queue_vdm_unlocked usb: Fix regression caused by invalid ep0 maxpacket in virtual SuperSpeed device usb: ohci: Prevent missed ohci interrupts usb: typec: qcom-pmic: fix pdphy start() error handling usb: typec: qcom-pmic: fix use-after-free on late probe errors usb: gadget: f_fs: Fix a race condition when processing setup packets. USB: core: Fix access violation during port device removal usb: dwc3: core: Prevent phy suspend during init usb: xhci-plat: Don't include xhci.h usb: gadget: uvc: use correct buffer size when parsing configfs lists usb: gadget: composite: fix OS descriptors w_value logic usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete
2 parents 3f1d086 + ae11f04 commit 3c15237

File tree

15 files changed

+147
-79
lines changed

15 files changed

+147
-79
lines changed

drivers/usb/core/hub.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5110,9 +5110,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
51105110
}
51115111
if (usb_endpoint_maxp(&udev->ep0.desc) == i) {
51125112
; /* Initial ep0 maxpacket guess is right */
5113-
} else if ((udev->speed == USB_SPEED_FULL ||
5113+
} else if (((udev->speed == USB_SPEED_FULL ||
51145114
udev->speed == USB_SPEED_HIGH) &&
5115-
(i == 8 || i == 16 || i == 32 || i == 64)) {
5115+
(i == 8 || i == 16 || i == 32 || i == 64)) ||
5116+
(udev->speed >= USB_SPEED_SUPER && i > 0)) {
51165117
/* Initial guess is wrong; use the descriptor's value */
51175118
if (udev->speed == USB_SPEED_FULL)
51185119
dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);

drivers/usb/core/port.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ static ssize_t disable_show(struct device *dev,
5151
struct usb_port *port_dev = to_usb_port(dev);
5252
struct usb_device *hdev = to_usb_device(dev->parent->parent);
5353
struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
54-
struct usb_interface *intf = to_usb_interface(hub->intfdev);
54+
struct usb_interface *intf = to_usb_interface(dev->parent);
5555
int port1 = port_dev->portnum;
5656
u16 portstatus, unused;
5757
bool disabled;
5858
int rc;
5959
struct kernfs_node *kn;
6060

61+
if (!hub)
62+
return -ENODEV;
6163
hub_get(hub);
6264
rc = usb_autopm_get_interface(intf);
6365
if (rc < 0)
@@ -101,12 +103,14 @@ static ssize_t disable_store(struct device *dev, struct device_attribute *attr,
101103
struct usb_port *port_dev = to_usb_port(dev);
102104
struct usb_device *hdev = to_usb_device(dev->parent->parent);
103105
struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
104-
struct usb_interface *intf = to_usb_interface(hub->intfdev);
106+
struct usb_interface *intf = to_usb_interface(dev->parent);
105107
int port1 = port_dev->portnum;
106108
bool disabled;
107109
int rc;
108110
struct kernfs_node *kn;
109111

112+
if (!hub)
113+
return -ENODEV;
110114
rc = kstrtobool(buf, &disabled);
111115
if (rc)
112116
return rc;

drivers/usb/dwc3/core.c

Lines changed: 38 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,27 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
104104
return 0;
105105
}
106106

107+
void dwc3_enable_susphy(struct dwc3 *dwc, bool enable)
108+
{
109+
u32 reg;
110+
111+
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
112+
if (enable && !dwc->dis_u3_susphy_quirk)
113+
reg |= DWC3_GUSB3PIPECTL_SUSPHY;
114+
else
115+
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
116+
117+
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
118+
119+
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
120+
if (enable && !dwc->dis_u2_susphy_quirk)
121+
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
122+
else
123+
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
124+
125+
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
126+
}
127+
107128
void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
108129
{
109130
u32 reg;
@@ -585,11 +606,8 @@ static int dwc3_core_ulpi_init(struct dwc3 *dwc)
585606
*/
586607
static int dwc3_phy_setup(struct dwc3 *dwc)
587608
{
588-
unsigned int hw_mode;
589609
u32 reg;
590610

591-
hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
592-
593611
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
594612

595613
/*
@@ -599,21 +617,16 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
599617
reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX;
600618

601619
/*
602-
* Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY
603-
* to '0' during coreConsultant configuration. So default value
604-
* will be '0' when the core is reset. Application needs to set it
605-
* to '1' after the core initialization is completed.
606-
*/
607-
if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
608-
reg |= DWC3_GUSB3PIPECTL_SUSPHY;
609-
610-
/*
611-
* For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be cleared after
612-
* power-on reset, and it can be set after core initialization, which is
613-
* after device soft-reset during initialization.
620+
* Above DWC_usb3.0 1.94a, it is recommended to set
621+
* DWC3_GUSB3PIPECTL_SUSPHY to '0' during coreConsultant configuration.
622+
* So default value will be '0' when the core is reset. Application
623+
* needs to set it to '1' after the core initialization is completed.
624+
*
625+
* Similarly for DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be
626+
* cleared after power-on reset, and it can be set after core
627+
* initialization.
614628
*/
615-
if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD)
616-
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
629+
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
617630

618631
if (dwc->u2ss_inp3_quirk)
619632
reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK;
@@ -639,9 +652,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
639652
if (dwc->tx_de_emphasis_quirk)
640653
reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis);
641654

642-
if (dwc->dis_u3_susphy_quirk)
643-
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
644-
645655
if (dwc->dis_del_phy_power_chg_quirk)
646656
reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
647657

@@ -689,24 +699,15 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
689699
}
690700

691701
/*
692-
* Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
693-
* '0' during coreConsultant configuration. So default value will
694-
* be '0' when the core is reset. Application needs to set it to
695-
* '1' after the core initialization is completed.
696-
*/
697-
if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
698-
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
699-
700-
/*
701-
* For DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared after
702-
* power-on reset, and it can be set after core initialization, which is
703-
* after device soft-reset during initialization.
702+
* Above DWC_usb3.0 1.94a, it is recommended to set
703+
* DWC3_GUSB2PHYCFG_SUSPHY to '0' during coreConsultant configuration.
704+
* So default value will be '0' when the core is reset. Application
705+
* needs to set it to '1' after the core initialization is completed.
706+
*
707+
* Similarly for DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared
708+
* after power-on reset, and it can be set after core initialization.
704709
*/
705-
if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD)
706-
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
707-
708-
if (dwc->dis_u2_susphy_quirk)
709-
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
710+
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
710711

711712
if (dwc->dis_enblslpm_quirk)
712713
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
@@ -1227,21 +1228,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
12271228
if (ret)
12281229
goto err_exit_phy;
12291230

1230-
if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD &&
1231-
!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) {
1232-
if (!dwc->dis_u3_susphy_quirk) {
1233-
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
1234-
reg |= DWC3_GUSB3PIPECTL_SUSPHY;
1235-
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
1236-
}
1237-
1238-
if (!dwc->dis_u2_susphy_quirk) {
1239-
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
1240-
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
1241-
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
1242-
}
1243-
}
1244-
12451231
dwc3_core_setup_global_control(dwc);
12461232
dwc3_core_num_eps(dwc);
12471233

drivers/usb/dwc3/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,7 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc);
15801580
void dwc3_event_buffers_cleanup(struct dwc3 *dwc);
15811581

15821582
int dwc3_core_soft_reset(struct dwc3 *dwc);
1583+
void dwc3_enable_susphy(struct dwc3 *dwc, bool enable);
15831584

15841585
#if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
15851586
int dwc3_host_init(struct dwc3 *dwc);

drivers/usb/dwc3/gadget.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2924,6 +2924,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
29242924
dwc3_ep0_out_start(dwc);
29252925

29262926
dwc3_gadget_enable_irq(dwc);
2927+
dwc3_enable_susphy(dwc, true);
29272928

29282929
return 0;
29292930

@@ -4690,6 +4691,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
46904691
if (!dwc->gadget)
46914692
return;
46924693

4694+
dwc3_enable_susphy(dwc, false);
46934695
usb_del_gadget(dwc->gadget);
46944696
dwc3_gadget_free_endpoints(dwc);
46954697
usb_put_gadget(dwc->gadget);

drivers/usb/dwc3/host.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
#include <linux/irq.h>
1111
#include <linux/of.h>
1212
#include <linux/platform_device.h>
13+
#include <linux/usb.h>
14+
#include <linux/usb/hcd.h>
1315

1416
#include "../host/xhci-port.h"
1517
#include "../host/xhci-ext-caps.h"
1618
#include "../host/xhci-caps.h"
19+
#include "../host/xhci-plat.h"
1720
#include "core.h"
1821

1922
#define XHCI_HCSPARAMS1 0x4
@@ -57,6 +60,24 @@ static void dwc3_power_off_all_roothub_ports(struct dwc3 *dwc)
5760
}
5861
}
5962

63+
static void dwc3_xhci_plat_start(struct usb_hcd *hcd)
64+
{
65+
struct platform_device *pdev;
66+
struct dwc3 *dwc;
67+
68+
if (!usb_hcd_is_primary_hcd(hcd))
69+
return;
70+
71+
pdev = to_platform_device(hcd->self.controller);
72+
dwc = dev_get_drvdata(pdev->dev.parent);
73+
74+
dwc3_enable_susphy(dwc, true);
75+
}
76+
77+
static const struct xhci_plat_priv dwc3_xhci_plat_quirk = {
78+
.plat_start = dwc3_xhci_plat_start,
79+
};
80+
6081
static void dwc3_host_fill_xhci_irq_res(struct dwc3 *dwc,
6182
int irq, char *name)
6283
{
@@ -167,6 +188,11 @@ int dwc3_host_init(struct dwc3 *dwc)
167188
}
168189
}
169190

191+
ret = platform_device_add_data(xhci, &dwc3_xhci_plat_quirk,
192+
sizeof(struct xhci_plat_priv));
193+
if (ret)
194+
goto err;
195+
170196
ret = platform_device_add(xhci);
171197
if (ret) {
172198
dev_err(dwc->dev, "failed to register xHCI device\n");
@@ -192,6 +218,7 @@ void dwc3_host_exit(struct dwc3 *dwc)
192218
if (dwc->sys_wakeup)
193219
device_init_wakeup(&dwc->xhci->dev, false);
194220

221+
dwc3_enable_susphy(dwc, false);
195222
platform_device_unregister(dwc->xhci);
196223
dwc->xhci = NULL;
197224
}

drivers/usb/gadget/composite.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,7 +2112,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
21122112
buf[5] = 0x01;
21132113
switch (ctrl->bRequestType & USB_RECIP_MASK) {
21142114
case USB_RECIP_DEVICE:
2115-
if (w_index != 0x4 || (w_value >> 8))
2115+
if (w_index != 0x4 || (w_value & 0xff))
21162116
break;
21172117
buf[6] = w_index;
21182118
/* Number of ext compat interfaces */
@@ -2128,9 +2128,9 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
21282128
}
21292129
break;
21302130
case USB_RECIP_INTERFACE:
2131-
if (w_index != 0x5 || (w_value >> 8))
2131+
if (w_index != 0x5 || (w_value & 0xff))
21322132
break;
2133-
interface = w_value & 0xFF;
2133+
interface = w_value >> 8;
21342134
if (interface >= MAX_CONFIG_INTERFACES ||
21352135
!os_desc_cfg->interface[interface])
21362136
break;

drivers/usb/gadget/function/f_fs.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
852852
work);
853853
int ret = io_data->status;
854854
bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
855+
unsigned long flags;
855856

856857
if (io_data->read && ret > 0) {
857858
kthread_use_mm(io_data->mm);
@@ -864,6 +865,11 @@ static void ffs_user_copy_worker(struct work_struct *work)
864865
if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)
865866
eventfd_signal(io_data->ffs->ffs_eventfd);
866867

868+
spin_lock_irqsave(&io_data->ffs->eps_lock, flags);
869+
usb_ep_free_request(io_data->ep, io_data->req);
870+
io_data->req = NULL;
871+
spin_unlock_irqrestore(&io_data->ffs->eps_lock, flags);
872+
867873
if (io_data->read)
868874
kfree(io_data->to_free);
869875
ffs_free_buffer(io_data);
@@ -877,7 +883,6 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep,
877883
struct ffs_data *ffs = io_data->ffs;
878884

879885
io_data->status = req->status ? req->status : req->actual;
880-
usb_ep_free_request(_ep, req);
881886

882887
INIT_WORK(&io_data->work, ffs_user_copy_worker);
883888
queue_work(ffs->io_completion_wq, &io_data->work);
@@ -3806,7 +3811,7 @@ static int ffs_func_setup(struct usb_function *f,
38063811
__ffs_event_add(ffs, FUNCTIONFS_SETUP);
38073812
spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags);
38083813

3809-
return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
3814+
return ffs->ev.setup.wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
38103815
}
38113816

38123817
static bool ffs_func_req_match(struct usb_function *f,

drivers/usb/gadget/function/uvc_configfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ static int __uvcg_iter_item_entries(const char *page, size_t len,
9292

9393
while (pg - page < len) {
9494
i = 0;
95-
while (i < sizeof(buf) && (pg - page < len) &&
95+
while (i < bufsize && (pg - page < len) &&
9696
*pg != '\0' && *pg != '\n')
9797
buf[i++] = *pg++;
98-
if (i == sizeof(buf)) {
98+
if (i == bufsize) {
9999
ret = -EINVAL;
100100
goto out_free_buf;
101101
}

drivers/usb/host/ohci-hcd.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
888888
/* Check for an all 1's result which is a typical consequence
889889
* of dead, unclocked, or unplugged (CardBus...) devices
890890
*/
891+
again:
891892
if (ints == ~(u32)0) {
892893
ohci->rh_state = OHCI_RH_HALTED;
893894
ohci_dbg (ohci, "device removed!\n");
@@ -982,6 +983,13 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
982983
}
983984
spin_unlock(&ohci->lock);
984985

986+
/* repeat until all enabled interrupts are handled */
987+
if (ohci->rh_state != OHCI_RH_HALTED) {
988+
ints = ohci_readl(ohci, &regs->intrstatus);
989+
if (ints && (ints & ohci_readl(ohci, &regs->intrenable)))
990+
goto again;
991+
}
992+
985993
return IRQ_HANDLED;
986994
}
987995

0 commit comments

Comments
 (0)