USB: RTS/DTR signal patch for airprime driver
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.
This commit is contained in:
parent
12bdbe03c8
commit
cf0cb1ae02
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user