Commit d542ed82 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: handlers - handle errors from input_open_device()

Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent d0ffb9be
...@@ -130,6 +130,7 @@ static int evdev_open(struct inode *inode, struct file *file) ...@@ -130,6 +130,7 @@ static int evdev_open(struct inode *inode, struct file *file)
struct evdev_client *client; struct evdev_client *client;
struct evdev *evdev; struct evdev *evdev;
int i = iminor(inode) - EVDEV_MINOR_BASE; int i = iminor(inode) - EVDEV_MINOR_BASE;
int error;
if (i >= EVDEV_MINORS) if (i >= EVDEV_MINORS)
return -ENODEV; return -ENODEV;
...@@ -146,8 +147,14 @@ static int evdev_open(struct inode *inode, struct file *file) ...@@ -146,8 +147,14 @@ static int evdev_open(struct inode *inode, struct file *file)
client->evdev = evdev; client->evdev = evdev;
list_add_tail(&client->node, &evdev->client_list); list_add_tail(&client->node, &evdev->client_list);
if (!evdev->open++ && evdev->exist) if (!evdev->open++ && evdev->exist) {
input_open_device(&evdev->handle); error = input_open_device(&evdev->handle);
if (error) {
list_del(&client->node);
kfree(client);
return error;
}
}
file->private_data = client; file->private_data = client;
return 0; return 0;
......
...@@ -170,6 +170,7 @@ static int joydev_open(struct inode *inode, struct file *file) ...@@ -170,6 +170,7 @@ static int joydev_open(struct inode *inode, struct file *file)
struct joydev_client *client; struct joydev_client *client;
struct joydev *joydev; struct joydev *joydev;
int i = iminor(inode) - JOYDEV_MINOR_BASE; int i = iminor(inode) - JOYDEV_MINOR_BASE;
int error;
if (i >= JOYDEV_MINORS) if (i >= JOYDEV_MINORS)
return -ENODEV; return -ENODEV;
...@@ -185,8 +186,14 @@ static int joydev_open(struct inode *inode, struct file *file) ...@@ -185,8 +186,14 @@ static int joydev_open(struct inode *inode, struct file *file)
client->joydev = joydev; client->joydev = joydev;
list_add_tail(&client->node, &joydev->client_list); list_add_tail(&client->node, &joydev->client_list);
if (!joydev->open++ && joydev->exist) if (!joydev->open++ && joydev->exist) {
input_open_device(&joydev->handle); error = input_open_device(&joydev->handle);
if (error) {
list_del(&client->node);
kfree(client);
return error;
}
}
file->private_data = client; file->private_data = client;
return 0; return 0;
......
...@@ -66,6 +66,9 @@ struct mousedev { ...@@ -66,6 +66,9 @@ struct mousedev {
struct list_head client_list; struct list_head client_list;
struct input_handle handle; struct input_handle handle;
struct list_head mixdev_node;
int mixdev_open;
struct mousedev_hw_data packet; struct mousedev_hw_data packet;
unsigned int pkt_count; unsigned int pkt_count;
int old_x[4], old_y[4]; int old_x[4], old_y[4];
...@@ -111,6 +114,7 @@ static struct input_handler mousedev_handler; ...@@ -111,6 +114,7 @@ static struct input_handler mousedev_handler;
static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
static struct mousedev mousedev_mix; static struct mousedev mousedev_mix;
static LIST_HEAD(mousedev_mix_list);
#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
#define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
...@@ -364,18 +368,63 @@ static void mousedev_free(struct mousedev *mousedev) ...@@ -364,18 +368,63 @@ static void mousedev_free(struct mousedev *mousedev)
kfree(mousedev); kfree(mousedev);
} }
static void mixdev_release(void) static int mixdev_add_device(struct mousedev *mousedev)
{ {
struct input_handle *handle; int error;
list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { if (mousedev_mix.open) {
struct mousedev *mousedev = handle->private; error = input_open_device(&mousedev->handle);
if (error)
return error;
if (!mousedev->open) { mousedev->open++;
if (mousedev->exist) mousedev->mixdev_open++;
input_close_device(&mousedev->handle); }
else
mousedev_free(mousedev); list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
return 0;
}
static void mixdev_remove_device(struct mousedev *mousedev)
{
if (mousedev->mixdev_open) {
mousedev->mixdev_open = 0;
if (!--mousedev->open && mousedev->exist)
input_close_device(&mousedev->handle);
}
list_del_init(&mousedev->mixdev_node);
}
static void mixdev_open_devices(void)
{
struct mousedev *mousedev;
list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
if (mousedev->exist && !mousedev->open) {
if (input_open_device(&mousedev->handle))
continue;
mousedev->open++;
mousedev->mixdev_open++;
}
}
}
static void mixdev_close_devices(void)
{
struct mousedev *mousedev, *next;
list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) {
if (mousedev->mixdev_open) {
mousedev->mixdev_open = 0;
if (!--mousedev->open) {
if (mousedev->exist)
input_close_device(&mousedev->handle);
else
mousedev_free(mousedev);
}
} }
} }
} }
...@@ -392,23 +441,22 @@ static int mousedev_release(struct inode *inode, struct file *file) ...@@ -392,23 +441,22 @@ static int mousedev_release(struct inode *inode, struct file *file)
if (!--mousedev->open) { if (!--mousedev->open) {
if (mousedev->minor == MOUSEDEV_MIX) if (mousedev->minor == MOUSEDEV_MIX)
mixdev_release(); mixdev_close_devices();
else if (!mousedev_mix.open) { else if (mousedev->exist)
if (mousedev->exist) input_close_device(&mousedev->handle);
input_close_device(&mousedev->handle); else
else mousedev_free(mousedev);
mousedev_free(mousedev);
}
} }
return 0; return 0;
} }
static int mousedev_open(struct inode *inode, struct file *file) static int mousedev_open(struct inode *inode, struct file *file)
{ {
struct mousedev_client *client; struct mousedev_client *client;
struct input_handle *handle;
struct mousedev *mousedev; struct mousedev *mousedev;
int error;
int i; int i;
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
...@@ -436,15 +484,16 @@ static int mousedev_open(struct inode *inode, struct file *file) ...@@ -436,15 +484,16 @@ static int mousedev_open(struct inode *inode, struct file *file)
list_add_tail(&client->node, &mousedev->client_list); list_add_tail(&client->node, &mousedev->client_list);
if (!mousedev->open++) { if (!mousedev->open++) {
if (mousedev->minor == MOUSEDEV_MIX) { if (mousedev->minor == MOUSEDEV_MIX)
list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { mixdev_open_devices();
struct mousedev *md = handle->private; else if (mousedev->exist) {
if (!md->open && md->exist) error = input_open_device(&mousedev->handle);
input_open_device(handle); if (error) {
list_del(&client->node);
kfree(client);
return error;
} }
} else }
if (!mousedev_mix.open && mousedev->exist)
input_open_device(&mousedev->handle);
} }
file->private_data = client; file->private_data = client;
...@@ -683,11 +732,9 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev ...@@ -683,11 +732,9 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev
if (error) if (error)
goto err_remove_link; goto err_remove_link;
if (mousedev_mix.open) { error = mixdev_add_device(mousedev);
error = input_open_device(&mousedev->handle); if (error)
if (error) goto err_unregister_handle;
goto err_unregister_handle;
}
return 0; return 0;
...@@ -715,16 +762,15 @@ static void mousedev_disconnect(struct input_handle *handle) ...@@ -715,16 +762,15 @@ static void mousedev_disconnect(struct input_handle *handle)
MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
mousedev->exist = 0; mousedev->exist = 0;
mixdev_remove_device(mousedev);
if (mousedev->open) { if (mousedev->open) {
input_close_device(handle); input_close_device(handle);
wake_up_interruptible(&mousedev->wait); wake_up_interruptible(&mousedev->wait);
list_for_each_entry(client, &mousedev->client_list, node) list_for_each_entry(client, &mousedev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP); kill_fasync(&client->fasync, SIGIO, POLL_HUP);
} else { } else
if (mousedev_mix.open)
input_close_device(handle);
mousedev_free(mousedev); mousedev_free(mousedev);
}
} }
static const struct input_device_id mousedev_ids[] = { static const struct input_device_id mousedev_ids[] = {
......
...@@ -151,6 +151,7 @@ static int tsdev_open(struct inode *inode, struct file *file) ...@@ -151,6 +151,7 @@ static int tsdev_open(struct inode *inode, struct file *file)
int i = iminor(inode) - TSDEV_MINOR_BASE; int i = iminor(inode) - TSDEV_MINOR_BASE;
struct tsdev_client *client; struct tsdev_client *client;
struct tsdev *tsdev; struct tsdev *tsdev;
int error;
printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled "
"for removal.\nSee Documentation/feature-removal-schedule.txt " "for removal.\nSee Documentation/feature-removal-schedule.txt "
...@@ -171,8 +172,14 @@ static int tsdev_open(struct inode *inode, struct file *file) ...@@ -171,8 +172,14 @@ static int tsdev_open(struct inode *inode, struct file *file)
client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0;
list_add_tail(&client->node, &tsdev->client_list); list_add_tail(&client->node, &tsdev->client_list);
if (!tsdev->open++ && tsdev->exist) if (!tsdev->open++ && tsdev->exist) {
input_open_device(&tsdev->handle); error = input_open_device(&tsdev->handle);
if (error) {
list_del(&client->node);
kfree(client);
return error;
}
}
file->private_data = client; file->private_data = client;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment