mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
USB: core: add endpoint-blacklist quirk
commit73f8bda9b5upstream Add a new device quirk that can be used to blacklist endpoints. Since commit3e4f8e21c4("USB: core: fix check for duplicate endpoints") USB core ignores any duplicate endpoints found during descriptor parsing. In order to handle devices where the first interfaces with duplicate endpoints are the ones that should have their endpoints ignored, we need to add a blacklist. Tested-by: edes <edes@gmx.net> Cc: stable <stable@vger.kernel.org> Signed-off-by: Johan Hovold <johan@kernel.org> Link: https://lore.kernel.org/r/20200203153830.26394-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> [sudip: adjust context] Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
f22f3c3150
commit
c795e16801
@@ -251,6 +251,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
|
||||
struct usb_host_interface *ifp, int num_ep,
|
||||
unsigned char *buffer, int size)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(ddev);
|
||||
unsigned char *buffer0 = buffer;
|
||||
struct usb_endpoint_descriptor *d;
|
||||
struct usb_host_endpoint *endpoint;
|
||||
@@ -292,6 +293,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
|
||||
goto skip_to_next_endpoint_or_interface_descriptor;
|
||||
}
|
||||
|
||||
/* Ignore blacklisted endpoints */
|
||||
if (udev->quirks & USB_QUIRK_ENDPOINT_BLACKLIST) {
|
||||
if (usb_endpoint_is_blacklisted(udev, ifp, d)) {
|
||||
dev_warn(ddev, "config %d interface %d altsetting %d has a blacklisted endpoint with address 0x%X, skipping\n",
|
||||
cfgno, inum, asnum,
|
||||
d->bEndpointAddress);
|
||||
goto skip_to_next_endpoint_or_interface_descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
|
||||
++ifp->desc.bNumEndpoints;
|
||||
|
||||
|
||||
@@ -344,6 +344,38 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
|
||||
{ } /* terminating entry must be last */
|
||||
};
|
||||
|
||||
/*
|
||||
* Entries for blacklisted endpoints that should be ignored when parsing
|
||||
* configuration descriptors.
|
||||
*
|
||||
* Matched for devices with USB_QUIRK_ENDPOINT_BLACKLIST.
|
||||
*/
|
||||
static const struct usb_device_id usb_endpoint_blacklist[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
bool usb_endpoint_is_blacklisted(struct usb_device *udev,
|
||||
struct usb_host_interface *intf,
|
||||
struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
const struct usb_device_id *id;
|
||||
unsigned int address;
|
||||
|
||||
for (id = usb_endpoint_blacklist; id->match_flags; ++id) {
|
||||
if (!usb_match_device(udev, id))
|
||||
continue;
|
||||
|
||||
if (!usb_match_one_id_intf(udev, intf, id))
|
||||
continue;
|
||||
|
||||
address = id->driver_info;
|
||||
if (address == epd->bEndpointAddress)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool usb_match_any_interface(struct usb_device *udev,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
|
||||
@@ -31,6 +31,9 @@ extern void usb_deauthorize_interface(struct usb_interface *);
|
||||
extern void usb_authorize_interface(struct usb_interface *);
|
||||
extern void usb_detect_quirks(struct usb_device *udev);
|
||||
extern void usb_detect_interface_quirks(struct usb_device *udev);
|
||||
extern bool usb_endpoint_is_blacklisted(struct usb_device *udev,
|
||||
struct usb_host_interface *intf,
|
||||
struct usb_endpoint_descriptor *epd);
|
||||
extern int usb_remove_device(struct usb_device *udev);
|
||||
|
||||
extern int usb_get_device_descriptor(struct usb_device *dev,
|
||||
|
||||
@@ -59,4 +59,7 @@
|
||||
/* Device needs a pause after every control message. */
|
||||
#define USB_QUIRK_DELAY_CTRL_MSG BIT(13)
|
||||
|
||||
/* device has blacklisted endpoints */
|
||||
#define USB_QUIRK_ENDPOINT_BLACKLIST BIT(15)
|
||||
|
||||
#endif /* __LINUX_USB_QUIRKS_H */
|
||||
|
||||
Reference in New Issue
Block a user