Commit 2d30408e authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'fixes-for-v4.14-rc5' of...

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.
parents 47a4b71c 7c80f9e4
...@@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended); ...@@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended);
static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
{ {
struct usb_composite_dev *cdev = get_gadget_data(gadget); struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_gadget_strings *gstr = cdev->driver->strings[0];
struct usb_string *dev_str = gstr->strings;
/* composite_disconnect() must already have been called /* composite_disconnect() must already have been called
* by the underlying peripheral controller driver! * by the underlying peripheral controller driver!
...@@ -2045,6 +2047,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) ...@@ -2045,6 +2047,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
composite_dev_cleanup(cdev); composite_dev_cleanup(cdev);
if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer)
dev_str[USB_GADGET_MANUFACTURER_IDX].s = "";
kfree(cdev->def_manufacturer); kfree(cdev->def_manufacturer);
kfree(cdev); kfree(cdev);
set_gadget_data(gadget, NULL); set_gadget_data(gadget, NULL);
......
...@@ -1143,7 +1143,8 @@ static struct configfs_attribute *interf_grp_attrs[] = { ...@@ -1143,7 +1143,8 @@ static struct configfs_attribute *interf_grp_attrs[] = {
NULL NULL
}; };
int usb_os_desc_prepare_interf_dir(struct config_group *parent, struct config_group *usb_os_desc_prepare_interf_dir(
struct config_group *parent,
int n_interf, int n_interf,
struct usb_os_desc **desc, struct usb_os_desc **desc,
char **names, char **names,
...@@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, ...@@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
if (!vlabuf) if (!vlabuf)
return -ENOMEM; return ERR_PTR(-ENOMEM);
os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); 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, ...@@ -1184,7 +1185,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
configfs_add_default_group(&d->group, os_desc_group); configfs_add_default_group(&d->group, os_desc_group);
} }
return 0; return os_desc_group;
} }
EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
void unregister_gadget_item(struct config_item *item); void unregister_gadget_item(struct config_item *item);
int usb_os_desc_prepare_interf_dir(struct config_group *parent, struct config_group *usb_os_desc_prepare_interf_dir(
struct config_group *parent,
int n_interf, int n_interf,
struct usb_os_desc **desc, struct usb_os_desc **desc,
char **names, char **names,
......
...@@ -908,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f) ...@@ -908,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f)
free_netdev(opts->net); free_netdev(opts->net);
} }
kfree(opts->rndis_interf_group); /* single VLA chunk */
kfree(opts); kfree(opts);
} }
...@@ -916,6 +917,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) ...@@ -916,6 +917,7 @@ static struct usb_function_instance *rndis_alloc_inst(void)
struct f_rndis_opts *opts; struct f_rndis_opts *opts;
struct usb_os_desc *descs[1]; struct usb_os_desc *descs[1];
char *names[1]; char *names[1];
struct config_group *rndis_interf_group;
opts = kzalloc(sizeof(*opts), GFP_KERNEL); opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts) if (!opts)
...@@ -940,8 +942,14 @@ static struct usb_function_instance *rndis_alloc_inst(void) ...@@ -940,8 +942,14 @@ static struct usb_function_instance *rndis_alloc_inst(void)
names[0] = "rndis"; names[0] = "rndis";
config_group_init_type_name(&opts->func_inst.group, "", config_group_init_type_name(&opts->func_inst.group, "",
&rndis_func_type); &rndis_func_type);
rndis_interf_group =
usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
names, THIS_MODULE); names, THIS_MODULE);
if (IS_ERR(rndis_interf_group)) {
rndis_free_inst(&opts->func_inst);
return ERR_CAST(rndis_interf_group);
}
opts->rndis_interf_group = rndis_interf_group;
return &opts->func_inst; return &opts->func_inst;
} }
......
...@@ -26,6 +26,7 @@ struct f_rndis_opts { ...@@ -26,6 +26,7 @@ struct f_rndis_opts {
bool bound; bool bound;
bool borrowed_net; bool borrowed_net;
struct config_group *rndis_interf_group;
struct usb_os_desc rndis_os_desc; struct usb_os_desc rndis_os_desc;
char rndis_ext_compat_id[16]; char rndis_ext_compat_id[16];
......
...@@ -419,6 +419,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) ...@@ -419,6 +419,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd)
static void set_link_state(struct dummy_hcd *dum_hcd) static void set_link_state(struct dummy_hcd *dum_hcd)
{ {
struct dummy *dum = dum_hcd->dum; struct dummy *dum = dum_hcd->dum;
unsigned int power_bit;
dum_hcd->active = 0; dum_hcd->active = 0;
if (dum->pullup) if (dum->pullup)
...@@ -429,17 +430,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd) ...@@ -429,17 +430,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd)
return; return;
set_link_state_by_speed(dum_hcd); set_link_state_by_speed(dum_hcd);
power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ?
USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER);
if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 ||
dum_hcd->active) dum_hcd->active)
dum_hcd->resuming = 0; dum_hcd->resuming = 0;
/* Currently !connected or in reset */ /* Currently !connected or in reset */
if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || if ((dum_hcd->port_status & power_bit) == 0 ||
(dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) {
unsigned disconnect = USB_PORT_STAT_CONNECTION & unsigned int disconnect = power_bit &
dum_hcd->old_status & (~dum_hcd->port_status); dum_hcd->old_status & (~dum_hcd->port_status);
unsigned reset = USB_PORT_STAT_RESET & unsigned int reset = USB_PORT_STAT_RESET &
(~dum_hcd->old_status) & dum_hcd->port_status; (~dum_hcd->old_status) & dum_hcd->port_status;
/* Report reset and disconnect events to the driver */ /* Report reset and disconnect events to the driver */
......
...@@ -202,12 +202,13 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf) ...@@ -202,12 +202,13 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
return tmp; return tmp;
} }
if (in) { if (in)
dev->in_pipe = usb_rcvbulkpipe(udev, dev->in_pipe = usb_rcvbulkpipe(udev,
in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
if (out)
dev->out_pipe = usb_sndbulkpipe(udev, dev->out_pipe = usb_sndbulkpipe(udev,
out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
}
if (iso_in) { if (iso_in) {
dev->iso_in = &iso_in->desc; dev->iso_in = &iso_in->desc;
dev->in_iso_pipe = usb_rcvisocpipe(udev, dev->in_iso_pipe = usb_rcvisocpipe(udev,
...@@ -1964,6 +1965,9 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param, ...@@ -1964,6 +1965,9 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param,
int status = 0; int status = 0;
struct urb *urbs[param->sglen]; struct urb *urbs[param->sglen];
if (!param->sglen || param->iterations > UINT_MAX / param->sglen)
return -EINVAL;
memset(&context, 0, sizeof(context)); memset(&context, 0, sizeof(context));
context.count = param->iterations * param->sglen; context.count = param->iterations * param->sglen;
context.dev = dev; context.dev = dev;
...@@ -2087,6 +2091,8 @@ usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param) ...@@ -2087,6 +2091,8 @@ usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param)
if (param->iterations <= 0) if (param->iterations <= 0)
return -EINVAL; return -EINVAL;
if (param->sglen > MAX_SGLEN)
return -EINVAL;
/* /*
* Just a bunch of test cases that every HCD is expected to handle. * Just a bunch of test cases that every HCD is expected to handle.
* *
......
...@@ -329,6 +329,14 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) ...@@ -329,6 +329,14 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
unsigned long val; unsigned long val;
void __iomem *base = phy->regs; void __iomem *base = phy->regs;
/*
* The USB driver may have already initiated the phy clock
* disable so wait to see if the clock turns off and if not
* then proceed with gating the clock.
*/
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) == 0)
return;
if (phy->is_legacy_phy) { if (phy->is_legacy_phy) {
val = readl(base + USB_SUSP_CTRL); val = readl(base + USB_SUSP_CTRL);
val |= USB_SUSP_SET; val |= USB_SUSP_SET;
...@@ -351,6 +359,15 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) ...@@ -351,6 +359,15 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
unsigned long val; unsigned long val;
void __iomem *base = phy->regs; void __iomem *base = phy->regs;
/*
* The USB driver may have already initiated the phy clock
* enable so wait to see if the clock turns on and if not
* then proceed with ungating the clock.
*/
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
USB_PHY_CLK_VALID) == 0)
return;
if (phy->is_legacy_phy) { if (phy->is_legacy_phy) {
val = readl(base + USB_SUSP_CTRL); val = readl(base + USB_SUSP_CTRL);
val |= USB_SUSP_CLR; val |= USB_SUSP_CLR;
......
...@@ -857,9 +857,9 @@ static void xfer_work(struct work_struct *work) ...@@ -857,9 +857,9 @@ static void xfer_work(struct work_struct *work)
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
usbhs_pipe_running(pipe, 1); usbhs_pipe_running(pipe, 1);
usbhsf_dma_start(pipe, fifo);
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
dma_async_issue_pending(chan); dma_async_issue_pending(chan);
usbhsf_dma_start(pipe, fifo);
usbhs_pipe_enable(pipe); usbhs_pipe_enable(pipe);
xfer_work_end: xfer_work_end:
......
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