USB: cdc_acm: Fix oops when Droids MuIn LCD is connected
authorErik Slagter <erik@slagter.name>
Wed, 11 May 2011 10:06:55 +0000 (12:06 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 11 May 2011 22:14:28 +0000 (15:14 -0700)
The Droids MuIn LCD operates like a serial remote terminal.
Data received are displayed directly on the LCD. This patch
fixes the kernel null pointer oops when it is plugged in.

Add NO_DATA_INTERFACE quirk to tell the driver that "control"
and "data" interfaces are not separated for this device, which
prevents dereferencing a null pointer in the device probe code.

Signed-off-by: Erik Slagter <erik@slagter.name>
Signed-off-by: Maxin B. John <maxin.john@gmail.com>
Tested-by: Erik Slagter <erik@slagter.name>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.h

index 58754b508a0f4443920bc3759026a5bc56d5a3ea..395a347f2ebbea52d86b20cb97bec70548b6a34a 100644 (file)
@@ -853,7 +853,7 @@ static int acm_probe(struct usb_interface *intf,
        u8 ac_management_function = 0;
        u8 call_management_function = 0;
        int call_interface_num = -1;
-       int data_interface_num;
+       int data_interface_num = -1;
        unsigned long quirks;
        int num_rx_buf;
        int i;
@@ -937,7 +937,11 @@ next_desc:
        if (!union_header) {
                if (call_interface_num > 0) {
                        dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n");
-                       data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
+                       /* quirks for Droids MuIn LCD */
+                       if (quirks & NO_DATA_INTERFACE)
+                               data_interface = usb_ifnum_to_if(usb_dev, 0);
+                       else
+                               data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
                        control_interface = intf;
                } else {
                        if (intf->cur_altsetting->desc.bNumEndpoints != 3) {
@@ -1535,6 +1539,11 @@ static const struct usb_device_id acm_ids[] = {
        .driver_info = NOT_A_MODEM,
        },
 
+       /* Support for Droids MuIn LCD */
+       { USB_DEVICE(0x04d8, 0x000b),
+       .driver_info = NO_DATA_INTERFACE,
+       },
+
        /* control interfaces without any protocol set */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
                USB_CDC_PROTO_NONE) },
index 7b5c0bd07f80cf1c6a2b7eb75aa130ac2e16608b..ca7937f26e27ee3dba53feeb00fab2f49d3099aa 100644 (file)
@@ -126,3 +126,4 @@ struct acm {
 #define SINGLE_RX_URB                  2
 #define NO_CAP_LINE                    4
 #define NOT_A_MODEM                    8
+#define NO_DATA_INTERFACE              16