aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2011-09-13 14:49:41 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-18 04:22:53 -0400
commitb4626c10928c13ee73b013dcbc23676333e79b59 (patch)
tree110d10e3fef918e66adf195cd8658982f617b006 /drivers/usb/serial
parent28c9fc68ebd32d473a8787d05c74e3f39c6c866b (diff)
USB: option: convert interface blacklisting to bitfields
It's cleaner than the array stuff, and we're about to add a bunch more blacklist entries. Second, there are devices that need both the sendsetup and the reserved interface blacklists, which the current code can't accommodate. 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')
-rw-r--r--drivers/usb/serial/option.c53
1 files changed, 26 insertions, 27 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index fe22e90bc879..d4fc3c38eee9 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -475,31 +475,24 @@ enum option_blacklist_reason {
475 OPTION_BLACKLIST_RESERVED_IF = 2 475 OPTION_BLACKLIST_RESERVED_IF = 2
476}; 476};
477 477
478#define MAX_BL_NUM 8
478struct option_blacklist_info { 479struct option_blacklist_info {
479 const u32 infolen; /* number of interface numbers on blacklist */ 480 /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */
480 const u8 *ifaceinfo; /* pointer to the array holding the numbers */ 481 const unsigned long sendsetup;
481 enum option_blacklist_reason reason; 482 /* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */
483 const unsigned long reserved;
482}; 484};
483 485
484static const u8 four_g_w14_no_sendsetup[] = { 0, 1 };
485static const struct option_blacklist_info four_g_w14_blacklist = { 486static const struct option_blacklist_info four_g_w14_blacklist = {
486 .infolen = ARRAY_SIZE(four_g_w14_no_sendsetup), 487 .sendsetup = BIT(0) | BIT(1),
487 .ifaceinfo = four_g_w14_no_sendsetup,
488 .reason = OPTION_BLACKLIST_SENDSETUP
489}; 488};
490 489
491static const u8 alcatel_x200_no_sendsetup[] = { 0, 1 };
492static const struct option_blacklist_info alcatel_x200_blacklist = { 490static const struct option_blacklist_info alcatel_x200_blacklist = {
493 .infolen = ARRAY_SIZE(alcatel_x200_no_sendsetup), 491 .sendsetup = BIT(0) | BIT(1),
494 .ifaceinfo = alcatel_x200_no_sendsetup,
495 .reason = OPTION_BLACKLIST_SENDSETUP
496}; 492};
497 493
498static const u8 zte_k3765_z_no_sendsetup[] = { 0, 1, 2 };
499static const struct option_blacklist_info zte_k3765_z_blacklist = { 494static const struct option_blacklist_info zte_k3765_z_blacklist = {
500 .infolen = ARRAY_SIZE(zte_k3765_z_no_sendsetup), 495 .sendsetup = BIT(0) | BIT(1) | BIT(2),
501 .ifaceinfo = zte_k3765_z_no_sendsetup,
502 .reason = OPTION_BLACKLIST_SENDSETUP
503}; 496};
504 497
505static const struct usb_device_id option_ids[] = { 498static const struct usb_device_id option_ids[] = {
@@ -1255,21 +1248,28 @@ static int option_probe(struct usb_serial *serial,
1255 return 0; 1248 return 0;
1256} 1249}
1257 1250
1258static enum option_blacklist_reason is_blacklisted(const u8 ifnum, 1251static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
1259 const struct option_blacklist_info *blacklist) 1252 const struct option_blacklist_info *blacklist)
1260{ 1253{
1261 const u8 *info; 1254 unsigned long num;
1262 int i; 1255 const unsigned long *intf_list;
1263 1256
1264 if (blacklist) { 1257 if (blacklist) {
1265 info = blacklist->ifaceinfo; 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 1266
1267 for (i = 0; i < blacklist->infolen; i++) { 1267 for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) {
1268 if (info[i] == ifnum) 1268 if (num == ifnum)
1269 return blacklist->reason; 1269 return true;
1270 } 1270 }
1271 } 1271 }
1272 return OPTION_BLACKLIST_NONE; 1272 return false;
1273} 1273}
1274 1274
1275static void option_instat_callback(struct urb *urb) 1275static void option_instat_callback(struct urb *urb)
@@ -1343,9 +1343,8 @@ static int option_send_setup(struct usb_serial_port *port)
1343 int val = 0; 1343 int val = 0;
1344 dbg("%s", __func__); 1344 dbg("%s", __func__);
1345 1345
1346 if (is_blacklisted(ifNum, 1346 if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP,
1347 (struct option_blacklist_info *) intfdata->private) 1347 (struct option_blacklist_info *) intfdata->private)) {
1348 == OPTION_BLACKLIST_SENDSETUP) {
1349 dbg("No send_setup on blacklisted interface #%d\n", ifNum); 1348 dbg("No send_setup on blacklisted interface #%d\n", ifNum);
1350 return -EIO; 1349 return -EIO;
1351 } 1350 }