[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>
This commit is contained in:
Dmitry Torokhov
2005-09-15 02:01:47 -05:00
committed by Greg Kroah-Hartman
parent 3c42f0c3dd
commit c5b7c7c395
21 changed files with 988 additions and 1029 deletions

View File

@@ -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 @@ struct usb_keyspan {
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 struct usb_driver keyspan_driver;
*/
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 void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
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 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
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 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
dev->data.bits_left += 8;
}
return(0);
return 0;
}
/*
@@ -311,10 +311,10 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
__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 @@ static int keyspan_open(struct input_dev *dev)
{
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 @@ static void keyspan_close(struct input_dev *dev)
{
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 void keyspan_close(struct input_dev *dev)
*/
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 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
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 @@ static void keyspan_disconnect(struct usb_interface *interface)
{
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");
}
/*