From: Bastien Nocera hadess@hadess.net
From: Bastien Nocera hadess@hadess.net
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.
Signed-off-by: Bastien Nocera hadess@hadess.net Cc: stable@vger.kernel.org # 5.8 Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Alan Stern stern@rowland.harvard.edu Co-developed-by: M. Vefa Bicakci m.v.b@runbox.com Signed-off-by: M. Vefa Bicakci m.v.b@runbox.com --- 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(-)
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 98b7449c11f3..4dfa44d6cc3c 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -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); diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 22c887f5c497..26f9fb9f67ca 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -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) diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index c893f54a3420..82538daac8b8 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -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);
On 22/10/2020 09.55, M. Vefa Bicakci wrote:
From: Bastien Nocera hadess@hadess.net
From: Bastien Nocera hadess@hadess.net
Ah, sorry for this mistake. This is the first time I sent patches authored by another person, with git-send-email. I should have tested with my own e-mail address initially.
I will fix this mistake with the next patch set version.
Thank you,
Vefa
On Thu, 2020-10-22 at 09:55 -0400, M. Vefa Bicakci wrote:
From: Bastien Nocera hadess@hadess.net
From: Bastien Nocera hadess@hadess.net
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.
Signed-off-by: Bastien Nocera hadess@hadess.net Cc: stable@vger.kernel.org # 5.8 Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Alan Stern stern@rowland.harvard.edu Co-developed-by: M. Vefa Bicakci m.v.b@runbox.com Signed-off-by: M. Vefa Bicakci m.v.b@runbox.com
You can also add my: Tested-by: Bastien Nocera hadess@hadess.net
On Tue, Oct 27, 2020 at 6:25 PM Bastien Nocera hadess@hadess.net wrote:
On Thu, 2020-10-22 at 09:55 -0400, M. Vefa Bicakci wrote:
From: Bastien Nocera hadess@hadess.net
From: Bastien Nocera hadess@hadess.net
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.
Signed-off-by: Bastien Nocera hadess@hadess.net Cc: stable@vger.kernel.org # 5.8 Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Alan Stern stern@rowland.harvard.edu Co-developed-by: M. Vefa Bicakci m.v.b@runbox.com Signed-off-by: M. Vefa Bicakci m.v.b@runbox.com
You can also add my: Tested-by: Bastien Nocera hadess@hadess.net
This patch works well for me. Tested-by: Pan (Pany) YUAN pany@fedoraproject.org
linux-stable-mirror@lists.linaro.org