ChangeSet 1.1002.3.13, 2003/02/21 17:03:07-08:00, [EMAIL PROTECTED]

[PATCH] USB pl2303: add locking now that the usb-serial core doesn't protect us.


 drivers/usb/serial/pl2303.c |   88 ++++++++++++++++++++++++++------------------
 1 files changed, 53 insertions(+), 35 deletions(-)


diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c       Fri Feb 28 14:50:42 2003
+++ b/drivers/usb/serial/pl2303.c       Fri Feb 28 14:50:42 2003
@@ -148,7 +148,8 @@
        .shutdown =             pl2303_shutdown,
 };
 
-struct pl2303_private { 
+struct pl2303_private {
+       spinlock_t lock;
        u8 line_control;
        u8 termios_initialized;
 };
@@ -164,6 +165,7 @@
                if (!priv)
                        return -ENOMEM;
                memset (priv, 0x00, sizeof (struct pl2303_private));
+               spin_lock_init(&priv->lock);
                usb_set_serial_port_data(&serial->port[i], priv);
        }
        return 0;
@@ -223,18 +225,21 @@
        int baud;
        int i;
 
-       dbg("%s -  port %d, initialized = %d", __FUNCTION__, port->number, 
priv->termios_initialized);
+       dbg("%s -  port %d", __FUNCTION__, port->number);
 
        if ((!port->tty) || (!port->tty->termios)) {
                dbg("%s - no tty structures", __FUNCTION__);
                return;
        }
 
+       spin_lock(&priv->lock);
        if (!priv->termios_initialized) {
                *(port->tty->termios) = tty_std_termios;
                port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
                priv->termios_initialized = 1;
        }
+       spin_unlock(&priv->lock);
+
        cflag = port->tty->termios->c_cflag;
        /* check that they really want us to change something */
        if (old_termios) {
@@ -341,11 +346,16 @@
        dbg ("0x21:0x20:0:0  %d", i);
 
        if (cflag && CBAUD) {
+               u8 control;
+
+               spin_lock (&priv->lock);
                if ((cflag && CBAUD) == B0)
                        priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
                else
                        priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
-               set_control_lines (serial->dev, priv->line_control);
+               control = priv->line_control;
+               spin_unlock (&priv->lock);
+               set_control_lines (serial->dev, control);
        }
        
        buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;
@@ -444,48 +454,50 @@
        
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (serial->dev) {
-               if (port->tty) {
-                       c_cflag = port->tty->termios->c_cflag;
-                       if (c_cflag & HUPCL) {
-                               /* drop DTR and RTS */
-                               priv = usb_get_serial_port_data(port);
-                               priv->line_control = 0;
-                               set_control_lines (port->serial->dev,
-                                                  priv->line_control);
-                       }
-               }
+       /* shutdown our urbs */
+       dbg("%s - shutting down urbs", __FUNCTION__);
+       result = usb_unlink_urb (port->write_urb);
+       if (result)
+               dbg("%s - usb_unlink_urb (write_urb)"
+                   " failed with reason: %d", __FUNCTION__,
+                    result);
+
+       result = usb_unlink_urb (port->read_urb);
+       if (result)
+               dbg("%s - usb_unlink_urb (read_urb) "
+                   "failed with reason: %d", __FUNCTION__,
+                    result);
 
-               /* shutdown our urbs */
-               dbg("%s - shutting down urbs", __FUNCTION__);
-               result = usb_unlink_urb (port->write_urb);
-               if (result)
-                       dbg("%s - usb_unlink_urb (write_urb)"
-                           " failed with reason: %d", __FUNCTION__,
-                            result);
-
-               result = usb_unlink_urb (port->read_urb);
-               if (result)
-                       dbg("%s - usb_unlink_urb (read_urb) "
-                           "failed with reason: %d", __FUNCTION__,
-                            result);
-
-               result = usb_unlink_urb (port->interrupt_in_urb);
-               if (result)
-                       dbg("%s - usb_unlink_urb (interrupt_in_urb)"
-                           " failed with reason: %d", __FUNCTION__,
-                            result);
+       result = usb_unlink_urb (port->interrupt_in_urb);
+       if (result)
+               dbg("%s - usb_unlink_urb (interrupt_in_urb)"
+                   " failed with reason: %d", __FUNCTION__,
+                    result);
+
+       if (port->tty) {
+               c_cflag = port->tty->termios->c_cflag;
+               if (c_cflag & HUPCL) {
+                       /* drop DTR and RTS */
+                       priv = usb_get_serial_port_data(port);
+                       spin_lock (&priv->lock);
+                       priv->line_control = 0;
+                       spin_unlock (&priv->lock);
+                       set_control_lines (port->serial->dev, 0);
+               }
        }
+
 }
 
 static int set_modem_info (struct usb_serial_port *port, unsigned int cmd, unsigned 
int *value)
 {
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        unsigned int arg;
+       u8 control;
 
        if (copy_from_user(&arg, value, sizeof(int)))
                return -EFAULT;
 
+       spin_lock (&priv->lock);
        switch (cmd) {
                case TIOCMBIS:
                        if (arg & TIOCM_RTS)
@@ -509,15 +521,21 @@
                        priv->line_control |= ((arg & TIOCM_DTR) ? CONTROL_DTR : 0);
                        break;
        }
+       control = priv->line_control;
+       spin_unlock (&priv->lock);
 
-       return set_control_lines (port->serial->dev, priv->line_control);
+       return set_control_lines (port->serial->dev, control);
 }
 
 static int get_modem_info (struct usb_serial_port *port, unsigned int *value)
 {
        struct pl2303_private *priv = usb_get_serial_port_data(port);
-       unsigned int mcr = priv->line_control;
+       unsigned int mcr;
        unsigned int result;
+
+       spin_lock (&priv->lock);
+       mcr = priv->line_control;
+       spin_unlock (&priv->lock);
 
        result = ((mcr & CONTROL_DTR)           ? TIOCM_DTR : 0)
                  | ((mcr & CONTROL_RTS)        ? TIOCM_RTS : 0);



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to