ChangeSet 1.1504.2.4, 2003/12/05 10:58:30-08:00, [EMAIL PROTECTED]

[PATCH] USB: add TIOCMIWAIT support to pl2303 driver


 drivers/usb/serial/pl2303.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 43 insertions(+)


diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c       Mon Dec 29 14:26:47 2003
+++ b/drivers/usb/serial/pl2303.c       Mon Dec 29 14:26:47 2003
@@ -169,6 +169,7 @@
 
 struct pl2303_private {
        spinlock_t lock;
+       wait_queue_head_t delta_msr_wait;
        u8 line_control;
        u8 line_status;
        u8 termios_initialized;
@@ -186,6 +187,7 @@
                        return -ENOMEM;
                memset (priv, 0x00, sizeof (struct pl2303_private));
                spin_lock_init(&priv->lock);
+               init_waitqueue_head(&priv->delta_msr_wait);
                usb_set_serial_port_data(serial->port[i], priv);
        }
        return 0;
@@ -556,11 +558,51 @@
        return result;
 }
 
+static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+{
+       struct pl2303_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       unsigned int prevstatus;
+       unsigned int status;
+       unsigned int changed;
+
+       spin_lock_irqsave (&priv->lock, flags);
+       prevstatus = priv->line_status;
+       spin_unlock_irqrestore (&priv->lock, flags);
+
+       while (1) {
+               interruptible_sleep_on(&priv->delta_msr_wait);
+               /* see if a signal did it */
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+               
+               spin_lock_irqsave (&priv->lock, flags);
+               status = priv->line_status;
+               spin_unlock_irqrestore (&priv->lock, flags);
+               
+               changed=prevstatus^status;
+               
+               if (((arg & TIOCM_RNG) && (changed & UART_RING)) ||
+                   ((arg & TIOCM_DSR) && (changed & UART_DSR)) ||
+                   ((arg & TIOCM_CD)  && (changed & UART_DCD)) ||
+                   ((arg & TIOCM_CTS) && (changed & UART_CTS)) ) {
+                       return 0;
+               }
+               prevstatus = status;
+       }
+       /* NOTREACHED */
+       return 0;
+}
+
 static int pl2303_ioctl (struct usb_serial_port *port, struct file *file, unsigned 
int cmd, unsigned long arg)
 {
        dbg("%s (%d) cmd = 0x%04x", __FUNCTION__, port->number, cmd);
 
        switch (cmd) {
+               case TIOCMIWAIT:
+                       dbg("%s (%d) TIOCMIWAIT", __FUNCTION__,  port->number);
+                       return wait_modem_info(port, arg);
+
                default:
                        dbg("%s not supported = 0x%04x", __FUNCTION__, cmd);
                        break;
@@ -703,6 +745,7 @@
        spin_lock_irqsave(&priv->lock, flags);
        status = priv->line_status;
        spin_unlock_irqrestore(&priv->lock, flags);
+       wake_up_interruptible (&priv->delta_msr_wait);
 
        /* break takes precedence over parity, */
        /* which takes precedence over framing errors */



-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills.  Sign up for IBM's
Free Linux Tutorials.  Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id78&alloc_id371&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to