diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f63004417058..7f33fe5ba03b 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -228,14 +228,16 @@ static void usb_free_dynids(struct usb_driver *usb_drv) } static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf, - const struct usb_driver *drv) + const struct usb_driver *drv, + struct usb_device_id *id_copy) { struct usb_dynid *dynid; guard(mutex)(&usb_dynids_lock); list_for_each_entry(dynid, &drv->dynids.list, node) { if (usb_match_one_id(intf, &dynid->id)) { - return &dynid->id; + *id_copy = dynid->id; + return id_copy; } } return NULL; @@ -321,6 +323,7 @@ static int usb_probe_interface(struct device *dev) struct usb_interface *intf = to_usb_interface(dev); struct usb_device *udev = interface_to_usbdev(intf); const struct usb_device_id *id; + struct usb_device_id id_copy; int error = -ENODEV; int lpm_disable_error = -ENODEV; @@ -340,7 +343,7 @@ static int usb_probe_interface(struct device *dev) return error; } - id = usb_match_dynamic_id(intf, driver); + id = usb_match_dynamic_id(intf, driver, &id_copy); if (!id) id = usb_match_id(intf, driver->id_table); if (!id) @@ -892,6 +895,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv) struct usb_interface *intf; const struct usb_driver *usb_drv; const struct usb_device_id *id; + struct usb_device_id id_copy; /* device drivers never match interfaces */ if (is_usb_device_driver(drv)) @@ -904,7 +908,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv) if (id) return 1; - id = usb_match_dynamic_id(intf, usb_drv); + id = usb_match_dynamic_id(intf, usb_drv, &id_copy); if (id) return 1; } diff --git a/include/linux/usb.h b/include/linux/usb.h index 25a203ac7a7e..83ff8e2c391d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1185,7 +1185,8 @@ extern ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf); * interface. It may also use usb_set_interface() to specify the * appropriate altsetting. If unwilling to manage the interface, * return -ENODEV, if genuine IO errors occurred, an appropriate - * negative errno value. + * negative errno value. The usb_device_id parameter is only valid during + * probe. * @disconnect: Called when the interface is no longer accessible, usually * because its device has been (or is being) disconnected or the * driver module is being unloaded.