Skip to content

Commit 2d30408

Browse files
committed
Merge tag 'fixes-for-v4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus
Felipe writes: USB: fixes for v4.14-rc5 A deadlock fix in dummy-hcd; Fixing a use-after-free bug in composite; Renesas got another fix for DMA programming (this time around a fix for receiving ZLP); Tegra PHY got a suspend fix; A memory leak on our configfs ABI got plugged. Other than these, a couple other minor fixes on usbtest.
2 parents 47a4b71 + 7c80f9e commit 2d30408

File tree

9 files changed

+62
-20
lines changed

9 files changed

+62
-20
lines changed

drivers/usb/gadget/composite.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended);
20262026
static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
20272027
{
20282028
struct usb_composite_dev *cdev = get_gadget_data(gadget);
2029+
struct usb_gadget_strings *gstr = cdev->driver->strings[0];
2030+
struct usb_string *dev_str = gstr->strings;
20292031

20302032
/* composite_disconnect() must already have been called
20312033
* by the underlying peripheral controller driver!
@@ -2045,6 +2047,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
20452047

20462048
composite_dev_cleanup(cdev);
20472049

2050+
if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer)
2051+
dev_str[USB_GADGET_MANUFACTURER_IDX].s = "";
2052+
20482053
kfree(cdev->def_manufacturer);
20492054
kfree(cdev);
20502055
set_gadget_data(gadget, NULL);

drivers/usb/gadget/configfs.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,11 +1143,12 @@ static struct configfs_attribute *interf_grp_attrs[] = {
11431143
NULL
11441144
};
11451145

1146-
int usb_os_desc_prepare_interf_dir(struct config_group *parent,
1147-
int n_interf,
1148-
struct usb_os_desc **desc,
1149-
char **names,
1150-
struct module *owner)
1146+
struct config_group *usb_os_desc_prepare_interf_dir(
1147+
struct config_group *parent,
1148+
int n_interf,
1149+
struct usb_os_desc **desc,
1150+
char **names,
1151+
struct module *owner)
11511152
{
11521153
struct config_group *os_desc_group;
11531154
struct config_item_type *os_desc_type, *interface_type;
@@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
11591160

11601161
char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
11611162
if (!vlabuf)
1162-
return -ENOMEM;
1163+
return ERR_PTR(-ENOMEM);
11631164

11641165
os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
11651166
os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
@@ -1184,7 +1185,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
11841185
configfs_add_default_group(&d->group, os_desc_group);
11851186
}
11861187

1187-
return 0;
1188+
return os_desc_group;
11881189
}
11891190
EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
11901191

drivers/usb/gadget/configfs.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55

66
void unregister_gadget_item(struct config_item *item);
77

8-
int usb_os_desc_prepare_interf_dir(struct config_group *parent,
9-
int n_interf,
10-
struct usb_os_desc **desc,
11-
char **names,
12-
struct module *owner);
8+
struct config_group *usb_os_desc_prepare_interf_dir(
9+
struct config_group *parent,
10+
int n_interf,
11+
struct usb_os_desc **desc,
12+
char **names,
13+
struct module *owner);
1314

1415
static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item)
1516
{

drivers/usb/gadget/function/f_rndis.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f)
908908
free_netdev(opts->net);
909909
}
910910

911+
kfree(opts->rndis_interf_group); /* single VLA chunk */
911912
kfree(opts);
912913
}
913914

@@ -916,6 +917,7 @@ static struct usb_function_instance *rndis_alloc_inst(void)
916917
struct f_rndis_opts *opts;
917918
struct usb_os_desc *descs[1];
918919
char *names[1];
920+
struct config_group *rndis_interf_group;
919921

920922
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
921923
if (!opts)
@@ -940,8 +942,14 @@ static struct usb_function_instance *rndis_alloc_inst(void)
940942
names[0] = "rndis";
941943
config_group_init_type_name(&opts->func_inst.group, "",
942944
&rndis_func_type);
943-
usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
944-
names, THIS_MODULE);
945+
rndis_interf_group =
946+
usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
947+
names, THIS_MODULE);
948+
if (IS_ERR(rndis_interf_group)) {
949+
rndis_free_inst(&opts->func_inst);
950+
return ERR_CAST(rndis_interf_group);
951+
}
952+
opts->rndis_interf_group = rndis_interf_group;
945953

946954
return &opts->func_inst;
947955
}

