diff options
Diffstat (limited to 'drivers/usb/serial/cypress_m8.c')
-rw-r--r-- | drivers/usb/serial/cypress_m8.c | 92 |
1 files changed, 37 insertions, 55 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 8efa19d..d341555 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -111,7 +111,6 @@ struct cypress_private { int baud_rate; /* stores current baud rate in integer form */ int isthrottled; /* if throttled, discard reads */ - wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ char prev_status, diff_status; /* used for TIOCMIWAIT */ /* we pass a pointer to this as the argument sent to cypress_set_termios old_termios */ @@ -130,13 +129,12 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static void cypress_send(struct usb_serial_port *port); static int cypress_write_room(struct tty_struct *tty); -static int cypress_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); static void cypress_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static int cypress_tiocmget(struct tty_struct *tty); static int cypress_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); +static int cypress_tiocmiwait(struct tty_struct *tty, unsigned long arg); static int cypress_chars_in_buffer(struct tty_struct *tty); static void cypress_throttle(struct tty_struct *tty); static void cypress_unthrottle(struct tty_struct *tty); @@ -159,10 +157,10 @@ static struct usb_serial_driver cypress_earthmate_device = { .dtr_rts = cypress_dtr_rts, .write = cypress_write, .write_room = cypress_write_room, - .ioctl = cypress_ioctl, .set_termios = cypress_set_termios, .tiocmget = cypress_tiocmget, .tiocmset = cypress_tiocmset, + .tiocmiwait = cypress_tiocmiwait, .chars_in_buffer = cypress_chars_in_buffer, .throttle = cypress_throttle, .unthrottle = cypress_unthrottle, @@ -185,10 +183,10 @@ static struct usb_serial_driver cypress_hidcom_device = { .dtr_rts = cypress_dtr_rts, .write = cypress_write, .write_room = cypress_write_room, - .ioctl = cypress_ioctl, .set_termios = cypress_set_termios, .tiocmget = cypress_tiocmget, .tiocmset = cypress_tiocmset, + .tiocmiwait = cypress_tiocmiwait, .chars_in_buffer = cypress_chars_in_buffer, .throttle = cypress_throttle, .unthrottle = cypress_unthrottle, @@ -211,10 +209,10 @@ static struct usb_serial_driver cypress_ca42v2_device = { .dtr_rts = cypress_dtr_rts, .write = cypress_write, .write_room = cypress_write_room, - .ioctl = cypress_ioctl, .set_termios = cypress_set_termios, .tiocmget = cypress_tiocmget, .tiocmset = cypress_tiocmset, + .tiocmiwait = cypress_tiocmiwait, .chars_in_buffer = cypress_chars_in_buffer, .throttle = cypress_throttle, .unthrottle = cypress_unthrottle, @@ -449,7 +447,6 @@ static int cypress_generic_port_probe(struct usb_serial_port *port) kfree(priv); return -ENOMEM; } - init_waitqueue_head(&priv->delta_msr_wait); usb_reset_configuration(serial->dev); @@ -635,12 +632,6 @@ static void cypress_close(struct usb_serial_port *port) struct cypress_private *priv = usb_get_serial_port_data(port); unsigned long flags; - /* writing is potentially harmful, lock must be taken */ - mutex_lock(&port->serial->disc_mutex); - if (port->serial->disconnected) { - mutex_unlock(&port->serial->disc_mutex); - return; - } spin_lock_irqsave(&priv->lock, flags); kfifo_reset_out(&priv->write_fifo); spin_unlock_irqrestore(&priv->lock, flags); @@ -652,7 +643,6 @@ static void cypress_close(struct usb_serial_port *port) if (stats) dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", priv->bytes_in, priv->bytes_out, priv->cmd_count); - mutex_unlock(&port->serial->disc_mutex); } /* cypress_close */ @@ -857,51 +847,43 @@ static int cypress_tiocmset(struct tty_struct *tty, } -static int cypress_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int cypress_tiocmiwait(struct tty_struct *tty, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; struct cypress_private *priv = usb_get_serial_port_data(port); - - dev_dbg(&port->dev, "%s - port %d, cmd 0x%.4x\n", __func__, port->number, cmd); - - switch (cmd) { - /* This code comes from drivers/char/serial.c and ftdi_sio.c */ - case TIOCMIWAIT: - while (priv != NULL) { - interruptible_sleep_on(&priv->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - else { - char diff = priv->diff_status; - if (diff == 0) - return -EIO; /* no change => error */ - - /* consume all events */ - priv->diff_status = 0; - - /* return 0 if caller wanted to know about - these bits */ - if (((arg & TIOCM_RNG) && (diff & UART_RI)) || - ((arg & TIOCM_DSR) && (diff & UART_DSR)) || - ((arg & TIOCM_CD) && (diff & UART_CD)) || - ((arg & TIOCM_CTS) && (diff & UART_CTS))) - return 0; - /* otherwise caller can't care less about what - * happened, and so we continue to wait for - * more events. - */ - } - } - return 0; - default: - break; + char diff; + + for (;;) { + interruptible_sleep_on(&port->port.delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + + if (port->serial->disconnected) + return -EIO; + + diff = priv->diff_status; + if (diff == 0) + return -EIO; /* no change => error */ + + /* consume all events */ + priv->diff_status = 0; + + /* return 0 if caller wanted to know about + these bits */ + if (((arg & TIOCM_RNG) && (diff & UART_RI)) || + ((arg & TIOCM_DSR) && (diff & UART_DSR)) || + ((arg & TIOCM_CD) && (diff & UART_CD)) || + ((arg & TIOCM_CTS) && (diff & UART_CTS))) + return 0; + /* otherwise caller can't care less about what + * happened, and so we continue to wait for + * more events. + */ } - dev_dbg(&port->dev, "%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h\n", __func__, cmd); - return -ENOIOCTLCMD; -} /* cypress_ioctl */ + return 0; +} static void cypress_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) @@ -1187,7 +1169,7 @@ static void cypress_read_int_callback(struct urb *urb) if (priv->current_status != priv->prev_status) { priv->diff_status |= priv->current_status ^ priv->prev_status; - wake_up_interruptible(&priv->delta_msr_wait); + wake_up_interruptible(&port->port.delta_msr_wait); priv->prev_status = priv->current_status; } spin_unlock_irqrestore(&priv->lock, flags); |