diff options
author | Jonathan Corbet <corbet@lwn.net> | 2008-05-15 11:25:03 -0400 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2008-05-18 17:43:40 -0400 |
commit | 0bec0bba7a507bdaf07312fcabdc00b5576abb32 (patch) | |
tree | 5ed654b439d0950e2fce87efe4cf97dc08394814 /drivers/pcmcia | |
parent | 0911810755fc9f15659cc3cb43912633b90027a0 (diff) |
pcmcia: cdev lock_kernel() pushdown
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/pcmcia_ioctl.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 5f186abca108..138396ef5be9 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/proc_fs.h> | 27 | #include <linux/proc_fs.h> |
28 | #include <linux/poll.h> | 28 | #include <linux/poll.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/smp_lock.h> | ||
30 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
31 | 32 | ||
32 | #define IN_CARD_SERVICES | 33 | #define IN_CARD_SERVICES |
@@ -397,20 +398,27 @@ static int ds_open(struct inode *inode, struct file *file) | |||
397 | struct pcmcia_socket *s; | 398 | struct pcmcia_socket *s; |
398 | user_info_t *user; | 399 | user_info_t *user; |
399 | static int warning_printed = 0; | 400 | static int warning_printed = 0; |
401 | int ret = 0; | ||
400 | 402 | ||
401 | ds_dbg(0, "ds_open(socket %d)\n", i); | 403 | ds_dbg(0, "ds_open(socket %d)\n", i); |
402 | 404 | ||
405 | lock_kernel(); | ||
403 | s = pcmcia_get_socket_by_nr(i); | 406 | s = pcmcia_get_socket_by_nr(i); |
404 | if (!s) | 407 | if (!s) { |
405 | return -ENODEV; | 408 | ret = -ENODEV; |
409 | goto out; | ||
410 | } | ||
406 | s = pcmcia_get_socket(s); | 411 | s = pcmcia_get_socket(s); |
407 | if (!s) | 412 | if (!s) { |
408 | return -ENODEV; | 413 | ret = -ENODEV; |
414 | goto out; | ||
415 | } | ||
409 | 416 | ||
410 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | 417 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { |
411 | if (s->pcmcia_state.busy) { | 418 | if (s->pcmcia_state.busy) { |
412 | pcmcia_put_socket(s); | 419 | pcmcia_put_socket(s); |
413 | return -EBUSY; | 420 | ret = -EBUSY; |
421 | goto out; | ||
414 | } | 422 | } |
415 | else | 423 | else |
416 | s->pcmcia_state.busy = 1; | 424 | s->pcmcia_state.busy = 1; |
@@ -419,7 +427,8 @@ static int ds_open(struct inode *inode, struct file *file) | |||
419 | user = kmalloc(sizeof(user_info_t), GFP_KERNEL); | 427 | user = kmalloc(sizeof(user_info_t), GFP_KERNEL); |
420 | if (!user) { | 428 | if (!user) { |
421 | pcmcia_put_socket(s); | 429 | pcmcia_put_socket(s); |
422 | return -ENOMEM; | 430 | ret = -ENOMEM; |
431 | goto out; | ||
423 | } | 432 | } |
424 | user->event_tail = user->event_head = 0; | 433 | user->event_tail = user->event_head = 0; |
425 | user->next = s->user; | 434 | user->next = s->user; |
@@ -441,7 +450,9 @@ static int ds_open(struct inode *inode, struct file *file) | |||
441 | 450 | ||
442 | if (s->pcmcia_state.present) | 451 | if (s->pcmcia_state.present) |
443 | queue_event(user, CS_EVENT_CARD_INSERTION); | 452 | queue_event(user, CS_EVENT_CARD_INSERTION); |
444 | return 0; | 453 | out: |
454 | unlock_kernel(); | ||
455 | return ret; | ||
445 | } /* ds_open */ | 456 | } /* ds_open */ |
446 | 457 | ||
447 | /*====================================================================*/ | 458 | /*====================================================================*/ |