From cdcf46014f5ca1349325c51ae3a49d2a941d5f27 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Tue, 20 Feb 2024 17:19:50 +0100 Subject: Revert "USB: core: Change usb_get_device_descriptor() API" This reverts commit eda9a296658203b1cc07d777c19c8c9eac6d0d17. Downstream NXP and stable have deviated to far, do not pull this in. Signed-off-by: Max Krummenacher --- 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, 43 insertions(+), 44 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8cbabc39f818..6c5934dbe9b3 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -983,7 +983,6 @@ 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; @@ -995,16 +994,13 @@ static int register_root_hub(struct usb_hcd *hcd) mutex_lock(&usb_bus_idr_lock); usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); - descr = usb_get_device_descriptor(usb_dev); - if (IS_ERR(descr)) { - retval = PTR_ERR(descr); + retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); + if (retval != sizeof usb_dev->descriptor) { 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; + return (retval < 0) ? retval : -EMSGSIZE; } - 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 36f625aaf348..fa8683c448c9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2649,17 +2649,12 @@ int usb_authorize_device(struct usb_device *usb_dev) } if (usb_dev->wusb) { - struct usb_device_descriptor *descr; - - descr = usb_get_device_descriptor(usb_dev); - if (IS_ERR(descr)) { - result = PTR_ERR(descr); + result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor)); + if (result < 0) { 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; @@ -4757,7 +4752,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, *descr; + struct usb_device_descriptor *buf; buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); if (!buf) @@ -4994,16 +4989,15 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, usb_ep0_reinit(udev); } - descr = usb_get_device_descriptor(udev); - if (IS_ERR(descr)) { - retval = PTR_ERR(descr); + retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); + if (retval < (signed)sizeof(udev->descriptor)) { 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 @@ -5120,7 +5114,7 @@ hub_power_remaining(struct usb_hub *hub) static int descriptors_changed(struct usb_device *udev, - struct usb_device_descriptor *new_device_descriptor, + struct usb_device_descriptor *old_device_descriptor, struct usb_host_bos *old_bos) { int changed = 0; @@ -5131,8 +5125,8 @@ static int descriptors_changed(struct usb_device *udev, int length; char *buf; - if (memcmp(&udev->descriptor, new_device_descriptor, - sizeof(*new_device_descriptor)) != 0) + if (memcmp(&udev->descriptor, old_device_descriptor, + sizeof(*old_device_descriptor)) != 0) return 1; if ((old_bos && !udev->bos) || (!old_bos && udev->bos)) @@ -5452,8 +5446,9 @@ 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 *descr; + struct usb_device_descriptor descriptor; int status = -ENODEV; + int retval; dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n", portstatus, portchange, portspeed(hub, portstatus)); @@ -5480,20 +5475,23 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, * changed device descriptors before resuscitating the * device. */ - descr = usb_get_device_descriptor(udev); - if (IS_ERR(descr)) { + descriptor = udev->descriptor; + retval = usb_get_device_descriptor(udev, + sizeof(udev->descriptor)); + if (retval < 0) { dev_dbg(&udev->dev, - "can't read device descriptor %ld\n", - PTR_ERR(descr)); + "can't read device descriptor %d\n", + retval); } else { - if (descriptors_changed(udev, descr, + if (descriptors_changed(udev, &descriptor, 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 1673e5d08926..4d59d927ae3e 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1039,35 +1039,40 @@ char *usb_cache_string(struct usb_device *udev, int index) } /* - * usb_get_device_descriptor - read the device descriptor - * @udev: the device whose device descriptor should be read + * 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 * * 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. * - * Returns: a pointer to a dynamically allocated usb_device_descriptor - * structure (which the caller must deallocate), or an ERR_PTR value. + * 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. */ -struct usb_device_descriptor *usb_get_device_descriptor(struct usb_device *udev) +int usb_get_device_descriptor(struct usb_device *dev, unsigned int size) { struct usb_device_descriptor *desc; int ret; + if (size > sizeof(*desc)) + return -EINVAL; desc = kmalloc(sizeof(*desc), GFP_NOIO); if (!desc) - return ERR_PTR(-ENOMEM); - - ret = usb_get_descriptor(udev, USB_DT_DEVICE, 0, desc, sizeof(*desc)); - if (ret == sizeof(*desc)) - return desc; + return -ENOMEM; + ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size); if (ret >= 0) - ret = -EMSGSIZE; + memcpy(&dev->descriptor, desc, size); kfree(desc); - return ERR_PTR(ret); + return ret; } /* diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 3bb2e1db42b5..82538daac8b8 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -42,8 +42,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 struct usb_device_descriptor *usb_get_device_descriptor( - struct usb_device *udev); +extern int usb_get_device_descriptor(struct usb_device *dev, + unsigned int size); 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