patch-2.4.0-test2 linux/drivers/usb/joydev.c

Next file: linux/drivers/usb/keybdev.c
Previous file: linux/drivers/usb/input.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/drivers/usb/joydev.c linux/drivers/usb/joydev.c
@@ -1,7 +1,7 @@
 /*
- *  joydev.c  Version 0.1
+ * $Id: joydev.c,v 1.11 2000/06/23 09:23:00 vojtech Exp $
  *
- *  Copyright (c) 1999 Vojtech Pavlik                                       
+ *  Copyright (c) 1999-2000 Vojtech Pavlik 
  *  Copyright (c) 1999 Colin Van Dyke 
  *
  *  Joystick device driver for the input driver suite.
@@ -50,10 +50,9 @@
 #define JOYDEV_BUFFER_SIZE	64
 
 struct joydev {
-	int used;
+	int exist;
 	int open;
 	int minor;
-	char name[32];
 	struct input_handle handle;
 	wait_queue_head_t wait;
 	devfs_handle_t devfs;
@@ -67,6 +66,7 @@
 	__u16 keypam[KEY_MAX - BTN_MISC];
 	__u8 absmap[ABS_MAX];
 	__u8 abspam[ABS_MAX];
+	__s16 abs[ABS_MAX];
 };
 
 struct joydev_list {
@@ -122,7 +122,9 @@
 		case EV_ABS:
 			event.type = JS_EVENT_AXIS;
 			event.number = joydev->absmap[code];
-			event.value = joydev_correct(value, &joydev->corr[event.number]);
+			event.value = joydev_correct(value, joydev->corr + event.number);
+			if (event.value == joydev->abs[event.number]) return;
+			joydev->abs[event.number] = event.value;
 			break;
 
 		default:
@@ -139,8 +141,7 @@
 			if (list->tail == (list->head = (list->head + 1) & (JOYDEV_BUFFER_SIZE - 1)))
 				list->startup = 0;
 
-		if (list->fasync)
-			kill_fasync(list->fasync, SIGIO, POLL_IN);
+		kill_fasync(&list->fasync, SIGIO, POLL_IN);
 
 		list = list->next;
 	}
@@ -167,18 +168,18 @@
 		listptr = &((*listptr)->next);
 	*listptr = (*listptr)->next;
 
-	if (!--list->joydev->open)
-		input_close_device(&list->joydev->handle);
-	
-	if (!--list->joydev->used) {
-		input_unregister_minor(list->joydev->devfs);
-		joydev_table[list->joydev->minor] = NULL;
-		kfree(list->joydev);
+	if (!--list->joydev->open) {
+		if (list->joydev->exist) {
+			input_close_device(&list->joydev->handle);
+		} else {
+			input_unregister_minor(list->joydev->devfs);
+			joydev_table[list->joydev->minor] = NULL;
+			kfree(list->joydev);
+		}
 	}
 
 	kfree(list);
 
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -190,12 +191,8 @@
 	if (i > JOYDEV_MINORS || !joydev_table[i])
 		return -ENODEV;
 
-	MOD_INC_USE_COUNT;
-
-	if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL))) {
-		MOD_DEC_USE_COUNT;
+	if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL)))
 		return -ENOMEM;
-	}
 	memset(list, 0, sizeof(struct joydev_list));
 
 	list->joydev = joydev_table[i];
@@ -204,10 +201,9 @@
 
 	file->private_data = list;
 
-	list->joydev->used++;
-
 	if (!list->joydev->open++)
-		input_open_device(&list->joydev->handle);
+		if (list->joydev->exist)
+			input_open_device(&list->joydev->handle);
 
 	return 0;
 }
@@ -234,8 +230,8 @@
 
 		data.buttons =  ((joydev->nkey > 0 && test_bit(joydev->keypam[0], input->key)) ? 1 : 0) |
 				((joydev->nkey > 1 && test_bit(joydev->keypam[1], input->key)) ? 2 : 0);
-		data.x = ((joydev_correct(input->abs[ABS_X], &joydev->corr[0]) / 256) + 128) >> joydev->glue.JS_CORR.x;
-		data.y = ((joydev_correct(input->abs[ABS_Y], &joydev->corr[1]) / 256) + 128) >> joydev->glue.JS_CORR.y;
+		data.x = (joydev->abs[0] / 256 + 128) >> joydev->glue.JS_CORR.x;
+		data.y = (joydev->abs[1] / 256 + 128) >> joydev->glue.JS_CORR.y;
 
 		if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)))
 			return -EFAULT;
@@ -280,13 +276,12 @@
 
 		if (list->startup < joydev->nkey) {
 			event.type = JS_EVENT_BUTTON | JS_EVENT_INIT;
-			event.value = !!test_bit(joydev->keypam[list->startup], input->key);
 			event.number = list->startup;
+			event.value = !!test_bit(joydev->keypam[event.number], input->key);
 		} else {
 			event.type = JS_EVENT_AXIS | JS_EVENT_INIT;
-			event.value = joydev_correct(input->abs[joydev->abspam[list->startup - joydev->nkey]],
-							&joydev->corr[list->startup - joydev->nkey]);
 			event.number = list->startup - joydev->nkey;
+			event.value = joydev->abs[event.number];
 		}
 
 		if (copy_to_user(buf + retval, &event, sizeof(struct js_event)))
@@ -322,6 +317,8 @@
 {
 	struct joydev_list *list = file->private_data;
 	struct joydev *joydev = list->joydev;
+	struct input_dev *dev = joydev->handle.dev;
+
 
 	switch (cmd) {
 
@@ -360,9 +357,11 @@
 						sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
 		default:
 			if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
-				int len = strlen(joydev->name) + 1;
+				int len;
+				if (!dev->name) return 0;
+				len = strlen(dev->name) + 1;
 				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-				if (copy_to_user((char *) arg, joydev->name, len)) return -EFAULT;
+				if (copy_to_user((char *) arg, dev->name, len)) return -EFAULT;
 				return len;
 			}
 	}
@@ -370,6 +369,7 @@
 }
 
 static struct file_operations joydev_fops = {
+	owner:		THIS_MODULE,
 	read:		joydev_read,
 	write:		joydev_write,
 	poll:		joydev_poll,
@@ -401,8 +401,6 @@
 
 	init_waitqueue_head(&joydev->wait);
 
-	sprintf(joydev->name, "joydev%d", joydev->minor);
-
 	joydev->minor = minor;
 	joydev_table[minor] = joydev;
 
@@ -410,7 +408,7 @@
 	joydev->handle.handler = handler;
 	joydev->handle.private = joydev;
 
-	joydev->used = 1;
+	joydev->exist = 1;
 
 	for (i = 0; i < ABS_MAX; i++)
 		if (test_bit(i, dev->absbit)) {
@@ -445,11 +443,13 @@
 		joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
 		joydev->corr[i].coef[2] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]);
 		joydev->corr[i].coef[3] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]);
+
+		joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
 	}
 
 	joydev->devfs = input_register_minor("js%d", minor, JOYDEV_MINOR_BASE);
 
-	printk("js%d: Joystick device for input%d\n", minor, dev->number);
+	printk(KERN_INFO "js%d: Joystick device for input%d\n", minor, dev->number);
 
 	return &joydev->handle;
 }
@@ -458,10 +458,11 @@
 {
 	struct joydev *joydev = handle->private;
 
-	if (joydev->open)
-		input_close_device(handle);	
+	joydev->exist = 0;
 
-	if (!--joydev->used) {
+	if (joydev->open) {
+		input_close_device(handle);	
+	} else {
 		input_unregister_minor(joydev->devfs);
 		joydev_table[joydev->minor] = NULL;
 		kfree(joydev);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)