Input: handlers - handle errors from input_open_device()
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
parent
d0ffb9be86
commit
d542ed82fd
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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;
|
|||||||
|
|
||||||
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,14 +368,58 @@ 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++;
|
||||||
|
mousedev->mixdev_open++;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
if (mousedev->exist)
|
||||||
input_close_device(&mousedev->handle);
|
input_close_device(&mousedev->handle);
|
||||||
else
|
else
|
||||||
@ -379,6 +427,7 @@ static void mixdev_release(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int mousedev_release(struct inode *inode, struct file *file)
|
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)
|
|||||||
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
|
|||||||
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,17 +762,16 @@ 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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user