aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 097f4e8488fe..9c36f0ece20f 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -27,10 +27,10 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/mutex.h>
30#include <linux/list.h> 31#include <linux/list.h>
31#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
33#include <asm/semaphore.h>
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include "usb-serial.h" 35#include "usb-serial.h"
36#include "pl2303.h" 36#include "pl2303.h"
@@ -189,11 +189,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
189 189
190 portNumber = tty->index - serial->minor; 190 portNumber = tty->index - serial->minor;
191 port = serial->port[portNumber]; 191 port = serial->port[portNumber];
192 if (!port) 192 if (!port) {
193 return -ENODEV; 193 retval = -ENODEV;
194 goto bailout_kref_put;
195 }
194 196
195 if (down_interruptible(&port->sem)) 197 if (mutex_lock_interruptible(&port->mutex)) {
196 return -ERESTARTSYS; 198 retval = -ERESTARTSYS;
199 goto bailout_kref_put;
200 }
197 201
198 ++port->open_count; 202 ++port->open_count;
199 203
@@ -209,7 +213,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
209 * safe because we are called with BKL held */ 213 * safe because we are called with BKL held */
210 if (!try_module_get(serial->type->driver.owner)) { 214 if (!try_module_get(serial->type->driver.owner)) {
211 retval = -ENODEV; 215 retval = -ENODEV;
212 goto bailout_kref_put; 216 goto bailout_mutex_unlock;
213 } 217 }
214 218
215 /* only call the device specific open if this 219 /* only call the device specific open if this
@@ -219,15 +223,16 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
219 goto bailout_module_put; 223 goto bailout_module_put;
220 } 224 }
221 225
222 up(&port->sem); 226 mutex_unlock(&port->mutex);
223 return 0; 227 return 0;
224 228
225bailout_module_put: 229bailout_module_put:
226 module_put(serial->type->driver.owner); 230 module_put(serial->type->driver.owner);
231bailout_mutex_unlock:
232 port->open_count = 0;
233 mutex_unlock(&port->mutex);
227bailout_kref_put: 234bailout_kref_put:
228 kref_put(&serial->kref, destroy_serial); 235 kref_put(&serial->kref, destroy_serial);
229 port->open_count = 0;
230 up(&port->sem);
231 return retval; 236 return retval;
232} 237}
233 238
@@ -240,10 +245,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
240 245
241 dbg("%s - port %d", __FUNCTION__, port->number); 246 dbg("%s - port %d", __FUNCTION__, port->number);
242 247
243 down(&port->sem); 248 mutex_lock(&port->mutex);
244 249
245 if (port->open_count == 0) { 250 if (port->open_count == 0) {
246 up(&port->sem); 251 mutex_unlock(&port->mutex);
247 return; 252 return;
248 } 253 }
249 254
@@ -262,7 +267,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
262 module_put(port->serial->type->driver.owner); 267 module_put(port->serial->type->driver.owner);
263 } 268 }
264 269
265 up(&port->sem); 270 mutex_unlock(&port->mutex);
266 kref_put(&port->serial->kref, destroy_serial); 271 kref_put(&port->serial->kref, destroy_serial);
267} 272}
268 273
@@ -783,7 +788,7 @@ int usb_serial_probe(struct usb_interface *interface,
783 port->number = i + serial->minor; 788 port->number = i + serial->minor;
784 port->serial = serial; 789 port->serial = serial;
785 spin_lock_init(&port->lock); 790 spin_lock_init(&port->lock);
786 sema_init(&port->sem, 1); 791 mutex_init(&port->mutex);
787 INIT_WORK(&port->work, usb_serial_port_softint, port); 792 INIT_WORK(&port->work, usb_serial_port_softint, port);
788 serial->port[i] = port; 793 serial->port[i] = port;
789 } 794 }