diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-12 05:17:34 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-12 05:17:34 -0400 |
commit | 2d30408ecfd450c8377186615b330d329ded18ea (patch) | |
tree | c216f8e271bb812e5d6b1b8e63b87a54bb4b7875 | |
parent | 47a4b71c0b15be08a0f5e3011e71551a269bbe59 (diff) | |
parent | 7c80f9e4a588f1925b07134bb2e3689335f6c6d8 (diff) |
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.
-rw-r--r-- | drivers/usb/gadget/composite.c | 5 | ||||
-rw-r--r-- | drivers/usb/gadget/configfs.c | 15 | ||||
-rw-r--r-- | drivers/usb/gadget/configfs.h | 11 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_rndis.c | 12 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_rndis.h | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/dummy_hcd.c | 9 | ||||
-rw-r--r-- | drivers/usb/misc/usbtest.c | 10 | ||||
-rw-r--r-- | drivers/usb/phy/phy-tegra-usb.c | 17 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 2 |
9 files changed, 62 insertions, 20 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index dd74c99d6ce1..5d061b3d8224 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended); | |||
2026 | static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) | 2026 | static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) |
2027 | { | 2027 | { |
2028 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 2028 | 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; | ||
2029 | 2031 | ||
2030 | /* composite_disconnect() must already have been called | 2032 | /* composite_disconnect() must already have been called |
2031 | * by the underlying peripheral controller driver! | 2033 | * by the underlying peripheral controller driver! |
@@ -2045,6 +2047,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) | |||
2045 | 2047 | ||
2046 | composite_dev_cleanup(cdev); | 2048 | composite_dev_cleanup(cdev); |
2047 | 2049 | ||
2050 | if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) | ||
2051 | dev_str[USB_GADGET_MANUFACTURER_IDX].s = ""; | ||
2052 | |||
2048 | kfree(cdev->def_manufacturer); | 2053 | kfree(cdev->def_manufacturer); |
2049 | kfree(cdev); | 2054 | kfree(cdev); |
2050 | set_gadget_data(gadget, NULL); | 2055 | set_gadget_data(gadget, NULL); |
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index a22a892de7b7..aeb9f3c40521 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c | |||
@@ -1143,11 +1143,12 @@ static struct configfs_attribute *interf_grp_attrs[] = { | |||
1143 | NULL | 1143 | NULL |
1144 | }; | 1144 | }; |
1145 | 1145 | ||
1146 | int usb_os_desc_prepare_interf_dir(struct config_group *parent, | 1146 | struct config_group *usb_os_desc_prepare_interf_dir( |
1147 | int n_interf, | 1147 | struct config_group *parent, |
1148 | struct usb_os_desc **desc, | 1148 | int n_interf, |
1149 | char **names, | 1149 | struct usb_os_desc **desc, |
1150 | struct module *owner) | 1150 | char **names, |
1151 | struct module *owner) | ||
1151 | { | 1152 | { |
1152 | struct config_group *os_desc_group; | 1153 | struct config_group *os_desc_group; |
1153 | struct config_item_type *os_desc_type, *interface_type; | 1154 | struct config_item_type *os_desc_type, *interface_type; |
@@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, | |||
1159 | 1160 | ||
1160 | char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); | 1161 | char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); |
1161 | if (!vlabuf) | 1162 | if (!vlabuf) |
1162 | return -ENOMEM; | 1163 | return ERR_PTR(-ENOMEM); |
1163 | 1164 | ||
1164 | os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); | 1165 | os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); |
1165 | os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); | 1166 | 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 | configfs_add_default_group(&d->group, os_desc_group); | 1185 | configfs_add_default_group(&d->group, os_desc_group); |
1185 | } | 1186 | } |
1186 | 1187 | ||
1187 | return 0; | 1188 | return os_desc_group; |
1188 | } | 1189 | } |
1189 | EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); | 1190 | EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); |
1190 | 1191 | ||
diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h index 36c468c4f5e9..540d5e92ed22 100644 --- a/drivers/usb/gadget/configfs.h +++ b/drivers/usb/gadget/configfs.h | |||
@@ -5,11 +5,12 @@ | |||
5 | 5 | ||
6 | void unregister_gadget_item(struct config_item *item); | 6 | void unregister_gadget_item(struct config_item *item); |
7 | 7 | ||
8 | int usb_os_desc_prepare_interf_dir(struct config_group *parent, | 8 | struct config_group *usb_os_desc_prepare_interf_dir( |
9 | int n_interf, | 9 | struct config_group *parent, |
10 | struct usb_os_desc **desc, | 10 | int n_interf, |
11 | char **names, | 11 | struct usb_os_desc **desc, |
12 | struct module *owner); | 12 | char **names, |
13 | struct module *owner); | ||
13 | 14 | ||
14 | static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) | 15 | static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) |
15 | { | 16 | { |
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index e1d5853ef1e4..c7c5b3ce1d98 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c | |||
@@ -908,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f) | |||
908 | free_netdev(opts->net); | 908 | free_netdev(opts->net); |
909 | } | 909 | } |
910 | 910 | ||
911 | kfree(opts->rndis_interf_group); /* single VLA chunk */ | ||
911 | kfree(opts); | 912 | kfree(opts); |
912 | } | 913 | } |
913 | 914 | ||
@@ -916,6 +917,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) | |||
916 | struct f_rndis_opts *opts; | 917 | struct f_rndis_opts *opts; |
917 | struct usb_os_desc *descs[1]; | 918 | struct usb_os_desc *descs[1]; |
918 | char *names[1]; | 919 | char *names[1]; |
920 | struct config_group *rndis_interf_group; | ||
919 | 921 | ||
920 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); | 922 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); |
921 | if (!opts) | 923 | if (!opts) |
@@ -940,8 +942,14 @@ static struct usb_function_instance *rndis_alloc_inst(void) | |||
940 | names[0] = "rndis"; | 942 | names[0] = "rndis"; |
941 | config_group_init_type_name(&opts->func_inst.group, "", | 943 | config_group_init_type_name(&opts->func_inst.group, "", |
942 | &rndis_func_type); | 944 | &rndis_func_type); |
943 | usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, | 945 | rndis_interf_group = |
944 | names, THIS_MODULE); | 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; | ||
945 | 953 | ||
946 | return &opts->func_inst; | 954 | return &opts->func_inst; |
947 | } | 955 | } |
diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h index a35ee3c2545d..efdb7ac381d9 100644 --- a/drivers/usb/gadget/function/u_rndis.h +++ b/drivers/usb/gadget/function/u_rndis.h | |||
@@ -26,6 +26,7 @@ struct f_rndis_opts { | |||
26 | bool bound; | 26 | bool bound; |
27 | bool borrowed_net; | 27 | bool borrowed_net; |
28 | 28 | ||
29 | struct config_group *rndis_interf_group; | ||
29 | struct usb_os_desc rndis_os_desc; | 30 | struct usb_os_desc rndis_os_desc; |
30 | char rndis_ext_compat_id[16]; | 31 | char rndis_ext_compat_id[16]; |
31 | 32 | ||
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index b17618a55f1b..f04e91ef9e7c 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c | |||
@@ -419,6 +419,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) | |||
419 | static void set_link_state(struct dummy_hcd *dum_hcd) | 419 | static void set_link_state(struct dummy_hcd *dum_hcd) |
420 | { | 420 | { |
421 | struct dummy *dum = dum_hcd->dum; | 421 | struct dummy *dum = dum_hcd->dum; |
422 | unsigned int power_bit; | ||
422 | 423 | ||
423 | dum_hcd->active = 0; | 424 | dum_hcd->active = 0; |
424 | if (dum->pullup) | 425 | if (dum->pullup) |
@@ -429,17 +430,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd) | |||
429 | return; | 430 | return; |
430 | 431 | ||
431 | set_link_state_by_speed(dum_hcd); | 432 | 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); | ||
432 | 435 | ||
433 | if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || | 436 | if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || |
434 | dum_hcd->active) | 437 | dum_hcd->active) |
435 | dum_hcd->resuming = 0; | 438 | dum_hcd->resuming = 0; |
436 | 439 | ||
437 | /* Currently !connected or in reset */ | 440 | /* 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 || |
439 | (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { | 442 | (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { |
440 | unsigned disconnect = USB_PORT_STAT_CONNECTION & | 443 | unsigned int disconnect = power_bit & |
441 | dum_hcd->old_status & (~dum_hcd->port_status); | 444 | dum_hcd->old_status & (~dum_hcd->port_status); |
442 | unsigned reset = USB_PORT_STAT_RESET & | 445 | unsigned int reset = USB_PORT_STAT_RESET & |
443 | (~dum_hcd->old_status) & dum_hcd->port_status; | 446 | (~dum_hcd->old_status) & dum_hcd->port_status; |
444 | 447 | ||
445 | /* Report reset and disconnect events to the driver */ | 448 | /* Report reset and disconnect events to the driver */ |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index eee82ca55b7b..b3fc602b2e24 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -202,12 +202,13 @@ found: | |||
202 | return tmp; | 202 | return tmp; |
203 | } | 203 | } |
204 | 204 | ||
205 | if (in) { | 205 | if (in) |
206 | dev->in_pipe = usb_rcvbulkpipe(udev, | 206 | dev->in_pipe = usb_rcvbulkpipe(udev, |
207 | in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 207 | in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); |
208 | if (out) | ||
208 | dev->out_pipe = usb_sndbulkpipe(udev, | 209 | dev->out_pipe = usb_sndbulkpipe(udev, |
209 | out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 210 | out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); |
210 | } | 211 | |
211 | if (iso_in) { | 212 | if (iso_in) { |
212 | dev->iso_in = &iso_in->desc; | 213 | dev->iso_in = &iso_in->desc; |
213 | dev->in_iso_pipe = usb_rcvisocpipe(udev, | 214 | dev->in_iso_pipe = usb_rcvisocpipe(udev, |
@@ -1964,6 +1965,9 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param, | |||
1964 | int status = 0; | 1965 | int status = 0; |
1965 | struct urb *urbs[param->sglen]; | 1966 | struct urb *urbs[param->sglen]; |
1966 | 1967 | ||
1968 | if (!param->sglen || param->iterations > UINT_MAX / param->sglen) | ||
1969 | return -EINVAL; | ||
1970 | |||
1967 | memset(&context, 0, sizeof(context)); | 1971 | memset(&context, 0, sizeof(context)); |
1968 | context.count = param->iterations * param->sglen; | 1972 | context.count = param->iterations * param->sglen; |
1969 | context.dev = dev; | 1973 | context.dev = dev; |
@@ -2087,6 +2091,8 @@ usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param) | |||
2087 | 2091 | ||
2088 | if (param->iterations <= 0) | 2092 | if (param->iterations <= 0) |
2089 | return -EINVAL; | 2093 | return -EINVAL; |
2094 | if (param->sglen > MAX_SGLEN) | ||
2095 | return -EINVAL; | ||
2090 | /* | 2096 | /* |
2091 | * Just a bunch of test cases that every HCD is expected to handle. | 2097 | * Just a bunch of test cases that every HCD is expected to handle. |
2092 | * | 2098 | * |
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 5fe4a5704bde..ccc2bf5274b4 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c | |||
@@ -329,6 +329,14 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) | |||
329 | unsigned long val; | 329 | unsigned long val; |
330 | void __iomem *base = phy->regs; | 330 | void __iomem *base = phy->regs; |
331 | 331 | ||
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 | |||
332 | if (phy->is_legacy_phy) { | 340 | if (phy->is_legacy_phy) { |
333 | val = readl(base + USB_SUSP_CTRL); | 341 | val = readl(base + USB_SUSP_CTRL); |
334 | val |= USB_SUSP_SET; | 342 | val |= USB_SUSP_SET; |
@@ -351,6 +359,15 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) | |||
351 | unsigned long val; | 359 | unsigned long val; |
352 | void __iomem *base = phy->regs; | 360 | void __iomem *base = phy->regs; |
353 | 361 | ||
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 | |||
354 | if (phy->is_legacy_phy) { | 371 | if (phy->is_legacy_phy) { |
355 | val = readl(base + USB_SUSP_CTRL); | 372 | val = readl(base + USB_SUSP_CTRL); |
356 | val |= USB_SUSP_CLR; | 373 | val |= USB_SUSP_CLR; |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 68f26904c316..50285b01da92 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -857,9 +857,9 @@ static void xfer_work(struct work_struct *work) | |||
857 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); | 857 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); |
858 | 858 | ||
859 | usbhs_pipe_running(pipe, 1); | 859 | usbhs_pipe_running(pipe, 1); |
860 | usbhsf_dma_start(pipe, fifo); | ||
861 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); | 860 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); |
862 | dma_async_issue_pending(chan); | 861 | dma_async_issue_pending(chan); |
862 | usbhsf_dma_start(pipe, fifo); | ||
863 | usbhs_pipe_enable(pipe); | 863 | usbhs_pipe_enable(pipe); |
864 | 864 | ||
865 | xfer_work_end: | 865 | xfer_work_end: |