Commit bf1c6744 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

USB: cdc-acm: clean up no-union-descriptor handling



For interfaces that lack a union descriptor, probe for a
"combined-interface" before falling back to the call-management
descriptor instead of the other way round.

This allows for the removal of the NO_DATA_INTERFACE quirk and makes the
probe algorithm somewhat easier to follow.

Acked-by: default avatarOliver Neukum <oneukum@suse.com>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20200921135951.24045-5-johan@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 319bb4a7
Loading
Loading
Loading
Loading
+10 −22
Original line number Diff line number Diff line
@@ -1219,26 +1219,19 @@ static int acm_probe(struct usb_interface *intf,
		call_intf_num = cmgmd->bDataInterface;

	if (!union_header) {
		if (call_intf_num > 0) {
		if (intf->cur_altsetting->desc.bNumEndpoints == 3) {
			dev_dbg(&intf->dev, "No union descriptor, assuming single interface\n");
			combined_interfaces = 1;
			control_interface = data_interface = intf;
			goto look_for_collapsed_interface;
		} else if (call_intf_num > 0) {
			dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n");
			/* quirks for Droids MuIn LCD */
			if (quirks & NO_DATA_INTERFACE) {
				data_interface = usb_ifnum_to_if(usb_dev, 0);
			} else {
			data_intf_num = call_intf_num;
			data_interface = usb_ifnum_to_if(usb_dev, data_intf_num);
			}
			control_interface = intf;
		} else {
			if (intf->cur_altsetting->desc.bNumEndpoints != 3) {
			dev_dbg(&intf->dev, "No union descriptor, giving up\n");
			return -ENODEV;
			} else {
				dev_warn(&intf->dev,"No union descriptor, testing for castrated device\n");
				combined_interfaces = 1;
				control_interface = data_interface = intf;
				goto look_for_collapsed_interface;
			}
		}
	} else {
		int class = -1;
@@ -1882,11 +1875,6 @@ static const struct usb_device_id acm_ids[] = {

	/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */

	/* Support for Droids MuIn LCD */
	{ USB_DEVICE(0x04d8, 0x000b),
	.driver_info = NO_DATA_INTERFACE,
	},

#if IS_ENABLED(CONFIG_INPUT_IMS_PCU)
	{ USB_DEVICE(0x04d8, 0x0082),	/* Application mode */
	.driver_info = IGNORE_DEVICE,
+5 −6
Original line number Diff line number Diff line
@@ -135,9 +135,8 @@ struct acm {
#define NO_UNION_NORMAL			BIT(0)
#define SINGLE_RX_URB			BIT(1)
#define NO_CAP_LINE			BIT(2)
#define NO_DATA_INTERFACE		BIT(4)
#define IGNORE_DEVICE			BIT(5)
#define QUIRK_CONTROL_LINE_STATE	BIT(6)
#define CLEAR_HALT_CONDITIONS		BIT(7)
#define SEND_ZERO_PACKET		BIT(8)
#define DISABLE_ECHO			BIT(9)
#define IGNORE_DEVICE			BIT(3)
#define QUIRK_CONTROL_LINE_STATE	BIT(4)
#define CLEAR_HALT_CONDITIONS		BIT(5)
#define SEND_ZERO_PACKET		BIT(6)
#define DISABLE_ECHO			BIT(7)