patch "usbcore: Check both id_table and match() when both available" added to usb-linus
Subsystems (2)
This is a note to let you know that I've just added the patch titled
usbcore: Check both id_table and match() when both available
to my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From 0942d59b0af46511d59dbf5bd69ec4a64d1a854c Mon Sep 17 00:00:00 2001
From: Bastien Nocera <[email protected]>
Date: Thu, 22 Oct 2020 09:55:20 -0400
Subject: usbcore: Check both id_table and match() when both available
From: Bastien Nocera <[email protected]>
When a USB device driver has both an id_table and a match() function, make sure to check both to find a match, first matching the id_table, then checking the match() function.
This makes it possible to have module autoloading done through the id_table when devices are plugged in, before checking for further device eligibility in the match() function.
--- drivers/usb/core/driver.c | 30 +++++++++++++++++++++--------- drivers/usb/core/generic.c | 4 +--- drivers/usb/core/usb.h | 2 ++ 3 files changed, 24 insertions(+), 12 deletions(-)
drivers/usb/core/driver.c +21 -9
@@ -839,6 +839,22 @@ const struct usb_device_id *usb_device_match_id(struct usb_device *udev,return NULL ; } +bool usb_driver_applicable (struct usb_device *udev, +struct usb_device_driver *udrv) +{ +if (udrv->id_table && udrv->match) +return usb_device_match_id (udev, udrv->id_table) !=NULL && + udrv->match (udev); + +if (udrv->id_table) +return usb_device_match_id (udev, udrv->id_table) !=NULL ; + +if (udrv->match) +return udrv->match (udev); + +return false; +} +static int usb_device_match (struct device *dev,struct device_driver *drv) {/* devices and interfaces are handled separately */
@@ -853,17 +869,14 @@ static int usb_device_match(struct device *dev, struct device_driver *drv) udev =to_usb_device (dev); udrv =to_usb_device_driver (drv); -if (udrv->id_table) -return usb_device_match_id (udev, udrv->id_table) !=NULL ; - -if (udrv->match) -return udrv->match (udev); -/* If the device driver under consideration does not have a * id_table or a match function, then let the driver's probe * function decide. */ -return 1 ; +if (!udrv->id_table && !udrv->match) +return 1 ; + +return usb_driver_applicable (udev, udrv); }else if (is_usb_interface (dev)) {struct usb_interface *intf;
@@ -941,8 +954,7 @@ static int __usb_bus_reprobe_drivers(struct device *dev, void *data)return 0 ; udev =to_usb_device (dev); -if (usb_device_match_id (udev, new_udriver->id_table) ==NULL && - (!new_udriver->match || new_udriver->match (udev) ==0 )) +if (!usb_driver_applicable (udev, new_udriver))return 0 ; ret =device_reprobe (dev);
drivers/usb/core/generic.c +1 -3
@@ -205,9 +205,7 @@ static int __check_for_non_generic_match(struct device_driver *drv, void *data) udrv =to_usb_device_driver (drv);if (udrv == &usb_generic_driver)return 0 ; -if (usb_device_match_id (udev, udrv->id_table) !=NULL ) -return 1 ; -return (udrv->match && udrv->match (udev)); +return usb_driver_applicable (udev, udrv); }static bool usb_generic_driver_match (struct usb_device *udev)
drivers/usb/core/usb.h +2 -0
@@ -74,6 +74,8 @@ extern int usb_match_device(struct usb_device *dev, const struct usb_device_id *id);extern const struct usb_device_id *usb_device_match_id (struct usb_device *udev,const struct usb_device_id *id); +extern bool usb_driver_applicable (struct usb_device *udev, +struct usb_device_driver *udrv);extern void usb_forced_unbind_intf (struct usb_interface *intf);extern void usb_unbind_and_rebind_marked_interfaces (struct usb_device *udev);
Signature · 1 line
2.29.1