drivers/usb/gadget/function/u_rndis.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct f_rndis_opts {
2626
bool bound;
2727
bool borrowed_net;
2828

29+
struct config_group *rndis_interf_group;
2930
struct usb_os_desc rndis_os_desc;
3031
char rndis_ext_compat_id[16];
3132

drivers/usb/gadget/udc/dummy_hcd.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd)
419419
static void set_link_state(struct dummy_hcd *dum_hcd)
420420
{
421421
struct dummy *dum = dum_hcd->dum;
422+
unsigned int power_bit;
422423

423424
dum_hcd->active = 0;
424425
if (dum->pullup)
@@ -429,17 +430,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd)
429430
return;
430431

431432
set_link_state_by_speed(dum_hcd);
433+
power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ?
434+
USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER);
432435

433436
if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 ||
434437
dum_hcd->active)
435438
dum_hcd->resuming = 0;
436439

437440
/* Currently !connected or in reset */
438-
if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 ||
441+
if ((dum_hcd->port_status & power_bit) == 0 ||
439442
(dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) {
440-
unsigned disconnect = USB_PORT_STAT_CONNECTION &
443+
unsigned int disconnect = power_bit &
441444
dum_hcd->old_status & (~dum_hcd->port_status);
442-
unsigned reset = USB_PORT_STAT_RESET &
445+
unsigned int reset = USB_PORT_STAT_RESET &
443446
(~dum_hcd->old_status) & dum_hcd->port_status;
444447

445448
/* Report reset and disconnect events to the driver */

drivers/usb/misc/usbtest.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,13 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
202202
return tmp;
203203
}
204204

205-
if (in) {
205+
if (in)
206206
dev->in_pipe = usb_rcvbulkpipe(udev,
207207
in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
208+
if (out)
208209
dev->out_pipe = usb_sndbulkpipe(udev,
209210
out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
210-
}
211+
211212
if (iso_in) {
212213
dev->iso_in = &iso_in->desc;
213214
dev->in_iso_pipe = usb_rcvisocpipe(udev,
@@ -1964,6 +1965,9 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param,
19641965
int status = 0;
19651966
struct urb *urbs[param->sglen];
19661967

1968+
if (!param->sglen || param->iterations > UINT_MAX / param->sglen)
1969+
return -EINVAL;
1970+
19671971
memset(&context, 0, sizeof(context));
19681972
context.count = param->iterations * param->sglen;
19691973
context.dev = dev;
@@ -2087,6 +2091,8 @@ usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param)
20872091

20882092
if (param->iterations <= 0)
20892093
return -EINVAL;
2094+
if (param->sglen > MAX_SGLEN)
2095+
return -EINVAL;
20902096
/*
20912097
* Just a bunch of test cases that every HCD is expected to handle.
20922098
*

drivers/usb/phy/phy-tegra-usb.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,14 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
329329
unsigned long val;
330330
void __iomem *base = phy->regs;
331331

332+
/*
333+
* The USB driver may have already initiated the phy clock
334+
* disable so wait to see if the clock turns off and if not
335+
* then proceed with gating the clock.
336+
*/
337+
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) == 0)
338+
return;
339+
332340
if (phy->is_legacy_phy) {
333341
val = readl(base + USB_SUSP_CTRL);
334342
val |= USB_SUSP_SET;
@@ -351,6 +359,15 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
351359
unsigned long val;
352360
void __iomem *base = phy->regs;
353361

362+
/*
363+
* The USB driver may have already initiated the phy clock
364+
* enable so wait to see if the clock turns on and if not
365+
* then proceed with ungating the clock.
366+
*/
367+
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
368+
USB_PHY_CLK_VALID) == 0)
369+
return;
370+
354371
if (phy->is_legacy_phy) {
355372
val = readl(base + USB_SUSP_CTRL);
356373
val |= USB_SUSP_CLR;

drivers/usb/renesas_usbhs/fifo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,9 +857,9 @@ static void xfer_work(struct work_struct *work)
857857
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
858858

859859
usbhs_pipe_running(pipe, 1);
860-
usbhsf_dma_start(pipe, fifo);
861860
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
862861
dma_async_issue_pending(chan);
862+
usbhsf_dma_start(pipe, fifo);
863863
usbhs_pipe_enable(pipe);
864864

865865
xfer_work_end:

0 commit comments

Comments
 (0)