USB: option: clean up blacklist handling
Clean up the unnecessarily complicated blacklist implementation somewhat. Signed-off-by: Johan Hovold <johan@kernel.org>
This commit is contained in:
parent
ec6f34e5b5
commit
46dc0fc4be
@ -507,18 +507,10 @@ static void option_instat_callback(struct urb *urb);
|
|||||||
#define VIATELECOM_VENDOR_ID 0x15eb
|
#define VIATELECOM_VENDOR_ID 0x15eb
|
||||||
#define VIATELECOM_PRODUCT_CDS7 0x0001
|
#define VIATELECOM_PRODUCT_CDS7 0x0001
|
||||||
|
|
||||||
/* some devices interfaces need special handling due to a number of reasons */
|
|
||||||
enum option_blacklist_reason {
|
|
||||||
OPTION_BLACKLIST_NONE = 0,
|
|
||||||
OPTION_BLACKLIST_SENDSETUP = 1,
|
|
||||||
OPTION_BLACKLIST_RESERVED_IF = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_BL_NUM 11
|
|
||||||
struct option_blacklist_info {
|
struct option_blacklist_info {
|
||||||
/* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */
|
/* bitmask of interface numbers blacklisted for send_setup */
|
||||||
const unsigned long sendsetup;
|
const unsigned long sendsetup;
|
||||||
/* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */
|
/* bitmask of interface numbers that are reserved */
|
||||||
const unsigned long reserved;
|
const unsigned long reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1822,36 +1814,13 @@ struct option_private {
|
|||||||
|
|
||||||
module_usb_serial_driver(serial_drivers, option_ids);
|
module_usb_serial_driver(serial_drivers, option_ids);
|
||||||
|
|
||||||
static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
|
|
||||||
const struct option_blacklist_info *blacklist)
|
|
||||||
{
|
|
||||||
unsigned long num;
|
|
||||||
const unsigned long *intf_list;
|
|
||||||
|
|
||||||
if (blacklist) {
|
|
||||||
if (reason == OPTION_BLACKLIST_SENDSETUP)
|
|
||||||
intf_list = &blacklist->sendsetup;
|
|
||||||
else if (reason == OPTION_BLACKLIST_RESERVED_IF)
|
|
||||||
intf_list = &blacklist->reserved;
|
|
||||||
else {
|
|
||||||
BUG_ON(reason);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) {
|
|
||||||
if (num == ifnum)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int option_probe(struct usb_serial *serial,
|
static int option_probe(struct usb_serial *serial,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct usb_interface_descriptor *iface_desc =
|
struct usb_interface_descriptor *iface_desc =
|
||||||
&serial->interface->cur_altsetting->desc;
|
&serial->interface->cur_altsetting->desc;
|
||||||
struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
|
struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
|
||||||
|
const struct option_blacklist_info *blacklist;
|
||||||
|
|
||||||
/* Never bind to the CD-Rom emulation interface */
|
/* Never bind to the CD-Rom emulation interface */
|
||||||
if (iface_desc->bInterfaceClass == 0x08)
|
if (iface_desc->bInterfaceClass == 0x08)
|
||||||
@ -1862,10 +1831,9 @@ static int option_probe(struct usb_serial *serial,
|
|||||||
* the same class/subclass/protocol as the serial interfaces. Look at
|
* the same class/subclass/protocol as the serial interfaces. Look at
|
||||||
* the Windows driver .INF files for reserved interface numbers.
|
* the Windows driver .INF files for reserved interface numbers.
|
||||||
*/
|
*/
|
||||||
if (is_blacklisted(
|
blacklist = (void *)id->driver_info;
|
||||||
iface_desc->bInterfaceNumber,
|
if (blacklist && test_bit(iface_desc->bInterfaceNumber,
|
||||||
OPTION_BLACKLIST_RESERVED_IF,
|
&blacklist->reserved))
|
||||||
(const struct option_blacklist_info *) id->driver_info))
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
/*
|
/*
|
||||||
* Don't bind network interface on Samsung GT-B3730, it is handled by
|
* Don't bind network interface on Samsung GT-B3730, it is handled by
|
||||||
@ -1876,8 +1844,8 @@ static int option_probe(struct usb_serial *serial,
|
|||||||
iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
|
iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* Store device id so we can use it during attach. */
|
/* Store the blacklist info so we can use it during attach. */
|
||||||
usb_set_serial_data(serial, (void *)id);
|
usb_set_serial_data(serial, (void *)blacklist);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1885,7 +1853,7 @@ static int option_probe(struct usb_serial *serial,
|
|||||||
static int option_attach(struct usb_serial *serial)
|
static int option_attach(struct usb_serial *serial)
|
||||||
{
|
{
|
||||||
struct usb_interface_descriptor *iface_desc;
|
struct usb_interface_descriptor *iface_desc;
|
||||||
const struct usb_device_id *id;
|
const struct option_blacklist_info *blacklist;
|
||||||
struct usb_wwan_intf_private *data;
|
struct usb_wwan_intf_private *data;
|
||||||
struct option_private *priv;
|
struct option_private *priv;
|
||||||
|
|
||||||
@ -1899,16 +1867,16 @@ static int option_attach(struct usb_serial *serial)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve device id stored at probe. */
|
/* Retrieve blacklist info stored at probe. */
|
||||||
id = usb_get_serial_data(serial);
|
blacklist = usb_get_serial_data(serial);
|
||||||
|
|
||||||
iface_desc = &serial->interface->cur_altsetting->desc;
|
iface_desc = &serial->interface->cur_altsetting->desc;
|
||||||
|
|
||||||
priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
|
priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
|
||||||
data->private = priv;
|
data->private = priv;
|
||||||
|
|
||||||
if (!is_blacklisted(iface_desc->bInterfaceNumber,
|
if (!blacklist || !test_bit(iface_desc->bInterfaceNumber,
|
||||||
OPTION_BLACKLIST_SENDSETUP,
|
&blacklist->sendsetup)) {
|
||||||
(struct option_blacklist_info *)id->driver_info)) {
|
|
||||||
data->send_setup = option_send_setup;
|
data->send_setup = option_send_setup;
|
||||||
}
|
}
|
||||||
spin_lock_init(&data->susp_lock);
|
spin_lock_init(&data->susp_lock);
|
||||||
|
Loading…
Reference in New Issue
Block a user