aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-04-22 04:09:05 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-04-22 04:09:05 -0400
commit5813dea9f33fff0420eab6b5892e5698094f838f (patch)
tree3846402f09e425009ae20f6f0f58be4227291cab
parentc3b46c73264b03000d1e18b22f5caf63332547c9 (diff)
parent38740a5b87d53ceb89eb2c970150f6e94e00373a (diff)
Merge tag 'fixes-for-v4.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus
Felipe writes: usb: fixes for v4.6-rc5 No more major fixes left. Out of the 6 fixes we have here, 4 are on dwc3. The most important is the memory leak fix in dwc3/debugfs.c. We also have a fix for PHY handling in suspend/resume and a fix for dwc3-omap's error handling. Suspend/resume also had the potential to trigger a NULL pointer dereference on dwc3; that's also fixed now. Our good ol' ffs function gets a use-after-free fix while the generic composite.c layer has a robustness fix by making sure reserved fields of a possible SSP device capability descriptor is cleared to 0.
-rw-r--r--drivers/usb/dwc3/core.c23
-rw-r--r--drivers/usb/dwc3/debugfs.c13
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c12
-rw-r--r--drivers/usb/dwc3/gadget.c6
-rw-r--r--drivers/usb/gadget/composite.c2
-rw-r--r--drivers/usb/gadget/function/f_fs.c5
6 files changed, 44 insertions, 17 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index fa20f5a99d12..34277ced26bd 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1150,6 +1150,11 @@ static int dwc3_suspend(struct device *dev)
1150 phy_exit(dwc->usb2_generic_phy); 1150 phy_exit(dwc->usb2_generic_phy);
1151 phy_exit(dwc->usb3_generic_phy); 1151 phy_exit(dwc->usb3_generic_phy);
1152 1152
1153 usb_phy_set_suspend(dwc->usb2_phy, 1);
1154 usb_phy_set_suspend(dwc->usb3_phy, 1);
1155 WARN_ON(phy_power_off(dwc->usb2_generic_phy) < 0);
1156 WARN_ON(phy_power_off(dwc->usb3_generic_phy) < 0);
1157
1153 pinctrl_pm_select_sleep_state(dev); 1158 pinctrl_pm_select_sleep_state(dev);
1154 1159
1155 return 0; 1160 return 0;
@@ -1163,11 +1168,21 @@ static int dwc3_resume(struct device *dev)
1163 1168
1164 pinctrl_pm_select_default_state(dev); 1169 pinctrl_pm_select_default_state(dev);
1165 1170
1171 usb_phy_set_suspend(dwc->usb2_phy, 0);
1172 usb_phy_set_suspend(dwc->usb3_phy, 0);
1173 ret = phy_power_on(dwc->usb2_generic_phy);
1174 if (ret < 0)
1175 return ret;
1176
1177 ret = phy_power_on(dwc->usb3_generic_phy);
1178 if (ret < 0)
1179 goto err_usb2phy_power;
1180
1166 usb_phy_init(dwc->usb3_phy); 1181 usb_phy_init(dwc->usb3_phy);
1167 usb_phy_init(dwc->usb2_phy); 1182 usb_phy_init(dwc->usb2_phy);
1168 ret = phy_init(dwc->usb2_generic_phy); 1183 ret = phy_init(dwc->usb2_generic_phy);
1169 if (ret < 0) 1184 if (ret < 0)
1170 return ret; 1185 goto err_usb3phy_power;
1171 1186
1172 ret = phy_init(dwc->usb3_generic_phy); 1187 ret = phy_init(dwc->usb3_generic_phy);
1173 if (ret < 0) 1188 if (ret < 0)
@@ -1200,6 +1215,12 @@ static int dwc3_resume(struct device *dev)
1200err_usb2phy_init: 1215err_usb2phy_init:
1201 phy_exit(dwc->usb2_generic_phy); 1216 phy_exit(dwc->usb2_generic_phy);
1202 1217
1218err_usb3phy_power:
1219 phy_power_off(dwc->usb3_generic_phy);
1220
1221err_usb2phy_power:
1222 phy_power_off(dwc->usb2_generic_phy);
1223
1203 return ret; 1224 return ret;
1204} 1225}
1205 1226
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index 9ac37fe1b6a7..cebf9e38b60a 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -645,7 +645,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
645 file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset); 645 file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset);
646 if (!file) { 646 if (!file) {
647 ret = -ENOMEM; 647 ret = -ENOMEM;
648 goto err1; 648 goto err2;
649 } 649 }
650 650
651 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) { 651 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
@@ -653,7 +653,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
653 dwc, &dwc3_mode_fops); 653 dwc, &dwc3_mode_fops);
654 if (!file) { 654 if (!file) {
655 ret = -ENOMEM; 655 ret = -ENOMEM;
656 goto err1; 656 goto err2;
657 } 657 }
658 } 658 }
659 659
@@ -663,19 +663,22 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
663 dwc, &dwc3_testmode_fops); 663 dwc, &dwc3_testmode_fops);
664 if (!file) { 664 if (!file) {
665 ret = -ENOMEM; 665 ret = -ENOMEM;
666 goto err1; 666 goto err2;
667 } 667 }
668 668
669 file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, 669 file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root,
670 dwc, &dwc3_link_state_fops); 670 dwc, &dwc3_link_state_fops);
671 if (!file) { 671 if (!file) {
672 ret = -ENOMEM; 672 ret = -ENOMEM;
673 goto err1; 673 goto err2;
674 } 674 }
675 } 675 }
676 676
677 return 0; 677 return 0;
678 678
679err2:
680 kfree(dwc->regset);
681
679err1: 682err1:
680 debugfs_remove_recursive(root); 683 debugfs_remove_recursive(root);
681 684
@@ -686,5 +689,5 @@ err0:
686void dwc3_debugfs_exit(struct dwc3 *dwc) 689void dwc3_debugfs_exit(struct dwc3 *dwc)
687{ 690{
688 debugfs_remove_recursive(dwc->root); 691 debugfs_remove_recursive(dwc->root);
689 dwc->root = NULL; 692 kfree(dwc->regset);
690} 693}
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 22e9606d8e08..55da2c7f727f 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -496,7 +496,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
496 ret = pm_runtime_get_sync(dev); 496 ret = pm_runtime_get_sync(dev);
497 if (ret < 0) { 497 if (ret < 0) {
498 dev_err(dev, "get_sync failed with err %d\n", ret); 498 dev_err(dev, "get_sync failed with err %d\n", ret);
499 goto err0; 499 goto err1;
500 } 500 }
501 501
502 dwc3_omap_map_offset(omap); 502 dwc3_omap_map_offset(omap);
@@ -516,28 +516,24 @@ static int dwc3_omap_probe(struct platform_device *pdev)
516 516
517 ret = dwc3_omap_extcon_register(omap); 517 ret = dwc3_omap_extcon_register(omap);
518 if (ret < 0) 518 if (ret < 0)
519 goto err2; 519 goto err1;
520 520
521 ret = of_platform_populate(node, NULL, NULL, dev); 521 ret = of_platform_populate(node, NULL, NULL, dev);
522 if (ret) { 522 if (ret) {
523 dev_err(&pdev->dev, "failed to create dwc3 core\n"); 523 dev_err(&pdev->dev, "failed to create dwc3 core\n");
524 goto err3; 524 goto err2;
525 } 525 }
526 526
527 dwc3_omap_enable_irqs(omap); 527 dwc3_omap_enable_irqs(omap);
528 528
529 return 0; 529 return 0;
530 530
531err3: 531err2:
532 extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb); 532 extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb);
533 extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb); 533 extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb);
534err2:
535 dwc3_omap_disable_irqs(omap);
536 534
537err1: 535err1:
538 pm_runtime_put_sync(dev); 536 pm_runtime_put_sync(dev);
539
540err0:
541 pm_runtime_disable(dev); 537 pm_runtime_disable(dev);
542 538
543 return ret; 539 return ret;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index d54a028cdfeb..8e4a1b195e9b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2936,6 +2936,9 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
2936 2936
2937int dwc3_gadget_suspend(struct dwc3 *dwc) 2937int dwc3_gadget_suspend(struct dwc3 *dwc)
2938{ 2938{
2939 if (!dwc->gadget_driver)
2940 return 0;
2941
2939 if (dwc->pullups_connected) { 2942 if (dwc->pullups_connected) {
2940 dwc3_gadget_disable_irq(dwc); 2943 dwc3_gadget_disable_irq(dwc);
2941 dwc3_gadget_run_stop(dwc, true, true); 2944 dwc3_gadget_run_stop(dwc, true, true);
@@ -2954,6 +2957,9 @@ int dwc3_gadget_resume(struct dwc3 *dwc)
2954 struct dwc3_ep *dep; 2957 struct dwc3_ep *dep;
2955 int ret; 2958 int ret;
2956 2959
2960 if (!dwc->gadget_driver)
2961 return 0;
2962
2957 /* Start with SuperSpeed Default */ 2963 /* Start with SuperSpeed Default */
2958 dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); 2964 dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
2959 2965
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index de9ffd60fcfa..524e233d48de 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -651,6 +651,8 @@ static int bos_desc(struct usb_composite_dev *cdev)
651 ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1); 651 ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1);
652 ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY; 652 ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
653 ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE; 653 ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE;
654 ssp_cap->bReserved = 0;
655 ssp_cap->wReserved = 0;
654 656
655 /* SSAC = 1 (2 attributes) */ 657 /* SSAC = 1 (2 attributes) */
656 ssp_cap->bmAttributes = cpu_to_le32(1); 658 ssp_cap->bmAttributes = cpu_to_le32(1);
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index e21ca2bd6839..15b648cbc75c 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -646,6 +646,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
646 work); 646 work);
647 int ret = io_data->req->status ? io_data->req->status : 647 int ret = io_data->req->status ? io_data->req->status :
648 io_data->req->actual; 648 io_data->req->actual;
649 bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
649 650
650 if (io_data->read && ret > 0) { 651 if (io_data->read && ret > 0) {
651 use_mm(io_data->mm); 652 use_mm(io_data->mm);
@@ -657,13 +658,11 @@ static void ffs_user_copy_worker(struct work_struct *work)
657 658
658 io_data->kiocb->ki_complete(io_data->kiocb, ret, ret); 659 io_data->kiocb->ki_complete(io_data->kiocb, ret, ret);
659 660
660 if (io_data->ffs->ffs_eventfd && 661 if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)
661 !(io_data->kiocb->ki_flags & IOCB_EVENTFD))
662 eventfd_signal(io_data->ffs->ffs_eventfd, 1); 662 eventfd_signal(io_data->ffs->ffs_eventfd, 1);
663 663
664 usb_ep_free_request(io_data->ep, io_data->req); 664 usb_ep_free_request(io_data->ep, io_data->req);
665 665
666 io_data->kiocb->private = NULL;
667 if (io_data->read) 666 if (io_data->read)
668 kfree(io_data->to_free); 667 kfree(io_data->to_free);
669 kfree(io_data->buf); 668 kfree(io_data->buf);