summaryrefslogtreecommitdiffstats
path: root/drivers/usb/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/input.c')
-rw-r--r--drivers/usb/input.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/usb/input.c b/drivers/usb/input.c
index a21df12dc..98f1a1109 100644
--- a/drivers/usb/input.c
+++ b/drivers/usb/input.c
@@ -360,15 +360,24 @@ void input_unregister_handler(struct input_handler *handler)
static int input_open_file(struct inode *inode, struct file *file)
{
struct input_handler *handler = input_table[MINOR(inode->i_rdev) >> 5];
- struct file_operations *old_fops;
+ struct file_operations *old_fops, *new_fops = NULL;
int err;
- if (!handler || !handler->fops || !handler->fops->open)
+ /* No load-on-demand here? */
+ if (!handler || !(new_fops = fops_get(handler->fops)))
return -ENODEV;
+ /*
+ * That's _really_ odd. Usually NULL ->open means "nothing special",
+ * not "no device". Oh, well...
+ */
+ if (!new_fops->open) {
+ fops_put(new_fops);
+ return -ENODEV;
+ }
old_fops = file->f_op;
- file->f_op = fops_get(handler->fops);
- err = handler->fops->open(inode, file);
+ file->f_op = new_fops;
+ err = new_fops->open(inode, file);
if (err) {
fops_put(file->f_op);
file->f_op = fops_get(old_fops);