diff options
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r-- | drivers/usb/serial/option.c | 60 |
1 files changed, 14 insertions, 46 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index efdcee15b520..f0c0c53359ad 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -507,18 +507,10 @@ static void option_instat_callback(struct urb *urb); | |||
507 | #define VIATELECOM_VENDOR_ID 0x15eb | 507 | #define VIATELECOM_VENDOR_ID 0x15eb |
508 | #define VIATELECOM_PRODUCT_CDS7 0x0001 | 508 | #define VIATELECOM_PRODUCT_CDS7 0x0001 |
509 | 509 | ||
510 | /* some devices interfaces need special handling due to a number of reasons */ | ||
511 | enum option_blacklist_reason { | ||
512 | OPTION_BLACKLIST_NONE = 0, | ||
513 | OPTION_BLACKLIST_SENDSETUP = 1, | ||
514 | OPTION_BLACKLIST_RESERVED_IF = 2 | ||
515 | }; | ||
516 | |||
517 | #define MAX_BL_NUM 11 | ||
518 | struct option_blacklist_info { | 510 | struct option_blacklist_info { |
519 | /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ | 511 | /* bitmask of interface numbers blacklisted for send_setup */ |
520 | const unsigned long sendsetup; | 512 | const unsigned long sendsetup; |
521 | /* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */ | 513 | /* bitmask of interface numbers that are reserved */ |
522 | const unsigned long reserved; | 514 | const unsigned long reserved; |
523 | }; | 515 | }; |
524 | 516 | ||
@@ -1822,36 +1814,13 @@ struct option_private { | |||
1822 | 1814 | ||
1823 | module_usb_serial_driver(serial_drivers, option_ids); | 1815 | module_usb_serial_driver(serial_drivers, option_ids); |
1824 | 1816 | ||
1825 | static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, | ||
1826 | const struct option_blacklist_info *blacklist) | ||
1827 | { | ||
1828 | unsigned long num; | ||
1829 | const unsigned long *intf_list; | ||
1830 | |||
1831 | if (blacklist) { | ||
1832 | if (reason == OPTION_BLACKLIST_SENDSETUP) | ||
1833 | intf_list = &blacklist->sendsetup; | ||
1834 | else if (reason == OPTION_BLACKLIST_RESERVED_IF) | ||
1835 | intf_list = &blacklist->reserved; | ||
1836 | else { | ||
1837 | BUG_ON(reason); | ||
1838 | return false; | ||
1839 | } | ||
1840 | |||
1841 | for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) { | ||
1842 | if (num == ifnum) | ||
1843 | return true; | ||
1844 | } | ||
1845 | } | ||
1846 | return false; | ||
1847 | } | ||
1848 | |||
1849 | static int option_probe(struct usb_serial *serial, | 1817 | static int option_probe(struct usb_serial *serial, |
1850 | const struct usb_device_id *id) | 1818 | const struct usb_device_id *id) |
1851 | { | 1819 | { |
1852 | struct usb_interface_descriptor *iface_desc = | 1820 | struct usb_interface_descriptor *iface_desc = |
1853 | &serial->interface->cur_altsetting->desc; | 1821 | &serial->interface->cur_altsetting->desc; |
1854 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; | 1822 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; |
1823 | const struct option_blacklist_info *blacklist; | ||
1855 | 1824 | ||
1856 | /* Never bind to the CD-Rom emulation interface */ | 1825 | /* Never bind to the CD-Rom emulation interface */ |
1857 | if (iface_desc->bInterfaceClass == 0x08) | 1826 | if (iface_desc->bInterfaceClass == 0x08) |
@@ -1862,10 +1831,9 @@ static int option_probe(struct usb_serial *serial, | |||
1862 | * the same class/subclass/protocol as the serial interfaces. Look at | 1831 | * the same class/subclass/protocol as the serial interfaces. Look at |
1863 | * the Windows driver .INF files for reserved interface numbers. | 1832 | * the Windows driver .INF files for reserved interface numbers. |
1864 | */ | 1833 | */ |
1865 | if (is_blacklisted( | 1834 | blacklist = (void *)id->driver_info; |
1866 | iface_desc->bInterfaceNumber, | 1835 | if (blacklist && test_bit(iface_desc->bInterfaceNumber, |
1867 | OPTION_BLACKLIST_RESERVED_IF, | 1836 | &blacklist->reserved)) |
1868 | (const struct option_blacklist_info *) id->driver_info)) | ||
1869 | return -ENODEV; | 1837 | return -ENODEV; |
1870 | /* | 1838 | /* |
1871 | * Don't bind network interface on Samsung GT-B3730, it is handled by | 1839 | * 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, | |||
1876 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) | 1844 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) |
1877 | return -ENODEV; | 1845 | return -ENODEV; |
1878 | 1846 | ||
1879 | /* Store device id so we can use it during attach. */ | 1847 | /* Store the blacklist info so we can use it during attach. */ |
1880 | usb_set_serial_data(serial, (void *)id); | 1848 | usb_set_serial_data(serial, (void *)blacklist); |
1881 | 1849 | ||
1882 | return 0; | 1850 | return 0; |
1883 | } | 1851 | } |
@@ -1885,7 +1853,7 @@ static int option_probe(struct usb_serial *serial, | |||
1885 | static int option_attach(struct usb_serial *serial) | 1853 | static int option_attach(struct usb_serial *serial) |
1886 | { | 1854 | { |
1887 | struct usb_interface_descriptor *iface_desc; | 1855 | struct usb_interface_descriptor *iface_desc; |
1888 | const struct usb_device_id *id; | 1856 | const struct option_blacklist_info *blacklist; |
1889 | struct usb_wwan_intf_private *data; | 1857 | struct usb_wwan_intf_private *data; |
1890 | struct option_private *priv; | 1858 | struct option_private *priv; |
1891 | 1859 | ||
@@ -1899,16 +1867,16 @@ static int option_attach(struct usb_serial *serial) | |||
1899 | return -ENOMEM; | 1867 | return -ENOMEM; |
1900 | } | 1868 | } |
1901 | 1869 | ||
1902 | /* Retrieve device id stored at probe. */ | 1870 | /* Retrieve blacklist info stored at probe. */ |
1903 | id = usb_get_serial_data(serial); | 1871 | blacklist = usb_get_serial_data(serial); |
1872 | |||
1904 | iface_desc = &serial->interface->cur_altsetting->desc; | 1873 | iface_desc = &serial->interface->cur_altsetting->desc; |
1905 | 1874 | ||
1906 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; | 1875 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; |
1907 | data->private = priv; | 1876 | data->private = priv; |
1908 | 1877 | ||
1909 | if (!is_blacklisted(iface_desc->bInterfaceNumber, | 1878 | if (!blacklist || !test_bit(iface_desc->bInterfaceNumber, |
1910 | OPTION_BLACKLIST_SENDSETUP, | 1879 | &blacklist->sendsetup)) { |
1911 | (struct option_blacklist_info *)id->driver_info)) { | ||
1912 | data->send_setup = option_send_setup; | 1880 | data->send_setup = option_send_setup; |
1913 | } | 1881 | } |
1914 | spin_lock_init(&data->susp_lock); | 1882 | spin_lock_init(&data->susp_lock); |