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)
committerSteve Conklin <sconklin@canonical.com>
Fri, 15 Jul 2011 17:21:06 +0000 (12:21 -0500)
BugLink: http://bugs.launchpad.net/bugs/793702

commit fd5054c169d29747a44b4e1419ff47f57ae82dbc upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>

drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.h

index 30bb8d0..83589f4 100644 (file)
@@ -946,7 +946,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;
@@ -1030,7 +1030,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) {
@@ -1622,6 +1626,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 5eeb570..a2446d6 100644 (file)
@@ -137,3 +137,4 @@ struct acm {
 #define SINGLE_RX_URB                  2
 #define NO_CAP_LINE                    4
 #define NOT_A_MODEM                    8
+#define NO_DATA_INTERFACE              16