Bugzilla – Attachment 48453 Details for
Bug 112672
joydev module not loaded
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
IDP Log In
|
Forgot Password
[patch]
input_device class instead of /sbin/hotplug
input-kill-sbin-hotplug.patch (text/plain), 8.97 KB, created by
Kay Sievers
on 2005-09-01 13:07:55 UTC
(
hide
)
Description:
input_device class instead of /sbin/hotplug
Filename:
MIME Type:
Creator:
Kay Sievers
Created:
2005-09-01 13:07:55 UTC
Size:
8.97 KB
patch
obsolete
>From: Hannes Reinecke <hare@suse.de> >(shipped with SUSE 9.3 kernels) > >Get rid of /sbin/hotplug calls in the input subsys by >exporting input devices as /sys/class/input_device/* > >diff --git a/drivers/input/input.c b/drivers/input/input.c >--- a/drivers/input/input.c >+++ b/drivers/input/input.c >@@ -47,6 +47,7 @@ static LIST_HEAD(input_dev_list); > static LIST_HEAD(input_handler_list); > > static struct input_handler *input_table[8]; >+static atomic_t input_device_num = ATOMIC_INIT(0); > > #ifdef CONFIG_PROC_FS > static struct proc_dir_entry *proc_bus_input_dir; >@@ -325,52 +326,27 @@ static struct input_device_id *input_mat > SPRINTF_BIT_A(bit, name, max); \ > } while (0) > >-static void input_call_hotplug(char *verb, struct input_dev *dev) >+static int __input_hotplug(struct input_dev *dev, char **envp, int num_envp, >+ char *buffer, int buffer_size) > { >- char *argv[3], **envp, *buf, *scratch; >- int i = 0, j, value; >+ char *scratch; >+ int i = 0, j; >+ scratch = buffer; > >- if (!hotplug_path[0]) { >- printk(KERN_ERR "input.c: calling hotplug without a hotplug agent defined\n"); >- return; >- } >- if (in_interrupt()) { >- printk(KERN_ERR "input.c: calling hotplug from interrupt\n"); >- return; >- } >- if (!current->fs->root) { >- printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n"); >- return; >- } >- if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) { >- printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n"); >- return; >- } >- if (!(buf = kmalloc(1024, GFP_KERNEL))) { >- kfree (envp); >- printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n"); >- return; >- } >- >- argv[0] = hotplug_path; >- argv[1] = "input"; >- argv[2] = NULL; >- >- envp[i++] = "HOME=/"; >- envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; >- >- scratch = buf; >- >- envp[i++] = scratch; >- scratch += sprintf(scratch, "ACTION=%s", verb) + 1; >+ if (!dev) >+ return -ENODEV; > > envp[i++] = scratch; > scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x", > dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1; > >+#ifdef INPUT_DEBUG >+ printk(KERN_DEBUG "%s: PRODUCT %x/%x/%x/%x\n", __FUNCTION__, >+ dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); >+#endif > if (dev->name) { > envp[i++] = scratch; >- scratch += sprintf(scratch, "NAME=%s", dev->name) + 1; >+ scratch += sprintf(scratch, "NAME=\"%s\"", dev->name) + 1; > } > > if (dev->phys) { >@@ -389,23 +365,126 @@ static void input_call_hotplug(char *ver > > envp[i++] = NULL; > >+ return 0; >+} >+ >+int input_hotplug(struct class_device *cdev, char **envp, int num_envp, >+ char *buffer, int buffer_size) >+{ >+ struct input_dev *dev; >+ >+ if (!cdev) >+ return -ENODEV; > #ifdef INPUT_DEBUG >- printk(KERN_DEBUG "input.c: calling %s %s [%s %s %s %s %s]\n", >- argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]); >+ printk(KERN_DEBUG "%s: entered for dev %p\n", __FUNCTION__, >+ &cdev->dev); > #endif > >- value = call_usermodehelper(argv [0], argv, envp, 0); >+ dev = container_of(cdev,struct input_dev,cdev); > >- kfree(buf); >- kfree(envp); >+ return __input_hotplug(dev, envp, num_envp, buffer, buffer_size); >+} > >-#ifdef INPUT_DEBUG >- if (value != 0) >- printk(KERN_DEBUG "input.c: hotplug returned %d\n", value); >-#endif >+#else >+int input_hotplug(struct class_device *cdev, char **envp, int num_envp, >+ char *buffer, int buffer_size) >+{ >+ return 0; > } >+#endif /* CONFIG_HOTPLUG */ > >-#endif >+#define INPUT_ATTR_BIT_B(bit, max) \ >+ do { \ >+ for (i = NBITS(max) - 1; i >= 0; i--) \ >+ if (dev->bit[i]) break; \ >+ for (; i >= 0; i--) \ >+ len += sprintf(buf + len, "%lx ", dev->bit[i]); \ >+ if (len) len += sprintf(buf + len, "\n"); \ >+ } while (0) >+ >+#define INPUT_ATTR_BIT_B2(bit, max, ev) \ >+ do { \ >+ if (test_bit(ev, dev->evbit)) \ >+ INPUT_ATTR_BIT_B(bit, max); \ >+ } while (0) >+ >+ >+static ssize_t input_class_show_ev(struct class_device *class_dev, char *buf) >+{ >+ struct input_dev *dev = container_of(class_dev, struct input_dev,cdev); >+ int i, len = 0; >+ >+ INPUT_ATTR_BIT_B(evbit, EV_MAX); >+ return len; >+} >+ >+#define INPUT_CLASS_ATTR_BIT(_name,_bit) \ >+static ssize_t input_class_show_##_bit(struct class_device *class_dev, \ >+ char *buf) \ >+{ \ >+ struct input_dev *dev = container_of(class_dev,struct input_dev,cdev); \ >+ int i, len = 0; \ >+\ >+ INPUT_ATTR_BIT_B2(_bit##bit, _name##_MAX, EV_##_name); \ >+ return len; \ >+} >+ >+INPUT_CLASS_ATTR_BIT(KEY,key) >+INPUT_CLASS_ATTR_BIT(REL,rel) >+INPUT_CLASS_ATTR_BIT(ABS,abs) >+INPUT_CLASS_ATTR_BIT(MSC,msc) >+INPUT_CLASS_ATTR_BIT(LED,led) >+INPUT_CLASS_ATTR_BIT(SND,snd) >+INPUT_CLASS_ATTR_BIT(FF,ff) >+ >+static ssize_t input_class_show_phys(struct class_device *class_dev, char *buf) >+{ >+ struct input_dev *dev = container_of(class_dev,struct input_dev,cdev); >+ >+ return sprintf(buf, "%s\n", dev->phys ? dev->phys : "(none)" ); >+} >+ >+static ssize_t input_class_show_name(struct class_device *class_dev, char *buf) >+{ >+ struct input_dev *dev = container_of(class_dev,struct input_dev,cdev); >+ >+ return sprintf(buf, "%s\n", dev->name ? dev->name : "(none)" ); >+} >+ >+static ssize_t input_class_show_product(struct class_device *class_dev, char *buf) >+{ >+ struct input_dev *dev = container_of(class_dev,struct input_dev,cdev); >+ >+ return sprintf(buf, "%x/%x/%x/%x\n", dev->id.bustype, dev->id.vendor, >+ dev->id.product, dev->id.version); >+} >+ >+static struct class_device_attribute input_device_class_attrs[] = { >+ __ATTR( product, S_IRUGO, input_class_show_product, NULL) , >+ __ATTR( phys, S_IRUGO, input_class_show_phys, NULL ), >+ __ATTR( name, S_IRUGO, input_class_show_name, NULL) , >+ __ATTR( ev, S_IRUGO, input_class_show_ev, NULL) , >+ __ATTR( key, S_IRUGO, input_class_show_key, NULL) , >+ __ATTR( rel, S_IRUGO, input_class_show_rel, NULL) , >+ __ATTR( abs, S_IRUGO, input_class_show_abs, NULL) , >+ __ATTR( msc, S_IRUGO, input_class_show_msc, NULL) , >+ __ATTR( led, S_IRUGO, input_class_show_led, NULL) , >+ __ATTR( snd, S_IRUGO, input_class_show_snd, NULL) , >+ __ATTR( ff, S_IRUGO, input_class_show_ff, NULL) , >+ __ATTR_NULL, >+}; >+ >+static void input_device_class_release( struct class_device *class_dev ) >+{ >+ put_device(class_dev->dev); >+} >+ >+static struct class input_device_class = { >+ .name = "input_device", >+ .hotplug = input_hotplug, >+ .release = input_device_class_release, >+ .class_dev_attrs = input_device_class_attrs, >+}; > > void input_register_device(struct input_dev *dev) > { >@@ -413,6 +492,18 @@ void input_register_device(struct input_ > struct input_handler *handler; > struct input_device_id *id; > >+ dev->cdev.class = &input_device_class; >+ >+ dev->cdev.dev = get_device(dev->dev); >+ sprintf(dev->cdev.class_id, "input%d", >+ atomic_inc_return(&input_device_num)); >+ >+ if (class_device_register(&dev->cdev)) { >+ if (dev->dev) >+ put_device(dev->dev); >+ return; >+ } >+ > set_bit(EV_SYN, dev->evbit); > > /* >@@ -437,10 +528,6 @@ void input_register_device(struct input_ > if ((handle = handler->connect(handler, dev, id))) > input_link_handle(handle); > >-#ifdef CONFIG_HOTPLUG >- input_call_hotplug("add", dev); >-#endif >- > #ifdef CONFIG_PROC_FS > input_devices_state++; > wake_up(&input_devices_poll_wait); >@@ -462,12 +549,10 @@ void input_unregister_device(struct inpu > handle->handler->disconnect(handle); > } > >-#ifdef CONFIG_HOTPLUG >- input_call_hotplug("remove", dev); >-#endif >- > list_del_init(&dev->node); > >+ class_device_unregister(&dev->cdev); >+ > #ifdef CONFIG_PROC_FS > input_devices_state++; > wake_up(&input_devices_poll_wait); >@@ -711,6 +796,13 @@ static int __init input_init(void) > input_class = class_simple_create(THIS_MODULE, "input"); > if (IS_ERR(input_class)) > return PTR_ERR(input_class); >+ >+ retval = class_register(&input_device_class); >+ if (retval) { >+ class_simple_destroy(input_class); >+ return retval; >+ } >+ > input_proc_init(); > retval = register_chrdev(INPUT_MAJOR, "input", &input_fops); > if (retval) { >@@ -718,6 +810,7 @@ static int __init input_init(void) > remove_proc_entry("devices", proc_bus_input_dir); > remove_proc_entry("handlers", proc_bus_input_dir); > remove_proc_entry("input", proc_bus); >+ class_unregister(&input_device_class); > class_simple_destroy(input_class); > return retval; > } >@@ -728,6 +821,7 @@ static int __init input_init(void) > remove_proc_entry("handlers", proc_bus_input_dir); > remove_proc_entry("input", proc_bus); > unregister_chrdev(INPUT_MAJOR, "input"); >+ class_unregister(&input_device_class); > class_simple_destroy(input_class); > } > return retval; >@@ -741,6 +835,7 @@ static void __exit input_exit(void) > > devfs_remove("input"); > unregister_chrdev(INPUT_MAJOR, "input"); >+ class_unregister(&input_device_class); > class_simple_destroy(input_class); > } > >diff --git a/include/linux/input.h b/include/linux/input.h >--- a/include/linux/input.h >+++ b/include/linux/input.h >@@ -12,6 +12,7 @@ > #ifdef __KERNEL__ > #include <linux/time.h> > #include <linux/list.h> >+#include <linux/device.h> > #else > #include <sys/time.h> > #include <sys/ioctl.h> >@@ -860,6 +861,7 @@ struct input_dev { > > struct input_handle *grab; > struct device *dev; >+ struct class_device cdev; > > struct list_head h_list; > struct list_head node;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 112672
: 48453