Reinhard Speyerer <rs...@arcor.de> wrote:

> Johan Hovold <jo...@kernel.org> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to