diff options
author | Dan Williams <dcbw@redhat.com> | 2011-09-13 14:49:41 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-09-18 04:22:53 -0400 |
commit | b4626c10928c13ee73b013dcbc23676333e79b59 (patch) | |
tree | 110d10e3fef918e66adf195cd8658982f617b006 /drivers/usb/serial | |
parent | 28c9fc68ebd32d473a8787d05c74e3f39c6c866b (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.c | 53 |
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 | ||
478 | struct option_blacklist_info { | 479 | struct 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 | ||
484 | static const u8 four_g_w14_no_sendsetup[] = { 0, 1 }; | ||
485 | static const struct option_blacklist_info four_g_w14_blacklist = { | 486 | static 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 | ||
491 | static const u8 alcatel_x200_no_sendsetup[] = { 0, 1 }; | ||
492 | static const struct option_blacklist_info alcatel_x200_blacklist = { | 490 | static 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 | ||
498 | static const u8 zte_k3765_z_no_sendsetup[] = { 0, 1, 2 }; | ||
499 | static const struct option_blacklist_info zte_k3765_z_blacklist = { | 494 | static 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 | ||
505 | static const struct usb_device_id option_ids[] = { | 498 | static 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 | ||
1258 | static enum option_blacklist_reason is_blacklisted(const u8 ifnum, | 1251 | static 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 | ||
1275 | static void option_instat_callback(struct urb *urb) | 1275 | static 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 | } |