Reinhard Speyerer <rspmn@xxxxxxxx> wrote: > Johan Hovold <johan@xxxxxxxxxx> 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html