Skip to content

Commit 0942d59

Browse files
hadessgregkh
authored andcommitted
usbcore: Check both id_table and match() when both available
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. 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> Tested-by: Bastien Nocera <hadess@hadess.net> Signed-off-by: Bastien Nocera <hadess@hadess.net> Signed-off-by: M. Vefa Bicakci <m.v.b@runbox.com> Tested-by: Pan (Pany) YUAN <pany@fedoraproject.org> Link: https://lore.kernel.org/r/20201022135521.375211-2-m.v.b@runbox.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 32d174d commit 0942d59

3 files changed

Lines changed: 24 additions & 12 deletions

File tree

drivers/usb/core/driver.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,22 @@ const struct usb_device_id *usb_device_match_id(struct usb_device *udev,
839839
return NULL;
840840
}
841841

842+
bool usb_driver_applicable(struct usb_device *udev,
843+
struct usb_device_driver *udrv)
844+
{
845+
if (udrv->id_table && udrv->match)
846+
return usb_device_match_id(udev, udrv->id_table) != NULL &&
847+
udrv->match(udev);
848+
849+
if (udrv->id_table)
850+
return usb_device_match_id(udev, udrv->id_table) != NULL;
851+
852+
if (udrv->match)
853+
return udrv->match(udev);
854+
855+
return false;
856+
}
857+
842858
static int usb_device_match(struct device *dev, struct device_driver *drv)
843859
{
844860
/* devices and interfaces are handled separately */
@@ -853,17 +869,14 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
853869
udev = to_usb_device(dev);
854870
udrv = to_usb_device_driver(drv);
855871

856-
if (udrv->id_table)
857-
return usb_device_match_id(udev, udrv->id_table) != NULL;
858-
859-
if (udrv->match)
860-
return udrv->match(udev);
861-
862872
/* If the device driver under consideration does not have a
863873
* id_table or a match function, then let the driver's probe
864874
* function decide.
865875
*/
866-
return 1;
876+
if (!udrv->id_table && !udrv->match)
877+
return 1;
878+
879+
return usb_driver_applicable(udev, udrv);
867880

868881
} else if (is_usb_interface(dev)) {
869882
struct usb_interface *intf;
@@ -941,8 +954,7 @@ static int __usb_bus_reprobe_drivers(struct device *dev, void *data)
941954
return 0;
942955

943956
udev = to_usb_device(dev);
944-
if (usb_device_match_id(udev, new_udriver->id_table) == NULL &&
945-
(!new_udriver->match || new_udriver->match(udev) == 0))
957+
if (!usb_driver_applicable(udev, new_udriver))
946958
return 0;
947959

948960
ret = device_reprobe(dev);

drivers/usb/core/generic.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,7 @@ static int __check_for_non_generic_match(struct device_driver *drv, void *data)
205205
udrv = to_usb_device_driver(drv);
206206
if (udrv == &usb_generic_driver)
207207
return 0;
208-
if (usb_device_match_id(udev, udrv->id_table) != NULL)
209-
return 1;
210-
return (udrv->match && udrv->match(udev));
208+
return usb_driver_applicable(udev, udrv);
211209
}
212210

213211
static bool usb_generic_driver_match(struct usb_device *udev)

drivers/usb/core/usb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ extern int usb_match_device(struct usb_device *dev,
7474
const struct usb_device_id *id);
7575
extern const struct usb_device_id *usb_device_match_id(struct usb_device *udev,
7676
const struct usb_device_id *id);
77+
extern bool usb_driver_applicable(struct usb_device *udev,
78+
struct usb_device_driver *udrv);
7779
extern void usb_forced_unbind_intf(struct usb_interface *intf);
7880
extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev);
7981

0 commit comments

Comments
 (0)