Reinhard Speyerer <[email protected]> wrote:
> Johan Hovold <[email protected]> wrote:
>
> > On Sun, Dec 21, 2014 at 11:25:45PM +0100, Reinhard Speyerer wrote:
> >
> > > When using a MC7304 with firmware revision SWI9X15C_05.05.16.02 on
> > > Knoppix 7.4.2 with Linux kernel 3.16.3 and the qcserial driver I noticed
> > > that AT unsolicited response codes (URCs) like +CREG were missing (the
> > > mobile
> > > has been set to AT+CREG=2 before and <LACx>/<CIx> is used instead of the
> > > real
> > > LACs/CIs):
> >
> > > Switching the mobile back to the option driver
> >
> > > caused the missing +CREG: to reappear:
> >
[...]
> > > An alternative to this patch would be to add the option_send_setup code
> > > to qcserial.c for Sierra Wireless VID/PID 0x1199/0x68c0 devices.
> >
> > I leaning towards adding modem-control support to qcserial (send_setup).
> >
> > Can you confirm that the vendor driver is sending these control
> > requests?
>
> Sorry, I could not verify that.
>
> >
> > And did you already verify that adding them to qcserial fixes the issue
> > with MC7304?
> >
>
> To verify that the URCs do not appear as a side effect of other option
> initialization code I will try to port the send_setup code to qcserial
> and report on the results.
>
With the qcserial.c patch below (for Linux kernel 3.16.3) I was able to
verify that adding the send_setup code fixes the missing URCs for the
MC7304. To avoid potential side effects for other ports of the MC7304
the send_setup code is only used for the AT port (USB interface 3).
Regards,
Reinhard
--- qcserial.c-std 2014-08-04 00:25:02.000000000 +0200
+++ qcserial.c-rls-sendsetup 2014-12-27 21:56:03.000000000 +0100
@@ -24,2 +24,6 @@
+struct qc_private {
+ u8 bInterfaceNumber;
+};
+
/* standard device layouts supported by this driver */
@@ -309,5 +313,43 @@
+/** send RTS/DTR state to the port.
+ *
+ * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN
+ * CDC.
+*/
+static int qc_send_setup(struct usb_serial_port *port)
+{
+ struct usb_serial *serial = port->serial;
+ struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
+ struct qc_private *priv = intfdata->private;
+ struct usb_wwan_port_private *portdata;
+ int val = 0;
+ int res;
+
+ portdata = usb_get_serial_port_data(port);
+
+ if (portdata->dtr_state)
+ val |= 0x01;
+ if (portdata->rts_state)
+ val |= 0x02;
+
+ res = usb_autopm_get_interface(serial->interface);
+ if (res)
+ return res;
+
+ res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ 0x22, 0x21, val, priv->bInterfaceNumber, NULL,
+ 0, USB_CTRL_SET_TIMEOUT);
+
+ usb_autopm_put_interface(serial->interface);
+
+ return res;
+}
+
static int qc_attach(struct usb_serial *serial)
{
+ struct usb_interface_descriptor *iface_desc;
+ const struct usb_device_id *id;
struct usb_wwan_intf_private *data;
+ struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
+ struct qc_private *priv;
@@ -317,2 +359,18 @@
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ kfree(data);
+ return -ENOMEM;
+ }
+
+ iface_desc = &serial->interface->cur_altsetting->desc;
+
+ priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
+ data->private = priv;
+
+ if (dev_desc->idVendor == cpu_to_le16(0x1199) &&
+ dev_desc->idProduct == cpu_to_le16(0x68c0) &&
+ priv->bInterfaceNumber == 3) {
+ data->send_setup = qc_send_setup;
+ }
spin_lock_init(&data->susp_lock);
@@ -327,4 +385,6 @@
struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
+ struct qc_private *qcpriv = priv->private;
usb_set_serial_data(serial, NULL);
+ kfree(qcpriv);
kfree(priv);
@@ -343,2 +403,3 @@
.close = usb_wwan_close,
+ .dtr_rts = usb_wwan_dtr_rts,
.write = usb_wwan_write,
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html