summary refs log tree commit diff
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorDavid Ward <david.ward@ll.mit.edu>2015-09-16 12:27:58 -0400
committerJohan Hovold <johan@kernel.org>2015-10-09 12:42:48 +0200
commitefd3e9151fea1b1140d39dc58ec7099a07f0bdff (patch)
treed8a62a72e02440b92f82223611fdbb6f76dcf8e6 /drivers/usb/serial
parent669e729f9fb4e05ff02dfa01cbb8606549c6cb7c (diff)
downloadlinux-efd3e9151fea1b1140d39dc58ec7099a07f0bdff.tar.gz
USB: qcserial: make AT URCs work for Sierra Wireless devices
Three Sierra Wireless modems have been found to require the CDC ACM
SET_CONTROL_LINE_STATE request on the AT port in order to receive
unsolicited response codes, most recently the Dell Wireless 5808e
(which is a re-branded Sierra Wireless EM7355). On the other hand,
the Sierra Wireless MC7710 does not seem to need this request, but
it was found to work either way.

Use this request on the AT port of devices with the Sierra Wireless
layout in the qcserial driver. The other modems that were moved to
the option driver to work around this can now be moved back.

Cc: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David Ward <david.ward@ll.mit.edu>
Signed-off-by: Johan Hovold <johan@kernel.org>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/qcserial.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index ebcec8cda858..c2d0e5cfd2c3 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -175,6 +175,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 	__u8 nintf;
 	__u8 ifnum;
 	int altsetting = -1;
+	bool sendsetup = false;
 
 	nintf = serial->dev->actconfig->desc.bNumInterfaces;
 	dev_dbg(dev, "Num Interfaces = %d\n", nintf);
@@ -286,6 +287,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 			break;
 		case 3:
 			dev_dbg(dev, "Modem port found\n");
+			sendsetup = true;
 			break;
 		default:
 			/* don't claim any unsupported interface */
@@ -337,17 +339,25 @@ done:
 		}
 	}
 
+	if (!retval)
+		usb_set_serial_data(serial, (void *)(unsigned long)sendsetup);
+
 	return retval;
 }
 
 static int qc_attach(struct usb_serial *serial)
 {
 	struct usb_wwan_intf_private *data;
+	bool sendsetup;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 
+	sendsetup = !!(unsigned long)(usb_get_serial_data(serial));
+	if (sendsetup)
+		data->use_send_setup = 1;
+
 	spin_lock_init(&data->susp_lock);
 
 	usb_set_serial_data(serial, data);
@@ -374,6 +384,7 @@ static struct usb_serial_driver qcdevice = {
 	.probe               = qcprobe,
 	.open		     = usb_wwan_open,
 	.close		     = usb_wwan_close,
+	.dtr_rts	     = usb_wwan_dtr_rts,
 	.write		     = usb_wwan_write,
 	.write_room	     = usb_wwan_write_room,
 	.chars_in_buffer     = usb_wwan_chars_in_buffer,