patch-2.4.0-test2 linux/drivers/usb/evdev.c
Next file: linux/drivers/usb/hid-debug.h
Previous file: linux/drivers/usb/dsbr100.c
Back to the patch index
Back to the overall index
- Lines: 191
- Date:
Fri Jun 23 21:01:29 2000
- Orig file:
v2.4.0-test1/linux/drivers/usb/evdev.c
- Orig date:
Wed Apr 26 16:34:08 2000
diff -u --recursive --new-file v2.4.0-test1/linux/drivers/usb/evdev.c linux/drivers/usb/evdev.c
@@ -1,7 +1,7 @@
/*
- * evdev.c Version 0.1
+ * $Id: evdev.c,v 1.10 2000/06/23 09:23:00 vojtech Exp $
*
- * Copyright (c) 1999 Vojtech Pavlik
+ * Copyright (c) 1999-2000 Vojtech Pavlik
*
* Event char devices, giving access to raw input device events.
*
@@ -39,7 +39,7 @@
#include <linux/input.h>
struct evdev {
- int used;
+ int exist;
int open;
int minor;
struct input_handle handle;
@@ -72,8 +72,7 @@
list->buffer[list->head].value = value;
list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1);
- if (list->fasync)
- kill_fasync(list->fasync, SIGIO, POLL_IN);
+ kill_fasync(&list->fasync, SIGIO, POLL_IN);
list = list->next;
}
@@ -100,18 +99,18 @@
listptr = &((*listptr)->next);
*listptr = (*listptr)->next;
- if (!--list->evdev->open)
- input_close_device(&list->evdev->handle);
-
- if (!--list->evdev->used) {
- input_unregister_minor(list->evdev->devfs);
- evdev_table[list->evdev->minor] = NULL;
- kfree(list->evdev);
+ if (!--list->evdev->open) {
+ if (list->evdev->exist) {
+ input_close_device(&list->evdev->handle);
+ } else {
+ input_unregister_minor(list->evdev->devfs);
+ evdev_table[list->evdev->minor] = NULL;
+ kfree(list->evdev);
+ }
}
kfree(list);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -123,12 +122,8 @@
if (i > EVDEV_MINORS || !evdev_table[i])
return -ENODEV;
- MOD_INC_USE_COUNT;
-
- if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL))) {
- MOD_DEC_USE_COUNT;
+ if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL)))
return -ENOMEM;
- }
memset(list, 0, sizeof(struct evdev_list));
list->evdev = evdev_table[i];
@@ -137,10 +132,9 @@
file->private_data = list;
- list->evdev->used++;
-
if (!list->evdev->open++)
- input_open_device(&list->evdev->handle);
+ if (list->evdev->exist)
+ input_open_device(&list->evdev->handle);
return 0;
}
@@ -207,14 +201,20 @@
struct evdev_list *list = file->private_data;
struct evdev *evdev = list->evdev;
struct input_dev *dev = evdev->handle.dev;
+ int retval;
switch (cmd) {
case EVIOCGVERSION:
- return put_user(EV_VERSION, (__u32 *) arg);
+ return put_user(EV_VERSION, (int *) arg);
+
case EVIOCGID:
- return copy_to_user(&dev->id, (void *) arg,
- sizeof(struct input_id)) ? -EFAULT : 0;
+ if ((retval = put_user(dev->idbus, ((short *) arg) + 0))) return retval;
+ if ((retval = put_user(dev->idvendor, ((short *) arg) + 1))) return retval;
+ if ((retval = put_user(dev->idproduct, ((short *) arg) + 2))) return retval;
+ if ((retval = put_user(dev->idversion, ((short *) arg) + 3))) return retval;
+ return 0;
+
default:
if (_IOC_TYPE(cmd) != 'E' || _IOC_DIR(cmd) != _IOC_READ)
@@ -222,8 +222,8 @@
if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
- long *bits = NULL;
- int len = 0;
+ long *bits;
+ int len;
switch (_IOC_NR(cmd) & EV_MAX) {
case 0: bits = dev->evbit; len = EV_MAX; break;
@@ -235,20 +235,40 @@
default: return -EINVAL;
}
len = NBITS(len) * sizeof(long);
- if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
- return copy_to_user((void *) arg, bits, len) ? -EFAULT : len;
+ if (len > _IOC_SIZE(cmd)) {
+ printk(KERN_WARNING "evdev.c: Truncating bitfield length from %d to %d\n",
+ len, _IOC_SIZE(cmd));
+ len = _IOC_SIZE(cmd);
+ }
+ return copy_to_user((char *) arg, bits, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
- int len = strlen(dev->name) + 1;
+ int len;
+ if (!dev->name) return 0;
+ len = strlen(dev->name) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user((char *) arg, dev->name, len) ? -EFAULT : len;
}
+
+ if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
+
+ int t = _IOC_NR(cmd) & ABS_MAX;
+
+ if ((retval = put_user(dev->abs[t], ((int *) arg) + 0))) return retval;
+ if ((retval = put_user(dev->absmin[t], ((int *) arg) + 1))) return retval;
+ if ((retval = put_user(dev->absmax[t], ((int *) arg) + 2))) return retval;
+ if ((retval = put_user(dev->absfuzz[t], ((int *) arg) + 3))) return retval;
+ if ((retval = put_user(dev->absflat[t], ((int *) arg) + 4))) return retval;
+
+ return 0;
+ }
}
return -EINVAL;
}
static struct file_operations evdev_fops = {
+ owner: THIS_MODULE,
read: evdev_read,
write: evdev_write,
poll: evdev_poll,
@@ -282,11 +302,11 @@
evdev->handle.handler = handler;
evdev->handle.private = evdev;
- evdev->used = 1;
+ evdev->exist = 1;
evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE);
- printk("event%d: Event device for input%d\n", minor, dev->number);
+ printk(KERN_INFO "event%d: Event device for input%d\n", minor, dev->number);
return &evdev->handle;
}
@@ -295,10 +315,11 @@
{
struct evdev *evdev = handle->private;
- if (evdev->open)
- input_close_device(handle);
+ evdev->exist = 0;
- if (!--evdev->used) {
+ if (evdev->open) {
+ input_close_device(handle);
+ } else {
input_unregister_minor(evdev->devfs);
evdev_table[evdev->minor] = NULL;
kfree(evdev);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)