From 015fbddefcfbf8b44c89b2e9b0b3dd77631f1e51 Mon Sep 17 00:00:00 2001 From: Ivan Orlov Date: Thu, 22 Jun 2023 00:25:14 +0400 Subject: USB: make usb class a const structure Now that the driver core allows for struct class to be in read-only memory, remove the usb_class structure and create the usbmisc_class const class structure declared at build time which places it into read-only memory, instead of having it to be dynamically allocated at load time. Additionally, now we register usb class at startup and unregister it when shutting down, so we don't have to count uses of the class. Therefore we don't need the 'usb_class' structure anymore. Due to this fact, remove all static functions related to class initialization and deinitialization. We can't use them in 'usb.c' since they are static and we don't really need them anymore. Since we have to register the class in usb_init function in 'usb.c' and use it in 'file.c' as well, declare the usbmisc_class structure as 'export' in the 'usb.h' file. Debatable moment: the class registration and unregistration functions could be extracted to the 'file.c'. I think we don't want to do this since it would be one-line functions. They would make the code paths more confusing and add calling overhead. Suggested-by: Greg Kroah-Hartman Signed-off-by: Ivan Orlov Link: https://lore.kernel.org/r/20230621202514.1223670-1-ivan.orlov0322@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/file.c | 68 +++++-------------------------------------------- drivers/usb/core/usb.c | 6 +++++ drivers/usb/core/usb.h | 1 + 3 files changed, 14 insertions(+), 61 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index c4ed3310e069..a88ced93b5e7 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -29,7 +29,6 @@ #define MAX_USB_MINORS 256 static const struct file_operations *usb_minors[MAX_USB_MINORS]; static DECLARE_RWSEM(minor_rwsem); -static DEFINE_MUTEX(init_usb_class_mutex); static int usb_open(struct inode *inode, struct file *file) { @@ -57,11 +56,6 @@ static const struct file_operations usb_fops = { .llseek = noop_llseek, }; -static struct usb_class { - struct kref kref; - struct class *class; -} *usb_class; - static char *usb_devnode(const struct device *dev, umode_t *mode) { struct usb_class_driver *drv; @@ -72,50 +66,10 @@ static char *usb_devnode(const struct device *dev, umode_t *mode) return drv->devnode(dev, mode); } -static int init_usb_class(void) -{ - int result = 0; - - if (usb_class != NULL) { - kref_get(&usb_class->kref); - goto exit; - } - - usb_class = kmalloc(sizeof(*usb_class), GFP_KERNEL); - if (!usb_class) { - result = -ENOMEM; - goto exit; - } - - kref_init(&usb_class->kref); - usb_class->class = class_create("usbmisc"); - if (IS_ERR(usb_class->class)) { - result = PTR_ERR(usb_class->class); - printk(KERN_ERR "class_create failed for usb devices\n"); - kfree(usb_class); - usb_class = NULL; - goto exit; - } - usb_class->class->devnode = usb_devnode; - -exit: - return result; -} - -static void release_usb_class(struct kref *kref) -{ - /* Ok, we cheat as we know we only have one usb_class */ - class_destroy(usb_class->class); - kfree(usb_class); - usb_class = NULL; -} - -static void destroy_usb_class(void) -{ - mutex_lock(&init_usb_class_mutex); - kref_put(&usb_class->kref, release_usb_class); - mutex_unlock(&init_usb_class_mutex); -} +const struct class usbmisc_class = { + .name = "usbmisc", + .devnode = usb_devnode, +}; int usb_major_init(void) { @@ -156,7 +110,7 @@ void usb_major_cleanup(void) int usb_register_dev(struct usb_interface *intf, struct usb_class_driver *class_driver) { - int retval; + int retval = 0; int minor_base = class_driver->minor_base; int minor; char name[20]; @@ -175,13 +129,6 @@ int usb_register_dev(struct usb_interface *intf, if (intf->minor >= 0) return -EADDRINUSE; - mutex_lock(&init_usb_class_mutex); - retval = init_usb_class(); - mutex_unlock(&init_usb_class_mutex); - - if (retval) - return retval; - dev_dbg(&intf->dev, "looking for a minor, starting at %d\n", minor_base); down_write(&minor_rwsem); @@ -200,7 +147,7 @@ int usb_register_dev(struct usb_interface *intf, /* create a usb class device for this usb interface */ snprintf(name, sizeof(name), class_driver->name, minor - minor_base); - intf->usb_dev = device_create(usb_class->class, &intf->dev, + intf->usb_dev = device_create(&usbmisc_class, &intf->dev, MKDEV(USB_MAJOR, minor), class_driver, "%s", kbasename(name)); if (IS_ERR(intf->usb_dev)) { @@ -234,7 +181,7 @@ void usb_deregister_dev(struct usb_interface *intf, return; dev_dbg(&intf->dev, "removing %d minor\n", intf->minor); - device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); + device_destroy(&usbmisc_class, MKDEV(USB_MAJOR, intf->minor)); down_write(&minor_rwsem); usb_minors[intf->minor] = NULL; @@ -242,6 +189,5 @@ void usb_deregister_dev(struct usb_interface *intf, intf->usb_dev = NULL; intf->minor = -1; - destroy_usb_class(); } EXPORT_SYMBOL_GPL(usb_deregister_dev); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 901ec732321c..39bdf9589b06 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -1101,6 +1101,9 @@ static int __init usb_init(void) retval = usb_major_init(); if (retval) goto major_init_failed; + retval = class_register(&usbmisc_class); + if (retval) + goto class_register_failed; retval = usb_register(&usbfs_driver); if (retval) goto driver_register_failed; @@ -1120,6 +1123,8 @@ hub_init_failed: usb_devio_init_failed: usb_deregister(&usbfs_driver); driver_register_failed: + class_unregister(&usbmisc_class); +class_register_failed: usb_major_cleanup(); major_init_failed: bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); @@ -1147,6 +1152,7 @@ static void __exit usb_exit(void) usb_deregister(&usbfs_driver); usb_devio_cleanup(); usb_hub_cleanup(); + class_unregister(&usbmisc_class); bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); bus_unregister(&usb_bus_type); usb_acpi_unregister(); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index ffe3f6818e9c..69ca59841083 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -141,6 +141,7 @@ static inline int usb_disable_usb2_hardware_lpm(struct usb_device *udev) #endif +extern const struct class usbmisc_class; extern const struct bus_type usb_bus_type; extern struct mutex usb_port_peer_mutex; extern struct device_type usb_device_type; -- cgit v1.2.3 From 484468fb0f7dbac88f050009a5145ed1ee744a7e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2023 08:30:23 -0600 Subject: usb: Explicitly include correct DT includes The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Acked-by: Herve Codina Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20230718143027.1064731-1-robh@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdns3-gadget.c | 1 + drivers/usb/cdns3/cdns3-plat.c | 1 + drivers/usb/cdns3/cdns3-ti.c | 1 + drivers/usb/cdns3/core.c | 1 + drivers/usb/chipidea/ci_hdrc_imx.c | 1 + drivers/usb/chipidea/ci_hdrc_tegra.c | 3 ++- drivers/usb/chipidea/usbmisc_imx.c | 3 ++- drivers/usb/common/common.c | 1 + drivers/usb/core/message.c | 1 + drivers/usb/core/of.c | 1 - drivers/usb/core/usb.c | 1 + drivers/usb/dwc2/gadget.c | 1 - drivers/usb/dwc2/platform.c | 2 +- drivers/usb/dwc3/dwc3-imx8mp.c | 1 + drivers/usb/dwc3/dwc3-keystone.c | 1 + drivers/usb/gadget/udc/fsl_udc_core.c | 1 - drivers/usb/gadget/udc/gr_udc.c | 5 ++--- drivers/usb/gadget/udc/max3420_udc.c | 4 +--- drivers/usb/gadget/udc/pxa27x_udc.c | 2 +- drivers/usb/gadget/udc/renesas_usb3.c | 2 +- drivers/usb/gadget/udc/renesas_usbf.c | 5 ++--- drivers/usb/gadget/udc/tegra-xudc.c | 1 - drivers/usb/gadget/udc/udc-xilinx.c | 6 ++---- drivers/usb/host/ehci-fsl.c | 2 +- drivers/usb/host/ehci-orion.c | 2 -- drivers/usb/host/fhci-hcd.c | 3 ++- drivers/usb/host/fsl-mph-dr-of.c | 3 ++- drivers/usb/host/ohci-at91.c | 2 +- drivers/usb/host/ohci-da8xx.c | 1 + drivers/usb/host/ohci-ppc-of.c | 3 ++- drivers/usb/host/xhci-plat.c | 1 - drivers/usb/host/xhci-rcar.c | 1 - drivers/usb/host/xhci-tegra.c | 2 +- drivers/usb/misc/usb251xb.c | 2 +- drivers/usb/mtu3/mtu3.h | 1 + drivers/usb/mtu3/mtu3_host.c | 1 + drivers/usb/musb/jz4740.c | 2 +- drivers/usb/musb/mediatek.c | 1 + drivers/usb/musb/mpfs.c | 1 + drivers/usb/musb/musb_dsps.c | 2 -- drivers/usb/musb/sunxi.c | 1 - drivers/usb/phy/phy-mxs-usb.c | 2 +- drivers/usb/phy/phy-tegra-usb.c | 2 +- drivers/usb/renesas_usbhs/common.c | 2 +- drivers/usb/renesas_usbhs/rza.c | 2 +- drivers/usb/renesas_usbhs/rza2.c | 1 - drivers/usb/typec/tcpm/fusb302.c | 2 +- drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 2 +- drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c | 2 -- drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c | 1 - drivers/usb/typec/ucsi/ucsi_glink.c | 1 - 51 files changed, 46 insertions(+), 48 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index ea19253fd2d0..e6f6aeb7b5bb 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -61,6 +61,7 @@ #include #include #include +#include #include "core.h" #include "gadget-export.h" diff --git a/drivers/usb/cdns3/cdns3-plat.c b/drivers/usb/cdns3/cdns3-plat.c index 1168dbeed2ce..2c1aca84f226 100644 --- a/drivers/usb/cdns3/cdns3-plat.c +++ b/drivers/usb/cdns3/cdns3-plat.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c index 81b9132e3aaa..5945c4b1e11f 100644 --- a/drivers/usb/cdns3/cdns3-ti.c +++ b/drivers/usb/cdns3/cdns3-ti.c @@ -15,6 +15,7 @@ #include #include #include +#include /* USB Wrapper register offsets */ #define USBSS_PID 0x0 diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 7b20d2d5c262..33548771a0d3 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 336ef6dd8e7d..aa2aebed8e2d 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c index ca36d11a69ea..8e78bf643e25 100644 --- a/drivers/usb/chipidea/ci_hdrc_tegra.c +++ b/drivers/usb/chipidea/ci_hdrc_tegra.c @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 9ee9621e2ccc..e8a712e5abad 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -4,10 +4,11 @@ */ #include -#include +#include #include #include #include +#include #include #include "ci_hdrc_imx.h" diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index c9bdeb4ddcb5..b84efae26e15 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b5811620f1de..0d2bfc909019 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -9,6 +9,7 @@ #include /* for scatterlist macros */ #include #include +#include #include #include #include diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c index 617e92569b2c..db4ccf9ce3d9 100644 --- a/drivers/usb/core/of.c +++ b/drivers/usb/core/of.c @@ -8,7 +8,6 @@ */ #include -#include #include /** diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 39bdf9589b06..bba87e5b7f8a 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 8b15742d9e8a..b517a7216de2 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 0a806f80217e..b1d48019e944 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c index 8b9a3bb587bf..4285bde58d2e 100644 --- a/drivers/usb/dwc3/dwc3-imx8mp.c +++ b/drivers/usb/dwc3/dwc3-imx8mp.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index 0a09aedc2573..4155e8d5a559 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index a67873a074b7..5265ca418cde 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index 09762559912d..0c3969301a53 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -36,9 +37,7 @@ #include #include #include -#include -#include -#include +#include #include diff --git a/drivers/usb/gadget/udc/max3420_udc.c b/drivers/usb/gadget/udc/max3420_udc.c index 12c519f32bf7..2d57786d3db7 100644 --- a/drivers/usb/gadget/udc/max3420_udc.c +++ b/drivers/usb/gadget/udc/max3420_udc.c @@ -19,9 +19,7 @@ #include #include #include -#include -#include -#include +#include #include #include #include diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index c4e1d957f913..61424cfd2e1c 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 59bb25de2015..3b01734ce1b7 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/gadget/udc/renesas_usbf.c b/drivers/usb/gadget/udc/renesas_usbf.c index 6cd0af83e91e..3482b41d0646 100644 --- a/drivers/usb/gadget/udc/renesas_usbf.c +++ b/drivers/usb/gadget/udc/renesas_usbf.c @@ -12,10 +12,9 @@ #include #include #include +#include #include -#include -#include -#include +#include #include #include #include diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 83eaa65ddde3..065046f1c9cb 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index a4a7b90a97e7..0a025bf14e06 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c @@ -18,10 +18,8 @@ #include #include #include -#include -#include -#include -#include +#include +#include #include #include #include diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 81d60a695510..3c776f4de4b8 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include "ehci.h" diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 2cfb27dc943a..a5f4e2f98346 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 66a045e01dad..9a1b5224f239 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -22,9 +22,10 @@ #include #include #include +#include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index a9877f2569f4..8508d37a2aff 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -10,7 +10,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index b9ce8d80f20b..3b023ea71f8d 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -17,13 +17,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include #include diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index e4191a868944..9bd6cb9af364 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 35a7ad7e2569..f64bfe5f4d4d 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -15,9 +15,10 @@ */ #include +#include #include #include -#include +#include static int ohci_ppc_of_start(struct usb_hcd *hcd) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index b26ea7cb4357..28218c8f1837 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index bf5261fed32c..ab9c5969e462 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include "xhci.h" diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 6ca8a37e53e1..51e236c1ff71 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c index e4edb486b69e..7da404f55a6d 100644 --- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index b4a7662dded5..c11840b9a6f1 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c index 177d2caf887c..9f2be22af844 100644 --- a/drivers/usb/mtu3/mtu3_host.c +++ b/drivers/usb/mtu3/mtu3_host.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index 5aabdd7e2511..b38df9226278 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c index 598ee5c0bf34..0a35aab3ab81 100644 --- a/drivers/usb/musb/mediatek.c +++ b/drivers/usb/musb/mediatek.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/musb/mpfs.c b/drivers/usb/musb/mpfs.c index 24b98716f7fc..f0f56df38835 100644 --- a/drivers/usb/musb/mpfs.c +++ b/drivers/usb/musb/mpfs.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "musb_core.h" diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 9119b1d51370..98b42dc04dee 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -26,9 +26,7 @@ #include #include -#include #include -#include #include #include diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index c5c6c4e09300..d54283fd026b 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index e1a2b2ea098b..50cf0003384a 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 8b2ff3a8882d..4ea47e6f835b 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 111b7ee152c4..dd1c17542439 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/renesas_usbhs/rza.c b/drivers/usb/renesas_usbhs/rza.c index 2d77edefb4b3..97b5217c5a90 100644 --- a/drivers/usb/renesas_usbhs/rza.c +++ b/drivers/usb/renesas_usbhs/rza.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include "common.h" #include "rza.h" diff --git a/drivers/usb/renesas_usbhs/rza2.c b/drivers/usb/renesas_usbhs/rza2.c index 3eed3334a17f..f079817250bb 100644 --- a/drivers/usb/renesas_usbhs/rza2.c +++ b/drivers/usb/renesas_usbhs/rza2.c @@ -8,7 +8,6 @@ #include #include -#include #include #include "common.h" #include "rza.h" diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c index 7fc1ffa14f76..bc21006e979c 100644 --- a/drivers/usb/typec/tcpm/fusb302.c +++ b/drivers/usb/typec/tcpm/fusb302.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c index a905160dd860..f2f3601cbbfb 100644 --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c index 4e1b846627d2..bb0b8479d80f 100644 --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c @@ -8,8 +8,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c index 56df04af2d2b..a8f3f4d3a450 100644 --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index 1fe9cb5b6bd9..bb1854b3311d 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -5,7 +5,6 @@ */ #include #include -#include #include #include #include -- cgit v1.2.3 From a08799cf17c22375752abfad3b4a2b34b3acb287 Mon Sep 17 00:00:00 2001 From: Stanley Chang Date: Tue, 25 Jul 2023 11:31:52 +0800 Subject: usb: phy: add usb phy notify port status API In Realtek SoC, the parameter of usb phy is designed to can dynamic tuning base on port status. Therefore, add a notify callback of phy driver when usb port status change. The Realtek phy driver is designed to dynamically adjust disconnection level and calibrate phy parameters. When the device connected bit changes and when the disconnected bit changes, do port status change notification: Check if portstatus is USB_PORT_STAT_CONNECTION and portchange is USB_PORT_STAT_C_CONNECTION. 1. The device is connected, the driver lowers the disconnection level and calibrates the phy parameters. 2. The device disconnects, the driver increases the disconnect level and calibrates the phy parameters. When controller to notify connect that device is already ready. If we adjust the disconnection level in notify_connect, the disconnect may have been triggered at this stage. So we need to change that as early as possible. The status change of connection is before port reset. Therefore, we add an api to notify phy the port status changes. In this stage, the device is not port enable, and it will not trigger disconnection. Signed-off-by: Stanley Chang Link: https://lore.kernel.org/r/20230725033318.8361-1-stanley_chang@realtek.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 23 +++++++++++++++++++++++ include/linux/usb/phy.h | 13 +++++++++++++ 2 files changed, 36 insertions(+) (limited to 'drivers/usb/core') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a739403a9e45..fcbad9e86328 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -614,6 +614,29 @@ static int hub_ext_port_status(struct usb_hub *hub, int port1, int type, ret = 0; } mutex_unlock(&hub->status_mutex); + + /* + * There is no need to lock status_mutex here, because status_mutex + * protects hub->status, and the phy driver only checks the port + * status without changing the status. + */ + if (!ret) { + struct usb_device *hdev = hub->hdev; + + /* + * Only roothub will be notified of port state changes, + * since the USB PHY only cares about changes at the next + * level. + */ + if (is_root_hub(hdev)) { + struct usb_hcd *hcd = bus_to_hcd(hdev->bus); + + if (hcd->usb_phy) + usb_phy_notify_port_status(hcd->usb_phy, + port1 - 1, *status, *change); + } + } + return ret; } diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index e4de6bc1f69b..b513749582d7 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -144,6 +144,10 @@ struct usb_phy { */ int (*set_wakeup)(struct usb_phy *x, bool enabled); + /* notify phy port status change */ + int (*notify_port_status)(struct usb_phy *x, int port, + u16 portstatus, u16 portchange); + /* notify phy connect status change */ int (*notify_connect)(struct usb_phy *x, enum usb_device_speed speed); @@ -316,6 +320,15 @@ usb_phy_set_wakeup(struct usb_phy *x, bool enabled) return 0; } +static inline int +usb_phy_notify_port_status(struct usb_phy *x, int port, u16 portstatus, u16 portchange) +{ + if (x && x->notify_port_status) + return x->notify_port_status(x, port, portstatus, portchange); + else + return 0; +} + static inline int usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) { -- cgit v1.2.3 From 85d07c55621676d47d873d2749b88f783cd4d5a1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 4 Aug 2023 15:10:59 -0400 Subject: USB: core: Unite old scheme and new scheme descriptor reads In preparation for reworking the usb_get_device_descriptor() routine, it is desirable to unite the two different code paths responsible for initially determining endpoint 0's maximum packet size in a newly discovered USB device. Making this determination presents a chicken-and-egg sort of problem, in that the only way to learn the maxpacket value is to get it from the device descriptor retrieved from the device, but communicating with the device to retrieve a descriptor requires us to know beforehand the ep0 maxpacket size. In practice this problem is solved in two different ways, referred to in hub.c as the "old scheme" and the "new scheme". The old scheme (which is the approach recommended by the USB-2 spec) involves asking the device to send just the first eight bytes of its device descriptor. Such a transfer uses packets containing no more than eight bytes each, and every USB device must have an ep0 maxpacket size >= 8, so this should succeed. Since the bMaxPacketSize0 field of the device descriptor lies within the first eight bytes, this is all we need. The new scheme is an imitation of the technique used in an early Windows USB implementation, giving it the happy advantage of working with a wide variety of devices (some of them at the time would not work with the old scheme, although that's probably less true now). It involves making an initial guess of the ep0 maxpacket size, asking the device to send up to 64 bytes worth of its device descriptor (which is only 18 bytes long), and then resetting the device to clear any error condition that might have resulted from the guess being wrong. The initial guess is determined by the connection speed; it should be correct in all cases other than full speed, for which the allowed values are 8, 16, 32, and 64 (in this case the initial guess is 64). The reason for this patch is that the old- and new-scheme parts of hub_port_init() use different code paths, one involving usb_get_device_descriptor() and one not, for their initial reads of the device descriptor. Since these reads have essentially the same purpose and are made under essentially the same circumstances, this is illogical. It makes more sense to have both of them use a common subroutine. This subroutine does basically what the new scheme's code did, because that approach is more general than the one used by the old scheme. It only needs to know how many bytes to transfer and whether or not it is being called for the first iteration of a retry loop (in case of certain time-out errors). There are two main differences from the former code: We initialize the bDescriptorType field of the transfer buffer to 0 before performing the transfer, to avoid possibly accessing an uninitialized value afterward. We read the device descriptor into a temporary buffer rather than storing it directly into udev->descriptor, which the old scheme implementation used to do. Since the whole point of this first read of the device descriptor is to determine the bMaxPacketSize0 value, that is what the new routine returns (or an error code). The value is stored in a local variable rather than in udev->descriptor. As a side effect, this necessitates moving a section of code that checks the bcdUSB field for SuperSpeed devices until after the full device descriptor has been retrieved. Signed-off-by: Alan Stern Cc: Oliver Neukum Link: https://lore.kernel.org/r/495cb5d4-f956-4f4a-a875-1e67e9489510@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 173 +++++++++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 79 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index fcbad9e86328..91abcd904d04 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4741,6 +4741,67 @@ static int hub_enable_device(struct usb_device *udev) return hcd->driver->enable_device(hcd, udev); } +/* + * Get the bMaxPacketSize0 value during initialization by reading the + * device's device descriptor. Since we don't already know this value, + * the transfer is unsafe and it ignores I/O errors, only testing for + * reasonable received values. + * + * For "old scheme" initialization, size will be 8 so we read just the + * start of the device descriptor, which should work okay regardless of + * the actual bMaxPacketSize0 value. For "new scheme" initialization, + * size will be 64 (and buf will point to a sufficiently large buffer), + * which might not be kosher according to the USB spec but it's what + * Windows does and what many devices expect. + * + * Returns: bMaxPacketSize0 or a negative error code. + */ +static int get_bMaxPacketSize0(struct usb_device *udev, + struct usb_device_descriptor *buf, int size, bool first_time) +{ + int i, rc; + + /* + * Retry on all errors; some devices are flakey. + * 255 is for WUSB devices, we actually need to use + * 512 (WUSB1.0[4.8.1]). + */ + for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) { + /* Start with invalid values in case the transfer fails */ + buf->bDescriptorType = buf->bMaxPacketSize0 = 0; + rc = usb_control_msg(udev, usb_rcvaddr0pipe(), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + USB_DT_DEVICE << 8, 0, + buf, size, + initial_descriptor_timeout); + switch (buf->bMaxPacketSize0) { + case 8: case 16: case 32: case 64: case 255: + if (buf->bDescriptorType == USB_DT_DEVICE) { + rc = buf->bMaxPacketSize0; + break; + } + fallthrough; + default: + if (rc >= 0) + rc = -EPROTO; + break; + } + + /* + * Some devices time out if they are powered on + * when already connected. They need a second + * reset, so return early. But only on the first + * attempt, lest we get into a time-out/reset loop. + */ + if (rc > 0 || (rc == -ETIMEDOUT && first_time && + udev->speed > USB_SPEED_FULL)) + break; + } + return rc; +} + +#define GET_DESCRIPTOR_BUFSIZE 64 + /* Reset device, (re)assign address, get device descriptor. * Device connection must be stable, no more debouncing needed. * Returns device in USB_STATE_ADDRESS, except on error. @@ -4765,6 +4826,12 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, int devnum = udev->devnum; const char *driver_name; bool do_new_scheme; + int maxp0; + struct usb_device_descriptor *buf; + + buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); + if (!buf) + return -ENOMEM; /* root hub ports have a slightly longer reset period * (from USB 2.0 spec, section 7.1.7.5) @@ -4884,9 +4951,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, } if (do_new_scheme) { - struct usb_device_descriptor *buf; - int r = 0; - retval = hub_enable_device(udev); if (retval < 0) { dev_err(&udev->dev, @@ -4895,52 +4959,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, goto fail; } -#define GET_DESCRIPTOR_BUFSIZE 64 - buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); - if (!buf) { - retval = -ENOMEM; - continue; - } - - /* Retry on all errors; some devices are flakey. - * 255 is for WUSB devices, we actually need to use - * 512 (WUSB1.0[4.8.1]). - */ - for (operations = 0; operations < GET_MAXPACKET0_TRIES; - ++operations) { - buf->bMaxPacketSize0 = 0; - r = usb_control_msg(udev, usb_rcvaddr0pipe(), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - USB_DT_DEVICE << 8, 0, - buf, GET_DESCRIPTOR_BUFSIZE, - initial_descriptor_timeout); - switch (buf->bMaxPacketSize0) { - case 8: case 16: case 32: case 64: case 255: - if (buf->bDescriptorType == - USB_DT_DEVICE) { - r = 0; - break; - } - fallthrough; - default: - if (r == 0) - r = -EPROTO; - break; - } - /* - * Some devices time out if they are powered on - * when already connected. They need a second - * reset. But only on the first attempt, - * lest we get into a time out/reset loop - */ - if (r == 0 || (r == -ETIMEDOUT && - retries == 0 && - udev->speed > USB_SPEED_FULL)) - break; - } - udev->descriptor.bMaxPacketSize0 = - buf->bMaxPacketSize0; - kfree(buf); + maxp0 = get_bMaxPacketSize0(udev, buf, + GET_DESCRIPTOR_BUFSIZE, retries == 0); retval = hub_port_reset(hub, port1, udev, delay, false); if (retval < 0) /* error or disconnect */ @@ -4951,14 +4971,13 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, retval = -ENODEV; goto fail; } - if (r) { - if (r != -ENODEV) + if (maxp0 < 0) { + if (maxp0 != -ENODEV) dev_err(&udev->dev, "device descriptor read/64, error %d\n", - r); - retval = -EMSGSIZE; + maxp0); + retval = maxp0; continue; } -#undef GET_DESCRIPTOR_BUFSIZE } /* @@ -5004,19 +5023,17 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, break; } - retval = usb_get_device_descriptor(udev, 8); - if (retval < 8) { + /* !do_new_scheme || wusb */ + maxp0 = get_bMaxPacketSize0(udev, buf, 8, retries == 0); + if (maxp0 < 0) { + retval = maxp0; if (retval != -ENODEV) dev_err(&udev->dev, "device descriptor read/8, error %d\n", retval); - if (retval >= 0) - retval = -EMSGSIZE; } else { u32 delay; - retval = 0; - delay = udev->parent->hub_delay; udev->hub_delay = min_t(u32, delay, USB_TP_TRANSMISSION_DELAY_MAX); @@ -5033,27 +5050,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, if (retval) goto fail; - /* - * Some superspeed devices have finished the link training process - * and attached to a superspeed hub port, but the device descriptor - * got from those devices show they aren't superspeed devices. Warm - * reset the port attached by the devices can fix them. - */ - if ((udev->speed >= USB_SPEED_SUPER) && - (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { - dev_err(&udev->dev, "got a wrong device descriptor, " - "warm reset device\n"); - hub_port_reset(hub, port1, udev, - HUB_BH_RESET_TIME, true); - retval = -EINVAL; - goto fail; - } - - if (udev->descriptor.bMaxPacketSize0 == 0xff || - udev->speed >= USB_SPEED_SUPER) + if (maxp0 == 0xff || udev->speed >= USB_SPEED_SUPER) i = 512; else - i = udev->descriptor.bMaxPacketSize0; + i = maxp0; if (usb_endpoint_maxp(&udev->ep0.desc) != i) { if (udev->speed == USB_SPEED_LOW || !(i == 8 || i == 16 || i == 32 || i == 64)) { @@ -5079,6 +5079,20 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, goto fail; } + /* + * Some superspeed devices have finished the link training process + * and attached to a superspeed hub port, but the device descriptor + * got from those devices show they aren't superspeed devices. Warm + * reset the port attached by the devices can fix them. + */ + if ((udev->speed >= USB_SPEED_SUPER) && + (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { + dev_err(&udev->dev, "got a wrong device descriptor, warm reset device\n"); + hub_port_reset(hub, port1, udev, HUB_BH_RESET_TIME, true); + retval = -EINVAL; + goto fail; + } + usb_detect_quirks(udev); if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) { @@ -5101,6 +5115,7 @@ fail: hub_port_disable(hub, port1, 0); update_devnum(udev, devnum); /* for disconnect processing */ } + kfree(buf); return retval; } -- cgit v1.2.3 From de28e469da75359a2bb8cd8778b78aa64b1be1f4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 4 Aug 2023 15:12:21 -0400 Subject: USB: core: Change usb_get_device_descriptor() API The usb_get_device_descriptor() routine reads the device descriptor from the udev device and stores it directly in udev->descriptor. This interface is error prone, because the USB subsystem expects in-memory copies of a device's descriptors to be immutable once the device has been initialized. The interface is changed so that the device descriptor is left in a kmalloc-ed buffer, not copied into the usb_device structure. A pointer to the buffer is returned to the caller, who is then responsible for kfree-ing it. The corresponding changes needed in the various callers are fairly small. Signed-off-by: Alan Stern Link: https://lore.kernel.org/r/d0111bb6-56c1-4f90-adf2-6cfe152f6561@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 10 +++++++--- drivers/usb/core/hub.c | 44 +++++++++++++++++++++++--------------------- drivers/usb/core/message.c | 29 ++++++++++++----------------- drivers/usb/core/usb.h | 4 ++-- 4 files changed, 44 insertions(+), 43 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8300baedafd2..6af0a31ff147 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -983,6 +983,7 @@ static int register_root_hub(struct usb_hcd *hcd) { struct device *parent_dev = hcd->self.controller; struct usb_device *usb_dev = hcd->self.root_hub; + struct usb_device_descriptor *descr; const int devnum = 1; int retval; @@ -994,13 +995,16 @@ static int register_root_hub(struct usb_hcd *hcd) mutex_lock(&usb_bus_idr_lock); usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); - retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); - if (retval != sizeof usb_dev->descriptor) { + descr = usb_get_device_descriptor(usb_dev); + if (IS_ERR(descr)) { + retval = PTR_ERR(descr); mutex_unlock(&usb_bus_idr_lock); dev_dbg (parent_dev, "can't read %s device descriptor %d\n", dev_name(&usb_dev->dev), retval); - return (retval < 0) ? retval : -EMSGSIZE; + return retval; } + usb_dev->descriptor = *descr; + kfree(descr); if (le16_to_cpu(usb_dev->descriptor.bcdUSB) >= 0x0201) { retval = usb_get_bos_descriptor(usb_dev); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 91abcd904d04..9279c8ccbcf2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2694,12 +2694,17 @@ int usb_authorize_device(struct usb_device *usb_dev) } if (usb_dev->wusb) { - result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor)); - if (result < 0) { + struct usb_device_descriptor *descr; + + descr = usb_get_device_descriptor(usb_dev); + if (IS_ERR(descr)) { + result = PTR_ERR(descr); dev_err(&usb_dev->dev, "can't re-read device descriptor for " "authorization: %d\n", result); goto error_device_descriptor; } + usb_dev->descriptor = *descr; + kfree(descr); } usb_dev->authorized = 1; @@ -4827,7 +4832,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, const char *driver_name; bool do_new_scheme; int maxp0; - struct usb_device_descriptor *buf; + struct usb_device_descriptor *buf, *descr; buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); if (!buf) @@ -5069,15 +5074,16 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, usb_ep0_reinit(udev); } - retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); - if (retval < (signed)sizeof(udev->descriptor)) { + descr = usb_get_device_descriptor(udev); + if (IS_ERR(descr)) { + retval = PTR_ERR(descr); if (retval != -ENODEV) dev_err(&udev->dev, "device descriptor read/all, error %d\n", retval); - if (retval >= 0) - retval = -ENOMSG; goto fail; } + udev->descriptor = *descr; + kfree(descr); /* * Some superspeed devices have finished the link training process @@ -5196,7 +5202,7 @@ hub_power_remaining(struct usb_hub *hub) static int descriptors_changed(struct usb_device *udev, - struct usb_device_descriptor *old_device_descriptor, + struct usb_device_descriptor *new_device_descriptor, struct usb_host_bos *old_bos) { int changed = 0; @@ -5207,8 +5213,8 @@ static int descriptors_changed(struct usb_device *udev, int length; char *buf; - if (memcmp(&udev->descriptor, old_device_descriptor, - sizeof(*old_device_descriptor)) != 0) + if (memcmp(&udev->descriptor, new_device_descriptor, + sizeof(*new_device_descriptor)) != 0) return 1; if ((old_bos && !udev->bos) || (!old_bos && udev->bos)) @@ -5533,9 +5539,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, { struct usb_port *port_dev = hub->ports[port1 - 1]; struct usb_device *udev = port_dev->child; - struct usb_device_descriptor descriptor; + struct usb_device_descriptor *descr; int status = -ENODEV; - int retval; dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n", portstatus, portchange, portspeed(hub, portstatus)); @@ -5562,23 +5567,20 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, * changed device descriptors before resuscitating the * device. */ - descriptor = udev->descriptor; - retval = usb_get_device_descriptor(udev, - sizeof(udev->descriptor)); - if (retval < 0) { + descr = usb_get_device_descriptor(udev); + if (IS_ERR(descr)) { dev_dbg(&udev->dev, - "can't read device descriptor %d\n", - retval); + "can't read device descriptor %ld\n", + PTR_ERR(descr)); } else { - if (descriptors_changed(udev, &descriptor, + if (descriptors_changed(udev, descr, udev->bos)) { dev_dbg(&udev->dev, "device descriptor has changed\n"); - /* for disconnect() calls */ - udev->descriptor = descriptor; } else { status = 0; /* Nothing to do */ } + kfree(descr); } #ifdef CONFIG_PM } else if (udev->state == USB_STATE_SUSPENDED && diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 0d2bfc909019..077dfe48d01c 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1041,40 +1041,35 @@ char *usb_cache_string(struct usb_device *udev, int index) EXPORT_SYMBOL_GPL(usb_cache_string); /* - * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) - * @dev: the device whose device descriptor is being updated - * @size: how much of the descriptor to read + * usb_get_device_descriptor - read the device descriptor + * @udev: the device whose device descriptor should be read * * Context: task context, might sleep. * - * Updates the copy of the device descriptor stored in the device structure, - * which dedicates space for this purpose. - * * Not exported, only for use by the core. If drivers really want to read * the device descriptor directly, they can call usb_get_descriptor() with * type = USB_DT_DEVICE and index = 0. * - * This call is synchronous, and may not be used in an interrupt context. - * - * Return: The number of bytes received on success, or else the status code - * returned by the underlying usb_control_msg() call. + * Returns: a pointer to a dynamically allocated usb_device_descriptor + * structure (which the caller must deallocate), or an ERR_PTR value. */ -int usb_get_device_descriptor(struct usb_device *dev, unsigned int size) +struct usb_device_descriptor *usb_get_device_descriptor(struct usb_device *udev) { struct usb_device_descriptor *desc; int ret; - if (size > sizeof(*desc)) - return -EINVAL; desc = kmalloc(sizeof(*desc), GFP_NOIO); if (!desc) - return -ENOMEM; + return ERR_PTR(-ENOMEM); + + ret = usb_get_descriptor(udev, USB_DT_DEVICE, 0, desc, sizeof(*desc)); + if (ret == sizeof(*desc)) + return desc; - ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size); if (ret >= 0) - memcpy(&dev->descriptor, desc, size); + ret = -EMSGSIZE; kfree(desc); - return ret; + return ERR_PTR(ret); } /* diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 69ca59841083..60363153fc3f 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -43,8 +43,8 @@ extern bool usb_endpoint_is_ignored(struct usb_device *udev, struct usb_endpoint_descriptor *epd); extern int usb_remove_device(struct usb_device *udev); -extern int usb_get_device_descriptor(struct usb_device *dev, - unsigned int size); +extern struct usb_device_descriptor *usb_get_device_descriptor( + struct usb_device *udev); extern int usb_set_isoch_delay(struct usb_device *dev); extern int usb_get_bos_descriptor(struct usb_device *dev); extern void usb_release_bos_descriptor(struct usb_device *dev); -- cgit v1.2.3 From ff33299ec8bb80cdcc073ad9c506bd79bb2ed20b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 4 Aug 2023 15:14:14 -0400 Subject: USB: core: Fix race by not overwriting udev->descriptor in hub_port_init() Syzbot reported an out-of-bounds read in sysfs.c:read_descriptors(): BUG: KASAN: slab-out-of-bounds in read_descriptors+0x263/0x280 drivers/usb/core/sysfs.c:883 Read of size 8 at addr ffff88801e78b8c8 by task udevd/5011 CPU: 0 PID: 5011 Comm: udevd Not tainted 6.4.0-rc6-syzkaller-00195-g40f71e7cd3c6 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd9/0x150 lib/dump_stack.c:106 print_address_description.constprop.0+0x2c/0x3c0 mm/kasan/report.c:351 print_report mm/kasan/report.c:462 [inline] kasan_report+0x11c/0x130 mm/kasan/report.c:572 read_descriptors+0x263/0x280 drivers/usb/core/sysfs.c:883 ... Allocated by task 758: ... __do_kmalloc_node mm/slab_common.c:966 [inline] __kmalloc+0x5e/0x190 mm/slab_common.c:979 kmalloc include/linux/slab.h:563 [inline] kzalloc include/linux/slab.h:680 [inline] usb_get_configuration+0x1f7/0x5170 drivers/usb/core/config.c:887 usb_enumerate_device drivers/usb/core/hub.c:2407 [inline] usb_new_device+0x12b0/0x19d0 drivers/usb/core/hub.c:2545 As analyzed by Khazhy Kumykov, the cause of this bug is a race between read_descriptors() and hub_port_init(): The first routine uses a field in udev->descriptor, not expecting it to change, while the second overwrites it. Prior to commit 45bf39f8df7f ("USB: core: Don't hold device lock while reading the "descriptors" sysfs file") this race couldn't occur, because the routines were mutually exclusive thanks to the device locking. Removing that locking from read_descriptors() exposed it to the race. The best way to fix the bug is to keep hub_port_init() from changing udev->descriptor once udev has been initialized and registered. Drivers expect the descriptors stored in the kernel to be immutable; we should not undermine this expectation. In fact, this change should have been made long ago. So now hub_port_init() will take an additional argument, specifying a buffer in which to store the device descriptor it reads. (If udev has not yet been initialized, the buffer pointer will be NULL and then hub_port_init() will store the device descriptor in udev as before.) This eliminates the data race responsible for the out-of-bounds read. The changes to hub_port_init() appear more extensive than they really are, because of indentation changes resulting from an attempt to avoid writing to other parts of the usb_device structure after it has been initialized. Similar changes should be made to the code that reads the BOS descriptor, but that can be handled in a separate patch later on. This patch is sufficient to fix the bug found by syzbot. Reported-and-tested-by: syzbot+18996170f8096c6174d0@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-usb/000000000000c0ffe505fe86c9ca@google.com/#r Signed-off-by: Alan Stern Cc: Khazhy Kumykov Fixes: 45bf39f8df7f ("USB: core: Don't hold device lock while reading the "descriptors" sysfs file") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/b958b47a-9a46-4c22-a9f9-e42e42c31251@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 114 ++++++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 44 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 9279c8ccbcf2..878913f4b4b3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4816,10 +4816,17 @@ static int get_bMaxPacketSize0(struct usb_device *udev, * the port lock. For a newly detected device that is not accessible * through any global pointers, it's not necessary to lock the device, * but it is still necessary to lock the port. + * + * For a newly detected device, @dev_descr must be NULL. The device + * descriptor retrieved from the device will then be stored in + * @udev->descriptor. For an already existing device, @dev_descr + * must be non-NULL. The device descriptor will be stored there, + * not in @udev->descriptor, because descriptors for registered + * devices are meant to be immutable. */ static int hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - int retry_counter) + int retry_counter, struct usb_device_descriptor *dev_descr) { struct usb_device *hdev = hub->hdev; struct usb_hcd *hcd = bus_to_hcd(hdev->bus); @@ -4831,6 +4838,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, int devnum = udev->devnum; const char *driver_name; bool do_new_scheme; + const bool initial = !dev_descr; int maxp0; struct usb_device_descriptor *buf, *descr; @@ -4869,32 +4877,34 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, } oldspeed = udev->speed; - /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... - * it's fixed size except for full speed devices. - * For Wireless USB devices, ep0 max packet is always 512 (tho - * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. - */ - switch (udev->speed) { - case USB_SPEED_SUPER_PLUS: - case USB_SPEED_SUPER: - case USB_SPEED_WIRELESS: /* fixed at 512 */ - udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); - break; - case USB_SPEED_HIGH: /* fixed at 64 */ - udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); - break; - case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ - /* to determine the ep0 maxpacket size, try to read - * the device descriptor to get bMaxPacketSize0 and - * then correct our initial guess. + if (initial) { + /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... + * it's fixed size except for full speed devices. + * For Wireless USB devices, ep0 max packet is always 512 (tho + * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. */ - udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); - break; - case USB_SPEED_LOW: /* fixed at 8 */ - udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); - break; - default: - goto fail; + switch (udev->speed) { + case USB_SPEED_SUPER_PLUS: + case USB_SPEED_SUPER: + case USB_SPEED_WIRELESS: /* fixed at 512 */ + udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); + break; + case USB_SPEED_HIGH: /* fixed at 64 */ + udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); + break; + case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ + /* to determine the ep0 maxpacket size, try to read + * the device descriptor to get bMaxPacketSize0 and + * then correct our initial guess. + */ + udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); + break; + case USB_SPEED_LOW: /* fixed at 8 */ + udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); + break; + default: + goto fail; + } } if (udev->speed == USB_SPEED_WIRELESS) @@ -4917,22 +4927,24 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, if (udev->speed < USB_SPEED_SUPER) dev_info(&udev->dev, "%s %s USB device number %d using %s\n", - (udev->config) ? "reset" : "new", speed, + (initial ? "new" : "reset"), speed, devnum, driver_name); - /* Set up TT records, if needed */ - if (hdev->tt) { - udev->tt = hdev->tt; - udev->ttport = hdev->ttport; - } else if (udev->speed != USB_SPEED_HIGH - && hdev->speed == USB_SPEED_HIGH) { - if (!hub->tt.hub) { - dev_err(&udev->dev, "parent hub has no TT\n"); - retval = -EINVAL; - goto fail; + if (initial) { + /* Set up TT records, if needed */ + if (hdev->tt) { + udev->tt = hdev->tt; + udev->ttport = hdev->ttport; + } else if (udev->speed != USB_SPEED_HIGH + && hdev->speed == USB_SPEED_HIGH) { + if (!hub->tt.hub) { + dev_err(&udev->dev, "parent hub has no TT\n"); + retval = -EINVAL; + goto fail; + } + udev->tt = &hub->tt; + udev->ttport = port1; } - udev->tt = &hub->tt; - udev->ttport = port1; } /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way? @@ -4966,6 +4978,12 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, maxp0 = get_bMaxPacketSize0(udev, buf, GET_DESCRIPTOR_BUFSIZE, retries == 0); + if (maxp0 > 0 && !initial && + maxp0 != udev->descriptor.bMaxPacketSize0) { + dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n"); + retval = -ENODEV; + goto fail; + } retval = hub_port_reset(hub, port1, udev, delay, false); if (retval < 0) /* error or disconnect */ @@ -5039,6 +5057,12 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, } else { u32 delay; + if (!initial && maxp0 != udev->descriptor.bMaxPacketSize0) { + dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n"); + retval = -ENODEV; + goto fail; + } + delay = udev->parent->hub_delay; udev->hub_delay = min_t(u32, delay, USB_TP_TRANSMISSION_DELAY_MAX); @@ -5082,7 +5106,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, retval); goto fail; } - udev->descriptor = *descr; + if (initial) + udev->descriptor = *descr; + else + *dev_descr = *descr; kfree(descr); /* @@ -5392,7 +5419,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, } /* reset (non-USB 3.0 devices) and get descriptor */ - status = hub_port_init(hub, udev, port1, i); + status = hub_port_init(hub, udev, port1, i, NULL); if (status < 0) goto loop; @@ -6022,7 +6049,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) struct usb_device *parent_hdev = udev->parent; struct usb_hub *parent_hub; struct usb_hcd *hcd = bus_to_hcd(udev->bus); - struct usb_device_descriptor descriptor = udev->descriptor; + struct usb_device_descriptor descriptor; struct usb_host_bos *bos; int i, j, ret = 0; int port1 = udev->portnum; @@ -6058,7 +6085,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) /* ep0 maxpacket size may change; let the HCD know about it. * Other endpoints will be handled by re-enumeration. */ usb_ep0_reinit(udev); - ret = hub_port_init(parent_hub, udev, port1, i); + ret = hub_port_init(parent_hub, udev, port1, i, &descriptor); if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV) break; } @@ -6070,7 +6097,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev) /* Device might have changed firmware (DFU or similar) */ if (descriptors_changed(udev, &descriptor, bos)) { dev_info(&udev->dev, "device firmware changed\n"); - udev->descriptor = descriptor; /* for disconnect() calls */ goto re_enumerate; } -- cgit v1.2.3 From 1e4c574225cc5a0553115e5eb5787d1474db5b0f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 8 Aug 2023 20:44:18 -0400 Subject: USB: Remove remnants of Wireless USB and UWB Wireless USB has long been defunct, and kernel support for it was removed in 2020 by commit caa6772db4c1 ("Staging: remove wusbcore and UWB from the kernel tree."). Nevertheless, some vestiges of the old implementation still clutter up the USB subsystem and one or two other places. Let's get rid of them once and for all. The only parts still left are the user-facing APIs in include/uapi/linux/usb/ch9.h. (There are also a couple of misleading instances, such as the Sierra Wireless USB modem, which is a USB modem made by Sierra Wireless.) Signed-off-by: Alan Stern Link: https://lore.kernel.org/r/b4f2710f-a2de-4fb0-b50f-76776f3a961b@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mediatek/mt76/usb.c | 3 +- drivers/usb/core/config.c | 3 - drivers/usb/core/devices.c | 1 - drivers/usb/core/hcd.c | 40 +------- drivers/usb/core/hub.c | 155 +++++++++---------------------- drivers/usb/core/sysfs.c | 3 - drivers/usb/core/urb.c | 27 ++---- drivers/usb/core/usb.c | 11 --- drivers/usb/host/xhci-mem.c | 3 - drivers/usb/host/xhci.c | 11 +-- include/linux/usb.h | 12 --- include/linux/usb/ch9.h | 5 +- include/linux/usb/composite.h | 23 ----- include/linux/usb/hcd.h | 2 - include/uapi/linux/usb/ch11.h | 6 +- include/uapi/linux/usb/ch9.h | 5 +- 16 files changed, 62 insertions(+), 248 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 5e5c7bf51174..1584665fe3cb 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -286,8 +286,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev) struct usb_device *udev = interface_to_usbdev(uintf); return (!disable_usb_sg && udev->bus->sg_tablesize > 0 && - (udev->bus->no_sg_constraint || - udev->speed == USB_SPEED_WIRELESS)); + udev->bus->no_sg_constraint); } static int diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 725b8dbcfe5f..b19e38d5fd10 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -1051,9 +1051,6 @@ int usb_get_bos_descriptor(struct usb_device *dev) } switch (cap_type) { - case USB_CAP_TYPE_WIRELESS_USB: - /* Wireless USB cap descriptor is handled by wusb */ - break; case USB_CAP_TYPE_EXT: dev->bos->ext_cap = (struct usb_ext_cap_descriptor *)buffer; diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 2c14a9636056..a247da73f34d 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -424,7 +424,6 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, case USB_SPEED_UNKNOWN: /* usb 1.1 root hub code */ case USB_SPEED_FULL: speed = "12"; break; - case USB_SPEED_WIRELESS: /* Wireless has no real fixed speed */ case USB_SPEED_HIGH: speed = "480"; break; case USB_SPEED_SUPER: diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6af0a31ff147..12b6dfeaf658 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -156,27 +156,6 @@ static const u8 usb3_rh_dev_descriptor[18] = { 0x01 /* __u8 bNumConfigurations; */ }; -/* usb 2.5 (wireless USB 1.0) root hub device descriptor */ -static const u8 usb25_rh_dev_descriptor[18] = { - 0x12, /* __u8 bLength; */ - USB_DT_DEVICE, /* __u8 bDescriptorType; Device */ - 0x50, 0x02, /* __le16 bcdUSB; v2.5 */ - - 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ - 0x00, /* __u8 bDeviceSubClass; */ - 0x00, /* __u8 bDeviceProtocol; [ usb 2.0 no TT ] */ - 0xFF, /* __u8 bMaxPacketSize0; always 0xFF (WUSB Spec 7.4.1). */ - - 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation 0x1d6b */ - 0x02, 0x00, /* __le16 idProduct; device 0x0002 */ - KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ - - 0x03, /* __u8 iManufacturer; */ - 0x02, /* __u8 iProduct; */ - 0x01, /* __u8 iSerialNumber; */ - 0x01 /* __u8 bNumConfigurations; */ -}; - /* usb 2.0 root hub device descriptor */ static const u8 usb2_rh_dev_descriptor[18] = { 0x12, /* __u8 bLength; */ @@ -368,7 +347,7 @@ static const u8 ss_rh_config_descriptor[] = { }; /* authorized_default behaviour: - * -1 is authorized for all devices except wireless (old behaviour) + * -1 is authorized for all devices (leftover from wireless USB) * 0 is unauthorized for all devices * 1 is authorized for all devices * 2 is authorized for internal devices @@ -383,7 +362,7 @@ module_param(authorized_default, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(authorized_default, "Default USB device authorization: 0 is not authorized, 1 is " "authorized, 2 is authorized for internal devices, -1 is " - "authorized except for wireless USB (default, old behaviour)"); + "authorized (default, same as 1)"); /*-------------------------------------------------------------------------*/ /** @@ -578,9 +557,6 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) case HCD_USB3: bufp = usb3_rh_dev_descriptor; break; - case HCD_USB25: - bufp = usb25_rh_dev_descriptor; - break; case HCD_USB2: bufp = usb2_rh_dev_descriptor; break; @@ -602,7 +578,6 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) bufp = ss_rh_config_descriptor; len = sizeof ss_rh_config_descriptor; break; - case HCD_USB25: case HCD_USB2: bufp = hs_rh_config_descriptor; len = sizeof hs_rh_config_descriptor; @@ -2848,18 +2823,14 @@ int usb_add_hcd(struct usb_hcd *hcd, hcd->dev_policy = USB_DEVICE_AUTHORIZE_NONE; break; - case USB_AUTHORIZE_ALL: - hcd->dev_policy = USB_DEVICE_AUTHORIZE_ALL; - break; - case USB_AUTHORIZE_INTERNAL: hcd->dev_policy = USB_DEVICE_AUTHORIZE_INTERNAL; break; + case USB_AUTHORIZE_ALL: case USB_AUTHORIZE_WIRED: default: - hcd->dev_policy = hcd->wireless ? - USB_DEVICE_AUTHORIZE_NONE : USB_DEVICE_AUTHORIZE_ALL; + hcd->dev_policy = USB_DEVICE_AUTHORIZE_ALL; break; } @@ -2903,9 +2874,6 @@ int usb_add_hcd(struct usb_hcd *hcd, case HCD_USB2: rhdev->speed = USB_SPEED_HIGH; break; - case HCD_USB25: - rhdev->speed = USB_SPEED_WIRELESS; - break; case HCD_USB3: rhdev->speed = USB_SPEED_SUPER; break; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 878913f4b4b3..b3c09e4c8492 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2140,22 +2140,6 @@ EXPORT_SYMBOL_GPL(usb_set_device_state); * USB-3.0 buses the address is assigned by the controller hardware * and it usually is not the same as the device number. * - * WUSB devices are simple: they have no hubs behind, so the mapping - * device <-> virtual port number becomes 1:1. Why? to simplify the - * life of the device connection logic in - * drivers/usb/wusbcore/devconnect.c. When we do the initial secret - * handshake we need to assign a temporary address in the unauthorized - * space. For simplicity we use the first virtual port number found to - * be free [drivers/usb/wusbcore/devconnect.c:wusbhc_devconnect_ack()] - * and that becomes it's address [X < 128] or its unauthorized address - * [X | 0x80]. - * - * We add 1 as an offset to the one-based USB-stack port number - * (zero-based wusb virtual port index) for two reasons: (a) dev addr - * 0 is reserved by USB for default address; (b) Linux's USB stack - * uses always #1 for the root hub of the controller. So USB stack's - * port #1, which is wusb virtual-port #0 has address #2. - * * Devices connected under xHCI are not as simple. The host controller * supports virtualization, so the hardware assigns device addresses and * the HCD must setup data structures before issuing a set address @@ -2168,19 +2152,13 @@ static void choose_devnum(struct usb_device *udev) /* be safe when more hub events are proceed in parallel */ mutex_lock(&bus->devnum_next_mutex); - if (udev->wusb) { - devnum = udev->portnum + 1; - BUG_ON(test_bit(devnum, bus->devmap.devicemap)); - } else { - /* Try to allocate the next devnum beginning at - * bus->devnum_next. */ - devnum = find_next_zero_bit(bus->devmap.devicemap, 128, - bus->devnum_next); - if (devnum >= 128) - devnum = find_next_zero_bit(bus->devmap.devicemap, - 128, 1); - bus->devnum_next = (devnum >= 127 ? 1 : devnum + 1); - } + + /* Try to allocate the next devnum beginning at bus->devnum_next. */ + devnum = find_next_zero_bit(bus->devmap.devicemap, 128, + bus->devnum_next); + if (devnum >= 128) + devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1); + bus->devnum_next = (devnum >= 127 ? 1 : devnum + 1); if (devnum < 128) { set_bit(devnum, bus->devmap.devicemap); udev->devnum = devnum; @@ -2198,9 +2176,7 @@ static void release_devnum(struct usb_device *udev) static void update_devnum(struct usb_device *udev, int devnum) { - /* The address for a WUSB device is managed by wusbcore. */ - if (!udev->wusb) - udev->devnum = devnum; + udev->devnum = devnum; if (!udev->devaddr) udev->devaddr = (u8)devnum; } @@ -2693,20 +2669,6 @@ int usb_authorize_device(struct usb_device *usb_dev) goto error_autoresume; } - if (usb_dev->wusb) { - struct usb_device_descriptor *descr; - - descr = usb_get_device_descriptor(usb_dev); - if (IS_ERR(descr)) { - result = PTR_ERR(descr); - dev_err(&usb_dev->dev, "can't re-read device descriptor for " - "authorization: %d\n", result); - goto error_device_descriptor; - } - usb_dev->descriptor = *descr; - kfree(descr); - } - usb_dev->authorized = 1; /* Choose and set the configuration. This registers the interfaces * with the driver core and lets interface drivers bind to them. @@ -2723,7 +2685,6 @@ int usb_authorize_device(struct usb_device *usb_dev) } dev_info(&usb_dev->dev, "authorized to connect\n"); -error_device_descriptor: usb_autosuspend_device(usb_dev); error_autoresume: out_authorized: @@ -2806,17 +2767,6 @@ out: return USB_SSP_GEN_UNKNOWN; } -/* Returns 1 if @hub is a WUSB root hub, 0 otherwise */ -static unsigned hub_is_wusb(struct usb_hub *hub) -{ - struct usb_hcd *hcd; - if (hub->hdev->parent != NULL) /* not a root hub? */ - return 0; - hcd = bus_to_hcd(hub->hdev->bus); - return hcd->wireless; -} - - #ifdef CONFIG_USB_FEW_INIT_RETRIES #define PORT_RESET_TRIES 2 #define SET_ADDRESS_TRIES 1 @@ -2969,9 +2919,7 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, udev->tx_lanes = 1; udev->ssp_rate = USB_SSP_GEN_UNKNOWN; } - if (hub_is_wusb(hub)) - udev->speed = USB_SPEED_WIRELESS; - else if (udev->ssp_rate != USB_SSP_GEN_UNKNOWN) + if (udev->ssp_rate != USB_SSP_GEN_UNKNOWN) udev->speed = USB_SPEED_SUPER_PLUS; else if (hub_is_superspeed(hub->hdev)) udev->speed = USB_SPEED_SUPER; @@ -4880,13 +4828,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, if (initial) { /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... * it's fixed size except for full speed devices. - * For Wireless USB devices, ep0 max packet is always 512 (tho - * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. */ switch (udev->speed) { case USB_SPEED_SUPER_PLUS: case USB_SPEED_SUPER: - case USB_SPEED_WIRELESS: /* fixed at 512 */ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); break; case USB_SPEED_HIGH: /* fixed at 64 */ @@ -4907,10 +4852,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, } } - if (udev->speed == USB_SPEED_WIRELESS) - speed = "variable speed Wireless"; - else - speed = usb_speed_string(udev->speed); + speed = usb_speed_string(udev->speed); /* * The controller driver may be NULL if the controller device @@ -5003,50 +4945,44 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, } } + for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) { + retval = hub_set_address(udev, devnum); + if (retval >= 0) + break; + msleep(200); + } + if (retval < 0) { + if (retval != -ENODEV) + dev_err(&udev->dev, "device not accepting address %d, error %d\n", + devnum, retval); + goto fail; + } + if (udev->speed >= USB_SPEED_SUPER) { + devnum = udev->devnum; + dev_info(&udev->dev, + "%s SuperSpeed%s%s USB device number %d using %s\n", + (udev->config) ? "reset" : "new", + (udev->speed == USB_SPEED_SUPER_PLUS) ? + " Plus" : "", + (udev->ssp_rate == USB_SSP_GEN_2x2) ? + " Gen 2x2" : + (udev->ssp_rate == USB_SSP_GEN_2x1) ? + " Gen 2x1" : + (udev->ssp_rate == USB_SSP_GEN_1x2) ? + " Gen 1x2" : "", + devnum, driver_name); + } + /* - * If device is WUSB, we already assigned an - * unauthorized address in the Connect Ack sequence; - * authorization will assign the final address. + * cope with hardware quirkiness: + * - let SET_ADDRESS settle, some device hardware wants it + * - read ep0 maxpacket even for high and low speed, */ - if (udev->wusb == 0) { - for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) { - retval = hub_set_address(udev, devnum); - if (retval >= 0) - break; - msleep(200); - } - if (retval < 0) { - if (retval != -ENODEV) - dev_err(&udev->dev, "device not accepting address %d, error %d\n", - devnum, retval); - goto fail; - } - if (udev->speed >= USB_SPEED_SUPER) { - devnum = udev->devnum; - dev_info(&udev->dev, - "%s SuperSpeed%s%s USB device number %d using %s\n", - (udev->config) ? "reset" : "new", - (udev->speed == USB_SPEED_SUPER_PLUS) ? - " Plus" : "", - (udev->ssp_rate == USB_SSP_GEN_2x2) ? - " Gen 2x2" : - (udev->ssp_rate == USB_SSP_GEN_2x1) ? - " Gen 2x1" : - (udev->ssp_rate == USB_SSP_GEN_1x2) ? - " Gen 1x2" : "", - devnum, driver_name); - } + msleep(10); - /* cope with hardware quirkiness: - * - let SET_ADDRESS settle, some device hardware wants it - * - read ep0 maxpacket even for high and low speed, - */ - msleep(10); - if (do_new_scheme) - break; - } + if (do_new_scheme) + break; - /* !do_new_scheme || wusb */ maxp0 = get_bMaxPacketSize0(udev, buf, 8, retries == 0); if (maxp0 < 0) { retval = maxp0; @@ -5128,7 +5064,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, usb_detect_quirks(udev); - if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) { + if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) { retval = usb_get_bos_descriptor(udev); if (!retval) { udev->lpm_capable = usb_device_supports_lpm(udev); @@ -5404,7 +5340,6 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, usb_set_device_state(udev, USB_STATE_POWERED); udev->bus_mA = hub->mA_per_port; udev->level = hdev->level + 1; - udev->wusb = hub_is_wusb(hub); /* Devices connected to SuperSpeed hubs are USB 3.0 or later */ if (hub_is_superspeed(hub->hdev)) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 323dc02becbe..5d21718afb05 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -161,9 +161,6 @@ static ssize_t speed_show(struct device *dev, struct device_attribute *attr, case USB_SPEED_HIGH: speed = "480"; break; - case USB_SPEED_WIRELESS: - speed = "480"; - break; case USB_SPEED_SUPER: speed = "5000"; break; diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 9f3c54032556..7576920e2d5a 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -480,8 +480,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) urb->iso_frame_desc[n].status = -EXDEV; urb->iso_frame_desc[n].actual_length = 0; } - } else if (urb->num_sgs && !urb->dev->bus->no_sg_constraint && - dev->speed != USB_SPEED_WIRELESS) { + } else if (urb->num_sgs && !urb->dev->bus->no_sg_constraint) { struct scatterlist *sg; int i; @@ -540,17 +539,9 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) case USB_ENDPOINT_XFER_ISOC: case USB_ENDPOINT_XFER_INT: /* too small? */ - switch (dev->speed) { - case USB_SPEED_WIRELESS: - if ((urb->interval < 6) - && (xfertype == USB_ENDPOINT_XFER_INT)) - return -EINVAL; - fallthrough; - default: - if (urb->interval <= 0) - return -EINVAL; - break; - } + if (urb->interval <= 0) + return -EINVAL; + /* too big? */ switch (dev->speed) { case USB_SPEED_SUPER_PLUS: @@ -560,10 +551,6 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) return -EINVAL; max = 1 << 15; break; - case USB_SPEED_WIRELESS: - if (urb->interval > 16) - return -EINVAL; - break; case USB_SPEED_HIGH: /* units are microframes */ /* NOTE usb handles 2^15 */ if (urb->interval > (1024 * 8)) @@ -587,10 +574,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) default: return -EINVAL; } - if (dev->speed != USB_SPEED_WIRELESS) { - /* Round down to a power of 2, no more than max */ - urb->interval = min(max, 1 << ilog2(urb->interval)); - } + /* Round down to a power of 2, no more than max */ + urb->interval = min(max, 1 << ilog2(urb->interval)); } return usb_hcd_submit_urb(urb, mem_flags); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index bba87e5b7f8a..0945ff8df500 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -602,14 +602,6 @@ struct device_type usb_device_type = { #endif }; - -/* Returns 1 if @usb_bus is WUSB, 0 otherwise */ -static unsigned usb_bus_is_wusb(struct usb_bus *bus) -{ - struct usb_hcd *hcd = bus_to_hcd(bus); - return hcd->wireless; -} - static bool usb_dev_authorized(struct usb_device *dev, struct usb_hcd *hcd) { struct usb_hub *hub; @@ -749,9 +741,6 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, #endif dev->authorized = usb_dev_authorized(dev, usb_hcd); - if (!root_hub) - dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0; - return dev; } EXPORT_SYMBOL_GPL(usb_alloc_dev); diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 19a402123de0..8714ab5bf04d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1108,9 +1108,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_LS); max_packets = MAX_PACKET(8); break; - case USB_SPEED_WIRELESS: - xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); - return -EINVAL; default: /* Speed was set earlier, this shouldn't happen. */ return -EINVAL; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index fae994f679d4..e1b1b64a0723 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2194,7 +2194,6 @@ static unsigned int xhci_get_block_size(struct usb_device *udev) case USB_SPEED_SUPER_PLUS: return SS_BLOCK; case USB_SPEED_UNKNOWN: - case USB_SPEED_WIRELESS: default: /* Should never happen */ return 1; @@ -2555,10 +2554,7 @@ static void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci, case USB_SPEED_HIGH: interval_bw->overhead[HS_OVERHEAD_TYPE] -= 1; break; - case USB_SPEED_SUPER: - case USB_SPEED_SUPER_PLUS: - case USB_SPEED_UNKNOWN: - case USB_SPEED_WIRELESS: + default: /* Should never happen because only LS/FS/HS endpoints will get * added to the endpoint list. */ @@ -2615,10 +2611,7 @@ static void xhci_add_ep_to_interval_table(struct xhci_hcd *xhci, case USB_SPEED_HIGH: interval_bw->overhead[HS_OVERHEAD_TYPE] += 1; break; - case USB_SPEED_SUPER: - case USB_SPEED_SUPER_PLUS: - case USB_SPEED_UNKNOWN: - case USB_SPEED_WIRELESS: + default: /* Should never happen because only LS/FS/HS endpoints will get * added to the endpoint list. */ diff --git a/include/linux/usb.h b/include/linux/usb.h index 25f8e62a30ec..a21074861f91 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -25,7 +25,6 @@ struct usb_device; struct usb_driver; -struct wusb_dev; /*-------------------------------------------------------------------------*/ @@ -425,7 +424,6 @@ struct usb_host_config { struct usb_host_bos { struct usb_bos_descriptor *desc; - /* wireless cap descriptor is handled by wusb */ struct usb_ext_cap_descriptor *ext_cap; struct usb_ss_cap_descriptor *ss_cap; struct usb_ssp_cap_descriptor *ssp_cap; @@ -612,7 +610,6 @@ struct usb3_lpm_parameters { * WUSB devices are not, until we authorize them from user space. * FIXME -- complete doc * @authenticated: Crypto authentication passed - * @wusb: device is Wireless USB * @lpm_capable: device supports LPM * @lpm_devinit_allow: Allow USB3 device initiated LPM, exit latency is in range * @usb2_hw_lpm_capable: device can perform USB2 hardware LPM @@ -634,8 +631,6 @@ struct usb3_lpm_parameters { * @do_remote_wakeup: remote wakeup should be enabled * @reset_resume: needs reset instead of resume * @port_is_suspended: the upstream port is suspended (L2 or U3) - * @wusb_dev: if this is a Wireless USB device, link to the WUSB - * specific data for the device. * @slot_id: Slot ID assigned by xHCI * @removable: Device can be physically removed from this port * @l1_params: best effor service latency for USB2 L1 LPM state, and L1 timeout. @@ -696,7 +691,6 @@ struct usb_device { unsigned have_langid:1; unsigned authorized:1; unsigned authenticated:1; - unsigned wusb:1; unsigned lpm_capable:1; unsigned lpm_devinit_allow:1; unsigned usb2_hw_lpm_capable:1; @@ -727,7 +721,6 @@ struct usb_device { unsigned reset_resume:1; unsigned port_is_suspended:1; - struct wusb_dev *wusb_dev; int slot_id; struct usb2_lpm_parameters l1_params; struct usb3_lpm_parameters u1_params; @@ -1742,11 +1735,6 @@ static inline void usb_fill_bulk_urb(struct urb *urb, * encoding of the endpoint interval, and express polling intervals in * microframes (eight per millisecond) rather than in frames (one per * millisecond). - * - * Wireless USB also uses the logarithmic encoding, but specifies it in units of - * 128us instead of 125us. For Wireless USB devices, the interval is passed - * through to the host controller, rather than being translated into microframe - * units. */ static inline void usb_fill_int_urb(struct urb *urb, struct usb_device *dev, diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index 969e7dba6358..c93b410b314a 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -3,7 +3,7 @@ * This file holds USB constants and structures that are needed for * USB device APIs. These are used by the USB device model, which is * defined in chapter 9 of the USB 2.0 specification and in the - * Wireless USB 1.0 (spread around). Linux has several APIs in C that + * Wireless USB 1.0 spec (now defunct). Linux has several APIs in C that * need these: * * - the host side Linux-USB kernel driver API; @@ -14,9 +14,6 @@ * act either as a USB host or as a USB device. That means the host and * device side APIs benefit from working well together. * - * There's also "Wireless USB", using low power short range radios for - * peripheral interconnection but otherwise building on the USB framework. - * * Note all descriptors are declared '__attribute__((packed))' so that: * * [a] they never get padded, either internally (USB spec writers diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 07531c4f4350..6014340ba980 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -450,29 +450,6 @@ static inline struct usb_composite_driver *to_cdriver( * * One of these devices is allocated and initialized before the * associated device driver's bind() is called. - * - * OPEN ISSUE: it appears that some WUSB devices will need to be - * built by combining a normal (wired) gadget with a wireless one. - * This revision of the gadget framework should probably try to make - * sure doing that won't hurt too much. - * - * One notion for how to handle Wireless USB devices involves: - * - * (a) a second gadget here, discovery mechanism TBD, but likely - * needing separate "register/unregister WUSB gadget" calls; - * (b) updates to usb_gadget to include flags "is it wireless", - * "is it wired", plus (presumably in a wrapper structure) - * bandgroup and PHY info; - * (c) presumably a wireless_ep wrapping a usb_ep, and reporting - * wireless-specific parameters like maxburst and maxsequence; - * (d) configurations that are specific to wireless links; - * (e) function drivers that understand wireless configs and will - * support wireless for (additional) function instances; - * (f) a function to support association setup (like CBAF), not - * necessarily requiring a wireless adapter; - * (g) composite device setup that can create one or more wireless - * configs, including appropriate association setup support; - * (h) more, TBD. */ struct usb_composite_dev { struct usb_gadget *gadget; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 4e9623e8492b..61d4f0b793dc 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -154,7 +154,6 @@ struct usb_hcd { /* The next flag is a stopgap, to be removed when all the HCDs * support the new root-hub polling mechanism. */ unsigned uses_new_polling:1; - unsigned wireless:1; /* Wireless USB HCD */ unsigned has_tt:1; /* Integrated TT in root hub */ unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */ unsigned can_do_streams:1; /* HC supports streams */ @@ -249,7 +248,6 @@ struct hc_driver { #define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ #define HCD_USB11 0x0010 /* USB 1.1 */ #define HCD_USB2 0x0020 /* USB 2.0 */ -#define HCD_USB25 0x0030 /* Wireless USB 1.0 (USB 2.5)*/ #define HCD_USB3 0x0040 /* USB 3.0 */ #define HCD_USB31 0x0050 /* USB 3.1 */ #define HCD_USB32 0x0060 /* USB 3.2 */ diff --git a/include/uapi/linux/usb/ch11.h b/include/uapi/linux/usb/ch11.h index fb0cd24c392c..ce4c83f2e66a 100644 --- a/include/uapi/linux/usb/ch11.h +++ b/include/uapi/linux/usb/ch11.h @@ -15,10 +15,8 @@ /* This is arbitrary. * From USB 2.0 spec Table 11-13, offset 7, a hub can * have up to 255 ports. The most yet reported is 10. - * - * Current Wireless USB host hardware (Intel i1480 for example) allows - * up to 22 devices to connect. Upcoming hardware might raise that - * limit. Because the arrays need to add a bit for hub status data, we + * Upcoming hardware might raise that limit. + * Because the arrays need to add a bit for hub status data, we * use 31, so plus one evens out to four bytes. */ #define USB_MAXCHILDREN 31 diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h index 62d318377379..8a147abfc680 100644 --- a/include/uapi/linux/usb/ch9.h +++ b/include/uapi/linux/usb/ch9.h @@ -3,7 +3,7 @@ * This file holds USB constants and structures that are needed for * USB device APIs. These are used by the USB device model, which is * defined in chapter 9 of the USB 2.0 specification and in the - * Wireless USB 1.0 (spread around). Linux has several APIs in C that + * Wireless USB 1.0 spec (now defunct). Linux has several APIs in C that * need these: * * - the master/host side Linux-USB kernel driver API; @@ -14,9 +14,6 @@ * act either as a USB master/host or as a USB slave/device. That means * the master and slave side APIs benefit from working well together. * - * There's also "Wireless USB", using low power short range radios for - * peripheral interconnection but otherwise building on the USB framework. - * * Note all descriptors are declared '__attribute__((packed))' so that: * * [a] they never get padded, either internally (USB spec writers -- cgit v1.2.3 From 5198c0eeb8ff98ee673a2420ba96d93c477c6ef4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 11 Aug 2023 11:47:15 -0400 Subject: USB: core: Fix unused variable warning in usb_alloc_dev() The kernel test robot reported that a recent commit caused a "variable set but not used" warning. As a result of that commit, the variable no longer serves any purpose; it should be removed. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202308092350.HR4PVHUt-lkp@intel.com/ Signed-off-by: Alan Stern Fixes: 1e4c574225cc ("USB: Remove remnants of Wireless USB and UWB") Link: https://lore.kernel.org/r/7223cc66-f006-42ae-9f30-a6c546bf97a7@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/usb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0945ff8df500..2a938cf47ccd 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -645,7 +645,6 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, { struct usb_device *dev; struct usb_hcd *usb_hcd = bus_to_hcd(bus); - unsigned root_hub = 0; unsigned raw_port = port1; dev = kzalloc(sizeof(*dev), GFP_KERNEL); @@ -695,7 +694,6 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, dev->dev.parent = bus->controller; device_set_of_node_from_dev(&dev->dev, bus->sysdev); dev_set_name(&dev->dev, "usb%d", bus->busnum); - root_hub = 1; } else { /* match any labeling on the hubs; it's one-based */ if (parent->devpath[0] == '0') { -- cgit v1.2.3 From 59cf445754566984fd55af19ba7146c76e6627bc Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 11 Aug 2023 13:38:46 -0400 Subject: USB: core: Fix oversight in SuperSpeed initialization Commit 85d07c556216 ("USB: core: Unite old scheme and new scheme descriptor reads") altered the way USB devices are enumerated following detection, and in the process it messed up the initialization of SuperSpeed (or faster) devices: [ 31.650759] usb 2-1: new SuperSpeed Plus Gen 2x1 USB device number 2 using xhci_hcd [ 31.663107] usb 2-1: device descriptor read/8, error -71 [ 31.952697] usb 2-1: new SuperSpeed Plus Gen 2x1 USB device number 3 using xhci_hcd [ 31.965122] usb 2-1: device descriptor read/8, error -71 [ 32.080991] usb usb2-port1: attempt power cycle ... The problem was caused by the commit forgetting that in SuperSpeed or faster devices, the device descriptor uses a logarithmic encoding of the bMaxPacketSize0 value. (For some reason I thought the 255 case in the switch statement was meant for these devices, but it isn't -- it was meant for Wireless USB and is no longer needed.) We can fix the oversight by testing for buf->bMaxPacketSize0 = 9 (meaning 512, the actual maxpacket size for ep0 on all SuperSpeed devices) and straightening out the logic that checks and adjusts our initial guesses of the maxpacket value. Reported-and-tested-by: Thinh Nguyen Closes: https://lore.kernel.org/linux-usb/20230810002257.nadxmfmrobkaxgnz@synopsys.com/ Signed-off-by: Alan Stern Fixes: 85d07c556216 ("USB: core: Unite old scheme and new scheme descriptor reads") Link: https://lore.kernel.org/r/8809e6c5-59d5-4d2d-ac8f-6d106658ad73@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b3c09e4c8492..3c54b218301c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4728,7 +4728,7 @@ static int get_bMaxPacketSize0(struct usb_device *udev, buf, size, initial_descriptor_timeout); switch (buf->bMaxPacketSize0) { - case 8: case 16: case 32: case 64: case 255: + case 8: case 16: case 32: case 64: case 9: if (buf->bDescriptorType == USB_DT_DEVICE) { rc = buf->bMaxPacketSize0; break; @@ -5015,23 +5015,35 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, if (retval) goto fail; - if (maxp0 == 0xff || udev->speed >= USB_SPEED_SUPER) - i = 512; - else - i = maxp0; - if (usb_endpoint_maxp(&udev->ep0.desc) != i) { - if (udev->speed == USB_SPEED_LOW || - !(i == 8 || i == 16 || i == 32 || i == 64)) { - dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); - retval = -EMSGSIZE; - goto fail; - } + /* + * Check the ep0 maxpacket guess and correct it if necessary. + * maxp0 is the value stored in the device descriptor; + * i is the value it encodes (logarithmic for SuperSpeed or greater). + */ + i = maxp0; + if (udev->speed >= USB_SPEED_SUPER) { + if (maxp0 <= 16) + i = 1 << maxp0; + else + i = 0; /* Invalid */ + } + if (usb_endpoint_maxp(&udev->ep0.desc) == i) { + ; /* Initial ep0 maxpacket guess is right */ + } else if ((udev->speed == USB_SPEED_FULL || + udev->speed == USB_SPEED_HIGH) && + (i == 8 || i == 16 || i == 32 || i == 64)) { + /* Initial guess is wrong; use the descriptor's value */ if (udev->speed == USB_SPEED_FULL) dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); else dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i); udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i); usb_ep0_reinit(udev); + } else { + /* Initial guess is wrong and descriptor's value is invalid */ + dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", maxp0); + retval = -EMSGSIZE; + goto fail; } descr = usb_get_device_descriptor(udev); -- cgit v1.2.3 From 20deab8bfc936063385fdce19287f1f630cb2f4b Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Tue, 15 Aug 2023 15:46:48 +0800 Subject: usb: core: Use module_led_trigger macro to simplify the code Use the module_led_trigger macro to simplify the code, which is the same as declaring with module_init() and module_exit(). Signed-off-by: Li Zetao Link: https://lore.kernel.org/r/20230815074648.1015175-1-lizetao1@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/ledtrig-usbport.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers/usb/core') diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c index ba371a24ff78..85c999f71ad7 100644 --- a/drivers/usb/core/ledtrig-usbport.c +++ b/drivers/usb/core/ledtrig-usbport.c @@ -350,18 +350,7 @@ static struct led_trigger usbport_led_trigger = { .deactivate = usbport_trig_deactivate, }; -static int __init usbport_trig_init(void) -{ - return led_trigger_register(&usbport_led_trigger); -} - -static void __exit usbport_trig_exit(void) -{ - led_trigger_unregister(&usbport_led_trigger); -} - -module_init(usbport_trig_init); -module_exit(usbport_trig_exit); +module_led_trigger(usbport_led_trigger); MODULE_AUTHOR("Rafał Miłecki "); MODULE_DESCRIPTION("USB port trigger"); -- cgit v1.2.3