aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/uio/uio.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 3a6934bf7131..4f28f4bf8366 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -47,6 +47,9 @@ static struct uio_class {
47 struct class *class; 47 struct class *class;
48} *uio_class; 48} *uio_class;
49 49
50/* Protect idr accesses */
51static DEFINE_MUTEX(minor_lock);
52
50/* 53/*
51 * attributes 54 * attributes
52 */ 55 */
@@ -231,7 +234,6 @@ static void uio_dev_del_attributes(struct uio_device *idev)
231 234
232static int uio_get_minor(struct uio_device *idev) 235static int uio_get_minor(struct uio_device *idev)
233{ 236{
234 static DEFINE_MUTEX(minor_lock);
235 int retval = -ENOMEM; 237 int retval = -ENOMEM;
236 int id; 238 int id;
237 239
@@ -253,7 +255,9 @@ exit:
253 255
254static void uio_free_minor(struct uio_device *idev) 256static void uio_free_minor(struct uio_device *idev)
255{ 257{
258 mutex_lock(&minor_lock);
256 idr_remove(&uio_idr, idev->minor); 259 idr_remove(&uio_idr, idev->minor);
260 mutex_unlock(&minor_lock);
257} 261}
258 262
259/** 263/**
@@ -297,8 +301,9 @@ static int uio_open(struct inode *inode, struct file *filep)
297 struct uio_listener *listener; 301 struct uio_listener *listener;
298 int ret = 0; 302 int ret = 0;
299 303
300 lock_kernel(); 304 mutex_lock(&minor_lock);
301 idev = idr_find(&uio_idr, iminor(inode)); 305 idev = idr_find(&uio_idr, iminor(inode));
306 mutex_unlock(&minor_lock);
302 if (!idev) { 307 if (!idev) {
303 ret = -ENODEV; 308 ret = -ENODEV;
304 goto out; 309 goto out;
@@ -324,18 +329,15 @@ static int uio_open(struct inode *inode, struct file *filep)
324 if (ret) 329 if (ret)
325 goto err_infoopen; 330 goto err_infoopen;
326 } 331 }
327 unlock_kernel();
328 return 0; 332 return 0;
329 333
330err_infoopen: 334err_infoopen:
331
332 kfree(listener); 335 kfree(listener);
333err_alloc_listener:
334 336
337err_alloc_listener:
335 module_put(idev->owner); 338 module_put(idev->owner);
336 339
337out: 340out:
338 unlock_kernel();
339 return ret; 341 return ret;
340} 342}
341 343