From: Martin Schiller <[EMAIL PROTECTED]>

I encountered some problems with the airprime driver in use with a Novatel
Merlin XU870:

Closing an open Connection to e.g. /dev/ttyUSB0 doesn't reset the
RTS/DTR lines of the Modem.  Consequently, when I use minicom to
establish a connection by "ATD*99#" the modem doesn't hang up even if i
exit minicom and so I cannot reuse the modem unless I remove it and plug
it in again.

With the attached patch, the RTS/DTR lines are resetted on a close.  The
code was mainly taken from the option.c driver.
---
 drivers/usb/serial/airprime.c |   47 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 18816bf..310a8b5 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -44,8 +44,43 @@ struct airprime_private {
        int outstanding_urbs;
        int throttled;
        struct urb *read_urbp[NUM_READ_URBS];
+
+       /* Settings for the port */
+       int rts_state;  /* Handshaking pins (outputs) */
+       int dtr_state;
+       int cts_state;  /* Handshaking pins (inputs) */
+       int dsr_state;
+       int dcd_state;
+       int ri_state;
 };
 
+static int airprime_send_setup(struct usb_serial_port *port)
+{
+       struct usb_serial *serial = port->serial;
+       struct airprime_private *priv;
+
+       dbg("%s", __FUNCTION__);
+
+       if (port->number != 0)
+               return 0;
+
+       priv = usb_get_serial_port_data(port);
+
+       if (port->tty) {
+               int val = 0;
+               if (priv->dtr_state)
+                       val |= 0x01;
+               if (priv->rts_state)
+                       val |= 0x02;
+
+               return usb_control_msg(serial->dev,
+                               usb_rcvctrlpipe(serial->dev, 0),
+                               0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+       }
+
+       return 0;
+}
+
 static void airprime_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
@@ -118,6 +153,10 @@ static int airprime_open(struct usb_serial_port *port, 
struct file *filp)
                usb_set_serial_port_data(port, priv);
        }
 
+       /* Set some sane defaults */
+       priv->rts_state = 1;
+       priv->dtr_state = 1;
+
        for (i = 0; i < NUM_READ_URBS; ++i) {
                buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!buffer) {
@@ -151,6 +190,9 @@ static int airprime_open(struct usb_serial_port *port, 
struct file *filp)
                /* remember this urb so we can kill it when the port is closed 
*/
                priv->read_urbp[i] = urb;
        }
+
+       airprime_send_setup(port);
+
        goto out;
 
  errout:
@@ -176,6 +218,11 @@ static void airprime_close(struct usb_serial_port *port, 
struct file * filp)
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
+       priv->rts_state = 0;
+       priv->dtr_state = 0;
+
+       airprime_send_setup(port);
+
        for (i = 0; i < NUM_READ_URBS; ++i) {
                usb_kill_urb (priv->read_urbp[i]);
                kfree (priv->read_urbp[i]->transfer_buffer);
-- 
1.5.0.2


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to