[PATCH] drivers/usb/input: convert to dynamic input_dev allocation

Input: convert drivers/iusb/input to dynamic input_dev allocation

This is required for input_dev sysfs integration

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 99de1b3..5b8d65f 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -20,6 +20,7 @@
 #include <linux/moduleparam.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 #define DRIVER_VERSION	"v0.1"
 #define DRIVER_AUTHOR	"Michael Downey <downey@zymeta.com>"
@@ -75,7 +76,7 @@
 	char				name[128];
 	char				phys[64];
 	struct usb_device*		udev;
-	struct input_dev		input;
+	struct input_dev		*input;
 	struct usb_interface*		interface;
 	struct usb_endpoint_descriptor* in_endpoint;
 	struct urb*			irq_urb;
@@ -136,12 +137,11 @@
  */
 static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
 {
-	char codes[4*RECV_SIZE];
+	char codes[4 * RECV_SIZE];
 	int i;
 
-	for (i = 0; i < RECV_SIZE; i++) {
-		snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]);
-	}
+	for (i = 0; i < RECV_SIZE; i++)
+		snprintf(codes + i * 3, 4, "%02x ", dev->in_buffer[i]);
 
 	dev_info(&dev->udev->dev, "%s\n", codes);
 }
@@ -153,7 +153,7 @@
 static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
 {
 	if (dev->data.bits_left >= bits_needed)
-		return(0);
+		return 0;
 
 	/*
 	 * Somehow we've missed the last message. The message will be repeated
@@ -162,7 +162,7 @@
 	if (dev->data.pos >= dev->data.len) {
 		dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
 			__FUNCTION__, dev->data.pos, dev->data.len);
-		return(-1);
+		return -1;
 	}
 
 	/* Load as much as we can into the tester. */
@@ -172,7 +172,7 @@
 		dev->data.bits_left += 8;
 	}
 
-	return(0);
+	return 0;
 }
 
 /*
@@ -311,10 +311,10 @@
 			__FUNCTION__, message.system, message.button, message.toggle);
 
 		if (message.toggle != remote->toggle) {
-			input_regs(&remote->input, regs);
-			input_report_key(&remote->input, keyspan_key_table[message.button], 1);
-			input_report_key(&remote->input, keyspan_key_table[message.button], 0);
-			input_sync(&remote->input);
+			input_regs(remote->input, regs);
+			input_report_key(remote->input, keyspan_key_table[message.button], 1);
+			input_report_key(remote->input, keyspan_key_table[message.button], 0);
+			input_sync(remote->input);
 			remote->toggle = message.toggle;
 		}
 
@@ -397,14 +397,9 @@
 {
 	struct usb_keyspan *remote = dev->private;
 
-	if (remote->open++)
-		return 0;
-
 	remote->irq_urb->dev = remote->udev;
-	if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) {
-		remote->open--;
+	if (usb_submit_urb(remote->irq_urb, GFP_KERNEL))
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -413,8 +408,26 @@
 {
 	struct usb_keyspan *remote = dev->private;
 
-	if (!--remote->open)
-		usb_kill_urb(remote->irq_urb);
+	usb_kill_urb(remote->irq_urb);
+}
+
+static struct usb_endpoint_descriptor *keyspan_get_in_endpoint(struct usb_host_interface *iface)
+{
+
+	struct usb_endpoint_descriptor *endpoint;
+	int i;
+
+	for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
+		endpoint = &iface->endpoint[i].desc;
+
+		if ((endpoint->bEndpointAddress & USB_DIR_IN) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+			/* we found our interrupt in endpoint */
+			return endpoint;
+		}
+	}
+
+	return NULL;
 }
 
 /*
@@ -422,110 +435,78 @@
  */
 static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id)
 {
-	int i;
-	int retval = -ENOMEM;
-	char path[64];
-	char *buf;
-	struct usb_keyspan *remote = NULL;
-	struct usb_host_interface *iface_desc;
+	struct usb_device *udev = interface_to_usbdev(interface);
 	struct usb_endpoint_descriptor *endpoint;
-	struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
+	struct usb_keyspan *remote;
+	struct input_dev *input_dev;
+	int i, retval;
 
-	/* allocate memory for our device state and initialize it */
-	remote = kmalloc(sizeof(*remote), GFP_KERNEL);
-	if (remote == NULL) {
-		err("Out of memory\n");
-		goto error;
+	endpoint = keyspan_get_in_endpoint(interface->cur_altsetting);
+	if (!endpoint)
+		return -ENODEV;
+
+	remote = kzalloc(sizeof(*remote), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!remote || !input_dev) {
+		retval = -ENOMEM;
+		goto fail1;
 	}
-	memset(remote, 0x00, sizeof(*remote));
 
 	remote->udev = udev;
+	remote->input = input_dev;
 	remote->interface = interface;
+	remote->in_endpoint = endpoint;
 	remote->toggle = -1;	/* Set to -1 so we will always not match the toggle from the first remote message. */
 
-	/* set up the endpoint information */
-	/* use only the first in interrupt endpoint */
-	iface_desc = interface->cur_altsetting;
-	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
-		endpoint = &iface_desc->endpoint[i].desc;
-
-		if (!remote->in_endpoint &&
-		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
-		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
-			/* we found our interrupt in endpoint */
-			remote->in_endpoint = endpoint;
-
-			remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
-			if (!remote->in_buffer) {
-				retval = -ENOMEM;
-				goto error;
-			}
-		}
-	}
-
-	if (!remote->in_endpoint) {
-		err("Could not find interrupt input endpoint.\n");
-		retval = -ENODEV;
-		goto error;
+	remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
+	if (!remote->in_buffer) {
+		retval = -ENOMEM;
+		goto fail1;
 	}
 
 	remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!remote->irq_urb) {
-		err("Failed to allocate urb.\n");
 		retval = -ENOMEM;
-		goto error;
+		goto fail2;
 	}
 
-	retval = keyspan_setup(remote->udev);
+	retval = keyspan_setup(udev);
 	if (retval) {
-		err("Failed to setup device.\n");
 		retval = -ENODEV;
-		goto error;
+		goto fail3;
 	}
 
-	/*
-	 * Setup the input system with the bits we are going to be reporting
-	 */
-	remote->input.evbit[0] = BIT(EV_KEY);		/* We will only report KEY events. */
-	for (i = 0; i < 32; ++i) {
-		if (keyspan_key_table[i] != KEY_RESERVED) {
-			set_bit(keyspan_key_table[i], remote->input.keybit);
-		}
+	if (udev->manufacturer)
+		strlcpy(remote->name, udev->manufacturer, sizeof(remote->name));
+
+	if (udev->product) {
+		if (udev->manufacturer)
+			strlcat(remote->name, " ", sizeof(remote->name));
+		strlcat(remote->name, udev->product, sizeof(remote->name));
 	}
 
-	remote->input.private = remote;
-	remote->input.open = keyspan_open;
-	remote->input.close = keyspan_close;
-
-	usb_make_path(remote->udev, path, 64);
-	sprintf(remote->phys, "%s/input0", path);
-
-	remote->input.name = remote->name;
-	remote->input.phys = remote->phys;
-	remote->input.id.bustype = BUS_USB;
-	remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor);
-	remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct);
-	remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice);
-
-	if (!(buf = kmalloc(63, GFP_KERNEL))) {
-		usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
-		kfree(remote);
-		return -ENOMEM;
-	}
-
-	if (remote->udev->descriptor.iManufacturer &&
-	    usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0)
-		strcat(remote->name, buf);
-
-	if (remote->udev->descriptor.iProduct &&
-	    usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0)
-		sprintf(remote->name, "%s %s", remote->name, buf);
-
 	if (!strlen(remote->name))
