diff options
author | Dan Williams <dcbw@redhat.com> | 2011-09-13 14:51:13 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-09-18 04:23:10 -0400 |
commit | 0d905fd5ece4ab65e8407c450077744e1c8f661b (patch) | |
tree | 8bdf394a8aec9d24372609c66ed0b7206f894acb /drivers/usb/serial/option.c | |
parent | b4626c10928c13ee73b013dcbc23676333e79b59 (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.c | 79 |
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 | ||
498 | static const struct option_blacklist_info huawei_cdc12_blacklist = { | ||
499 | .reserved = BIT(1) | BIT(2), | ||
500 | }; | ||
501 | |||
498 | static const struct usb_device_id option_ids[] = { | 502 | static 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) | |||
1207 | module_init(option_init); | 1214 | module_init(option_init); |
1208 | module_exit(option_exit); | 1215 | module_exit(option_exit); |
1209 | 1216 | ||
1217 | static 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 | |||
1210 | static int option_probe(struct usb_serial *serial, | 1241 | static 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 | ||
1251 | static 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 | |||
1275 | static void option_instat_callback(struct urb *urb) | 1282 | static void option_instat_callback(struct urb *urb) |
1276 | { | 1283 | { |
1277 | int err; | 1284 | int err; |