aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/option.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2011-09-13 14:51:13 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-18 04:23:10 -0400
commit0d905fd5ece4ab65e8407c450077744e1c8f661b (patch)
tree8bdf394a8aec9d24372609c66ed0b7206f894acb /drivers/usb/serial/option.c
parentb4626c10928c13ee73b013dcbc23676333e79b59 (diff)
USB: option: convert Huawei K3765, K4505, K4605 reservered interface to blacklist
That's what the blacklist is for... Signed-off-by: Dan Williams <dcbw@redhat.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r--drivers/usb/serial/option.c79
1 files changed, 43 insertions, 36 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index d4fc3c38eee..fc9e874a768 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -495,6 +495,10 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {
495 .sendsetup = BIT(0) | BIT(1) | BIT(2), 495 .sendsetup = BIT(0) | BIT(1) | BIT(2),
496}; 496};
497 497
498static const struct option_blacklist_info huawei_cdc12_blacklist = {
499 .reserved = BIT(1) | BIT(2),
500};
501
498static const struct usb_device_id option_ids[] = { 502static const struct usb_device_id option_ids[] = {
499 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, 503 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
500 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, 504 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -592,12 +596,15 @@ static const struct usb_device_id option_ids[] = {
592 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, 596 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },
593 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, 597 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },
594 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, 598 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) },
595 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) }, 599 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
596 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, 600 .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
601 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
602 .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
597 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, 603 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
598 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, 604 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
599 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, 605 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) },
600 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff) }, 606 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
607 .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
601 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, 608 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
602 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, 609 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
603 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, 610 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
@@ -1207,10 +1214,35 @@ static void __exit option_exit(void)
1207module_init(option_init); 1214module_init(option_init);
1208module_exit(option_exit); 1215module_exit(option_exit);
1209 1216
1217static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
1218 const struct option_blacklist_info *blacklist)
1219{
1220 unsigned long num;
1221 const unsigned long *intf_list;
1222
1223 if (blacklist) {
1224 if (reason == OPTION_BLACKLIST_SENDSETUP)
1225 intf_list = &blacklist->sendsetup;
1226 else if (reason == OPTION_BLACKLIST_RESERVED_IF)
1227 intf_list = &blacklist->reserved;
1228 else {
1229 BUG_ON(reason);
1230 return false;
1231 }
1232
1233 for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) {
1234 if (num == ifnum)
1235 return true;
1236 }
1237 }
1238 return false;
1239}
1240
1210static int option_probe(struct usb_serial *serial, 1241static int option_probe(struct usb_serial *serial,
1211 const struct usb_device_id *id) 1242 const struct usb_device_id *id)
1212{ 1243{
1213 struct usb_wwan_intf_private *data; 1244 struct usb_wwan_intf_private *data;
1245
1214 /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ 1246 /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */
1215 if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && 1247 if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
1216 serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && 1248 serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
@@ -1223,14 +1255,14 @@ static int option_probe(struct usb_serial *serial,
1223 serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) 1255 serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
1224 return -ENODEV; 1256 return -ENODEV;
1225 1257
1226 /* Don't bind network interfaces on Huawei K3765, K4505 & K4605 */ 1258 /* Don't bind reserved interfaces (like network ones) which often have
1227 if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID && 1259 * the same class/subclass/protocol as the serial interfaces. Look at
1228 (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 || 1260 * the Windows driver .INF files for reserved interface numbers.
1229 serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505 || 1261 */
1230 serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4605) && 1262 if (is_blacklisted(
1231 (serial->interface->cur_altsetting->desc.bInterfaceNumber == 1 || 1263 serial->interface->cur_altsetting->desc.bInterfaceNumber,
1232 serial->interface->cur_altsetting->desc.bInterfaceNumber == 2)) 1264 OPTION_BLACKLIST_RESERVED_IF,
1233 return -ENODEV; 1265 (const struct option_blacklist_info *) id->driver_info))
1234 1266
1235 /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ 1267 /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */
1236 if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID && 1268 if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID &&
@@ -1239,7 +1271,6 @@ static int option_probe(struct usb_serial *serial,
1239 return -ENODEV; 1271 return -ENODEV;
1240 1272
1241 data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); 1273 data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
1242
1243 if (!data) 1274 if (!data)
1244 return -ENOMEM; 1275 return -ENOMEM;
1245 data->send_setup = option_send_setup; 1276 data->send_setup = option_send_setup;
@@ -1248,30 +1279,6 @@ static int option_probe(struct usb_serial *serial,
1248 return 0; 1279 return 0;
1249} 1280}
1250 1281
1251static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
1252 const struct option_blacklist_info *blacklist)
1253{
1254 unsigned long num;
1255 const unsigned long *intf_list;
1256
1257 if (blacklist) {
1258 if (reason == OPTION_BLACKLIST_SENDSETUP)
1259 intf_list = &blacklist->sendsetup;
1260 else if (reason == OPTION_BLACKLIST_RESERVED_IF)
1261 intf_list = &blacklist->reserved;
1262 else {
1263 BUG_ON(reason);
1264 return false;
1265 }
1266
1267 for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) {
1268 if (num == ifnum)
1269 return true;
1270 }
1271 }
1272 return false;
1273}
1274
1275static void option_instat_callback(struct urb *urb) 1282static void option_instat_callback(struct urb *urb)
1276{ 1283{
1277 int err; 1284 int err;