summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_ioctl.c
diff options
context:
space:
mode:
authorJonathan Corbet <corbet@lwn.net>2008-05-15 17:25:03 +0200
committerJonathan Corbet <corbet@lwn.net>2008-05-18 23:43:40 +0200
commit0bec0bba7a507bdaf07312fcabdc00b5576abb32 (patch)
tree5ed654b439d0950e2fce87efe4cf97dc08394814 /drivers/pcmcia/pcmcia_ioctl.c
parentcosa: cdev lock_kernel() pushdown (diff)
downloadlinux-0bec0bba7a507bdaf07312fcabdc00b5576abb32.tar.xz
linux-0bec0bba7a507bdaf07312fcabdc00b5576abb32.zip
pcmcia: cdev lock_kernel() pushdown
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to '')
-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 @@
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <linux/pci.h>
+#include <linux/smp_lock.h>
#include <linux/workqueue.h>
#define IN_CARD_SERVICES
@@ -397,20 +398,27 @@ static int ds_open(struct inode *inode, struct file *file)
struct pcmcia_socket *s;
user_info_t *user;
static int warning_printed = 0;
+ int ret = 0;
ds_dbg(0, "ds_open(socket %d)\n", i);
+ lock_kernel();
s = pcmcia_get_socket_by_nr(i);
- if (!s)
- return -ENODEV;
+ if (!s) {
+ ret = -ENODEV;
+ goto out;
+ }
s = pcmcia_get_socket(s);
- if (!s)
- return -ENODEV;
+ if (!s) {
+ ret = -ENODEV;
+ goto out;
+ }
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
if (s->pcmcia_state.busy) {
pcmcia_put_socket(s);
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
else
s->pcmcia_state.busy = 1;
@@ -419,7 +427,8 @@ static int ds_open(struct inode *inode, struct file *file)
user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
if (!user) {
pcmcia_put_socket(s);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
user->event_tail = user->event_head = 0;
user->next = s->user;
@@ -441,7 +450,9 @@ static int ds_open(struct inode *inode, struct file *file)
if (s->pcmcia_state.present)
queue_event(user, CS_EVENT_CARD_INSERTION);
- return 0;
+out:
+ unlock_kernel();
+ return ret;
} /* ds_open */
/*====================================================================*/