-		sprintf(remote->name, "USB Keyspan Remote %04x:%04x",
-			remote->input.id.vendor, remote->input.id.product);
+		snprintf(remote->name, sizeof(remote->name),
+			 "USB Keyspan Remote %04x:%04x",
+			 le16_to_cpu(udev->descriptor.idVendor),
+			 le16_to_cpu(udev->descriptor.idProduct));
 
-	kfree(buf);
+	usb_make_path(udev, remote->phys, sizeof(remote->phys));
+	strlcat(remote->phys, "/input0", sizeof(remote->phys));
+
+	input_dev->name = remote->name;
+	input_dev->phys = remote->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &interface->dev;
+
+	input_dev->evbit[0] = BIT(EV_KEY);		/* We will only report KEY events. */
+	for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
+		if (keyspan_key_table[i] != KEY_RESERVED)
+			set_bit(keyspan_key_table[i], input_dev->keybit);
+
+	input_dev->private = remote;
+	input_dev->open = keyspan_open;
+	input_dev->close = keyspan_close;
 
 	/*
 	 * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open()
@@ -538,27 +519,17 @@
 	remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	/* we can register the device now, as it is ready */
-	input_register_device(&remote->input);
+	input_register_device(remote->input);
 
 	/* save our data pointer in this interface device */
 	usb_set_intfdata(interface, remote);
 
-	/* let the user know what node this device is now attached to */
-	info("connected: %s on %s", remote->name, path);
 	return 0;
 
-error:
-	/*
-	 * In case of error we need to clean up any allocated buffers
-	 */
-	if (remote->irq_urb)
-		usb_free_urb(remote->irq_urb);
-
-	if (remote->in_buffer)
-		usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
-
-	if (remote)
-		kfree(remote);
+ fail3:	usb_free_urb(remote->irq_urb);
+ fail2:	usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+ fail1:	kfree(remote);
+	input_free_device(input_dev);
 
 	return retval;
 }
@@ -570,23 +541,16 @@
 {
 	struct usb_keyspan *remote;
 
-	/* prevent keyspan_open() from racing keyspan_disconnect() */
-	lock_kernel();
-
 	remote = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
 
 	if (remote) {	/* We have a valid driver structure so clean up everything we allocated. */
-		input_unregister_device(&remote->input);
+		input_unregister_device(remote->input);
 		usb_kill_urb(remote->irq_urb);
 		usb_free_urb(remote->irq_urb);
-		usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma);
+		usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
 		kfree(remote);
 	}
-
-	unlock_kernel();
-
-	info("USB Keyspan now disconnected");
 }
 
 /*