USB: pl2303: add custom tiocmiwait operation
[cascardo/linux.git] / drivers / usb / serial / pl2303.c
index 54adc91..1f7fd1a 100644 (file)
@@ -139,7 +139,6 @@ struct pl2303_serial_private {
 
 struct pl2303_private {
        spinlock_t lock;
-       wait_queue_head_t delta_msr_wait;
        u8 line_control;
        u8 line_status;
 };
@@ -150,7 +149,7 @@ static int pl2303_vendor_read(__u16 value, __u16 index,
        int res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                        VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE,
                        value, index, buf, 1, 100);
-       dev_dbg(&serial->dev->dev, "0x%x:0x%x:0x%x:0x%x  %d - %x\n",
+       dev_dbg(&serial->interface->dev, "0x%x:0x%x:0x%x:0x%x  %d - %x\n",
                VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, value, index,
                res, buf[0]);
        return res;
@@ -162,7 +161,7 @@ static int pl2303_vendor_write(__u16 value, __u16 index,
        int res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                        VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE,
                        value, index, NULL, 0, 100);
-       dev_dbg(&serial->dev->dev, "0x%x:0x%x:0x%x:0x%x  %d\n",
+       dev_dbg(&serial->interface->dev, "0x%x:0x%x:0x%x:0x%x  %d\n",
                VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, value, index,
                res);
        return res;
@@ -233,7 +232,6 @@ static int pl2303_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
 
        spin_lock_init(&priv->lock);
-       init_waitqueue_head(&priv->delta_msr_wait);
 
        usb_set_serial_port_data(port, priv);
 
@@ -250,14 +248,15 @@ static int pl2303_port_remove(struct usb_serial_port *port)
        return 0;
 }
 
-static int set_control_lines(struct usb_device *dev, u8 value)
+static int pl2303_set_control_lines(struct usb_serial_port *port, u8 value)
 {
+       struct usb_device *dev = port->serial->dev;
        int retval;
 
        retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                                 SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
                                 value, 0, NULL, 0, 100);
-       dev_dbg(&dev->dev, "%s - value = %d, retval = %d\n", __func__,
+       dev_dbg(&port->dev, "%s - value = %d, retval = %d\n", __func__,
                value, retval);
        return retval;
 }
@@ -439,7 +438,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
        if (control != priv->line_control) {
                control = priv->line_control;
                spin_unlock_irqrestore(&priv->lock, flags);
-               set_control_lines(serial->dev, control);
+               pl2303_set_control_lines(port, control);
        } else {
                spin_unlock_irqrestore(&priv->lock, flags);
        }
@@ -482,7 +481,7 @@ static void pl2303_dtr_rts(struct usb_serial_port *port, int on)
                priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
        control = priv->line_control;
        spin_unlock_irqrestore(&priv->lock, flags);
-       set_control_lines(port->serial->dev, control);
+       pl2303_set_control_lines(port, control);
 }
 
 static void pl2303_close(struct usb_serial_port *port)
@@ -552,7 +551,7 @@ static int pl2303_tiocmset(struct tty_struct *tty,
 
        mutex_lock(&serial->disc_mutex);
        if (!serial->disconnected)
-               ret = set_control_lines(serial->dev, control);
+               ret = pl2303_set_control_lines(port, control);
        else
                ret = -ENODEV;
        mutex_unlock(&serial->disc_mutex);
@@ -594,8 +593,9 @@ static int pl2303_carrier_raised(struct usb_serial_port *port)
        return 0;
 }
 
-static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+static int pl2303_tiocmiwait(struct tty_struct *tty, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        unsigned int prevstatus;
@@ -607,11 +607,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        while (1) {
-               interruptible_sleep_on(&priv->delta_msr_wait);
+               interruptible_sleep_on(&port->delta_msr_wait);
                /* see if a signal did it */
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
+               if (port->serial->disconnected)
+                       return -EIO;
+
                spin_lock_irqsave(&priv->lock, flags);
                status = priv->line_status;
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -650,10 +653,6 @@ static int pl2303_ioctl(struct tty_struct *tty,
                        return -EFAULT;
 
                return 0;
-
-       case TIOCMIWAIT:
-               dev_dbg(&port->dev, "%s TIOCMIWAIT\n", __func__);
-               return wait_modem_info(port, arg);
        default:
                dev_dbg(&port->dev, "%s not supported = 0x%04x\n", __func__, cmd);
                break;
@@ -719,7 +718,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
        spin_unlock_irqrestore(&priv->lock, flags);
        if (priv->line_status & UART_BREAK_ERROR)
                usb_serial_handle_break(port);
-       wake_up_interruptible(&priv->delta_msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
 
        tty = tty_port_tty_get(&port->port);
        if (!tty)
@@ -783,7 +782,7 @@ static void pl2303_process_read_urb(struct urb *urb)
        line_status = priv->line_status;
        priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
        spin_unlock_irqrestore(&priv->lock, flags);
-       wake_up_interruptible(&priv->delta_msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
 
        if (!urb->actual_length)
                return;
@@ -834,6 +833,7 @@ static struct usb_serial_driver pl2303_device = {
        .set_termios =          pl2303_set_termios,
        .tiocmget =             pl2303_tiocmget,
        .tiocmset =             pl2303_tiocmset,
+       .tiocmiwait =           pl2303_tiocmiwait,
        .process_read_urb =     pl2303_process_read_urb,
        .read_int_callback =    pl2303_read_int_callback,
        .attach =               pl2303_startup,