Commit e1127c36 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

USB serial drivers

changes due to open_count being handled by the usb-serial core code.
parent 9fb1cce0
...@@ -191,9 +191,6 @@ static void belkin_sa_shutdown (struct usb_serial *serial) ...@@ -191,9 +191,6 @@ static void belkin_sa_shutdown (struct usb_serial *serial)
/* stop reads and writes on all ports */ /* stop reads and writes on all ports */
for (i=0; i < serial->num_ports; ++i) { for (i=0; i < serial->num_ports; ++i) {
while (serial->port[i].open_count > 0) {
belkin_sa_close (&serial->port[i], NULL);
}
/* My special items, the standard routines free my urbs */ /* My special items, the standard routines free my urbs */
if (serial->port[i].private) if (serial->port[i].private)
kfree(serial->port[i].private); kfree(serial->port[i].private);
...@@ -207,26 +204,22 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp) ...@@ -207,26 +204,22 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" port %d", port->number); dbg(__FUNCTION__" port %d", port->number);
++port->open_count; /*Start reading from the device*/
/* TODO: Look at possibility of submitting mulitple URBs to device to
if (port->open_count == 1) { * enhance buffering. Win trace shows 16 initial read URBs.
/*Start reading from the device*/ */
/* TODO: Look at possibility of submitting mulitple URBs to device to port->read_urb->dev = port->serial->dev;
* enhance buffering. Win trace shows 16 initial read URBs. retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
*/ if (retval) {
port->read_urb->dev = port->serial->dev; err("usb_submit_urb(read bulk) failed");
retval = usb_submit_urb(port->read_urb, GFP_KERNEL); goto exit;
if (retval) {
err("usb_submit_urb(read bulk) failed");
goto exit;
}
port->interrupt_in_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (retval)
err(" usb_submit_urb(read int) failed");
} }
port->interrupt_in_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (retval)
err(" usb_submit_urb(read int) failed");
exit: exit:
return retval; return retval;
} /* belkin_sa_open */ } /* belkin_sa_open */
...@@ -245,16 +238,11 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp) ...@@ -245,16 +238,11 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" port %d", port->number); dbg(__FUNCTION__" port %d", port->number);
--port->open_count; if (serial->dev) {
/* shutdown our bulk reads and writes */
if (port->open_count <= 0) { usb_unlink_urb (port->write_urb);
if (serial->dev) { usb_unlink_urb (port->read_urb);
/* shutdown our bulk reads and writes */ usb_unlink_urb (port->interrupt_in_urb);
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
usb_unlink_urb (port->interrupt_in_urb);
}
port->open_count = 0;
} }
} /* belkin_sa_close */ } /* belkin_sa_close */
......
...@@ -130,11 +130,7 @@ static void cyberjack_shutdown (struct usb_serial *serial) ...@@ -130,11 +130,7 @@ static void cyberjack_shutdown (struct usb_serial *serial)
dbg (__FUNCTION__); dbg (__FUNCTION__);
/* stop reads and writes on all ports */
for (i=0; i < serial->num_ports; ++i) { for (i=0; i < serial->num_ports; ++i) {
while (serial->port[i].open_count > 0) {
cyberjack_close (&serial->port[i], NULL);
}
/* My special items, the standard routines free my urbs */ /* My special items, the standard routines free my urbs */
if (serial->port[i].private) if (serial->port[i].private)
kfree(serial->port[i].private); kfree(serial->port[i].private);
...@@ -151,31 +147,27 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp) ...@@ -151,31 +147,27 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__ " - port %d", port->number); dbg(__FUNCTION__ " - port %d", port->number);
++port->open_count; /* force low_latency on so that our tty_push actually forces
* the data through, otherwise it is scheduled, and with high
* data rates (like with OHCI) data can get lost.
*/
port->tty->low_latency = 1;
if (port->open_count == 1) { priv = (struct cyberjack_private *)port->private;
/* force low_latency on so that our tty_push actually forces priv->rdtodo = 0;
* the data through, otherwise it is scheduled, and with high priv->wrfilled = 0;
* data rates (like with OHCI) data can get lost. priv->wrsent = 0;
*/
port->tty->low_latency = 1;
priv = (struct cyberjack_private *)port->private; /* shutdown any bulk reads that might be going on */
priv->rdtodo = 0; usb_unlink_urb (port->write_urb);
priv->wrfilled = 0; usb_unlink_urb (port->read_urb);
priv->wrsent = 0; usb_unlink_urb (port->interrupt_in_urb);
/* shutdown any bulk reads that might be going on */ port->interrupt_in_urb->dev = port->serial->dev;
usb_unlink_urb (port->write_urb); result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
usb_unlink_urb (port->read_urb); if (result)
usb_unlink_urb (port->interrupt_in_urb); err(" usb_submit_urb(read int) failed");
dbg(__FUNCTION__ " - usb_submit_urb(int urb)");
port->interrupt_in_urb->dev = port->serial->dev;
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result)
err(" usb_submit_urb(read int) failed");
dbg(__FUNCTION__ " - usb_submit_urb(int urb)");
}
return result; return result;
} }
...@@ -184,16 +176,11 @@ static void cyberjack_close (struct usb_serial_port *port, struct file *filp) ...@@ -184,16 +176,11 @@ static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
{ {
dbg(__FUNCTION__ " - port %d", port->number); dbg(__FUNCTION__ " - port %d", port->number);
--port->open_count; if (port->serial->dev) {
/* shutdown any bulk reads that might be going on */
if (port->open_count <= 0) { usb_unlink_urb (port->write_urb);
if (port->serial->dev) { usb_unlink_urb (port->read_urb);
/* shutdown any bulk reads that might be going on */ usb_unlink_urb (port->interrupt_in_urb);
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
usb_unlink_urb (port->interrupt_in_urb);
}
port->open_count = 0;
} }
} }
......
...@@ -1490,28 +1490,17 @@ dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_cou ...@@ -1490,28 +1490,17 @@ dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_cou
return( -EAGAIN ); return( -EAGAIN );
} }
/* inc module use count before sleeping to wait for closes */
++port->open_count;
/* wait for a close in progress to finish */ /* wait for a close in progress to finish */
while( priv->dp_in_close ) { while( priv->dp_in_close ) {
cond_wait_interruptible_timeout_irqrestore( cond_wait_interruptible_timeout_irqrestore(
&priv->dp_close_wait, DIGI_RETRY_TIMEOUT, &priv->dp_close_wait, DIGI_RETRY_TIMEOUT,
&priv->dp_port_lock, flags ); &priv->dp_port_lock, flags );
if( signal_pending(current) ) { if( signal_pending(current) ) {
--port->open_count;
return( -EINTR ); return( -EINTR );
} }
spin_lock_irqsave( &priv->dp_port_lock, flags ); spin_lock_irqsave( &priv->dp_port_lock, flags );
} }
/* if port is already open, just return */
/* be sure exactly one open proceeds */
if( port->open_count != 1) {
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
return( 0 );
}
spin_unlock_irqrestore( &priv->dp_port_lock, flags ); spin_unlock_irqrestore( &priv->dp_port_lock, flags );
/* read modem signals automatically whenever they change */ /* read modem signals automatically whenever they change */
...@@ -1557,14 +1546,6 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co ...@@ -1557,14 +1546,6 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co
/* do cleanup only after final close on this port */ /* do cleanup only after final close on this port */
spin_lock_irqsave( &priv->dp_port_lock, flags ); spin_lock_irqsave( &priv->dp_port_lock, flags );
if( port->open_count > 1 ) {
--port->open_count;
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
return;
} else if( port->open_count <= 0 ) {
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
return;
}
priv->dp_in_close = 1; priv->dp_in_close = 1;
spin_unlock_irqrestore( &priv->dp_port_lock, flags ); spin_unlock_irqrestore( &priv->dp_port_lock, flags );
...@@ -1637,7 +1618,6 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co ...@@ -1637,7 +1618,6 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co
spin_lock_irqsave( &priv->dp_port_lock, flags ); spin_lock_irqsave( &priv->dp_port_lock, flags );
priv->dp_write_urb_in_use = 0; priv->dp_write_urb_in_use = 0;
priv->dp_in_close = 0; priv->dp_in_close = 0;
--port->open_count;
wake_up_interruptible( &priv->dp_close_wait ); wake_up_interruptible( &priv->dp_close_wait );
spin_unlock_irqrestore( &priv->dp_port_lock, flags ); spin_unlock_irqrestore( &priv->dp_port_lock, flags );
...@@ -1765,8 +1745,6 @@ static void digi_shutdown( struct usb_serial *serial ) ...@@ -1765,8 +1745,6 @@ static void digi_shutdown( struct usb_serial *serial )
{ {
int i; int i;
struct digi_port *priv;
unsigned long flags;
dbg( "digi_shutdown: TOP, in_interrupt()=%d", in_interrupt() ); dbg( "digi_shutdown: TOP, in_interrupt()=%d", in_interrupt() );
...@@ -1777,16 +1755,6 @@ dbg( "digi_shutdown: TOP, in_interrupt()=%d", in_interrupt() ); ...@@ -1777,16 +1755,6 @@ dbg( "digi_shutdown: TOP, in_interrupt()=%d", in_interrupt() );
usb_unlink_urb( serial->port[i].write_urb ); usb_unlink_urb( serial->port[i].write_urb );
} }
/* dec module use count */
for( i=0; i<serial->type->num_ports; i++ ) {
priv = serial->port[i].private;
spin_lock_irqsave( &priv->dp_port_lock, flags );
while( serial->port[i].open_count > 0 ) {
--serial->port[i].open_count;
}
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
}
/* free the private data structures for all ports */ /* free the private data structures for all ports */
/* number of regular ports + 1 for the out-of-band port */ /* number of regular ports + 1 for the out-of-band port */
for( i=0; i<serial->type->num_ports+1; i++ ) for( i=0; i<serial->type->num_ports+1; i++ )
......
...@@ -157,35 +157,29 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp) ...@@ -157,35 +157,29 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__ " - port %d", port->number); dbg(__FUNCTION__ " - port %d", port->number);
++port->open_count; /* Force default termio settings */
empeg_set_termios (port, NULL) ;
if (port->open_count == 1) { bytes_in = 0;
bytes_out = 0;
/* Force default termio settings */ /* Start reading from the device */
empeg_set_termios (port, NULL) ; FILL_BULK_URB(
port->read_urb,
bytes_in = 0; serial->dev,
bytes_out = 0; usb_rcvbulkpipe(serial->dev,
port->bulk_in_endpointAddress),
/* Start reading from the device */ port->read_urb->transfer_buffer,
FILL_BULK_URB( port->read_urb->transfer_buffer_length,
port->read_urb, empeg_read_bulk_callback,
serial->dev, port);
usb_rcvbulkpipe(serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
empeg_read_bulk_callback,
port);
port->read_urb->transfer_flags |= USB_QUEUE_BULK;
result = usb_submit_urb(port->read_urb, GFP_KERNEL); port->read_urb->transfer_flags |= USB_QUEUE_BULK;
if (result) result = usb_submit_urb(port->read_urb, GFP_KERNEL);
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
} if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
return result; return result;
} }
...@@ -204,16 +198,10 @@ static void empeg_close (struct usb_serial_port *port, struct file * filp) ...@@ -204,16 +198,10 @@ static void empeg_close (struct usb_serial_port *port, struct file * filp)
if (!serial) if (!serial)
return; return;
--port->open_count; if (serial->dev) {
/* shutdown our bulk read */
if (port->open_count <= 0) { usb_unlink_urb (port->read_urb);
if (serial->dev) {
/* shutdown our bulk read */
usb_unlink_urb (port->read_urb);
}
port->open_count = 0;
} }
/* Uncomment the following line if you want to see some statistics in your syslog */ /* Uncomment the following line if you want to see some statistics in your syslog */
/* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
} }
...@@ -491,17 +479,7 @@ static int empeg_startup (struct usb_serial *serial) ...@@ -491,17 +479,7 @@ static int empeg_startup (struct usb_serial *serial)
static void empeg_shutdown (struct usb_serial *serial) static void empeg_shutdown (struct usb_serial *serial)
{ {
int i;
dbg (__FUNCTION__); dbg (__FUNCTION__);
/* stop reads and writes on all ports */
for (i=0; i < serial->num_ports; ++i) {
while (serial->port[i].open_count > 0) {
empeg_close (&serial->port[i], NULL);
}
}
} }
......
...@@ -294,14 +294,8 @@ static int ftdi_8U232AM_startup (struct usb_serial *serial) ...@@ -294,14 +294,8 @@ static int ftdi_8U232AM_startup (struct usb_serial *serial)
static void ftdi_sio_shutdown (struct usb_serial *serial) static void ftdi_sio_shutdown (struct usb_serial *serial)
{ {
dbg (__FUNCTION__); dbg (__FUNCTION__);
/* stop reads and writes on all ports */
while (serial->port[0].open_count > 0) {
ftdi_sio_close (&serial->port[0], NULL);
}
if (serial->port[0].private){ if (serial->port[0].private){
kfree(serial->port[0].private); kfree(serial->port[0].private);
serial->port[0].private = NULL; serial->port[0].private = NULL;
...@@ -319,45 +313,41 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp) ...@@ -319,45 +313,41 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__); dbg(__FUNCTION__);
++port->open_count; /* This will push the characters through immediately rather
than queue a task to deliver them */
port->tty->low_latency = 1;
if (port->open_count == 1){ /* No error checking for this (will get errors later anyway) */
/* This will push the characters through immediately rather /* See ftdi_sio.h for description of what is reset */
than queue a task to deliver them */ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
port->tty->low_latency = 1; FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE,
FTDI_SIO_RESET_SIO,
0, buf, 0, WDR_TIMEOUT);
/* No error checking for this (will get errors later anyway) */ /* Setup termios defaults. According to tty_io.c the
/* See ftdi_sio.h for description of what is reset */ settings are driver specific */
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), port->tty->termios->c_cflag =
FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, B9600 | CS8 | CREAD | HUPCL | CLOCAL;
FTDI_SIO_RESET_SIO,
0, buf, 0, WDR_TIMEOUT);
/* Setup termios defaults. According to tty_io.c the /* ftdi_sio_set_termios will send usb control messages */
settings are driver specific */ ftdi_sio_set_termios(port, &tmp_termios);
port->tty->termios->c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
/* ftdi_sio_set_termios will send usb control messages */ /* Turn on RTS and DTR since we are not flow controlling by default */
ftdi_sio_set_termios(port, &tmp_termios); if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0),HIGH) < 0) {
err(__FUNCTION__ " Error from DTR HIGH urb");
/* Turn on RTS and DTR since we are not flow controlling by default */
if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0),HIGH) < 0) {
err(__FUNCTION__ " Error from DTR HIGH urb");
}
if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),HIGH) < 0){
err(__FUNCTION__ " Error from RTS HIGH urb");
}
/* Start reading from the device */
FILL_BULK_URB(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
ftdi_sio_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
} }
if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),HIGH) < 0){
err(__FUNCTION__ " Error from RTS HIGH urb");
}
/* Start reading from the device */
FILL_BULK_URB(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
ftdi_sio_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
return result; return result;
} /* ftdi_sio_open */ } /* ftdi_sio_open */
...@@ -371,41 +361,31 @@ static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp) ...@@ -371,41 +361,31 @@ static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
dbg( __FUNCTION__); dbg( __FUNCTION__);
--port->open_count; if (serial->dev) {
if (c_cflag & HUPCL){
if (port->open_count <= 0) { /* Disable flow control */
if (serial->dev) { if (usb_control_msg(serial->dev,
if (c_cflag & HUPCL){ usb_sndctrlpipe(serial->dev, 0),
/* Disable flow control */ FTDI_SIO_SET_FLOW_CTRL_REQUEST,
if (usb_control_msg(serial->dev, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
usb_sndctrlpipe(serial->dev, 0), 0, 0, buf, 0, WDR_TIMEOUT) < 0) {
FTDI_SIO_SET_FLOW_CTRL_REQUEST, err("error from flowcontrol urb");
FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, }
0, 0, buf, 0, WDR_TIMEOUT) < 0) {
err("error from flowcontrol urb"); /* drop DTR */
} if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0), LOW) < 0){
err("Error from DTR LOW urb");
/* drop DTR */ }
if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0), LOW) < 0){ /* drop RTS */
err("Error from DTR LOW urb"); if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0) {
} err("Error from RTS LOW urb");
/* drop RTS */ }
if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0) { } /* Note change no line is hupcl is off */
err("Error from RTS LOW urb");
} /* shutdown our bulk reads and writes */
} /* Note change no line is hupcl is off */ /* ***CHECK*** behaviour when there is nothing queued */
usb_unlink_urb (port->write_urb);
/* shutdown our bulk reads and writes */ usb_unlink_urb (port->read_urb);
/* ***CHECK*** behaviour when there is nothing queued */
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
}
port->open_count = 0;
} else {
/* Send a HUP if necessary */
if (!(port->tty->termios->c_cflag & CLOCAL)){
tty_hangup(port->tty);
}
} }
} /* ftdi_sio_close */ } /* ftdi_sio_close */
......
...@@ -987,124 +987,117 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) ...@@ -987,124 +987,117 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
if (edge_port == NULL) if (edge_port == NULL)
return -ENODEV; return -ENODEV;
++port->open_count; /* force low_latency on so that our tty_push actually forces the data through,
otherwise it is scheduled, and with high data rates (like with OHCI) data
if (port->open_count == 1) { can get lost. */
/* force low_latency on so that our tty_push actually forces the data through, port->tty->low_latency = 1;
otherwise it is scheduled, and with high data rates (like with OHCI) data
can get lost. */ /* see if we've set up our endpoint info yet (can't set it up in edge_startup
port->tty->low_latency = 1; as the structures were not set up at that time.) */
serial = port->serial;
/* see if we've set up our endpoint info yet (can't set it up in edge_startup edge_serial = (struct edgeport_serial *)serial->private;
as the structures were not set up at that time.) */ if (edge_serial == NULL) {
serial = port->serial; return -ENODEV;
edge_serial = (struct edgeport_serial *)serial->private; }
if (edge_serial == NULL) { if (edge_serial->interrupt_in_buffer == NULL) {
port->open_count = 0; struct usb_serial_port *port0 = &serial->port[0];
return -ENODEV;
}
if (edge_serial->interrupt_in_buffer == NULL) {
struct usb_serial_port *port0 = &serial->port[0];
/* not set up yet, so do it now */
edge_serial->interrupt_in_buffer = port0->interrupt_in_buffer;
edge_serial->interrupt_in_endpoint = port0->interrupt_in_endpointAddress;
edge_serial->interrupt_read_urb = port0->interrupt_in_urb;
edge_serial->bulk_in_buffer = port0->bulk_in_buffer;
edge_serial->bulk_in_endpoint = port0->bulk_in_endpointAddress;
edge_serial->read_urb = port0->read_urb;
edge_serial->bulk_out_endpoint = port0->bulk_out_endpointAddress;
/* set up our interrupt urb */ /* not set up yet, so do it now */
FILL_INT_URB(edge_serial->interrupt_read_urb, edge_serial->interrupt_in_buffer = port0->interrupt_in_buffer;
serial->dev, edge_serial->interrupt_in_endpoint = port0->interrupt_in_endpointAddress;
usb_rcvintpipe(serial->dev, edge_serial->interrupt_read_urb = port0->interrupt_in_urb;
port0->interrupt_in_endpointAddress), edge_serial->bulk_in_buffer = port0->bulk_in_buffer;
port0->interrupt_in_buffer, edge_serial->bulk_in_endpoint = port0->bulk_in_endpointAddress;
edge_serial->interrupt_read_urb->transfer_buffer_length, edge_serial->read_urb = port0->read_urb;
edge_interrupt_callback, edge_serial, edge_serial->bulk_out_endpoint = port0->bulk_out_endpointAddress;
edge_serial->interrupt_read_urb->interval);
/* set up our interrupt urb */
/* set up our bulk in urb */ FILL_INT_URB(edge_serial->interrupt_read_urb,
FILL_BULK_URB(edge_serial->read_urb, serial->dev, serial->dev,
usb_rcvbulkpipe(serial->dev, port0->bulk_in_endpointAddress), usb_rcvintpipe(serial->dev,
port0->bulk_in_buffer, port0->interrupt_in_endpointAddress),
edge_serial->read_urb->transfer_buffer_length, port0->interrupt_in_buffer,
edge_bulk_in_callback, edge_serial); edge_serial->interrupt_read_urb->transfer_buffer_length,
edge_interrupt_callback, edge_serial,
/* start interrupt read for this edgeport edge_serial->interrupt_read_urb->interval);
* this interrupt will continue as long as the edgeport is connected */
response = usb_submit_urb (edge_serial->interrupt_read_urb, GFP_KERNEL);
if (response) {
err(__FUNCTION__" - Error %d submitting control urb", response);
}
}
/* initialize our wait queues */ /* set up our bulk in urb */
init_waitqueue_head(&edge_port->wait_open); FILL_BULK_URB(edge_serial->read_urb, serial->dev,
init_waitqueue_head(&edge_port->wait_chase); usb_rcvbulkpipe(serial->dev, port0->bulk_in_endpointAddress),
init_waitqueue_head(&edge_port->delta_msr_wait); port0->bulk_in_buffer,
init_waitqueue_head(&edge_port->wait_command); edge_serial->read_urb->transfer_buffer_length,
edge_bulk_in_callback, edge_serial);
/* initialize our icount structure */
memset (&(edge_port->icount), 0x00, sizeof(edge_port->icount)); /* start interrupt read for this edgeport
* this interrupt will continue as long as the edgeport is connected */
/* initialize our port settings */ response = usb_submit_urb (edge_serial->interrupt_read_urb, GFP_KERNEL);
edge_port->txCredits = 0; /* Can't send any data yet */ if (response) {
edge_port->shadowMCR = MCR_MASTER_IE; /* Must always set this bit to enable ints! */ err(__FUNCTION__" - Error %d submitting control urb", response);
edge_port->chaseResponsePending = FALSE;
/* send a open port command */
edge_port->openPending = TRUE;
edge_port->open = FALSE;
response = send_iosp_ext_cmd (edge_port, IOSP_CMD_OPEN_PORT, 0);
if (response < 0) {
err(__FUNCTION__" - error sending open port command");
edge_port->openPending = FALSE;
port->open_count = 0;
return -ENODEV;
}
/* now wait for the port to be completly opened */
timeout = OPEN_TIMEOUT;
while (timeout && edge_port->openPending == TRUE) {
timeout = interruptible_sleep_on_timeout (&edge_port->wait_open, timeout);
} }
}
/* initialize our wait queues */
init_waitqueue_head(&edge_port->wait_open);
init_waitqueue_head(&edge_port->wait_chase);
init_waitqueue_head(&edge_port->delta_msr_wait);
init_waitqueue_head(&edge_port->wait_command);
/* initialize our icount structure */
memset (&(edge_port->icount), 0x00, sizeof(edge_port->icount));
/* initialize our port settings */
edge_port->txCredits = 0; /* Can't send any data yet */
edge_port->shadowMCR = MCR_MASTER_IE; /* Must always set this bit to enable ints! */
edge_port->chaseResponsePending = FALSE;
/* send a open port command */
edge_port->openPending = TRUE;
edge_port->open = FALSE;
response = send_iosp_ext_cmd (edge_port, IOSP_CMD_OPEN_PORT, 0);
if (response < 0) {
err(__FUNCTION__" - error sending open port command");
edge_port->openPending = FALSE;
return -ENODEV;
}
if (edge_port->open == FALSE) { /* now wait for the port to be completly opened */
/* open timed out */ timeout = OPEN_TIMEOUT;
dbg(__FUNCTION__" - open timedout"); while (timeout && edge_port->openPending == TRUE) {
edge_port->openPending = FALSE; timeout = interruptible_sleep_on_timeout (&edge_port->wait_open, timeout);
port->open_count = 0; }
return -ENODEV;
}
/* create the txfifo */ if (edge_port->open == FALSE) {
edge_port->txfifo.head = 0; /* open timed out */
edge_port->txfifo.tail = 0; dbg(__FUNCTION__" - open timedout");
edge_port->txfifo.count = 0; edge_port->openPending = FALSE;
edge_port->txfifo.size = edge_port->maxTxCredits; return -ENODEV;
edge_port->txfifo.fifo = kmalloc (edge_port->maxTxCredits, GFP_KERNEL); }
if (!edge_port->txfifo.fifo) { /* create the txfifo */
dbg(__FUNCTION__" - no memory"); edge_port->txfifo.head = 0;
edge_close (port, filp); edge_port->txfifo.tail = 0;
return -ENOMEM; edge_port->txfifo.count = 0;
} edge_port->txfifo.size = edge_port->maxTxCredits;
edge_port->txfifo.fifo = kmalloc (edge_port->maxTxCredits, GFP_KERNEL);
/* Allocate a URB for the write */ if (!edge_port->txfifo.fifo) {
edge_port->write_urb = usb_alloc_urb (0, GFP_KERNEL); dbg(__FUNCTION__" - no memory");
edge_close (port, filp);
return -ENOMEM;
}
if (!edge_port->write_urb) { /* Allocate a URB for the write */
dbg(__FUNCTION__" - no memory"); edge_port->write_urb = usb_alloc_urb (0, GFP_KERNEL);
edge_close (port, filp);
return -ENOMEM;
}
dbg(__FUNCTION__"(%d) - Initialize TX fifo to %d bytes", port->number, edge_port->maxTxCredits); if (!edge_port->write_urb) {
dbg(__FUNCTION__" - no memory");
edge_close (port, filp);
return -ENOMEM;
} }
dbg(__FUNCTION__"(%d) - Initialize TX fifo to %d bytes", port->number, edge_port->maxTxCredits);
dbg(__FUNCTION__" exited"); dbg(__FUNCTION__" exited");
return 0; return 0;
...@@ -1234,52 +1227,47 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) ...@@ -1234,52 +1227,47 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
if ((edge_serial == NULL) || (edge_port == NULL)) if ((edge_serial == NULL) || (edge_port == NULL))
return; return;
--port->open_count; if (serial->dev) {
// block until tx is empty
if (port->open_count <= 0) { block_until_tx_empty(edge_port);
if (serial->dev) {
// block until tx is empty
block_until_tx_empty(edge_port);
edge_port->closePending = TRUE; edge_port->closePending = TRUE;
/* flush and chase */ /* flush and chase */
edge_port->chaseResponsePending = TRUE; edge_port->chaseResponsePending = TRUE;
dbg(__FUNCTION__" - Sending IOSP_CMD_CHASE_PORT"); dbg(__FUNCTION__" - Sending IOSP_CMD_CHASE_PORT");
status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0);
if (status == 0) { if (status == 0) {
// block until chase finished // block until chase finished
block_until_chase_response(edge_port); block_until_chase_response(edge_port);
} else { } else {
edge_port->chaseResponsePending = FALSE; edge_port->chaseResponsePending = FALSE;
} }
/* close the port */ /* close the port */
dbg(__FUNCTION__" - Sending IOSP_CMD_CLOSE_PORT"); dbg(__FUNCTION__" - Sending IOSP_CMD_CLOSE_PORT");
send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0);
//port->close = TRUE; //port->close = TRUE;
edge_port->closePending = FALSE; edge_port->closePending = FALSE;
edge_port->open = FALSE; edge_port->open = FALSE;
edge_port->openPending = FALSE; edge_port->openPending = FALSE;
if (edge_port->write_urb) {
usb_unlink_urb (edge_port->write_urb);
}
}
if (edge_port->write_urb) { if (edge_port->write_urb) {
/* if this urb had a transfer buffer already (old transfer) free it */ usb_unlink_urb (edge_port->write_urb);
if (edge_port->write_urb->transfer_buffer != NULL) {
kfree(edge_port->write_urb->transfer_buffer);
}
usb_free_urb (edge_port->write_urb);
} }
if (edge_port->txfifo.fifo) { }
kfree(edge_port->txfifo.fifo);
if (edge_port->write_urb) {
/* if this urb had a transfer buffer already (old transfer) free it */
if (edge_port->write_urb->transfer_buffer != NULL) {
kfree(edge_port->write_urb->transfer_buffer);
} }
port->open_count = 0; usb_free_urb (edge_port->write_urb);
}
if (edge_port->txfifo.fifo) {
kfree(edge_port->txfifo.fifo);
} }
dbg(__FUNCTION__" exited"); dbg(__FUNCTION__" exited");
...@@ -3027,9 +3015,6 @@ static void edge_shutdown (struct usb_serial *serial) ...@@ -3027,9 +3015,6 @@ static void edge_shutdown (struct usb_serial *serial)
/* stop reads and writes on all ports */ /* stop reads and writes on all ports */
for (i=0; i < serial->num_ports; ++i) { for (i=0; i < serial->num_ports; ++i) {
while (serial->port[i].open_count > 0) {
edge_close (&serial->port[i], NULL);
}
kfree (serial->port[i].private); kfree (serial->port[i].private);
serial->port[i].private = NULL; serial->port[i].private = NULL;
} }
......
...@@ -123,93 +123,89 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) ...@@ -123,93 +123,89 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__ " - port %d", port->number); dbg(__FUNCTION__ " - port %d", port->number);
++port->open_count; bytes_in = 0;
bytes_out = 0;
if (port->open_count == 1) { priv = (struct ipaq_private *)kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
bytes_in = 0; if (priv == NULL) {
bytes_out = 0; err(__FUNCTION__ " - Out of memory");
priv = (struct ipaq_private *)kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); return -ENOMEM;
if (priv == NULL) { }
err(__FUNCTION__ " - Out of memory"); port->private = (void *)priv;
return -ENOMEM; priv->active = 0;
priv->queue_len = 0;
INIT_LIST_HEAD(&priv->queue);
INIT_LIST_HEAD(&priv->freelist);
for (i = 0; i < URBDATA_QUEUE_MAX / PACKET_SIZE; i++) {
pkt = kmalloc(sizeof(struct ipaq_packet), GFP_KERNEL);
if (pkt == NULL) {
goto enomem;
} }
port->private = (void *)priv; pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL);
priv->active = 0; if (pkt->data == NULL) {
priv->queue_len = 0; kfree(pkt);
INIT_LIST_HEAD(&priv->queue); goto enomem;
INIT_LIST_HEAD(&priv->freelist);
for (i = 0; i < URBDATA_QUEUE_MAX / PACKET_SIZE; i++) {
pkt = kmalloc(sizeof(struct ipaq_packet), GFP_KERNEL);
if (pkt == NULL) {
goto enomem;
}
pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL);
if (pkt->data == NULL) {
kfree(pkt);
goto enomem;
}
pkt->len = 0;
pkt->written = 0;
INIT_LIST_HEAD(&pkt->list);
list_add(&pkt->list, &priv->freelist);
priv->free_len += PACKET_SIZE;
} }
pkt->len = 0;
pkt->written = 0;
INIT_LIST_HEAD(&pkt->list);
list_add(&pkt->list, &priv->freelist);
priv->free_len += PACKET_SIZE;
}
/* /*
* Force low latency on. This will immediately push data to the line * Force low latency on. This will immediately push data to the line
* discipline instead of queueing. * discipline instead of queueing.
*/ */
port->tty->low_latency = 1; port->tty->low_latency = 1;
port->tty->raw = 1; port->tty->raw = 1;
port->tty->real_raw = 1; port->tty->real_raw = 1;
/* /*
* Lose the small buffers usbserial provides. Make larger ones. * Lose the small buffers usbserial provides. Make larger ones.
*/ */
kfree(port->bulk_in_buffer);
kfree(port->bulk_out_buffer);
port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL);
if (port->bulk_in_buffer == NULL) {
goto enomem;
}
port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL);
if (port->bulk_out_buffer == NULL) {
kfree(port->bulk_in_buffer); kfree(port->bulk_in_buffer);
kfree(port->bulk_out_buffer); goto enomem;
port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); }
if (port->bulk_in_buffer == NULL) { port->read_urb->transfer_buffer = port->bulk_in_buffer;
goto enomem; port->write_urb->transfer_buffer = port->bulk_out_buffer;
} port->read_urb->transfer_buffer_length = URBDATA_SIZE;
port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE;
if (port->bulk_out_buffer == NULL) {
kfree(port->bulk_in_buffer); /* Start reading from the device */
goto enomem; FILL_BULK_URB(port->read_urb, serial->dev,
} usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer = port->bulk_in_buffer; port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
port->write_urb->transfer_buffer = port->bulk_out_buffer; ipaq_read_bulk_callback, port);
port->read_urb->transfer_buffer_length = URBDATA_SIZE; result = usb_submit_urb(port->read_urb, GFP_KERNEL);
port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE; if (result) {
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
/* Start reading from the device */ }
FILL_BULK_URB(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
ipaq_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result) {
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
}
/* /*
* Send out two control messages observed in win98 sniffs. Not sure what * Send out two control messages observed in win98 sniffs. Not sure what
* they do. * they do.
*/ */
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
0x1, 0, NULL, 0, 5 * HZ); 0x1, 0, NULL, 0, 5 * HZ);
if (result < 0) { if (result < 0) {
err(__FUNCTION__ " - failed doing control urb, error %d", result); err(__FUNCTION__ " - failed doing control urb, error %d", result);
} }
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
0x1, 0, NULL, 0, 5 * HZ); 0x1, 0, NULL, 0, 5 * HZ);
if (result < 0) { if (result < 0) {
err(__FUNCTION__ " - failed doing control urb, error %d", result); err(__FUNCTION__ " - failed doing control urb, error %d", result);
}
} }
return result; return result;
...@@ -237,22 +233,16 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp) ...@@ -237,22 +233,16 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp)
if (!serial) if (!serial)
return; return;
--port->open_count; /*
* shut down bulk read and write
*/
if (port->open_count <= 0) { usb_unlink_urb(port->write_urb);
usb_unlink_urb(port->read_urb);
/* ipaq_destroy_lists(port);
* shut down bulk read and write kfree(priv);
*/ port->private = NULL;
usb_unlink_urb(port->write_urb);
usb_unlink_urb(port->read_urb);
ipaq_destroy_lists(port);
kfree(priv);
port->private = NULL;
port->open_count = 0;
}
/* Uncomment the following line if you want to see some statistics in your syslog */ /* Uncomment the following line if you want to see some statistics in your syslog */
/* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
} }
...@@ -507,16 +497,7 @@ static int ipaq_startup(struct usb_serial *serial) ...@@ -507,16 +497,7 @@ static int ipaq_startup(struct usb_serial *serial)
static void ipaq_shutdown(struct usb_serial *serial) static void ipaq_shutdown(struct usb_serial *serial)
{ {
int i;
dbg (__FUNCTION__); dbg (__FUNCTION__);
/* stop reads and writes on all ports */
for (i=0; i < serial->num_ports; ++i) {
while (serial->port[i].open_count > 0) {
ipaq_close(&serial->port[i], NULL);
}
}
} }
static int __init ipaq_init(void) static int __init ipaq_init(void)
......
...@@ -283,45 +283,42 @@ static int ir_open (struct usb_serial_port *port, struct file *filp) ...@@ -283,45 +283,42 @@ static int ir_open (struct usb_serial_port *port, struct file *filp)
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
++port->open_count; if (buffer_size) {
/* override the default buffer sizes */
if (port->open_count == 1) { buffer = kmalloc (buffer_size, GFP_KERNEL);
if (buffer_size) { if (!buffer) {
/* override the default buffer sizes */ err ("%s - out of memory.", __FUNCTION__);
buffer = kmalloc (buffer_size, GFP_KERNEL); return -ENOMEM;
if (!buffer) {
err ("%s - out of memory.", __FUNCTION__);
return -ENOMEM;
}
kfree (port->read_urb->transfer_buffer);
port->read_urb->transfer_buffer = buffer;
port->read_urb->transfer_buffer_length = buffer_size;
buffer = kmalloc (buffer_size, GFP_KERNEL);
if (!buffer) {
err ("%s - out of memory.", __FUNCTION__);
return -ENOMEM;
}
kfree (port->write_urb->transfer_buffer);
port->write_urb->transfer_buffer = buffer;
port->write_urb->transfer_buffer_length = buffer_size;
port->bulk_out_size = buffer_size;
} }
kfree (port->read_urb->transfer_buffer);
/* Start reading from the device */ port->read_urb->transfer_buffer = buffer;
usb_fill_bulk_urb ( port->read_urb->transfer_buffer_length = buffer_size;
port->read_urb,
serial->dev, buffer = kmalloc (buffer_size, GFP_KERNEL);
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), if (!buffer) {
port->read_urb->transfer_buffer, err ("%s - out of memory.", __FUNCTION__);
port->read_urb->transfer_buffer_length, return -ENOMEM;
ir_read_bulk_callback, }
port); kfree (port->write_urb->transfer_buffer);
port->read_urb->transfer_flags = USB_QUEUE_BULK; port->write_urb->transfer_buffer = buffer;
result = usb_submit_urb(port->read_urb, GFP_KERNEL); port->write_urb->transfer_buffer_length = buffer_size;
if (result) port->bulk_out_size = buffer_size;
err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
} }
/* Start reading from the device */
usb_fill_bulk_urb (
port->read_urb,
serial->dev,
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
ir_read_bulk_callback,
port);
port->read_urb->transfer_flags = USB_QUEUE_BULK;
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
return result; return result;
} }
...@@ -338,15 +335,9 @@ static void ir_close (struct usb_serial_port *port, struct file * filp) ...@@ -338,15 +335,9 @@ static void ir_close (struct usb_serial_port *port, struct file * filp)
if (!serial) if (!serial)
return; return;
--port->open_count; if (serial->dev) {
/* shutdown our bulk read */
if (port->open_count <= 0) { usb_unlink_urb (port->read_urb);
if (serial->dev) {
/* shutdown our bulk read */
usb_unlink_urb (port->read_urb);
}
port->open_count = 0;
} }
} }
......
...@@ -852,7 +852,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) ...@@ -852,7 +852,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
struct keyspan_serial_private *s_priv; struct keyspan_serial_private *s_priv;
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
const struct keyspan_device_details *d_details; const struct keyspan_device_details *d_details;
int i, already_active, err; int i, err;
struct urb *urb; struct urb *urb;
s_priv = (struct keyspan_serial_private *)(serial->private); s_priv = (struct keyspan_serial_private *)(serial->private);
...@@ -861,12 +861,6 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) ...@@ -861,12 +861,6 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
dbg("keyspan_open called for port%d.\n", port->number); dbg("keyspan_open called for port%d.\n", port->number);
already_active = port->open_count;
++port->open_count;
if (already_active)
return 0;
p_priv = (struct keyspan_port_private *)(port->private); p_priv = (struct keyspan_port_private *)(port->private);
/* Set some sane defaults */ /* Set some sane defaults */
...@@ -924,19 +918,16 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp) ...@@ -924,19 +918,16 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
p_priv->out_flip = 0; p_priv->out_flip = 0;
p_priv->in_flip = 0; p_priv->in_flip = 0;
if (--port->open_count <= 0) { if (serial->dev) {
if (serial->dev) { /* Stop reading/writing urbs */
/* Stop reading/writing urbs */ stop_urb(p_priv->inack_urb);
stop_urb(p_priv->inack_urb); stop_urb(p_priv->outcont_urb);
stop_urb(p_priv->outcont_urb); for (i = 0; i < 2; i++) {
for (i = 0; i < 2; i++) { stop_urb(p_priv->in_urbs[i]);
stop_urb(p_priv->in_urbs[i]); stop_urb(p_priv->out_urbs[i]);
stop_urb(p_priv->out_urbs[i]);
}
} }
port->open_count = 0;
port->tty = 0;
} }
port->tty = 0;
} }
...@@ -1762,9 +1753,6 @@ static void keyspan_shutdown (struct usb_serial *serial) ...@@ -1762,9 +1753,6 @@ static void keyspan_shutdown (struct usb_serial *serial)
/* Now free per port private data */ /* Now free per port private data */
for (i = 0; i < serial->num_ports; i++) { for (i = 0; i < serial->num_ports; i++) {
port = &serial->port[i]; port = &serial->port[i];
while (port->open_count > 0) {
--port->open_count;
}
kfree(port->private); kfree(port->private);
} }
} }
......
...@@ -662,52 +662,45 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp) ...@@ -662,52 +662,45 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
int rc = 0; int rc = 0;
struct keyspan_pda_private *priv; struct keyspan_pda_private *priv;
++port->open_count; /* find out how much room is in the Tx ring */
rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
if (port->open_count == 1) { 6, /* write_room */
/* find out how much room is in the Tx ring */ USB_TYPE_VENDOR | USB_RECIP_INTERFACE
rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | USB_DIR_IN,
6, /* write_room */ 0, /* value */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE 0, /* index */
| USB_DIR_IN, &room,
0, /* value */ 1,
0, /* index */ 2*HZ);
&room, if (rc < 0) {
1, dbg(__FUNCTION__" - roomquery failed");
2*HZ); goto error;
if (rc < 0) { }
dbg(__FUNCTION__" - roomquery failed"); if (rc == 0) {
goto error; dbg(__FUNCTION__" - roomquery returned 0 bytes");
} rc = -EIO;
if (rc == 0) { goto error;
dbg(__FUNCTION__" - roomquery returned 0 bytes"); }
rc = -EIO; priv = (struct keyspan_pda_private *)(port->private);
goto error; priv->tx_room = room;
} priv->tx_throttled = room ? 0 : 1;
priv = (struct keyspan_pda_private *)(port->private);
priv->tx_room = room;
priv->tx_throttled = room ? 0 : 1;
/* the normal serial device seems to always turn on DTR and RTS here,
so do the same */
if (port->tty->termios->c_cflag & CBAUD)
keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
else
keyspan_pda_set_modem_info(serial, 0);
/*Start reading from the device*/
port->interrupt_in_urb->dev = serial->dev;
rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (rc) {
dbg(__FUNCTION__" - usb_submit_urb(read int) failed");
goto error;
}
/* the normal serial device seems to always turn on DTR and RTS here,
so do the same */
if (port->tty->termios->c_cflag & CBAUD)
keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
else
keyspan_pda_set_modem_info(serial, 0);
/*Start reading from the device*/
port->interrupt_in_urb->dev = serial->dev;
rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (rc) {
dbg(__FUNCTION__" - usb_submit_urb(read int) failed");
goto error;
} }
return rc;
error: error:
--port->open_count;
return rc; return rc;
} }
...@@ -716,19 +709,14 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp) ...@@ -716,19 +709,14 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
{ {
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
--port->open_count; if (serial->dev) {
/* the normal serial device seems to always shut off DTR and RTS now */
if (port->open_count <= 0) { if (port->tty->termios->c_cflag & HUPCL)
if (serial->dev) { keyspan_pda_set_modem_info(serial, 0);
/* the normal serial device seems to always shut off DTR and RTS now */
if (port->tty->termios->c_cflag & HUPCL)
keyspan_pda_set_modem_info(serial, 0);
/* shutdown our bulk reads and writes */ /* shutdown our bulk reads and writes */
usb_unlink_urb (port->write_urb); usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->interrupt_in_urb); usb_unlink_urb (port->interrupt_in_urb);
}
port->open_count = 0;
} }
} }
...@@ -805,9 +793,6 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) ...@@ -805,9 +793,6 @@ static void keyspan_pda_shutdown (struct usb_serial *serial)
{ {
dbg (__FUNCTION__); dbg (__FUNCTION__);
while (serial->port[0].open_count > 0) {
keyspan_pda_close (&serial->port[0], NULL);
}
kfree(serial->port[0].private); kfree(serial->port[0].private);
} }
......
...@@ -317,9 +317,6 @@ static void klsi_105_shutdown (struct usb_serial *serial) ...@@ -317,9 +317,6 @@ static void klsi_105_shutdown (struct usb_serial *serial)
struct klsi_105_private *priv = struct klsi_105_private *priv =
(struct klsi_105_private*) serial->port[i].private; (struct klsi_105_private*) serial->port[i].private;
unsigned long flags; unsigned long flags;
while (serial->port[i].open_count > 0) {
klsi_105_close (&serial->port[i], NULL);
}
if (priv) { if (priv) {
/* kill our write urb pool */ /* kill our write urb pool */
...@@ -355,85 +352,80 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp) ...@@ -355,85 +352,80 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp)
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
struct klsi_105_private *priv = (struct klsi_105_private *)port->private; struct klsi_105_private *priv = (struct klsi_105_private *)port->private;
int retval = 0; int retval = 0;
int rc;
int i;
unsigned long line_state;
dbg(__FUNCTION__" port %d", port->number); dbg(__FUNCTION__" port %d", port->number);
++port->open_count; /* force low_latency on so that our tty_push actually forces
* the data through
* port->tty->low_latency = 1; */
if (port->open_count == 1) { /* Do a defined restart:
int rc; * Set up sane default baud rate and send the 'READ_ON'
int i; * vendor command.
unsigned long line_state; * FIXME: set modem line control (how?)
* Then read the modem line control and store values in
/* force low_latency on so that our tty_push actually forces * priv->line_state.
* the data through */
* port->tty->low_latency = 1; */ priv->cfg.pktlen = 5;
priv->cfg.baudrate = kl5kusb105a_sio_b9600;
/* Do a defined restart: priv->cfg.databits = kl5kusb105a_dtb_8;
* Set up sane default baud rate and send the 'READ_ON' priv->cfg.unknown1 = 0;
* vendor command. priv->cfg.unknown2 = 1;
* FIXME: set modem line control (how?) klsi_105_chg_port_settings(serial, &(priv->cfg));
* Then read the modem line control and store values in
* priv->line_state. /* set up termios structure */
*/ priv->termios.c_iflag = port->tty->termios->c_iflag;
priv->cfg.pktlen = 5; priv->termios.c_oflag = port->tty->termios->c_oflag;
priv->cfg.baudrate = kl5kusb105a_sio_b9600; priv->termios.c_cflag = port->tty->termios->c_cflag;
priv->cfg.databits = kl5kusb105a_dtb_8; priv->termios.c_lflag = port->tty->termios->c_lflag;
priv->cfg.unknown1 = 0; for (i=0; i<NCCS; i++)
priv->cfg.unknown2 = 1; priv->termios.c_cc[i] = port->tty->termios->c_cc[i];
klsi_105_chg_port_settings(serial, &(priv->cfg));
/* set up termios structure */
priv->termios.c_iflag = port->tty->termios->c_iflag;
priv->termios.c_oflag = port->tty->termios->c_oflag;
priv->termios.c_cflag = port->tty->termios->c_cflag;
priv->termios.c_lflag = port->tty->termios->c_lflag;
for (i=0; i<NCCS; i++)
priv->termios.c_cc[i] = port->tty->termios->c_cc[i];
/* READ_ON and urb submission */
FILL_BULK_URB(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
klsi_105_read_bulk_callback,
port);
port->read_urb->transfer_flags |= USB_QUEUE_BULK;
rc = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (rc) {
err(__FUNCTION__
" - failed submitting read urb, error %d", rc);
retval = rc;
goto exit;
}
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), /* READ_ON and urb submission */
KL5KUSB105A_SIO_CONFIGURE, FILL_BULK_URB(port->read_urb, serial->dev,
USB_TYPE_VENDOR|USB_DIR_OUT|USB_RECIP_INTERFACE, usb_rcvbulkpipe(serial->dev,
KL5KUSB105A_SIO_CONFIGURE_READ_ON, port->bulk_in_endpointAddress),
0, /* index */ port->read_urb->transfer_buffer,
NULL, port->read_urb->transfer_buffer_length,
0, klsi_105_read_bulk_callback,
KLSI_TIMEOUT); port);
if (rc < 0) { port->read_urb->transfer_flags |= USB_QUEUE_BULK;
err("Enabling read failed (error = %d)", rc);
retval = rc;
} else
dbg(__FUNCTION__ " - enabled reading");
rc = klsi_105_get_line_state(serial, &line_state); rc = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (rc >= 0) { if (rc) {
priv->line_state = line_state; err(__FUNCTION__
dbg(__FUNCTION__ " - failed submitting read urb, error %d", rc);
" - read line state 0x%lx", line_state); retval = rc;
retval = 0; goto exit;
} else
retval = rc;
} }
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0),
KL5KUSB105A_SIO_CONFIGURE,
USB_TYPE_VENDOR|USB_DIR_OUT|USB_RECIP_INTERFACE,
KL5KUSB105A_SIO_CONFIGURE_READ_ON,
0, /* index */
NULL,
0,
KLSI_TIMEOUT);
if (rc < 0) {
err("Enabling read failed (error = %d)", rc);
retval = rc;
} else
dbg(__FUNCTION__ " - enabled reading");
rc = klsi_105_get_line_state(serial, &line_state);
if (rc >= 0) {
priv->line_state = line_state;
dbg(__FUNCTION__
" - read line state 0x%lx", line_state);
retval = 0;
} else
retval = rc;
exit: exit:
return retval; return retval;
} /* klsi_105_open */ } /* klsi_105_open */
...@@ -444,6 +436,7 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp) ...@@ -444,6 +436,7 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp)
struct usb_serial *serial; struct usb_serial *serial;
struct klsi_105_private *priv struct klsi_105_private *priv
= (struct klsi_105_private *)port->private; = (struct klsi_105_private *)port->private;
int rc;
dbg(__FUNCTION__" port %d", port->number); dbg(__FUNCTION__" port %d", port->number);
serial = get_usb_serial (port, __FUNCTION__); serial = get_usb_serial (port, __FUNCTION__);
...@@ -451,31 +444,26 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp) ...@@ -451,31 +444,26 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp)
if(!serial) if(!serial)
return; return;
--port->open_count; /* send READ_OFF */
rc = usb_control_msg (serial->dev,
if (port->open_count <= 0) { usb_sndctrlpipe(serial->dev, 0),
/* send READ_OFF */ KL5KUSB105A_SIO_CONFIGURE,
int rc = usb_control_msg(serial->dev, USB_TYPE_VENDOR | USB_DIR_OUT,
usb_sndctrlpipe(serial->dev, 0), KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
KL5KUSB105A_SIO_CONFIGURE, 0, /* index */
USB_TYPE_VENDOR | USB_DIR_OUT, NULL, 0,
KL5KUSB105A_SIO_CONFIGURE_READ_OFF, KLSI_TIMEOUT);
0, /* index */ if (rc < 0)
NULL, 0, err("Disabling read failed (error = %d)", rc);
KLSI_TIMEOUT);
if (rc < 0) /* shutdown our bulk reads and writes */
err("Disabling read failed (error = %d)", rc); usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
/* shutdown our bulk reads and writes */ /* unlink our write pool */
usb_unlink_urb (port->write_urb); /* FIXME */
usb_unlink_urb (port->read_urb); /* wgg - do I need this? I think so. */
/* unlink our write pool */ usb_unlink_urb (port->interrupt_in_urb);
/* FIXME */ info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out);
/* wgg - do I need this? I think so. */
usb_unlink_urb (port->interrupt_in_urb);
port->open_count = 0;
info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out);
}
} /* klsi_105_close */ } /* klsi_105_close */
......
...@@ -324,9 +324,6 @@ static void mct_u232_shutdown (struct usb_serial *serial) ...@@ -324,9 +324,6 @@ static void mct_u232_shutdown (struct usb_serial *serial)
/* stop reads and writes on all ports */ /* stop reads and writes on all ports */
for (i=0; i < serial->num_ports; ++i) { for (i=0; i < serial->num_ports; ++i) {
while (serial->port[i].open_count > 0) {
mct_u232_close (&serial->port[i], NULL);
}
/* My special items, the standard routines free my urbs */ /* My special items, the standard routines free my urbs */
if (serial->port[i].private) if (serial->port[i].private)
kfree(serial->port[i].private); kfree(serial->port[i].private);
...@@ -341,60 +338,55 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp) ...@@ -341,60 +338,55 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" port %d", port->number); dbg(__FUNCTION__" port %d", port->number);
++port->open_count; /* Compensate for a hardware bug: although the Sitecom U232-P25
* device reports a maximum output packet size of 32 bytes,
if (port->open_count == 1) { * it seems to be able to accept only 16 bytes (and that's what
/* Compensate for a hardware bug: although the Sitecom U232-P25 * SniffUSB says too...)
* device reports a maximum output packet size of 32 bytes, */
* it seems to be able to accept only 16 bytes (and that's what if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID)
* SniffUSB says too...) port->bulk_out_size = 16;
*/
if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID)
port->bulk_out_size = 16;
/* Do a defined restart: the normal serial device seems to
* always turn on DTR and RTS here, so do the same. I'm not
* sure if this is really necessary. But it should not harm
* either.
*/
if (port->tty->termios->c_cflag & CBAUD)
priv->control_state = TIOCM_DTR | TIOCM_RTS;
else
priv->control_state = 0;
mct_u232_set_modem_ctrl(serial, priv->control_state);
priv->last_lcr = (MCT_U232_DATA_BITS_8 |
MCT_U232_PARITY_NONE |
MCT_U232_STOP_BITS_1);
mct_u232_set_line_ctrl(serial, priv->last_lcr);
/* Read modem status and update control state */ /* Do a defined restart: the normal serial device seems to
mct_u232_get_modem_stat(serial, &priv->last_msr); * always turn on DTR and RTS here, so do the same. I'm not
mct_u232_msr_to_state(&priv->control_state, priv->last_msr); * sure if this is really necessary. But it should not harm
* either.
{ */
/* Puh, that's dirty */ if (port->tty->termios->c_cflag & CBAUD)
struct usb_serial_port *rport; priv->control_state = TIOCM_DTR | TIOCM_RTS;
rport = &serial->port[1]; else
rport->tty = port->tty; priv->control_state = 0;
rport->private = port->private; mct_u232_set_modem_ctrl(serial, priv->control_state);
port->read_urb = rport->interrupt_in_urb;
} priv->last_lcr = (MCT_U232_DATA_BITS_8 |
MCT_U232_PARITY_NONE |
MCT_U232_STOP_BITS_1);
mct_u232_set_line_ctrl(serial, priv->last_lcr);
port->read_urb->dev = port->serial->dev; /* Read modem status and update control state */
retval = usb_submit_urb(port->read_urb, GFP_KERNEL); mct_u232_get_modem_stat(serial, &priv->last_msr);
if (retval) { mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
err("usb_submit_urb(read bulk) failed");
goto exit;
}
port->interrupt_in_urb->dev = port->serial->dev; {
retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); /* Puh, that's dirty */
if (retval) struct usb_serial_port *rport;
err(" usb_submit_urb(read int) failed"); rport = &serial->port[1];
rport->tty = port->tty;
rport->private = port->private;
port->read_urb = rport->interrupt_in_urb;
}
port->read_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (retval) {
err("usb_submit_urb(read bulk) failed");
goto exit;
} }
port->interrupt_in_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (retval)
err(" usb_submit_urb(read int) failed");
exit: exit:
return 0; return 0;
} /* mct_u232_open */ } /* mct_u232_open */
...@@ -404,16 +396,11 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp) ...@@ -404,16 +396,11 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
{ {
dbg(__FUNCTION__" port %d", port->number); dbg(__FUNCTION__" port %d", port->number);
--port->open_count; if (port->serial->dev) {
/* shutdown our urbs */
if (port->open_count <= 0) { usb_unlink_urb (port->write_urb);
if (port->serial->dev) { usb_unlink_urb (port->read_urb);
/* shutdown our urbs */ usb_unlink_urb (port->interrupt_in_urb);
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
usb_unlink_urb (port->interrupt_in_urb);
}
port->open_count = 0;
} }
} /* mct_u232_close */ } /* mct_u232_close */
......
...@@ -157,30 +157,25 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) ...@@ -157,30 +157,25 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
if (!serial) if (!serial)
return -ENODEV; return -ENODEV;
++port->open_count; od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
if( !od ) {
if (port->open_count == 1) { err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data));
od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); return -ENOMEM;
if( !od ) {
err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data));
port->open_count = 0;
return -ENOMEM;
}
port->private = od;
wport = &serial->port[1];
wport->tty = port->tty;
/* Start reading from the device */
FILL_BULK_URB(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
omninet_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
} }
port->private = od;
wport = &serial->port[1];
wport->tty = port->tty;
/* Start reading from the device */
FILL_BULK_URB(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
omninet_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
return result; return result;
} }
...@@ -199,20 +194,15 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp) ...@@ -199,20 +194,15 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp)
if (!serial) if (!serial)
return; return;
--port->open_count; if (serial->dev) {
wport = &serial->port[1];
if (port->open_count <= 0) { usb_unlink_urb (wport->write_urb);
if (serial->dev) { usb_unlink_urb (port->read_urb);
wport = &serial->port[1];
usb_unlink_urb (wport->write_urb);
usb_unlink_urb (port->read_urb);
}
port->open_count = 0;
od = (struct omninet_data *)port->private;
if (od)
kfree(od);
} }
od = (struct omninet_data *)port->private;
if (od)
kfree(od);
} }
...@@ -377,10 +367,6 @@ static void omninet_write_bulk_callback (struct urb *urb) ...@@ -377,10 +367,6 @@ static void omninet_write_bulk_callback (struct urb *urb)
static void omninet_shutdown (struct usb_serial *serial) static void omninet_shutdown (struct usb_serial *serial)
{ {
dbg (__FUNCTION__); dbg (__FUNCTION__);
while (serial->port[0].open_count > 0) {
omninet_close (&serial->port[0], NULL);
}
} }
......
...@@ -367,56 +367,52 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) ...@@ -367,56 +367,52 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
dbg (__FUNCTION__ " - port %d", port->number); dbg (__FUNCTION__ " - port %d", port->number);
++port->open_count; #define FISH(a,b,c,d) \
result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \
if (port->open_count == 1) { b, a, c, d, buf, 1, 100); \
#define FISH(a,b,c,d) \ dbg("0x%x:0x%x:0x%x:0x%x %d - %x",a,b,c,d,result,buf[0]);
result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \
b, a, c, d, buf, 1, 100); \ #define SOUP(a,b,c,d) \
dbg("0x%x:0x%x:0x%x:0x%x %d - %x",a,b,c,d,result,buf[0]); result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \
b, a, c, d, NULL, 0, 100); \
#define SOUP(a,b,c,d) \ dbg("0x%x:0x%x:0x%x:0x%x %d",a,b,c,d,result);
result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \
b, a, c, d, NULL, 0, 100); \ FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
dbg("0x%x:0x%x:0x%x:0x%x %d",a,b,c,d,result); SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 0);
FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 0); FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1);
FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1); SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1);
FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0xc0);
FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 4);
SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1);
SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0xc0); /* Setup termios */
SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 4); *(port->tty->termios) = tty_std_termios;
port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
/* Setup termios */
*(port->tty->termios) = tty_std_termios; pl2303_set_termios (port, &tmp_termios);
port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
//FIXME: need to assert RTS and DTR if CRTSCTS off
pl2303_set_termios (port, &tmp_termios);
dbg (__FUNCTION__ " - submitting read urb");
//FIXME: need to assert RTS and DTR if CRTSCTS off port->read_urb->dev = serial->dev;
result = usb_submit_urb (port->read_urb, GFP_KERNEL);
dbg (__FUNCTION__ " - submitting read urb"); if (result) {
port->read_urb->dev = serial->dev; err(__FUNCTION__ " - failed submitting read urb, error %d", result);
result = usb_submit_urb (port->read_urb, GFP_KERNEL); pl2303_close (port, NULL);
if (result) { return -EPROTO;
err(__FUNCTION__ " - failed submitting read urb, error %d", result); }
pl2303_close (port, NULL);
return -EPROTO;
}
dbg (__FUNCTION__ " - submitting interrupt urb"); dbg (__FUNCTION__ " - submitting interrupt urb");
port->interrupt_in_urb->dev = serial->dev; port->interrupt_in_urb->dev = serial->dev;
result = usb_submit_urb (port->interrupt_in_urb, GFP_KERNEL); result = usb_submit_urb (port->interrupt_in_urb, GFP_KERNEL);
if (result) { if (result) {
err(__FUNCTION__ " - failed submitting interrupt urb, error %d", result); err(__FUNCTION__ " - failed submitting interrupt urb, error %d", result);
pl2303_close (port, NULL); pl2303_close (port, NULL);
return -EPROTO; return -EPROTO;
}
} }
return 0; return 0;
} }
...@@ -437,39 +433,35 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp) ...@@ -437,39 +433,35 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp)
dbg (__FUNCTION__ " - port %d", port->number); dbg (__FUNCTION__ " - port %d", port->number);
--port->open_count; if (serial->dev) {
if (port->open_count <= 0) { c_cflag = port->tty->termios->c_cflag;
if (serial->dev) { if (c_cflag & HUPCL) {
c_cflag = port->tty->termios->c_cflag; /* drop DTR and RTS */
if (c_cflag & HUPCL) { priv = port->private;
/* drop DTR and RTS */ priv->line_control = 0;
priv = port->private; set_control_lines (port->serial->dev,
priv->line_control = 0; priv->line_control);
set_control_lines (port->serial->dev, }
priv->line_control);
}
/* shutdown our urbs */ /* shutdown our urbs */
dbg (__FUNCTION__ " - shutting down urbs"); dbg (__FUNCTION__ " - shutting down urbs");
result = usb_unlink_urb (port->write_urb); result = usb_unlink_urb (port->write_urb);
if (result) if (result)
dbg (__FUNCTION__ " - usb_unlink_urb " dbg (__FUNCTION__ " - usb_unlink_urb "
"(write_urb) failed with reason: %d", "(write_urb) failed with reason: %d",
result); result);
result = usb_unlink_urb (port->read_urb); result = usb_unlink_urb (port->read_urb);
if (result) if (result)
dbg (__FUNCTION__ " - usb_unlink_urb " dbg (__FUNCTION__ " - usb_unlink_urb "
"(read_urb) failed with reason: %d", "(read_urb) failed with reason: %d",
result); result);
result = usb_unlink_urb (port->interrupt_in_urb); result = usb_unlink_urb (port->interrupt_in_urb);
if (result) if (result)
dbg (__FUNCTION__ " - usb_unlink_urb " dbg (__FUNCTION__ " - usb_unlink_urb "
"(interrupt_in_urb) failed with reason: %d", "(interrupt_in_urb) failed with reason: %d",
result); result);
}
port->open_count = 0;
} }
} }
...@@ -577,12 +569,8 @@ static void pl2303_shutdown (struct usb_serial *serial) ...@@ -577,12 +569,8 @@ static void pl2303_shutdown (struct usb_serial *serial)
dbg (__FUNCTION__); dbg (__FUNCTION__);
/* stop everything on all ports */
for (i = 0; i < serial->num_ports; ++i) for (i = 0; i < serial->num_ports; ++i)
while (serial->port[i].open_count > 0) { kfree (serial->port[i].private);
pl2303_close (&serial->port[i], NULL);
kfree (serial->port[i].private);
}
} }
......
...@@ -268,32 +268,31 @@ static int visor_open (struct usb_serial_port *port, struct file *filp) ...@@ -268,32 +268,31 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__ " - port %d", port->number); dbg(__FUNCTION__ " - port %d", port->number);
if (!port->read_urb) { if (!port->read_urb) {
/* this is needed for some brain dead Sony devices */
err ("Device lied about number of ports, please use a lower one."); err ("Device lied about number of ports, please use a lower one.");
return -ENODEV; return -ENODEV;
} }
++port->open_count; bytes_in = 0;
bytes_out = 0;
/*
* Force low_latency on so that our tty_push actually forces the data
* through, otherwise it is scheduled, and with high data rates (like
* with OHCI) data can get lost.
*/
port->tty->low_latency = 1;
if (port->open_count == 1) { /* Start reading from the device */
bytes_in = 0; usb_fill_bulk_urb (port->read_urb, serial->dev,
bytes_out = 0; usb_rcvbulkpipe (serial->dev,
port->bulk_in_endpointAddress),
/* force low_latency on so that our tty_push actually forces the data through, port->read_urb->transfer_buffer,
otherwise it is scheduled, and with high data rates (like with OHCI) data port->read_urb->transfer_buffer_length,
can get lost. */ visor_read_bulk_callback, port);
port->tty->low_latency = 1; result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
/* Start reading from the device */ err(__FUNCTION__ " - failed submitting read urb, error %d", result);
usb_fill_bulk_urb (port->read_urb, serial->dev,
usb_rcvbulkpipe (serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
visor_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
}
return result; return result;
} }
...@@ -313,28 +312,23 @@ static void visor_close (struct usb_serial_port *port, struct file * filp) ...@@ -313,28 +312,23 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
if (!serial) if (!serial)
return; return;
--port->open_count; if (serial->dev) {
/* only send a shutdown message if the
if (port->open_count <= 0) { * device is still here */
if (serial->dev) { transfer_buffer = kmalloc (0x12, GFP_KERNEL);
/* only send a shutdown message if the if (!transfer_buffer) {
* device is still here */ err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12);
transfer_buffer = kmalloc (0x12, GFP_KERNEL); } else {
if (!transfer_buffer) { /* send a shutdown message to the device */
err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12); usb_control_msg (serial->dev,
} else { usb_rcvctrlpipe(serial->dev, 0),
/* send a shutdown message to the device */ VISOR_CLOSE_NOTIFICATION, 0xc2,
usb_control_msg (serial->dev, 0x0000, 0x0000,
usb_rcvctrlpipe(serial->dev, 0), transfer_buffer, 0x12, 300);
VISOR_CLOSE_NOTIFICATION, 0xc2, kfree (transfer_buffer);
0x0000, 0x0000,
transfer_buffer, 0x12, 300);
kfree (transfer_buffer);
}
/* shutdown our bulk read */
usb_unlink_urb (port->read_urb);
} }
port->open_count = 0; /* shutdown our bulk read */
usb_unlink_urb (port->read_urb);
} }
/* Uncomment the following line if you want to see some statistics in your syslog */ /* Uncomment the following line if you want to see some statistics in your syslog */
/* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
...@@ -396,7 +390,7 @@ static int visor_write (struct usb_serial_port *port, int from_user, const unsig ...@@ -396,7 +390,7 @@ static int visor_write (struct usb_serial_port *port, int from_user, const unsig
usb_free_urb (urb); usb_free_urb (urb);
return count; return count;
} }
static int visor_write_room (struct usb_serial_port *port) static int visor_write_room (struct usb_serial_port *port)
...@@ -655,16 +649,9 @@ static int clie_3_5_startup (struct usb_serial *serial) ...@@ -655,16 +649,9 @@ static int clie_3_5_startup (struct usb_serial *serial)
static void visor_shutdown (struct usb_serial *serial) static void visor_shutdown (struct usb_serial *serial)
{ {
int i;
dbg (__FUNCTION__); dbg (__FUNCTION__);
/* stop reads and writes on all ports */
for (i=0; i < serial->num_ports; ++i)
serial->port[i].open_count = 0;
} }
static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
{ {
dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd); dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd);
......
...@@ -306,58 +306,49 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) ...@@ -306,58 +306,49 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" - port %d", port->number); dbg(__FUNCTION__" - port %d", port->number);
++port->open_count; /* set up some stuff for our command port */
command_port = &port->serial->port[COMMAND_PORT];
if (port->open_count == 1) { if (command_port->private == NULL) {
/* set up some stuff for our command port */ info = (struct whiteheat_private *)kmalloc (sizeof(struct whiteheat_private), GFP_KERNEL);
command_port = &port->serial->port[COMMAND_PORT]; if (info == NULL) {
if (command_port->private == NULL) { err(__FUNCTION__ " - out of memory");
info = (struct whiteheat_private *)kmalloc (sizeof(struct whiteheat_private), GFP_KERNEL); retval = -ENOMEM;
if (info == NULL) { goto exit;
err(__FUNCTION__ " - out of memory");
retval = -ENOMEM;
goto error_exit;
}
init_waitqueue_head(&info->wait_command);
command_port->private = info;
command_port->write_urb->complete = command_port_write_callback;
command_port->read_urb->complete = command_port_read_callback;
command_port->read_urb->dev = port->serial->dev;
command_port->tty = port->tty; /* need this to "fake" our our sanity check macros */
retval = usb_submit_urb (command_port->read_urb, GFP_KERNEL);
if (retval) {
err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
goto error_exit;
}
} }
/* Start reading from the device */ init_waitqueue_head(&info->wait_command);
port->read_urb->dev = port->serial->dev; command_port->private = info;
retval = usb_submit_urb(port->read_urb, GFP_KERNEL); command_port->write_urb->complete = command_port_write_callback;
command_port->read_urb->complete = command_port_read_callback;
command_port->read_urb->dev = port->serial->dev;
command_port->tty = port->tty; /* need this to "fake" our our sanity check macros */
retval = usb_submit_urb (command_port->read_urb, GFP_KERNEL);
if (retval) { if (retval) {
err(__FUNCTION__ " - failed submitting read urb, error %d", retval); err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
goto error_exit; goto exit;
} }
}
/* send an open port command */ /* Start reading from the device */
/* firmware uses 1 based port numbering */ port->read_urb->dev = port->serial->dev;
open_command.port = port->number - port->serial->minor + 1; retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
retval = whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command)); if (retval) {
if (retval) err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
goto error_exit; goto exit;
/* Need to do device specific setup here (control lines, baud rate, etc.) */
/* FIXME!!! */
} }
dbg(__FUNCTION__ " - exit"); /* send an open port command */
return retval; /* firmware uses 1 based port numbering */
open_command.port = port->number - port->serial->minor + 1;
retval = whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
if (retval)
goto exit;
error_exit: /* Need to do device specific setup here (control lines, baud rate, etc.) */
--port->open_count; /* FIXME!!! */
dbg(__FUNCTION__ " - error_exit"); exit:
dbg(__FUNCTION__ " - exit, retval = %d", retval);
return retval; return retval;
} }
...@@ -368,22 +359,17 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp) ...@@ -368,22 +359,17 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
dbg(__FUNCTION__ " - port %d", port->number); dbg(__FUNCTION__ " - port %d", port->number);
--port->open_count; /* send a close command to the port */
/* firmware uses 1 based port numbering */
close_command.port = port->number - port->serial->minor + 1;
whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));
if (port->open_count <= 0) { /* Need to change the control lines here */
/* send a close command to the port */ /* FIXME */
/* firmware uses 1 based port numbering */
close_command.port = port->number - port->serial->minor + 1;
whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));
/* Need to change the control lines here */ /* shutdown our bulk reads and writes */
/* FIXME */ usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
/* shutdown our bulk reads and writes */
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
port->open_count = 0;
}
} }
...@@ -641,18 +627,10 @@ static int whiteheat_real_startup (struct usb_serial *serial) ...@@ -641,18 +627,10 @@ static int whiteheat_real_startup (struct usb_serial *serial)
static void whiteheat_real_shutdown (struct usb_serial *serial) static void whiteheat_real_shutdown (struct usb_serial *serial)
{ {
struct usb_serial_port *command_port; struct usb_serial_port *command_port;
int i;
dbg(__FUNCTION__); dbg(__FUNCTION__);
/* stop reads and writes on all ports */
for (i=0; i < serial->num_ports; ++i) {
while (serial->port[i].open_count > 0) {
whiteheat_close (&serial->port[i], NULL);
}
}
/* free up our private data for our command port */ /* free up our private data for our command port */
command_port = &serial->port[COMMAND_PORT]; command_port = &serial->port[COMMAND_PORT];
if (command_port->private != NULL) { if (command_port->private != NULL) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment