Input: evdev - rearrange ioctl handling

Split ioctl handling into 3 separate sections: fixed-length ioctls,
variable-length ioctls and multi-number variable length handlers.
This reduces identation and makes the code a bit clearer.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 08f48c0..c908c5f 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -492,13 +492,15 @@
 }
 
 #define OLD_KEY_MAX	0x1ff
-static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user *p, int compat_mode)
+static int handle_eviocgbit(struct input_dev *dev,
+			    unsigned int type, unsigned int size,
+			    void __user *p, int compat_mode)
 {
 	static unsigned long keymax_warn_time;
 	unsigned long *bits;
 	int len;
 
-	switch (_IOC_NR(cmd) & EV_MAX) {
+	switch (type) {
 
 	case      0: bits = dev->evbit;  len = EV_MAX;  break;
 	case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
@@ -517,7 +519,7 @@
 	 * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len'
 	 * should be in bytes, not in bits.
 	 */
-	if ((_IOC_NR(cmd) & EV_MAX) == EV_KEY && _IOC_SIZE(cmd) == OLD_KEY_MAX) {
+	if (type == EV_KEY && size == OLD_KEY_MAX) {
 		len = OLD_KEY_MAX;
 		if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000))
 			printk(KERN_WARNING
@@ -528,7 +530,7 @@
 				BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));
 	}
 
-	return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
+	return bits_to_user(bits, len, size, p, compat_mode);
 }
 #undef OLD_KEY_MAX
 
@@ -542,8 +544,10 @@
 	struct ff_effect effect;
 	int __user *ip = (int __user *)p;
 	unsigned int i, t, u, v;
+	unsigned int size;
 	int error;
 
+	/* First we check for fixed-length commands */
 	switch (cmd) {
 
 	case EVIOCGVERSION:
@@ -610,101 +614,102 @@
 			return evdev_grab(evdev, client);
 		else
 			return evdev_ungrab(evdev, client);
+	}
 
-	default:
+	size = _IOC_SIZE(cmd);
 
-		if (_IOC_TYPE(cmd) != 'E')
-			return -EINVAL;
+	/* Now check variable-length commands */
+#define EVIOC_MASK_SIZE(nr)	((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
 
-		if (_IOC_DIR(cmd) == _IOC_READ) {
+	switch (EVIOC_MASK_SIZE(cmd)) {
 
-			if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
-				return handle_eviocgbit(dev, cmd, p, compat_mode);
+	case EVIOCGKEY(0):
+		return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
-				return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
-						    p, compat_mode);
+	case EVIOCGLED(0):
+		return bits_to_user(dev->led, LED_MAX, size, p, compat_mode);
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
-				return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
-						    p, compat_mode);
+	case EVIOCGSND(0):
+		return bits_to_user(dev->snd, SND_MAX, size, p, compat_mode);
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
-				return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
-						    p, compat_mode);
+	case EVIOCGSW(0):
+		return bits_to_user(dev->sw, SW_MAX, size, p, compat_mode);
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
-				return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
-						    p, compat_mode);
+	case EVIOCGNAME(0):
+		return str_to_user(dev->name, size, p);
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
-				return str_to_user(dev->name, _IOC_SIZE(cmd), p);
+	case EVIOCGPHYS(0):
+		return str_to_user(dev->phys, size, p);
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
-				return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
+	case EVIOCGUNIQ(0):
+		return str_to_user(dev->uniq, size, p);
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
-				return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
+	case EVIOC_MASK_SIZE(EVIOCSFF):
+		if (input_ff_effect_from_user(p, size, &effect))
+			return -EFAULT;
 
-			if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
+		error = input_ff_upload(dev, &effect, file);
 
-				t = _IOC_NR(cmd) & ABS_MAX;
-				abs = dev->absinfo[t];
+		if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
+			return -EFAULT;
 
-				if (copy_to_user(p, &abs, min_t(size_t,
-								_IOC_SIZE(cmd),
-								sizeof(struct input_absinfo))))
-					return -EFAULT;
+		return error;
+	}
 
-				return 0;
-			}
+	/* Multi-number variable-length handlers */
+	if (_IOC_TYPE(cmd) != 'E')
+		return -EINVAL;
 
-		}
+	if (_IOC_DIR(cmd) == _IOC_READ) {
 
-		if (_IOC_DIR(cmd) == _IOC_WRITE) {
+		if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
+			return handle_eviocgbit(dev,
+						_IOC_NR(cmd) & EV_MAX, size,
+						p, compat_mode);
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) {
+		if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
 
-				if (input_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect))
-					return -EFAULT;
+			t = _IOC_NR(cmd) & ABS_MAX;
+			abs = dev->absinfo[t];
 
-				error = input_ff_upload(dev, &effect, file);
+			if (copy_to_user(p, &abs, min_t(size_t,
+					size, sizeof(struct input_absinfo))))
+				return -EFAULT;
 
-				if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
-					return -EFAULT;
-
-				return error;
-			}
-
-			if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
-
-				t = _IOC_NR(cmd) & ABS_MAX;
-
-				if (copy_from_user(&abs, p, min_t(size_t,
-								  _IOC_SIZE(cmd),
-								  sizeof(struct input_absinfo))))
-					return -EFAULT;
-
-				if (_IOC_SIZE(cmd) < sizeof(struct input_absinfo))
-					abs.resolution = 0;
-
-				/* We can't change number of reserved MT slots */
-				if (t == ABS_MT_SLOT)
-					return -EINVAL;
-
-				/*
-				 * Take event lock to ensure that we are not
-				 * changing device parameters in the middle
-				 * of event.
-				 */
-				spin_lock_irq(&dev->event_lock);
-				dev->absinfo[t] = abs;
-				spin_unlock_irq(&dev->event_lock);
-
-				return 0;
-			}
+			return 0;
 		}
 	}
+
+	if (_IOC_DIR(cmd) == _IOC_READ) {
+
+		if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
+
+			t = _IOC_NR(cmd) & ABS_MAX;
+
+			if (copy_from_user(&abs, p, min_t(size_t,
+					size, sizeof(struct input_absinfo))))
+				return -EFAULT;
+
+			if (size < sizeof(struct input_absinfo))
+				abs.resolution = 0;
+
+			/* We can't change number of reserved MT slots */
+			if (t == ABS_MT_SLOT)
+				return -EINVAL;
+
+			/*
+			 * Take event lock to ensure that we are not
+			 * changing device parameters in the middle
+			 * of event.
+			 */
+			spin_lock_irq(&dev->event_lock);
+			dev->absinfo[t] = abs;
+			spin_unlock_irq(&dev->event_lock);
+
+			return 0;
+		}
+	}
+
 	return -EINVAL;
 }