aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2014-11-06 12:08:33 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-11-06 15:25:40 -0500
commit2a8cdfde9237c4e1bd7c2e68c415b006491d23cc (patch)
treebad488692ec7149d3b326010b374f2419c80a139 /drivers/usb
parente5452dd4cb93b04b704eb6d4e7623178715f17ce (diff)
USB: cdc-acm: add quirk for control-line state requests
Add new quirk for devices that cannot handle control-line state requests. Note that we currently send these requests to all devices, regardless of whether they claim to support it, but that errors are only logged if support is claimed. Since commit 0943d8ead30e ("USB: cdc-acm: use tty-port dtr_rts"), which only changed the timings for these requests slightly, this has been reported to cause occasional firmware crashes on Simtec Electronics Entropy Key devices after re-enumeration. Enable the quirk for this device. Reported-by: Nix <nix@esperi.org.uk> Tested-by: Nix <nix@esperi.org.uk> Cc: stable <stable@vger.kernel.org> # v3.16 Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/class/cdc-acm.c14
-rw-r--r--drivers/usb/class/cdc-acm.h2
2 files changed, 14 insertions, 2 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 9d6495424b06..077d58ac3dcb 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -148,8 +148,15 @@ static int acm_ctrl_msg(struct acm *acm, int request, int value,
148/* devices aren't required to support these requests. 148/* devices aren't required to support these requests.
149 * the cdc acm descriptor tells whether they do... 149 * the cdc acm descriptor tells whether they do...
150 */ 150 */
151#define acm_set_control(acm, control) \ 151static inline int acm_set_control(struct acm *acm, int control)
152 acm_ctrl_msg(acm, USB_CDC_REQ_SET_CONTROL_LINE_STATE, control, NULL, 0) 152{
153 if (acm->quirks & QUIRK_CONTROL_LINE_STATE)
154 return -EOPNOTSUPP;
155
156 return acm_ctrl_msg(acm, USB_CDC_REQ_SET_CONTROL_LINE_STATE,
157 control, NULL, 0);
158}
159
153#define acm_set_line(acm, line) \ 160#define acm_set_line(acm, line) \
154 acm_ctrl_msg(acm, USB_CDC_REQ_SET_LINE_CODING, 0, line, sizeof *(line)) 161 acm_ctrl_msg(acm, USB_CDC_REQ_SET_LINE_CODING, 0, line, sizeof *(line))
155#define acm_send_break(acm, ms) \ 162#define acm_send_break(acm, ms) \
@@ -1320,6 +1327,7 @@ made_compressed_probe:
1320 tty_port_init(&acm->port); 1327 tty_port_init(&acm->port);
1321 acm->port.ops = &acm_port_ops; 1328 acm->port.ops = &acm_port_ops;
1322 init_usb_anchor(&acm->delayed); 1329 init_usb_anchor(&acm->delayed);
1330 acm->quirks = quirks;
1323 1331
1324 buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); 1332 buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
1325 if (!buf) { 1333 if (!buf) {
@@ -1687,6 +1695,8 @@ static const struct usb_device_id acm_ids[] = {
1687 { USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */ 1695 { USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */
1688 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ 1696 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
1689 }, 1697 },
1698 { USB_DEVICE(0x20df, 0x0001), /* Simtec Electronics Entropy Key */
1699 .driver_info = QUIRK_CONTROL_LINE_STATE, },
1690 { USB_DEVICE(0x2184, 0x001c) }, /* GW Instek AFG-2225 */ 1700 { USB_DEVICE(0x2184, 0x001c) }, /* GW Instek AFG-2225 */
1691 { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ 1701 { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
1692 }, 1702 },
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index fc75651afe1c..d3251ebd09e2 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -121,6 +121,7 @@ struct acm {
121 unsigned int throttle_req:1; /* throttle requested */ 121 unsigned int throttle_req:1; /* throttle requested */
122 u8 bInterval; 122 u8 bInterval;
123 struct usb_anchor delayed; /* writes queued for a device about to be woken */ 123 struct usb_anchor delayed; /* writes queued for a device about to be woken */
124 unsigned long quirks;
124}; 125};
125 126
126#define CDC_DATA_INTERFACE_TYPE 0x0a 127#define CDC_DATA_INTERFACE_TYPE 0x0a
@@ -132,3 +133,4 @@ struct acm {
132#define NOT_A_MODEM BIT(3) 133#define NOT_A_MODEM BIT(3)
133#define NO_DATA_INTERFACE BIT(4) 134#define NO_DATA_INTERFACE BIT(4)
134#define IGNORE_DEVICE BIT(5) 135#define IGNORE_DEVICE BIT(5)
136#define QUIRK_CONTROL_LINE_STATE BIT(6)