X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Finput%2Fmousedev.c;h=8137e50ded87de13d31d378557a68ba58d3cedb5;hb=b2300b9efe1b8174833e17f37e975c9da00c388a;hp=715def79390c68d89017663dedfed82c0bb91d42;hpb=464b241575f3700e14492e34f26bcd1794280f55;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 715def7..8137e50 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -14,9 +14,9 @@ #define MOUSEDEV_MIX 31 #include +#include #include #include -#include #include #include #include @@ -265,6 +265,7 @@ static void mousedev_notify_readers(struct mousedev *mousedev, unsigned int new_head; int wake_readers = 0; + rcu_read_lock(); list_for_each_entry_rcu(client, &mousedev->client_list, node) { /* Just acquire the lock, interrupts already disabled */ @@ -309,6 +310,7 @@ static void mousedev_notify_readers(struct mousedev *mousedev, wake_readers = 1; } } + rcu_read_unlock(); if (wake_readers) wake_up_interruptible(&mousedev->wait); @@ -413,6 +415,7 @@ static void mousedev_free(struct device *dev) { struct mousedev *mousedev = container_of(dev, struct mousedev, dev); + input_put_device(mousedev->handle.dev); kfree(mousedev); } @@ -428,8 +431,11 @@ static int mousedev_open_device(struct mousedev *mousedev) mixdev_open_devices(); else if (!mousedev->exist) retval = -ENODEV; - else if (!mousedev->open++) + else if (!mousedev->open++) { retval = input_open_device(&mousedev->handle); + if (retval) + mousedev->open--; + } mutex_unlock(&mousedev->mutex); return retval; @@ -496,12 +502,7 @@ static void mousedev_attach_client(struct mousedev *mousedev, spin_lock(&mousedev->client_lock); list_add_tail_rcu(&client->node, &mousedev->client_list); spin_unlock(&mousedev->client_lock); - /* - * We don't use synchronize_rcu() here because read-side - * critical section is protected by a spinlock (dev->event_lock) - * instead of rcu_read_lock(). - */ - synchronize_sched(); + synchronize_rcu(); } static void mousedev_detach_client(struct mousedev *mousedev, @@ -510,7 +511,7 @@ static void mousedev_detach_client(struct mousedev *mousedev, spin_lock(&mousedev->client_lock); list_del_rcu(&client->node); spin_unlock(&mousedev->client_lock); - synchronize_sched(); + synchronize_rcu(); } static int mousedev_release(struct inode *inode, struct file *file) @@ -545,16 +546,21 @@ static int mousedev_open(struct inode *inode, struct file *file) if (i >= MOUSEDEV_MINORS) return -ENODEV; + lock_kernel(); error = mutex_lock_interruptible(&mousedev_table_mutex); - if (error) + if (error) { + unlock_kernel(); return error; + } mousedev = mousedev_table[i]; if (mousedev) get_device(&mousedev->dev); mutex_unlock(&mousedev_table_mutex); - if (!mousedev) + if (!mousedev) { + unlock_kernel(); return -ENODEV; + } client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); if (!client) { @@ -573,6 +579,7 @@ static int mousedev_open(struct inode *inode, struct file *file) goto err_free_client; file->private_data = client; + unlock_kernel(); return 0; err_free_client: @@ -580,6 +587,7 @@ static int mousedev_open(struct inode *inode, struct file *file) kfree(client); err_put_mousedev: put_device(&mousedev->dev); + unlock_kernel(); return error; } @@ -866,7 +874,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, mousedev->minor = minor; mousedev->exist = 1; - mousedev->handle.dev = dev; + mousedev->handle.dev = input_get_device(dev); mousedev->handle.name = mousedev->name; mousedev->handle.handler = handler; mousedev->handle.private = mousedev; @@ -998,35 +1006,46 @@ static const struct input_device_id mousedev_ids[] = { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT, - .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, - .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, - .relbit = { BIT(REL_X) | BIT(REL_Y) }, + .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) }, + .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) }, + .relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) }, }, /* A mouse like device, at least one button, two relative axes */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT, - .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, - .relbit = { BIT(REL_WHEEL) }, + .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) }, + .relbit = { BIT_MASK(REL_WHEEL) }, }, /* A separate scrollwheel */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, - .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, - .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, + .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) }, + .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, + .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, }, /* A tablet like device, at least touch detection, two absolute axes */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, - .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) }, - .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | - BIT(ABS_TOOL_WIDTH) }, + .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) }, + .keybit = { [BIT_WORD(BTN_TOOL_FINGER)] = + BIT_MASK(BTN_TOOL_FINGER) }, + .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | + BIT_MASK(ABS_PRESSURE) | + BIT_MASK(ABS_TOOL_WIDTH) }, }, /* A touchpad */ + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT | + INPUT_DEVICE_ID_MATCH_ABSBIT, + .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) }, + .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) }, + .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, + }, /* Mouse-like device with absolute X and Y but ordinary + clicks, like hp ILO2 High Performance mouse */ { }, /* Terminating entry */ };