On Tue, 22 Nov 2005 14:13:53 -0800
Greg KH <[EMAIL PROTECTED]> wrote:

| On Tue, Nov 22, 2005 at 07:59:26PM -0200, Luiz Fernando Capitulino wrote:
| > @@ -60,6 +61,7 @@ struct usb_serial_port {
| >     struct usb_serial *     serial;
| >     struct tty_struct *     tty;
| >     spinlock_t              lock;
| > +   struct semaphore        sem;
| 
| You forgot to document what this semaphore is used for.

 Here goes the second patch again, with the documentation now.

 As I said before, would be good to apply these two patches now, and I
can cleanup the spinlock usage until next week.


 Fixes a race-condition in the access of the port structure, described
in detail at: http://marc.theaimsgroup.com/?l=linux-kernel&m=113216151918308&w=2

Signed-off-by: Luiz Capitulino <[EMAIL PROTECTED]>

 drivers/usb/serial/usb-serial.c |   14 +++++++++++++-
 drivers/usb/serial/usb-serial.h |    4 ++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff -Nparu -X /home/lcapitulino/kernels/dontdiff 
a/drivers/usb/serial/usb-serial.c a~/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c   2005-11-23 15:30:20.000000000 -0200
+++ a~/drivers/usb/serial/usb-serial.c  2005-11-23 15:23:19.000000000 -0200
@@ -30,6 +30,7 @@
 #include <linux/list.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
+#include <asm/semaphore.h>
 #include <linux/usb.h>
 #include "usb-serial.h"
 #include "pl2303.h"
@@ -190,6 +191,9 @@ static int serial_open (struct tty_struc
        port = serial->port[portNumber];
        if (!port)
                return -ENODEV;
+
+       if (down_interruptible(&port->sem))
+               return -ERESTARTSYS;
         
        ++port->open_count;
 
@@ -215,6 +219,7 @@ static int serial_open (struct tty_struc
                        goto bailout_module_put;
        }
 
+       up(&port->sem);
        return 0;
 
 bailout_module_put:
@@ -222,6 +227,7 @@ bailout_module_put:
 bailout_kref_put:
        kref_put(&serial->kref, destroy_serial);
        port->open_count = 0;
+       up(&port->sem);
        return retval;
 }
 
@@ -234,8 +240,10 @@ static void serial_close(struct tty_stru
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
+       down(&port->sem);
+
        if (port->open_count == 0)
-               return;
+               goto out;
 
        --port->open_count;
        if (port->open_count == 0) {
@@ -253,6 +261,9 @@ static void serial_close(struct tty_stru
        }
 
        kref_put(&port->serial->kref, destroy_serial);
+
+out:
+       up(&port->sem);
 }
 
 static int serial_write (struct tty_struct * tty, const unsigned char *buf, 
int count)
@@ -774,6 +785,7 @@ int usb_serial_probe(struct usb_interfac
                port->number = i + serial->minor;
                port->serial = serial;
                spin_lock_init(&port->lock);
+               sema_init(&port->sem, 1);
                INIT_WORK(&port->work, usb_serial_port_softint, port);
                serial->port[i] = port;
        }
diff -Nparu -X /home/lcapitulino/kernels/dontdiff 
a/drivers/usb/serial/usb-serial.h a~/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h   2005-11-23 15:30:20.000000000 -0200
+++ a~/drivers/usb/serial/usb-serial.h  2005-11-23 15:23:59.000000000 -0200
@@ -16,6 +16,7 @@
 
 #include <linux/config.h>
 #include <linux/kref.h>
+#include <asm/semaphore.h>
 
 #define SERIAL_TTY_MAJOR       188     /* Nice legal number now */
 #define SERIAL_TTY_MINORS      255     /* loads of devices :) */
@@ -30,6 +31,8 @@
  * @serial: pointer back to the struct usb_serial owner of this port.
  * @tty: pointer to the corresponding tty for this port.
  * @lock: spinlock to grab when updating portions of this structure.
+ * @sem: semaphore used to synchronize serial_open() and serial_close()
+ *     access for this port.
  * @number: the number of the port (the minor number).
  * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
  * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
@@ -60,6 +63,7 @@ struct usb_serial_port {
        struct usb_serial *     serial;
        struct tty_struct *     tty;
        spinlock_t              lock;
+       struct semaphore        sem;
        unsigned char           number;
 
        unsigned char *         interrupt_in_buffer;


-- 
Luiz Fernando N. Capitulino


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&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