diff options
author | Erik Slagter <erik@slagter.name> | 2011-05-11 06:06:55 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-11 18:14:28 -0400 |
commit | fd5054c169d29747a44b4e1419ff47f57ae82dbc (patch) | |
tree | aa352fe27998b7f1e9bced69d4e46e0990ff891c /drivers/usb/class | |
parent | a9df304cf78d76108196da1ff1dad4d9a5737c2e (diff) |
USB: cdc_acm: Fix oops when Droids MuIn LCD is connected
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>
Diffstat (limited to 'drivers/usb/class')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 13 | ||||
-rw-r--r-- | drivers/usb/class/cdc-acm.h | 1 |
2 files changed, 12 insertions, 2 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 58754b508a0f..395a347f2ebb 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -853,7 +853,7 @@ static int acm_probe(struct usb_interface *intf, | |||
853 | u8 ac_management_function = 0; | 853 | u8 ac_management_function = 0; |
854 | u8 call_management_function = 0; | 854 | u8 call_management_function = 0; |
855 | int call_interface_num = -1; | 855 | int call_interface_num = -1; |
856 | int data_interface_num; | 856 | int data_interface_num = -1; |
857 | unsigned long quirks; | 857 | unsigned long quirks; |
858 | int num_rx_buf; | 858 | int num_rx_buf; |
859 | int i; | 859 | int i; |
@@ -937,7 +937,11 @@ next_desc: | |||
937 | if (!union_header) { | 937 | if (!union_header) { |
938 | if (call_interface_num > 0) { | 938 | if (call_interface_num > 0) { |
939 | dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n"); | 939 | dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n"); |
940 | data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); | 940 | /* quirks for Droids MuIn LCD */ |
941 | if (quirks & NO_DATA_INTERFACE) | ||
942 | data_interface = usb_ifnum_to_if(usb_dev, 0); | ||
943 | else | ||
944 | data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); | ||
941 | control_interface = intf; | 945 | control_interface = intf; |
942 | } else { | 946 | } else { |
943 | if (intf->cur_altsetting->desc.bNumEndpoints != 3) { | 947 | if (intf->cur_altsetting->desc.bNumEndpoints != 3) { |
@@ -1535,6 +1539,11 @@ static const struct usb_device_id acm_ids[] = { | |||
1535 | .driver_info = NOT_A_MODEM, | 1539 | .driver_info = NOT_A_MODEM, |
1536 | }, | 1540 | }, |
1537 | 1541 | ||
1542 | /* Support for Droids MuIn LCD */ | ||
1543 | { USB_DEVICE(0x04d8, 0x000b), | ||
1544 | .driver_info = NO_DATA_INTERFACE, | ||
1545 | }, | ||
1546 | |||
1538 | /* control interfaces without any protocol set */ | 1547 | /* control interfaces without any protocol set */ |
1539 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1548 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
1540 | USB_CDC_PROTO_NONE) }, | 1549 | USB_CDC_PROTO_NONE) }, |
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 7b5c0bd07f80..ca7937f26e27 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h | |||
@@ -126,3 +126,4 @@ struct acm { | |||
126 | #define SINGLE_RX_URB 2 | 126 | #define SINGLE_RX_URB 2 |
127 | #define NO_CAP_LINE 4 | 127 | #define NO_CAP_LINE 4 |
128 | #define NOT_A_MODEM 8 | 128 | #define NOT_A_MODEM 8 |
129 | #define NO_DATA_INTERFACE 16 | ||