aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_ioctl.c
diff options
context:
space:
mode:
authorJonathan Corbet <corbet@lwn.net>2008-05-15 11:25:03 -0400
committerJonathan Corbet <corbet@lwn.net>2008-05-18 17:43:40 -0400
commit0bec0bba7a507bdaf07312fcabdc00b5576abb32 (patch)
tree5ed654b439d0950e2fce87efe4cf97dc08394814 /drivers/pcmcia/pcmcia_ioctl.c
parent0911810755fc9f15659cc3cb43912633b90027a0 (diff)
pcmcia: cdev lock_kernel() pushdown
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/pcmcia/pcmcia_ioctl.c')
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c25
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; 453out:
454 unlock_kernel();
455 return ret;
445} /* ds_open */ 456} /* ds_open */
446 457
447/*====================================================================*/ 458/*====================================================================*/