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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
28c9fc68eb
commit
b4626c1092
@@ -475,31 +475,24 @@ enum option_blacklist_reason {
|
|||||||
OPTION_BLACKLIST_RESERVED_IF = 2
|
OPTION_BLACKLIST_RESERVED_IF = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_BL_NUM 8
|
||||||
struct option_blacklist_info {
|
struct option_blacklist_info {
|
||||||
const u32 infolen; /* number of interface numbers on blacklist */
|
/* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */
|
||||||
const u8 *ifaceinfo; /* pointer to the array holding the numbers */
|
const unsigned long sendsetup;
|
||||||
enum option_blacklist_reason reason;
|
/* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */
|
||||||
|
const unsigned long reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u8 four_g_w14_no_sendsetup[] = { 0, 1 };
|
|
||||||
static const struct option_blacklist_info four_g_w14_blacklist = {
|
static const struct option_blacklist_info four_g_w14_blacklist = {
|
||||||
.infolen = ARRAY_SIZE(four_g_w14_no_sendsetup),
|
.sendsetup = BIT(0) | BIT(1),
|
||||||
.ifaceinfo = four_g_w14_no_sendsetup,
|
|
||||||
.reason = OPTION_BLACKLIST_SENDSETUP
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u8 alcatel_x200_no_sendsetup[] = { 0, 1 };
|
|
||||||
static const struct option_blacklist_info alcatel_x200_blacklist = {
|
static const struct option_blacklist_info alcatel_x200_blacklist = {
|
||||||
.infolen = ARRAY_SIZE(alcatel_x200_no_sendsetup),
|
.sendsetup = BIT(0) | BIT(1),
|
||||||
.ifaceinfo = alcatel_x200_no_sendsetup,
|
|
||||||
.reason = OPTION_BLACKLIST_SENDSETUP
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u8 zte_k3765_z_no_sendsetup[] = { 0, 1, 2 };
|
|
||||||
static const struct option_blacklist_info zte_k3765_z_blacklist = {
|
static const struct option_blacklist_info zte_k3765_z_blacklist = {
|
||||||
.infolen = ARRAY_SIZE(zte_k3765_z_no_sendsetup),
|
.sendsetup = BIT(0) | BIT(1) | BIT(2),
|
||||||
.ifaceinfo = zte_k3765_z_no_sendsetup,
|
|
||||||
.reason = OPTION_BLACKLIST_SENDSETUP
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_device_id option_ids[] = {
|
static const struct usb_device_id option_ids[] = {
|
||||||
@@ -1255,21 +1248,28 @@ static int option_probe(struct usb_serial *serial,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum option_blacklist_reason is_blacklisted(const u8 ifnum,
|
static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
|
||||||
const struct option_blacklist_info *blacklist)
|
const struct option_blacklist_info *blacklist)
|
||||||
{
|
{
|
||||||
const u8 *info;
|
unsigned long num;
|
||||||
int i;
|
const unsigned long *intf_list;
|
||||||
|
|
||||||
if (blacklist) {
|
if (blacklist) {
|
||||||
info = blacklist->ifaceinfo;
|
if (reason == OPTION_BLACKLIST_SENDSETUP)
|
||||||
|
intf_list = &blacklist->sendsetup;
|
||||||
|
else if (reason == OPTION_BLACKLIST_RESERVED_IF)
|
||||||
|
intf_list = &blacklist->reserved;
|
||||||
|
else {
|
||||||
|
BUG_ON(reason);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < blacklist->infolen; i++) {
|
for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) {
|
||||||
if (info[i] == ifnum)
|
if (num == ifnum)
|
||||||
return blacklist->reason;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OPTION_BLACKLIST_NONE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void option_instat_callback(struct urb *urb)
|
static void option_instat_callback(struct urb *urb)
|
||||||
@@ -1343,9 +1343,8 @@ static int option_send_setup(struct usb_serial_port *port)
|
|||||||
int val = 0;
|
int val = 0;
|
||||||
dbg("%s", __func__);
|
dbg("%s", __func__);
|
||||||
|
|
||||||
if (is_blacklisted(ifNum,
|
if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP,
|
||||||
(struct option_blacklist_info *) intfdata->private)
|
(struct option_blacklist_info *) intfdata->private)) {
|
||||||
== OPTION_BLACKLIST_SENDSETUP) {
|
|
||||||
dbg("No send_setup on blacklisted interface #%d\n", ifNum);
|
dbg("No send_setup on blacklisted interface #%d\n", ifNum);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user