aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/option.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r--drivers/usb/serial/option.c60
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 */
511enum 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
518struct option_blacklist_info { 510struct 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
1823module_usb_serial_driver(serial_drivers, option_ids); 1815module_usb_serial_driver(serial_drivers, option_ids);
1824 1816
1825static 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
1849static int option_probe(struct usb_serial *serial, 1817static 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,
1885static int option_attach(struct usb_serial *serial) 1853static 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);