static int digi_tiocmget( struct usb_serial_port *port, struct file *file );
static int digi_tiocmset( struct usb_serial_port *port, struct file *file,
unsigned int set, unsigned int clear );
-static int digi_write( struct usb_serial_port *port, int from_user,
- const unsigned char *buf, int count );
+static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count );
static void digi_write_bulk_callback( struct urb *urb, struct pt_regs *regs );
static int digi_write_room( struct usb_serial_port *port );
static int digi_chars_in_buffer( struct usb_serial_port *port );
wake_up_interruptible( &port->write_wait );
/* wake up line discipline */
- if( (tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
- && tty->ldisc.write_wakeup )
- (tty->ldisc.write_wakeup)(tty);
-
- /* wake up other tty processes */
- wake_up_interruptible( &tty->write_wait );
- /* For 2.2.16 backport -- wake_up_interruptible( &tty->poll_wait ); */
-
+ tty_wakeup(tty);
}
}
-static int digi_write( struct usb_serial_port *port, int from_user,
- const unsigned char *buf, int count )
+static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count )
{
int ret,data_len,new_len;
struct digi_port *priv = usb_get_serial_port_data(port);
unsigned char *data = port->write_urb->transfer_buffer;
- unsigned char user_buf[64]; /* 64 bytes is max USB bulk packet */
unsigned long flags = 0;
-dbg( "digi_write: TOP: port=%d, count=%d, from_user=%d, in_interrupt=%ld",
-priv->dp_port_num, count, from_user, in_interrupt() );
+dbg( "digi_write: TOP: port=%d, count=%d, in_interrupt=%ld",
+priv->dp_port_num, count, in_interrupt() );
/* copy user data (which can sleep) before getting spin lock */
count = min( count, port->bulk_out_size-2 );
count = min( 64, count);
- if( from_user && copy_from_user( user_buf, buf, count ) ) {
- return( -EFAULT );
- }
/* be sure only one write proceeds at a time */
/* there are races on the port private buffer */
/* buffer data if count is 1 (probably put_char) if possible */
if( count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE ) {
- priv->dp_out_buf[priv->dp_out_buf_len++]
- = *(from_user ? user_buf : buf);
+ priv->dp_out_buf[priv->dp_out_buf_len++] = *buf;
new_len = 1;
} else {
new_len = 0;
data += priv->dp_out_buf_len;
/* copy in new data */
- memcpy( data, from_user ? user_buf : buf, new_len );
+ memcpy( data, buf, new_len );
if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) {
priv->dp_write_urb_in_use = 1;
dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count );
+ /* if disconnected, just clear flags */
+ if (!usb_get_intfdata(port->serial->interface))
+ goto exit;
+
/* do cleanup only after final close on this port */
spin_lock_irqsave( &priv->dp_port_lock, flags );
priv->dp_in_close = 1;
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
/* tell line discipline to process only XON/XOFF */
- tty->closing = 1;
+ tty->closing = 1;
/* wait for output to drain */
if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) {
/* flush driver and line discipline buffers */
if( tty->driver->flush_buffer )
tty->driver->flush_buffer( tty );
- if( tty->ldisc.flush_buffer )
- tty->ldisc.flush_buffer( tty );
+ tty_ldisc_flush(tty);
if (port->serial->dev) {
/* wait for transmit idle */
DIGI_CLOSE_TIMEOUT );
/* shutdown any outstanding bulk writes */
- usb_unlink_urb (port->write_urb);
+ usb_kill_urb(port->write_urb);
}
tty->closing = 0;
+exit:
spin_lock_irqsave( &priv->dp_port_lock, flags );
priv->dp_write_urb_in_use = 0;
priv->dp_in_close = 0;
/* stop reads and writes on all ports */
for( i=0; i<serial->type->num_ports+1; i++ ) {
- usb_unlink_urb( serial->port[i]->read_urb );
- usb_unlink_urb( serial->port[i]->write_urb );
+ usb_kill_urb(serial->port[i]->read_urb);
+ usb_kill_urb(serial->port[i]->write_urb);
}
/* free the private data structures for all ports */