Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4626c10 authored by Dan Williams's avatar Dan Williams Committed by Greg Kroah-Hartman
Browse files

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: default avatarDan Williams <dcbw@redhat.com>
Cc: stable <stable@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 28c9fc68
Loading
Loading
Loading
Loading
+26 −27
Original line number Diff line number Diff line
@@ -475,31 +475,24 @@ enum option_blacklist_reason {
		OPTION_BLACKLIST_RESERVED_IF = 2
};

#define MAX_BL_NUM  8
struct option_blacklist_info {
	const u32 infolen;	/* number of interface numbers on blacklist */
	const u8  *ifaceinfo;	/* pointer to the array holding the numbers */
	enum option_blacklist_reason reason;
	/* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */
	const unsigned long sendsetup;
	/* 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 = {
	.infolen = ARRAY_SIZE(four_g_w14_no_sendsetup),
	.ifaceinfo = four_g_w14_no_sendsetup,
	.reason = OPTION_BLACKLIST_SENDSETUP
	.sendsetup = BIT(0) | BIT(1),
};

static const u8 alcatel_x200_no_sendsetup[] = { 0, 1 };
static const struct option_blacklist_info alcatel_x200_blacklist = {
	.infolen = ARRAY_SIZE(alcatel_x200_no_sendsetup),
	.ifaceinfo = alcatel_x200_no_sendsetup,
	.reason = OPTION_BLACKLIST_SENDSETUP
	.sendsetup = BIT(0) | BIT(1),
};

static const u8 zte_k3765_z_no_sendsetup[] = { 0, 1, 2 };
static const struct option_blacklist_info zte_k3765_z_blacklist = {
	.infolen = ARRAY_SIZE(zte_k3765_z_no_sendsetup),
	.ifaceinfo = zte_k3765_z_no_sendsetup,
	.reason = OPTION_BLACKLIST_SENDSETUP
	.sendsetup = BIT(0) | BIT(1) | BIT(2),
};

static const struct usb_device_id option_ids[] = {
@@ -1255,21 +1248,28 @@ static int option_probe(struct usb_serial *serial,
	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 u8  *info;
	int i;
	unsigned long num;
	const unsigned long *intf_list;

	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++) {
			if (info[i] == ifnum)
				return blacklist->reason;
		for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) {
			if (num == ifnum)
				return true;
		}
	}
	return OPTION_BLACKLIST_NONE;
	return false;
}

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;
	dbg("%s", __func__);

	if (is_blacklisted(ifNum,
			   (struct option_blacklist_info *) intfdata->private)
	    == OPTION_BLACKLIST_SENDSETUP) {
	if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP,
			(struct option_blacklist_info *) intfdata->private)) {
		dbg("No send_setup on blacklisted interface #%d\n", ifNum);
		return -EIO;
	}