diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-03 08:07:14 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-03 08:07:14 -0500 |
commit | 8d6bbff67796262b5296b745989e4c9d9f2b4894 (patch) | |
tree | 49624174880accd352f8468aab81bac390d2971d | |
parent | 0c744ea4f77d72b3dcebb7a8f2684633ec79be88 (diff) | |
parent | 43aef5c2ca90535b3227e97e71604291875444ed (diff) |
Merge tag 'fixes-for-v4.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus
Felipe writes:
usb: fixes for v4.10-rc3
The first set of fixes for v4.10-rc cycle. The most
important of which is a big regression on dwc3-pci
which prevents it from probing altogether.
There's also a fix to avoid Overflow events on DWC3
and another to make sure we don't starve DMA
resources.
Dummy HCD got some love after a long hiatus and DWC2
got a couple fixes related to DMA usage. Other than
these, we have a set of minor fixes here and there.
-rw-r--r-- | drivers/usb/dwc2/gadget.c | 2 | ||||
-rw-r--r-- | drivers/usb/dwc2/params.c | 30 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.h | 10 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-omap.c | 6 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-pci.c | 17 | ||||
-rw-r--r-- | drivers/usb/dwc3/ep0.c | 46 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 24 | ||||
-rw-r--r-- | drivers/usb/gadget/composite.c | 12 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 14 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_hid.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/inode.c | 18 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/core.c | 6 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/dummy_hcd.c | 6 | ||||
-rw-r--r-- | include/uapi/linux/usb/functionfs.h | 1 |
14 files changed, 103 insertions, 91 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index b95930f20d90..c55db4aa54d6 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -3753,7 +3753,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, | |||
3753 | hs_ep->desc_list = dma_alloc_coherent(hsotg->dev, | 3753 | hs_ep->desc_list = dma_alloc_coherent(hsotg->dev, |
3754 | MAX_DMA_DESC_NUM_GENERIC * | 3754 | MAX_DMA_DESC_NUM_GENERIC * |
3755 | sizeof(struct dwc2_dma_desc), | 3755 | sizeof(struct dwc2_dma_desc), |
3756 | &hs_ep->desc_list_dma, GFP_KERNEL); | 3756 | &hs_ep->desc_list_dma, GFP_ATOMIC); |
3757 | if (!hs_ep->desc_list) { | 3757 | if (!hs_ep->desc_list) { |
3758 | ret = -ENOMEM; | 3758 | ret = -ENOMEM; |
3759 | goto error2; | 3759 | goto error2; |
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index a786256535b6..11fe68a4627b 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c | |||
@@ -247,8 +247,6 @@ MODULE_DEVICE_TABLE(of, dwc2_of_match_table); | |||
247 | static void dwc2_get_device_property(struct dwc2_hsotg *hsotg, | 247 | static void dwc2_get_device_property(struct dwc2_hsotg *hsotg, |
248 | char *property, u8 size, u64 *value) | 248 | char *property, u8 size, u64 *value) |
249 | { | 249 | { |
250 | u8 val8; | ||
251 | u16 val16; | ||
252 | u32 val32; | 250 | u32 val32; |
253 | 251 | ||
254 | switch (size) { | 252 | switch (size) { |
@@ -256,17 +254,7 @@ static void dwc2_get_device_property(struct dwc2_hsotg *hsotg, | |||
256 | *value = device_property_read_bool(hsotg->dev, property); | 254 | *value = device_property_read_bool(hsotg->dev, property); |
257 | break; | 255 | break; |
258 | case 1: | 256 | case 1: |
259 | if (device_property_read_u8(hsotg->dev, property, &val8)) | ||
260 | return; | ||
261 | |||
262 | *value = val8; | ||
263 | break; | ||
264 | case 2: | 257 | case 2: |
265 | if (device_property_read_u16(hsotg->dev, property, &val16)) | ||
266 | return; | ||
267 | |||
268 | *value = val16; | ||
269 | break; | ||
270 | case 4: | 258 | case 4: |
271 | if (device_property_read_u32(hsotg->dev, property, &val32)) | 259 | if (device_property_read_u32(hsotg->dev, property, &val32)) |
272 | return; | 260 | return; |
@@ -1100,13 +1088,13 @@ static void dwc2_set_gadget_dma(struct dwc2_hsotg *hsotg) | |||
1100 | /* Buffer DMA */ | 1088 | /* Buffer DMA */ |
1101 | dwc2_set_param_bool(hsotg, &p->g_dma, | 1089 | dwc2_set_param_bool(hsotg, &p->g_dma, |
1102 | false, "gadget-dma", | 1090 | false, "gadget-dma", |
1103 | true, false, | 1091 | dma_capable, false, |
1104 | dma_capable); | 1092 | dma_capable); |
1105 | 1093 | ||
1106 | /* DMA Descriptor */ | 1094 | /* DMA Descriptor */ |
1107 | dwc2_set_param_bool(hsotg, &p->g_dma_desc, false, | 1095 | dwc2_set_param_bool(hsotg, &p->g_dma_desc, false, |
1108 | "gadget-dma-desc", | 1096 | "gadget-dma-desc", |
1109 | p->g_dma, false, | 1097 | !!hw->dma_desc_enable, false, |
1110 | !!hw->dma_desc_enable); | 1098 | !!hw->dma_desc_enable); |
1111 | } | 1099 | } |
1112 | 1100 | ||
@@ -1130,8 +1118,14 @@ static void dwc2_set_parameters(struct dwc2_hsotg *hsotg, | |||
1130 | 1118 | ||
1131 | dwc2_set_param_bool(hsotg, &p->host_dma, | 1119 | dwc2_set_param_bool(hsotg, &p->host_dma, |
1132 | false, "host-dma", | 1120 | false, "host-dma", |
1133 | true, false, | 1121 | dma_capable, false, |
1134 | dma_capable); | 1122 | dma_capable); |
1123 | dwc2_set_param_host_rx_fifo_size(hsotg, | ||
1124 | params->host_rx_fifo_size); | ||
1125 | dwc2_set_param_host_nperio_tx_fifo_size(hsotg, | ||
1126 | params->host_nperio_tx_fifo_size); | ||
1127 | dwc2_set_param_host_perio_tx_fifo_size(hsotg, | ||
1128 | params->host_perio_tx_fifo_size); | ||
1135 | } | 1129 | } |
1136 | dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable); | 1130 | dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable); |
1137 | dwc2_set_param_dma_desc_fs_enable(hsotg, params->dma_desc_fs_enable); | 1131 | dwc2_set_param_dma_desc_fs_enable(hsotg, params->dma_desc_fs_enable); |
@@ -1140,12 +1134,6 @@ static void dwc2_set_parameters(struct dwc2_hsotg *hsotg, | |||
1140 | params->host_support_fs_ls_low_power); | 1134 | params->host_support_fs_ls_low_power); |
1141 | dwc2_set_param_enable_dynamic_fifo(hsotg, | 1135 | dwc2_set_param_enable_dynamic_fifo(hsotg, |
1142 | params->enable_dynamic_fifo); | 1136 | params->enable_dynamic_fifo); |
1143 | dwc2_set_param_host_rx_fifo_size(hsotg, | ||
1144 | params->host_rx_fifo_size); | ||
1145 | dwc2_set_param_host_nperio_tx_fifo_size(hsotg, | ||
1146 | params->host_nperio_tx_fifo_size); | ||
1147 | dwc2_set_param_host_perio_tx_fifo_size(hsotg, | ||
1148 | params->host_perio_tx_fifo_size); | ||
1149 | dwc2_set_param_max_transfer_size(hsotg, | 1137 | dwc2_set_param_max_transfer_size(hsotg, |
1150 | params->max_transfer_size); | 1138 | params->max_transfer_size); |
1151 | dwc2_set_param_max_packet_count(hsotg, | 1139 | dwc2_set_param_max_packet_count(hsotg, |
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index de5a8570be04..14b760209680 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -45,9 +45,7 @@ | |||
45 | #define DWC3_XHCI_RESOURCES_NUM 2 | 45 | #define DWC3_XHCI_RESOURCES_NUM 2 |
46 | 46 | ||
47 | #define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */ | 47 | #define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */ |
48 | #define DWC3_EVENT_SIZE 4 /* bytes */ | 48 | #define DWC3_EVENT_BUFFERS_SIZE 4096 |
49 | #define DWC3_EVENT_MAX_NUM 64 /* 2 events/endpoint */ | ||
50 | #define DWC3_EVENT_BUFFERS_SIZE (DWC3_EVENT_SIZE * DWC3_EVENT_MAX_NUM) | ||
51 | #define DWC3_EVENT_TYPE_MASK 0xfe | 49 | #define DWC3_EVENT_TYPE_MASK 0xfe |
52 | 50 | ||
53 | #define DWC3_EVENT_TYPE_DEV 0 | 51 | #define DWC3_EVENT_TYPE_DEV 0 |
@@ -311,9 +309,8 @@ | |||
311 | #define DWC3_DCFG_SUPERSPEED_PLUS (5 << 0) /* DWC_usb31 only */ | 309 | #define DWC3_DCFG_SUPERSPEED_PLUS (5 << 0) /* DWC_usb31 only */ |
312 | #define DWC3_DCFG_SUPERSPEED (4 << 0) | 310 | #define DWC3_DCFG_SUPERSPEED (4 << 0) |
313 | #define DWC3_DCFG_HIGHSPEED (0 << 0) | 311 | #define DWC3_DCFG_HIGHSPEED (0 << 0) |
314 | #define DWC3_DCFG_FULLSPEED2 (1 << 0) | 312 | #define DWC3_DCFG_FULLSPEED (1 << 0) |
315 | #define DWC3_DCFG_LOWSPEED (2 << 0) | 313 | #define DWC3_DCFG_LOWSPEED (2 << 0) |
316 | #define DWC3_DCFG_FULLSPEED1 (3 << 0) | ||
317 | 314 | ||
318 | #define DWC3_DCFG_NUMP_SHIFT 17 | 315 | #define DWC3_DCFG_NUMP_SHIFT 17 |
319 | #define DWC3_DCFG_NUMP(n) (((n) >> DWC3_DCFG_NUMP_SHIFT) & 0x1f) | 316 | #define DWC3_DCFG_NUMP(n) (((n) >> DWC3_DCFG_NUMP_SHIFT) & 0x1f) |
@@ -405,9 +402,8 @@ | |||
405 | #define DWC3_DSTS_SUPERSPEED_PLUS (5 << 0) /* DWC_usb31 only */ | 402 | #define DWC3_DSTS_SUPERSPEED_PLUS (5 << 0) /* DWC_usb31 only */ |
406 | #define DWC3_DSTS_SUPERSPEED (4 << 0) | 403 | #define DWC3_DSTS_SUPERSPEED (4 << 0) |
407 | #define DWC3_DSTS_HIGHSPEED (0 << 0) | 404 | #define DWC3_DSTS_HIGHSPEED (0 << 0) |
408 | #define DWC3_DSTS_FULLSPEED2 (1 << 0) | 405 | #define DWC3_DSTS_FULLSPEED (1 << 0) |
409 | #define DWC3_DSTS_LOWSPEED (2 << 0) | 406 | #define DWC3_DSTS_LOWSPEED (2 << 0) |
410 | #define DWC3_DSTS_FULLSPEED1 (3 << 0) | ||
411 | 407 | ||
412 | /* Device Generic Command Register */ | 408 | /* Device Generic Command Register */ |
413 | #define DWC3_DGCMD_SET_LMP 0x01 | 409 | #define DWC3_DGCMD_SET_LMP 0x01 |
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 29e80cc9b634..eb1b9cb3f9d1 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/irq.h> | ||
22 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
24 | #include <linux/platform_data/dwc3-omap.h> | 25 | #include <linux/platform_data/dwc3-omap.h> |
@@ -510,7 +511,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
510 | 511 | ||
511 | /* check the DMA Status */ | 512 | /* check the DMA Status */ |
512 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); | 513 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); |
513 | 514 | irq_set_status_flags(omap->irq, IRQ_NOAUTOEN); | |
514 | ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt, | 515 | ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt, |
515 | dwc3_omap_interrupt_thread, IRQF_SHARED, | 516 | dwc3_omap_interrupt_thread, IRQF_SHARED, |
516 | "dwc3-omap", omap); | 517 | "dwc3-omap", omap); |
@@ -531,7 +532,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
531 | } | 532 | } |
532 | 533 | ||
533 | dwc3_omap_enable_irqs(omap); | 534 | dwc3_omap_enable_irqs(omap); |
534 | 535 | enable_irq(omap->irq); | |
535 | return 0; | 536 | return 0; |
536 | 537 | ||
537 | err2: | 538 | err2: |
@@ -552,6 +553,7 @@ static int dwc3_omap_remove(struct platform_device *pdev) | |||
552 | extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb); | 553 | extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb); |
553 | extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb); | 554 | extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb); |
554 | dwc3_omap_disable_irqs(omap); | 555 | dwc3_omap_disable_irqs(omap); |
556 | disable_irq(omap->irq); | ||
555 | of_platform_depopulate(omap->dev); | 557 | of_platform_depopulate(omap->dev); |
556 | pm_runtime_put_sync(&pdev->dev); | 558 | pm_runtime_put_sync(&pdev->dev); |
557 | pm_runtime_disable(&pdev->dev); | 559 | pm_runtime_disable(&pdev->dev); |
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 2b73339f286b..cce0a220b6b0 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa | 38 | #define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa |
39 | #define PCI_DEVICE_ID_INTEL_APL 0x5aaa | 39 | #define PCI_DEVICE_ID_INTEL_APL 0x5aaa |
40 | #define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 | 40 | #define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 |
41 | #define PCI_DEVICE_ID_INTEL_GLK 0x31aa | ||
41 | 42 | ||
42 | #define PCI_INTEL_BXT_DSM_UUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511" | 43 | #define PCI_INTEL_BXT_DSM_UUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511" |
43 | #define PCI_INTEL_BXT_FUNC_PMU_PWR 4 | 44 | #define PCI_INTEL_BXT_FUNC_PMU_PWR 4 |
@@ -73,16 +74,6 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) | |||
73 | { | 74 | { |
74 | struct platform_device *dwc3 = dwc->dwc3; | 75 | struct platform_device *dwc3 = dwc->dwc3; |
75 | struct pci_dev *pdev = dwc->pci; | 76 | struct pci_dev *pdev = dwc->pci; |
76 | int ret; | ||
77 | |||
78 | struct property_entry sysdev_property[] = { | ||
79 | PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), | ||
80 | { }, | ||
81 | }; | ||
82 | |||
83 | ret = platform_device_add_properties(dwc3, sysdev_property); | ||
84 | if (ret) | ||
85 | return ret; | ||
86 | 77 | ||
87 | if (pdev->vendor == PCI_VENDOR_ID_AMD && | 78 | if (pdev->vendor == PCI_VENDOR_ID_AMD && |
88 | pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { | 79 | pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { |
@@ -105,6 +96,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) | |||
105 | PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"), | 96 | PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"), |
106 | PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), | 97 | PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), |
107 | PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), | 98 | PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), |
99 | PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), | ||
108 | { }, | 100 | { }, |
109 | }; | 101 | }; |
110 | 102 | ||
@@ -115,7 +107,8 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) | |||
115 | int ret; | 107 | int ret; |
116 | 108 | ||
117 | struct property_entry properties[] = { | 109 | struct property_entry properties[] = { |
118 | PROPERTY_ENTRY_STRING("dr-mode", "peripheral"), | 110 | PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), |
111 | PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), | ||
119 | { } | 112 | { } |
120 | }; | 113 | }; |
121 | 114 | ||
@@ -167,6 +160,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) | |||
167 | PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"), | 160 | PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"), |
168 | PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), | 161 | PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), |
169 | PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"), | 162 | PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"), |
163 | PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), | ||
170 | { }, | 164 | { }, |
171 | }; | 165 | }; |
172 | 166 | ||
@@ -274,6 +268,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { | |||
274 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), }, | 268 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), }, |
275 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), }, | 269 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), }, |
276 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), }, | 270 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), }, |
271 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK), }, | ||
277 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, | 272 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, |
278 | { } /* Terminating Entry */ | 273 | { } /* Terminating Entry */ |
279 | }; | 274 | }; |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 4878d187c7d4..9bb1f8526f3e 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -39,18 +39,13 @@ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep); | |||
39 | static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, | 39 | static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, |
40 | struct dwc3_ep *dep, struct dwc3_request *req); | 40 | struct dwc3_ep *dep, struct dwc3_request *req); |
41 | 41 | ||
42 | static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | 42 | static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum, |
43 | u32 len, u32 type, bool chain) | 43 | dma_addr_t buf_dma, u32 len, u32 type, bool chain) |
44 | { | 44 | { |
45 | struct dwc3_gadget_ep_cmd_params params; | ||
46 | struct dwc3_trb *trb; | 45 | struct dwc3_trb *trb; |
47 | struct dwc3_ep *dep; | 46 | struct dwc3_ep *dep; |
48 | 47 | ||
49 | int ret; | ||
50 | |||
51 | dep = dwc->eps[epnum]; | 48 | dep = dwc->eps[epnum]; |
52 | if (dep->flags & DWC3_EP_BUSY) | ||
53 | return 0; | ||
54 | 49 | ||
55 | trb = &dwc->ep0_trb[dep->trb_enqueue]; | 50 | trb = &dwc->ep0_trb[dep->trb_enqueue]; |
56 | 51 | ||
@@ -71,15 +66,23 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | |||
71 | trb->ctrl |= (DWC3_TRB_CTRL_IOC | 66 | trb->ctrl |= (DWC3_TRB_CTRL_IOC |
72 | | DWC3_TRB_CTRL_LST); | 67 | | DWC3_TRB_CTRL_LST); |
73 | 68 | ||
74 | if (chain) | 69 | trace_dwc3_prepare_trb(dep, trb); |
70 | } | ||
71 | |||
72 | static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum) | ||
73 | { | ||
74 | struct dwc3_gadget_ep_cmd_params params; | ||
75 | struct dwc3_ep *dep; | ||
76 | int ret; | ||
77 | |||
78 | dep = dwc->eps[epnum]; | ||
79 | if (dep->flags & DWC3_EP_BUSY) | ||
75 | return 0; | 80 | return 0; |
76 | 81 | ||
77 | memset(¶ms, 0, sizeof(params)); | 82 | memset(¶ms, 0, sizeof(params)); |
78 | params.param0 = upper_32_bits(dwc->ep0_trb_addr); | 83 | params.param0 = upper_32_bits(dwc->ep0_trb_addr); |
79 | params.param1 = lower_32_bits(dwc->ep0_trb_addr); | 84 | params.param1 = lower_32_bits(dwc->ep0_trb_addr); |
80 | 85 | ||
81 | trace_dwc3_prepare_trb(dep, trb); | ||
82 | |||
83 | ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms); | 86 | ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms); |
84 | if (ret < 0) | 87 | if (ret < 0) |
85 | return ret; | 88 | return ret; |
@@ -280,8 +283,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) | |||
280 | 283 | ||
281 | complete(&dwc->ep0_in_setup); | 284 | complete(&dwc->ep0_in_setup); |
282 | 285 | ||
283 | ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8, | 286 | dwc3_ep0_prepare_one_trb(dwc, 0, dwc->ctrl_req_addr, 8, |
284 | DWC3_TRBCTL_CONTROL_SETUP, false); | 287 | DWC3_TRBCTL_CONTROL_SETUP, false); |
288 | ret = dwc3_ep0_start_trans(dwc, 0); | ||
285 | WARN_ON(ret < 0); | 289 | WARN_ON(ret < 0); |
286 | } | 290 | } |
287 | 291 | ||
@@ -912,9 +916,9 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
912 | 916 | ||
913 | dwc->ep0_next_event = DWC3_EP0_COMPLETE; | 917 | dwc->ep0_next_event = DWC3_EP0_COMPLETE; |
914 | 918 | ||
915 | ret = dwc3_ep0_start_trans(dwc, epnum, | 919 | dwc3_ep0_prepare_one_trb(dwc, epnum, dwc->ctrl_req_addr, |
916 | dwc->ctrl_req_addr, 0, | 920 | 0, DWC3_TRBCTL_CONTROL_DATA, false); |
917 | DWC3_TRBCTL_CONTROL_DATA, false); | 921 | ret = dwc3_ep0_start_trans(dwc, epnum); |
918 | WARN_ON(ret < 0); | 922 | WARN_ON(ret < 0); |
919 | } | 923 | } |
920 | } | 924 | } |
@@ -993,9 +997,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, | |||
993 | req->direction = !!dep->number; | 997 | req->direction = !!dep->number; |
994 | 998 | ||
995 | if (req->request.length == 0) { | 999 | if (req->request.length == 0) { |
996 | ret = dwc3_ep0_start_trans(dwc, dep->number, | 1000 | dwc3_ep0_prepare_one_trb(dwc, dep->number, |
997 | dwc->ctrl_req_addr, 0, | 1001 | dwc->ctrl_req_addr, 0, |
998 | DWC3_TRBCTL_CONTROL_DATA, false); | 1002 | DWC3_TRBCTL_CONTROL_DATA, false); |
1003 | ret = dwc3_ep0_start_trans(dwc, dep->number); | ||
999 | } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) | 1004 | } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) |
1000 | && (dep->number == 0)) { | 1005 | && (dep->number == 0)) { |
1001 | u32 transfer_size = 0; | 1006 | u32 transfer_size = 0; |
@@ -1011,7 +1016,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, | |||
1011 | if (req->request.length > DWC3_EP0_BOUNCE_SIZE) { | 1016 | if (req->request.length > DWC3_EP0_BOUNCE_SIZE) { |
1012 | transfer_size = ALIGN(req->request.length - maxpacket, | 1017 | transfer_size = ALIGN(req->request.length - maxpacket, |
1013 | maxpacket); | 1018 | maxpacket); |
1014 | ret = dwc3_ep0_start_trans(dwc, dep->number, | 1019 | dwc3_ep0_prepare_one_trb(dwc, dep->number, |
1015 | req->request.dma, | 1020 | req->request.dma, |
1016 | transfer_size, | 1021 | transfer_size, |
1017 | DWC3_TRBCTL_CONTROL_DATA, | 1022 | DWC3_TRBCTL_CONTROL_DATA, |
@@ -1023,18 +1028,20 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, | |||
1023 | 1028 | ||
1024 | dwc->ep0_bounced = true; | 1029 | dwc->ep0_bounced = true; |
1025 | 1030 | ||
1026 | ret = dwc3_ep0_start_trans(dwc, dep->number, | 1031 | dwc3_ep0_prepare_one_trb(dwc, dep->number, |
1027 | dwc->ep0_bounce_addr, transfer_size, | 1032 | dwc->ep0_bounce_addr, transfer_size, |
1028 | DWC3_TRBCTL_CONTROL_DATA, false); | 1033 | DWC3_TRBCTL_CONTROL_DATA, false); |
1034 | ret = dwc3_ep0_start_trans(dwc, dep->number); | ||
1029 | } else { | 1035 | } else { |
1030 | ret = usb_gadget_map_request_by_dev(dwc->sysdev, | 1036 | ret = usb_gadget_map_request_by_dev(dwc->sysdev, |
1031 | &req->request, dep->number); | 1037 | &req->request, dep->number); |
1032 | if (ret) | 1038 | if (ret) |
1033 | return; | 1039 | return; |
1034 | 1040 | ||
1035 | ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma, | 1041 | dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma, |
1036 | req->request.length, DWC3_TRBCTL_CONTROL_DATA, | 1042 | req->request.length, DWC3_TRBCTL_CONTROL_DATA, |
1037 | false); | 1043 | false); |
1044 | ret = dwc3_ep0_start_trans(dwc, dep->number); | ||
1038 | } | 1045 | } |
1039 | 1046 | ||
1040 | WARN_ON(ret < 0); | 1047 | WARN_ON(ret < 0); |
@@ -1048,8 +1055,9 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) | |||
1048 | type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 | 1055 | type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 |
1049 | : DWC3_TRBCTL_CONTROL_STATUS2; | 1056 | : DWC3_TRBCTL_CONTROL_STATUS2; |
1050 | 1057 | ||
1051 | return dwc3_ep0_start_trans(dwc, dep->number, | 1058 | dwc3_ep0_prepare_one_trb(dwc, dep->number, |
1052 | dwc->ctrl_req_addr, 0, type, false); | 1059 | dwc->ctrl_req_addr, 0, type, false); |
1060 | return dwc3_ep0_start_trans(dwc, dep->number); | ||
1053 | } | 1061 | } |
1054 | 1062 | ||
1055 | static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) | 1063 | static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index efddaf5d11d1..204c754cc647 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -180,11 +180,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
180 | if (req->request.status == -EINPROGRESS) | 180 | if (req->request.status == -EINPROGRESS) |
181 | req->request.status = status; | 181 | req->request.status = status; |
182 | 182 | ||
183 | if (dwc->ep0_bounced && dep->number == 0) | 183 | if (dwc->ep0_bounced && dep->number <= 1) |
184 | dwc->ep0_bounced = false; | 184 | dwc->ep0_bounced = false; |
185 | else | 185 | |
186 | usb_gadget_unmap_request_by_dev(dwc->sysdev, | 186 | usb_gadget_unmap_request_by_dev(dwc->sysdev, |
187 | &req->request, req->direction); | 187 | &req->request, req->direction); |
188 | 188 | ||
189 | trace_dwc3_gadget_giveback(req); | 189 | trace_dwc3_gadget_giveback(req); |
190 | 190 | ||
@@ -1720,7 +1720,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) | |||
1720 | reg |= DWC3_DCFG_LOWSPEED; | 1720 | reg |= DWC3_DCFG_LOWSPEED; |
1721 | break; | 1721 | break; |
1722 | case USB_SPEED_FULL: | 1722 | case USB_SPEED_FULL: |
1723 | reg |= DWC3_DCFG_FULLSPEED1; | 1723 | reg |= DWC3_DCFG_FULLSPEED; |
1724 | break; | 1724 | break; |
1725 | case USB_SPEED_HIGH: | 1725 | case USB_SPEED_HIGH: |
1726 | reg |= DWC3_DCFG_HIGHSPEED; | 1726 | reg |= DWC3_DCFG_HIGHSPEED; |
@@ -2232,9 +2232,14 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
2232 | 2232 | ||
2233 | dep = dwc->eps[epnum]; | 2233 | dep = dwc->eps[epnum]; |
2234 | 2234 | ||
2235 | if (!(dep->flags & DWC3_EP_ENABLED) && | 2235 | if (!(dep->flags & DWC3_EP_ENABLED)) { |
2236 | !(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) | 2236 | if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) |
2237 | return; | 2237 | return; |
2238 | |||
2239 | /* Handle only EPCMDCMPLT when EP disabled */ | ||
2240 | if (event->endpoint_event != DWC3_DEPEVT_EPCMDCMPLT) | ||
2241 | return; | ||
2242 | } | ||
2238 | 2243 | ||
2239 | if (epnum == 0 || epnum == 1) { | 2244 | if (epnum == 0 || epnum == 1) { |
2240 | dwc3_ep0_interrupt(dwc, event); | 2245 | dwc3_ep0_interrupt(dwc, event); |
@@ -2531,8 +2536,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) | |||
2531 | dwc->gadget.ep0->maxpacket = 64; | 2536 | dwc->gadget.ep0->maxpacket = 64; |
2532 | dwc->gadget.speed = USB_SPEED_HIGH; | 2537 | dwc->gadget.speed = USB_SPEED_HIGH; |
2533 | break; | 2538 | break; |
2534 | case DWC3_DSTS_FULLSPEED2: | 2539 | case DWC3_DSTS_FULLSPEED: |
2535 | case DWC3_DSTS_FULLSPEED1: | ||
2536 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); | 2540 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); |
2537 | dwc->gadget.ep0->maxpacket = 64; | 2541 | dwc->gadget.ep0->maxpacket = 64; |
2538 | dwc->gadget.speed = USB_SPEED_FULL; | 2542 | dwc->gadget.speed = USB_SPEED_FULL; |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 41ab61f9b6e0..002822d98fda 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1694,9 +1694,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1694 | value = min(w_length, (u16) 1); | 1694 | value = min(w_length, (u16) 1); |
1695 | break; | 1695 | break; |
1696 | 1696 | ||
1697 | /* function drivers must handle get/set altsetting; if there's | 1697 | /* function drivers must handle get/set altsetting */ |
1698 | * no get() method, we know only altsetting zero works. | ||
1699 | */ | ||
1700 | case USB_REQ_SET_INTERFACE: | 1698 | case USB_REQ_SET_INTERFACE: |
1701 | if (ctrl->bRequestType != USB_RECIP_INTERFACE) | 1699 | if (ctrl->bRequestType != USB_RECIP_INTERFACE) |
1702 | goto unknown; | 1700 | goto unknown; |
@@ -1705,7 +1703,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1705 | f = cdev->config->interface[intf]; | 1703 | f = cdev->config->interface[intf]; |
1706 | if (!f) | 1704 | if (!f) |
1707 | break; | 1705 | break; |
1708 | if (w_value && !f->set_alt) | 1706 | |
1707 | /* | ||
1708 | * If there's no get_alt() method, we know only altsetting zero | ||
1709 | * works. There is no need to check if set_alt() is not NULL | ||
1710 | * as we check this in usb_add_function(). | ||
1711 | */ | ||
1712 | if (w_value && !f->get_alt) | ||
1709 | break; | 1713 | break; |
1710 | value = f->set_alt(f, w_index, w_value); | 1714 | value = f->set_alt(f, w_index, w_value); |
1711 | if (value == USB_GADGET_DELAYED_STATUS) { | 1715 | if (value == USB_GADGET_DELAYED_STATUS) { |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index aab3fc1dbb94..5e746adc8a2d 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -2091,8 +2091,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, | |||
2091 | 2091 | ||
2092 | case FFS_STRING: | 2092 | case FFS_STRING: |
2093 | /* | 2093 | /* |
2094 | * Strings are indexed from 1 (0 is magic ;) reserved | 2094 | * Strings are indexed from 1 (0 is reserved |
2095 | * for languages list or some such) | 2095 | * for languages list) |
2096 | */ | 2096 | */ |
2097 | if (*valuep > helper->ffs->strings_count) | 2097 | if (*valuep > helper->ffs->strings_count) |
2098 | helper->ffs->strings_count = *valuep; | 2098 | helper->ffs->strings_count = *valuep; |
@@ -2252,7 +2252,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, | |||
2252 | 2252 | ||
2253 | if (len < sizeof(*d) || | 2253 | if (len < sizeof(*d) || |
2254 | d->bFirstInterfaceNumber >= ffs->interfaces_count || | 2254 | d->bFirstInterfaceNumber >= ffs->interfaces_count || |
2255 | !d->Reserved1) | 2255 | d->Reserved1) |
2256 | return -EINVAL; | 2256 | return -EINVAL; |
2257 | for (i = 0; i < ARRAY_SIZE(d->Reserved2); ++i) | 2257 | for (i = 0; i < ARRAY_SIZE(d->Reserved2); ++i) |
2258 | if (d->Reserved2[i]) | 2258 | if (d->Reserved2[i]) |
@@ -3666,6 +3666,7 @@ static void ffs_closed(struct ffs_data *ffs) | |||
3666 | { | 3666 | { |
3667 | struct ffs_dev *ffs_obj; | 3667 | struct ffs_dev *ffs_obj; |
3668 | struct f_fs_opts *opts; | 3668 | struct f_fs_opts *opts; |
3669 | struct config_item *ci; | ||
3669 | 3670 | ||
3670 | ENTER(); | 3671 | ENTER(); |
3671 | ffs_dev_lock(); | 3672 | ffs_dev_lock(); |
@@ -3689,8 +3690,11 @@ static void ffs_closed(struct ffs_data *ffs) | |||
3689 | || !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount)) | 3690 | || !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount)) |
3690 | goto done; | 3691 | goto done; |
3691 | 3692 | ||
3692 | unregister_gadget_item(ffs_obj->opts-> | 3693 | ci = opts->func_inst.group.cg_item.ci_parent->ci_parent; |
3693 | func_inst.group.cg_item.ci_parent->ci_parent); | 3694 | ffs_dev_unlock(); |
3695 | |||
3696 | unregister_gadget_item(ci); | ||
3697 | return; | ||
3694 | done: | 3698 | done: |
3695 | ffs_dev_unlock(); | 3699 | ffs_dev_unlock(); |
3696 | } | 3700 | } |
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 3151d2a0fe59..5f8139b8e601 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c | |||
@@ -593,7 +593,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
593 | } | 593 | } |
594 | status = usb_ep_enable(hidg->out_ep); | 594 | status = usb_ep_enable(hidg->out_ep); |
595 | if (status < 0) { | 595 | if (status < 0) { |
596 | ERROR(cdev, "Enable IN endpoint FAILED!\n"); | 596 | ERROR(cdev, "Enable OUT endpoint FAILED!\n"); |
597 | goto fail; | 597 | goto fail; |
598 | } | 598 | } |
599 | hidg->out_ep->driver_data = hidg; | 599 | hidg->out_ep->driver_data = hidg; |
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index e8f4102d19df..6bde4396927c 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c | |||
@@ -1126,7 +1126,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1126 | /* data and/or status stage for control request */ | 1126 | /* data and/or status stage for control request */ |
1127 | } else if (dev->state == STATE_DEV_SETUP) { | 1127 | } else if (dev->state == STATE_DEV_SETUP) { |
1128 | 1128 | ||
1129 | /* IN DATA+STATUS caller makes len <= wLength */ | 1129 | len = min_t(size_t, len, dev->setup_wLength); |
1130 | if (dev->setup_in) { | 1130 | if (dev->setup_in) { |
1131 | retval = setup_req (dev->gadget->ep0, dev->req, len); | 1131 | retval = setup_req (dev->gadget->ep0, dev->req, len); |
1132 | if (retval == 0) { | 1132 | if (retval == 0) { |
@@ -1734,10 +1734,12 @@ static struct usb_gadget_driver gadgetfs_driver = { | |||
1734 | * such as configuration notifications. | 1734 | * such as configuration notifications. |
1735 | */ | 1735 | */ |
1736 | 1736 | ||
1737 | static int is_valid_config (struct usb_config_descriptor *config) | 1737 | static int is_valid_config(struct usb_config_descriptor *config, |
1738 | unsigned int total) | ||
1738 | { | 1739 | { |
1739 | return config->bDescriptorType == USB_DT_CONFIG | 1740 | return config->bDescriptorType == USB_DT_CONFIG |
1740 | && config->bLength == USB_DT_CONFIG_SIZE | 1741 | && config->bLength == USB_DT_CONFIG_SIZE |
1742 | && total >= USB_DT_CONFIG_SIZE | ||
1741 | && config->bConfigurationValue != 0 | 1743 | && config->bConfigurationValue != 0 |
1742 | && (config->bmAttributes & USB_CONFIG_ATT_ONE) != 0 | 1744 | && (config->bmAttributes & USB_CONFIG_ATT_ONE) != 0 |
1743 | && (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) == 0; | 1745 | && (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) == 0; |
@@ -1762,7 +1764,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1762 | } | 1764 | } |
1763 | spin_unlock_irq(&dev->lock); | 1765 | spin_unlock_irq(&dev->lock); |
1764 | 1766 | ||
1765 | if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) | 1767 | if ((len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) || |
1768 | (len > PAGE_SIZE * 4)) | ||
1766 | return -EINVAL; | 1769 | return -EINVAL; |
1767 | 1770 | ||
1768 | /* we might need to change message format someday */ | 1771 | /* we might need to change message format someday */ |
@@ -1786,7 +1789,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1786 | /* full or low speed config */ | 1789 | /* full or low speed config */ |
1787 | dev->config = (void *) kbuf; | 1790 | dev->config = (void *) kbuf; |
1788 | total = le16_to_cpu(dev->config->wTotalLength); | 1791 | total = le16_to_cpu(dev->config->wTotalLength); |
1789 | if (!is_valid_config (dev->config) || total >= length) | 1792 | if (!is_valid_config(dev->config, total) || |
1793 | total > length - USB_DT_DEVICE_SIZE) | ||
1790 | goto fail; | 1794 | goto fail; |
1791 | kbuf += total; | 1795 | kbuf += total; |
1792 | length -= total; | 1796 | length -= total; |
@@ -1795,10 +1799,13 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1795 | if (kbuf [1] == USB_DT_CONFIG) { | 1799 | if (kbuf [1] == USB_DT_CONFIG) { |
1796 | dev->hs_config = (void *) kbuf; | 1800 | dev->hs_config = (void *) kbuf; |
1797 | total = le16_to_cpu(dev->hs_config->wTotalLength); | 1801 | total = le16_to_cpu(dev->hs_config->wTotalLength); |
1798 | if (!is_valid_config (dev->hs_config) || total >= length) | 1802 | if (!is_valid_config(dev->hs_config, total) || |
1803 | total > length - USB_DT_DEVICE_SIZE) | ||
1799 | goto fail; | 1804 | goto fail; |
1800 | kbuf += total; | 1805 | kbuf += total; |
1801 | length -= total; | 1806 | length -= total; |
1807 | } else { | ||
1808 | dev->hs_config = NULL; | ||
1802 | } | 1809 | } |
1803 | 1810 | ||
1804 | /* could support multiple configs, using another encoding! */ | 1811 | /* could support multiple configs, using another encoding! */ |
@@ -1811,7 +1818,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1811 | || dev->dev->bDescriptorType != USB_DT_DEVICE | 1818 | || dev->dev->bDescriptorType != USB_DT_DEVICE |
1812 | || dev->dev->bNumConfigurations != 1) | 1819 | || dev->dev->bNumConfigurations != 1) |
1813 | goto fail; | 1820 | goto fail; |
1814 | dev->dev->bNumConfigurations = 1; | ||
1815 | dev->dev->bcdUSB = cpu_to_le16 (0x0200); | 1821 | dev->dev->bcdUSB = cpu_to_le16 (0x0200); |
1816 | 1822 | ||
1817 | /* triggers gadgetfs_bind(); then we can enumerate. */ | 1823 | /* triggers gadgetfs_bind(); then we can enumerate. */ |
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 9483489080f6..0402177f93cd 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c | |||
@@ -1317,7 +1317,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver) | |||
1317 | if (!ret) | 1317 | if (!ret) |
1318 | break; | 1318 | break; |
1319 | } | 1319 | } |
1320 | if (!ret && !udc->driver) | 1320 | if (ret) |
1321 | ret = -ENODEV; | ||
1322 | else if (udc->driver) | ||
1323 | ret = -EBUSY; | ||
1324 | else | ||
1321 | goto found; | 1325 | goto found; |
1322 | } else { | 1326 | } else { |
1323 | list_for_each_entry(udc, &udc_list, list) { | 1327 | list_for_each_entry(udc, &udc_list, list) { |
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 02b14e91ae6c..c60abe3a68f9 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c | |||
@@ -330,7 +330,7 @@ static void nuke(struct dummy *dum, struct dummy_ep *ep) | |||
330 | /* caller must hold lock */ | 330 | /* caller must hold lock */ |
331 | static void stop_activity(struct dummy *dum) | 331 | static void stop_activity(struct dummy *dum) |
332 | { | 332 | { |
333 | struct dummy_ep *ep; | 333 | int i; |
334 | 334 | ||
335 | /* prevent any more requests */ | 335 | /* prevent any more requests */ |
336 | dum->address = 0; | 336 | dum->address = 0; |
@@ -338,8 +338,8 @@ static void stop_activity(struct dummy *dum) | |||
338 | /* The timer is left running so that outstanding URBs can fail */ | 338 | /* The timer is left running so that outstanding URBs can fail */ |
339 | 339 | ||
340 | /* nuke any pending requests first, so driver i/o is quiesced */ | 340 | /* nuke any pending requests first, so driver i/o is quiesced */ |
341 | list_for_each_entry(ep, &dum->gadget.ep_list, ep.ep_list) | 341 | for (i = 0; i < DUMMY_ENDPOINTS; ++i) |
342 | nuke(dum, ep); | 342 | nuke(dum, &dum->ep[i]); |
343 | 343 | ||
344 | /* driver now does any non-usb quiescing necessary */ | 344 | /* driver now does any non-usb quiescing necessary */ |
345 | } | 345 | } |
diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index acc63697a0cc..b2a31a55a612 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h | |||
@@ -93,6 +93,7 @@ struct usb_ext_prop_desc { | |||
93 | * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2 | | 93 | * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2 | |
94 | * | 4 | length | LE32 | length of the whole data chunk | | 94 | * | 4 | length | LE32 | length of the whole data chunk | |
95 | * | 8 | flags | LE32 | combination of functionfs_flags | | 95 | * | 8 | flags | LE32 | combination of functionfs_flags | |
96 | * | | eventfd | LE32 | eventfd file descriptor | | ||
96 | * | | fs_count | LE32 | number of full-speed descriptors | | 97 | * | | fs_count | LE32 | number of full-speed descriptors | |
97 | * | | hs_count | LE32 | number of high-speed descriptors | | 98 | * | | hs_count | LE32 | number of high-speed descriptors | |
98 | * | | ss_count | LE32 | number of super-speed descriptors | | 99 | * | | ss_count | LE32 | number of super-speed descriptors | |