From 152c12f568d4fc6e9a7dfd42f2d51347fb41d9b7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:47:50 -0500 Subject: Input: clean up uinput driver (formatting, extra braces) Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 81 ++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 46 deletions(-) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 9871099..9c3d200 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -36,16 +36,6 @@ #include #include -static int uinput_dev_open(struct input_dev *dev) -{ - return 0; -} - -static void uinput_dev_close(struct input_dev *dev) -{ - -} - static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct uinput_device *udev; @@ -68,17 +58,20 @@ static int uinput_request_alloc_id(struct input_dev *dev, struct uinput_request /* Atomically allocate an ID for the given request. Returns 0 on success. */ struct uinput_device *udev = dev->private; int id; + int err = -1; down(&udev->requests_sem); - for (id=0; idrequests[id]) { udev->requests[id] = request; request->id = id; - up(&udev->requests_sem); - return 0; + err = 0; + break; } + up(&udev->requests_sem); - return -1; + return err; } static struct uinput_request* uinput_request_find(struct uinput_device *udev, int id) @@ -101,7 +94,7 @@ static void uinput_request_init(struct input_dev *dev, struct uinput_request *re /* Allocate an ID. If none are available right away, wait. */ request->retval = wait_event_interruptible(udev->requests_waitq, - !uinput_request_alloc_id(dev, request)); + !uinput_request_alloc_id(dev, request)); } static void uinput_request_submit(struct input_dev *dev, struct uinput_request *request) @@ -159,32 +152,30 @@ static int uinput_create_device(struct uinput_device *udev) return -EINVAL; } - udev->dev->open = uinput_dev_open; - udev->dev->close = uinput_dev_close; udev->dev->event = uinput_dev_event; udev->dev->upload_effect = uinput_dev_upload_effect; udev->dev->erase_effect = uinput_dev_erase_effect; udev->dev->private = udev; - init_waitqueue_head(&(udev->waitq)); + init_waitqueue_head(&udev->waitq); input_register_device(udev->dev); - set_bit(UIST_CREATED, &(udev->state)); + set_bit(UIST_CREATED, &udev->state); return 0; } static int uinput_destroy_device(struct uinput_device *udev) { - if (!test_bit(UIST_CREATED, &(udev->state))) { + if (!test_bit(UIST_CREATED, &udev->state)) { printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME); return -EINVAL; } input_unregister_device(udev->dev); - clear_bit(UIST_CREATED, &(udev->state)); + clear_bit(UIST_CREATED, &udev->state); return 0; } @@ -253,15 +244,15 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz struct uinput_user_dev *user_dev; struct input_dev *dev; struct uinput_device *udev; - int size, - retval; + int size; + int retval; retval = count; udev = file->private_data; dev = udev->dev; - user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL); + user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); if (!user_dev) { retval = -ENOMEM; goto exit; @@ -272,7 +263,7 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz goto exit; } - if (NULL != dev->name) + if (dev->name) kfree(dev->name); size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; @@ -314,14 +305,13 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t { struct uinput_device *udev = file->private_data; - if (test_bit(UIST_CREATED, &(udev->state))) { + if (test_bit(UIST_CREATED, &udev->state)) { struct input_event ev; if (copy_from_user(&ev, buffer, sizeof(struct input_event))) return -EFAULT; input_event(udev->dev, ev.type, ev.code, ev.value); - } - else + } else count = uinput_alloc_device(file, buffer, count); return count; @@ -332,26 +322,24 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, struct uinput_device *udev = file->private_data; int retval = 0; - if (!test_bit(UIST_CREATED, &(udev->state))) + if (!test_bit(UIST_CREATED, &udev->state)) return -ENODEV; - if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK)) + if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK)) return -EAGAIN; retval = wait_event_interruptible(udev->waitq, - (udev->head != udev->tail) || - !test_bit(UIST_CREATED, &(udev->state))); - + udev->head != udev->tail || !test_bit(UIST_CREATED, &udev->state)); if (retval) return retval; - if (!test_bit(UIST_CREATED, &(udev->state))) + if (!test_bit(UIST_CREATED, &udev->state)) return -ENODEV; while ((udev->head != udev->tail) && (retval + sizeof(struct input_event) <= count)) { - if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]), - sizeof(struct input_event))) return -EFAULT; + if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event))) + return -EFAULT; udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; retval += sizeof(struct input_event); } @@ -373,12 +361,12 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait) static int uinput_burn_device(struct uinput_device *udev) { - if (test_bit(UIST_CREATED, &(udev->state))) + if (test_bit(UIST_CREATED, &udev->state)) uinput_destroy_device(udev); - if (NULL != udev->dev->name) + if (udev->dev->name) kfree(udev->dev->name); - if (NULL != udev->dev->phys) + if (udev->dev->phys) kfree(udev->dev->phys); kfree(udev->dev); @@ -389,7 +377,8 @@ static int uinput_burn_device(struct uinput_device *udev) static int uinput_close(struct inode *inode, struct file *file) { - return uinput_burn_device(file->private_data); + uinput_burn_device(file->private_data); + return 0; } static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -415,7 +404,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd case UI_SET_SNDBIT: case UI_SET_FFBIT: case UI_SET_PHYS: - if (test_bit(UIST_CREATED, &(udev->state))) + if (test_bit(UIST_CREATED, &udev->state)) return -EINVAL; } @@ -511,7 +500,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd udev->dev->phys = NULL; break; } - udev->dev->phys[length-1] = '\0'; + udev->dev->phys[length - 1] = '\0'; break; case UI_BEGIN_FF_UPLOAD: @@ -520,7 +509,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req = uinput_request_find(udev, ff_up.request_id); - if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) { + if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) { retval = -EINVAL; break; } @@ -538,7 +527,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req = uinput_request_find(udev, ff_erase.request_id); - if (!(req && req->code==UI_FF_ERASE)) { + if (!(req && req->code == UI_FF_ERASE)) { retval = -EINVAL; break; } @@ -556,7 +545,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req = uinput_request_find(udev, ff_up.request_id); - if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) { + if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) { retval = -EINVAL; break; } @@ -572,7 +561,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req = uinput_request_find(udev, ff_erase.request_id); - if (!(req && req->code==UI_FF_ERASE)) { + if (!(req && req->code == UI_FF_ERASE)) { retval = -EINVAL; break; } -- cgit v1.1 From 0048e6030d41453c2f5ce0e9aead910d46cfd448 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:48:14 -0500 Subject: Input: uinput - use completions instead of events and manual wakeups in force feedback code. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 81 ++++++++++++++++++++++++--------------------- include/linux/uinput.h | 5 ++- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 9c3d200..c3eebf5 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -53,24 +53,23 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned i return 0; } -static int uinput_request_alloc_id(struct input_dev *dev, struct uinput_request *request) +static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request) { /* Atomically allocate an ID for the given request. Returns 0 on success. */ - struct uinput_device *udev = dev->private; int id; int err = -1; - down(&udev->requests_sem); + spin_lock(&udev->requests_lock); for (id = 0; id < UINPUT_NUM_REQUESTS; id++) if (!udev->requests[id]) { - udev->requests[id] = request; request->id = id; + udev->requests[id] = request; err = 0; break; } - up(&udev->requests_sem); + spin_unlock(&udev->requests_lock); return err; } @@ -79,70 +78,78 @@ static struct uinput_request* uinput_request_find(struct uinput_device *udev, in /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ if (id >= UINPUT_NUM_REQUESTS || id < 0) return NULL; - if (udev->requests[id]->completed) - return NULL; return udev->requests[id]; } -static void uinput_request_init(struct input_dev *dev, struct uinput_request *request, int code) +static inline int uinput_request_reserve_slot(struct uinput_device *udev, struct uinput_request *request) { - struct uinput_device *udev = dev->private; + /* Allocate slot. If none are available right away, wait. */ + return wait_event_interruptible(udev->requests_waitq, + !uinput_request_alloc_id(udev, request)); +} - memset(request, 0, sizeof(struct uinput_request)); - request->code = code; - init_waitqueue_head(&request->waitq); +static void uinput_request_done(struct uinput_device *udev, struct uinput_request *request) +{ + complete(&request->done); - /* Allocate an ID. If none are available right away, wait. */ - request->retval = wait_event_interruptible(udev->requests_waitq, - !uinput_request_alloc_id(dev, request)); + /* Mark slot as available */ + udev->requests[request->id] = NULL; + wake_up_interruptible(&udev->requests_waitq); } -static void uinput_request_submit(struct input_dev *dev, struct uinput_request *request) +static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request) { - struct uinput_device *udev = dev->private; int retval; /* Tell our userspace app about this new request by queueing an input event */ uinput_dev_event(dev, EV_UINPUT, request->code, request->id); /* Wait for the request to complete */ - retval = wait_event_interruptible(request->waitq, request->completed); - if (retval) - request->retval = retval; + retval = wait_for_completion_interruptible(&request->done); + if (!retval) + retval = request->retval; - /* Release this request's ID, let others know it's available */ - udev->requests[request->id] = NULL; - wake_up_interruptible(&udev->requests_waitq); + return retval; } static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect) { struct uinput_request request; + int retval; if (!test_bit(EV_FF, dev->evbit)) return -ENOSYS; - uinput_request_init(dev, &request, UI_FF_UPLOAD); - if (request.retval) - return request.retval; + request.id = -1; + init_completion(&request.done); + request.code = UI_FF_UPLOAD; request.u.effect = effect; - uinput_request_submit(dev, &request); - return request.retval; + + retval = uinput_request_reserve_slot(dev->private, &request); + if (!retval) + retval = uinput_request_submit(dev, &request); + + return retval; } static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) { struct uinput_request request; + int retval; if (!test_bit(EV_FF, dev->evbit)) return -ENOSYS; - uinput_request_init(dev, &request, UI_FF_ERASE); - if (request.retval) - return request.retval; + request.id = -1; + init_completion(&request.done); + request.code = UI_FF_ERASE; request.u.effect_id = effect_id; - uinput_request_submit(dev, &request); - return request.retval; + + retval = uinput_request_reserve_slot(dev->private, &request); + if (!retval) + retval = uinput_request_submit(dev, &request); + + return retval; } static int uinput_create_device(struct uinput_device *udev) @@ -189,7 +196,7 @@ static int uinput_open(struct inode *inode, struct file *file) if (!newdev) goto error; memset(newdev, 0, sizeof(struct uinput_device)); - init_MUTEX(&newdev->requests_sem); + spin_lock_init(&newdev->requests_lock); init_waitqueue_head(&newdev->requests_waitq); newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL); @@ -551,8 +558,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd } req->retval = ff_up.retval; memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect)); - req->completed = 1; - wake_up_interruptible(&req->waitq); + uinput_request_done(udev, req); break; case UI_END_FF_ERASE: @@ -566,8 +572,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req->retval = ff_erase.retval; - req->completed = 1; - wake_up_interruptible(&req->waitq); + uinput_request_done(udev, req); break; default: diff --git a/include/linux/uinput.h b/include/linux/uinput.h index 4c2c823..8487607 100644 --- a/include/linux/uinput.h +++ b/include/linux/uinput.h @@ -42,8 +42,7 @@ struct uinput_request { int code; /* UI_FF_UPLOAD, UI_FF_ERASE */ int retval; - wait_queue_head_t waitq; - int completed; + struct completion done; union { int effect_id; @@ -62,7 +61,7 @@ struct uinput_device { struct uinput_request *requests[UINPUT_NUM_REQUESTS]; wait_queue_head_t requests_waitq; - struct semaphore requests_sem; + spinlock_t requests_lock; }; #endif /* __KERNEL__ */ -- cgit v1.1 From ae87dff7ca2723a2428fb55dd57da1315878eb08 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:48:34 -0500 Subject: Input: serio - add modalias attribute and environment variable to simplify hotplug scripts. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index f367695..edd15db 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -389,6 +389,14 @@ static ssize_t serio_show_description(struct device *dev, struct device_attribut return sprintf(buf, "%s\n", serio->name); } +static ssize_t serio_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct serio *serio = to_serio_port(dev); + + return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n", + serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); +} + static ssize_t serio_show_id_type(struct device *dev, struct device_attribute *attr, char *buf) { struct serio *serio = to_serio_port(dev); @@ -487,6 +495,7 @@ static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute * static struct device_attribute serio_device_attrs[] = { __ATTR(description, S_IRUGO, serio_show_description, NULL), + __ATTR(modalias, S_IRUGO, serio_show_modalias, NULL), __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver), __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode), __ATTR_NULL @@ -785,36 +794,37 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv) #ifdef CONFIG_HOTPLUG -#define PUT_ENVP(fmt, val) \ -do { \ - envp[i++] = buffer; \ - length += snprintf(buffer, buffer_size - length, fmt, val); \ - if (buffer_size - length <= 0 || i >= num_envp) \ - return -ENOMEM; \ - length++; \ - buffer += length; \ -} while (0) +#define SERIO_ADD_HOTPLUG_VAR(fmt, val...) \ + do { \ + int err = add_hotplug_env_var(envp, num_envp, &i, \ + buffer, buffer_size, &len, \ + fmt, val); \ + if (err) \ + return err; \ + } while (0) + static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { struct serio *serio; int i = 0; - int length = 0; + int len = 0; if (!dev) return -ENODEV; serio = to_serio_port(dev); - PUT_ENVP("SERIO_TYPE=%02x", serio->id.type); - PUT_ENVP("SERIO_PROTO=%02x", serio->id.proto); - PUT_ENVP("SERIO_ID=%02x", serio->id.id); - PUT_ENVP("SERIO_EXTRA=%02x", serio->id.extra); - + SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type); + SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto); + SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id); + SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra); + SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", + serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); envp[i] = NULL; return 0; } -#undef PUT_ENVP +#undef SERIO_ADD_HOTPLUG_VAR #else -- cgit v1.1 From c27a748225fe5c7e485ea471178c26e43f9f7fbe Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:48:51 -0500 Subject: Input: acecad - drop unneeded cast and couple unneeded spaces. Noticed by Joe Perches. Signed-off-by: Dmitry Torokhov Acked-by: Stephane VOLTZ --- drivers/usb/input/acecad.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index ebcf7c9..68039b0 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c @@ -87,8 +87,8 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) if (prox) { int x = data[1] | (data[2] << 8); int y = data[3] | (data[4] << 8); - /*Pressure should compute the same way for flair and 302*/ - int pressure = data[5] | ((int)data[6] << 8); + /* Pressure should compute the same way for flair and 302 */ + int pressure = data[5] | (data[6] << 8); int touch = data[0] & 0x01; int stylus = (data[0] & 0x10) >> 4; int stylus2 = (data[0] & 0x20) >> 5; @@ -104,9 +104,9 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) input_sync(dev); resubmit: - status = usb_submit_urb (urb, GFP_ATOMIC); + status = usb_submit_urb(urb, GFP_ATOMIC); if (status) - err ("can't resubmit intr, %s-%s/input0, status %d", + err("can't resubmit intr, %s-%s/input0, status %d", acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status); } -- cgit v1.1 From 16a334c0de5a94b1d10a1ac9a33f4dedac89a075 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:49:08 -0500 Subject: Input: introduce usb_to_input_id() to uniformly produce struct input_id for USB input devices. Signed-off-by: Dmitry Torokhov --- drivers/usb/input/acecad.c | 6 ++---- drivers/usb/input/aiptek.c | 6 ++---- drivers/usb/input/ati_remote.c | 8 +++----- drivers/usb/input/hid-input.c | 6 ++---- drivers/usb/input/itmtouch.c | 6 ++---- drivers/usb/input/kbtab.c | 6 ++---- drivers/usb/input/mtouchusb.c | 6 ++---- drivers/usb/input/powermate.c | 6 ++---- drivers/usb/input/touchkitusb.c | 7 ++----- drivers/usb/input/usbkbd.c | 6 ++---- drivers/usb/input/usbmouse.c | 6 ++---- drivers/usb/input/wacom.c | 6 ++---- drivers/usb/input/xpad.c | 6 ++---- drivers/usb/media/konicawc.c | 6 ++---- include/linux/usb_input.h | 25 +++++++++++++++++++++++++ 15 files changed, 54 insertions(+), 58 deletions(-) create mode 100644 include/linux/usb_input.h diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index 68039b0..13532f3 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c @@ -31,6 +31,7 @@ #include #include #include +#include /* * Version Information @@ -212,10 +213,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ acecad->dev.name = acecad->name; acecad->dev.phys = acecad->phys; - acecad->dev.id.bustype = BUS_USB; - acecad->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - acecad->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - acecad->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &acecad->dev.id); acecad->dev.dev = &intf->dev; usb_fill_int_urb(acecad->irq, dev, pipe, diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 6bb0f25..cd0cbfe 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -2125,10 +2126,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek->inputdev.absflat[ABS_WHEEL] = 0; aiptek->inputdev.name = "Aiptek"; aiptek->inputdev.phys = aiptek->features.usbPath; - aiptek->inputdev.id.bustype = BUS_USB; - aiptek->inputdev.id.vendor = le16_to_cpu(usbdev->descriptor.idVendor); - aiptek->inputdev.id.product = le16_to_cpu(usbdev->descriptor.idProduct); - aiptek->inputdev.id.version = le16_to_cpu(usbdev->descriptor.bcdDevice); + usb_to_input_id(usbdev, &aiptek->inputdev.id); aiptek->inputdev.dev = &intf->dev; aiptek->usbdev = usbdev; diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 654ac45..fd99681 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -94,6 +94,7 @@ #include #include #include +#include #include /* @@ -635,11 +636,8 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) idev->name = ati_remote->name; idev->phys = ati_remote->phys; - idev->id.bustype = BUS_USB; - idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor); - idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct); - idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice); - idev->dev = &(ati_remote->udev->dev); + usb_to_input_id(ati_remote->udev, &idev->id); + idev->dev = &ati_remote->udev->dev; } static int ati_remote_initialize(struct ati_remote *ati_remote) diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 9ac1e90..e071c8e 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -31,6 +31,7 @@ #include #include #include +#include #undef DEBUG @@ -581,10 +582,7 @@ int hidinput_connect(struct hid_device *hid) hidinput->input.name = hid->name; hidinput->input.phys = hid->phys; hidinput->input.uniq = hid->uniq; - hidinput->input.id.bustype = BUS_USB; - hidinput->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - hidinput->input.id.product = le16_to_cpu(dev->descriptor.idProduct); - hidinput->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &hidinput->input.id); hidinput->input.dev = &hid->intf->dev; } diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c index 47dec6a..0dc439f 100644 --- a/drivers/usb/input/itmtouch.c +++ b/drivers/usb/input/itmtouch.c @@ -53,6 +53,7 @@ #include #include #include +#include /* only an 8 byte buffer necessary for a single packet */ #define ITM_BUFSIZE 8 @@ -184,10 +185,7 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id itmtouch->inputdev.name = itmtouch->name; itmtouch->inputdev.phys = itmtouch->phys; - itmtouch->inputdev.id.bustype = BUS_USB; - itmtouch->inputdev.id.vendor = udev->descriptor.idVendor; - itmtouch->inputdev.id.product = udev->descriptor.idProduct; - itmtouch->inputdev.id.version = udev->descriptor.bcdDevice; + usb_to_input_id(udev, &itmtouch->inputdev.id); itmtouch->inputdev.dev = &intf->dev; if (!strlen(itmtouch->name)) diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index d2f0f90..b6f6ac8 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -167,10 +168,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i kbtab->dev.name = "KB Gear Tablet"; kbtab->dev.phys = kbtab->phys; - kbtab->dev.id.bustype = BUS_USB; - kbtab->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - kbtab->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - kbtab->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &kbtab->dev.id); kbtab->dev.dev = &intf->dev; kbtab->usbdev = dev; diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index 09b5cc7..ff92750 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c @@ -53,6 +53,7 @@ #include #include #include +#include #define MTOUCHUSB_MIN_XC 0x0 #define MTOUCHUSB_MAX_RAW_XC 0x4000 @@ -232,10 +233,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i mtouch->input.name = mtouch->name; mtouch->input.phys = mtouch->phys; - mtouch->input.id.bustype = BUS_USB; - mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct); - mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); + usb_to_input_id(udev, &mtouch->input.id); mtouch->input.dev = &intf->dev; mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index 3975b30..ad4afe7 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -35,6 +35,7 @@ #include #include #include +#include #define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */ #define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */ @@ -389,10 +390,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0); pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL); pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED); - pm->input.id.bustype = BUS_USB; - pm->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - pm->input.id.product = le16_to_cpu(udev->descriptor.idProduct); - pm->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); + usb_to_input_id(udev, &pm->input.id); pm->input.event = powermate_input_event; pm->input.dev = &intf->dev; pm->input.phys = pm->phys; diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 386595e..4276c24 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c @@ -35,7 +35,7 @@ #define DEBUG #endif #include - +#include #define TOUCHKIT_MIN_XC 0x0 #define TOUCHKIT_MAX_XC 0x07ff @@ -202,10 +202,7 @@ static int touchkit_probe(struct usb_interface *intf, touchkit->input.name = touchkit->name; touchkit->input.phys = touchkit->phys; - touchkit->input.id.bustype = BUS_USB; - touchkit->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - touchkit->input.id.product = le16_to_cpu(udev->descriptor.idProduct); - touchkit->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); + usb_to_input_id(udev, &touchkit->input.id); touchkit->input.dev = &intf->dev; touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index f35db19..28987f1 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c @@ -32,6 +32,7 @@ #include #include #include +#include /* * Version Information @@ -288,10 +289,7 @@ static int usb_kbd_probe(struct usb_interface *iface, kbd->dev.name = kbd->name; kbd->dev.phys = kbd->phys; - kbd->dev.id.bustype = BUS_USB; - kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - kbd->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &kbd->dev.id); kbd->dev.dev = &iface->dev; if (dev->manufacturer) diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 1ec41b5..4104dec 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c @@ -32,6 +32,7 @@ #include #include #include +#include /* * Version Information @@ -171,10 +172,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ mouse->dev.name = mouse->name; mouse->dev.phys = mouse->phys; - mouse->dev.id.bustype = BUS_USB; - mouse->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - mouse->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - mouse->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &mouse->dev.id); mouse->dev.dev = &intf->dev; if (dev->manufacturer) diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index f6b34af..02412e3 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include @@ -823,10 +824,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->dev.name = wacom->features->name; wacom->dev.phys = wacom->phys; - wacom->dev.id.bustype = BUS_USB; - wacom->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - wacom->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - wacom->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &wacom->dev.id); wacom->dev.dev = &intf->dev; wacom->usbdev = dev; diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index a7fa1b1..18125e0 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -62,6 +62,7 @@ #include #include #include +#include #define DRIVER_VERSION "v0.0.5" #define DRIVER_AUTHOR "Marko Friedemann " @@ -256,10 +257,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->udev = udev; - xpad->dev.id.bustype = BUS_USB; - xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct); - xpad->dev.id.version = le16_to_cpu(udev->descriptor.bcdDevice); + usb_to_input_id(udev, &xpad->dev.id); xpad->dev.dev = &intf->dev; xpad->dev.private = xpad; xpad->dev.name = xpad_device[i].name; diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 08521a2..20ac9e1 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "usbvideo.h" @@ -845,10 +846,7 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id cam->input.private = cam; cam->input.evbit[0] = BIT(EV_KEY); cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0); - cam->input.id.bustype = BUS_USB; - cam->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - cam->input.id.product = le16_to_cpu(dev->descriptor.idProduct); - cam->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &cam->input.id); input_register_device(&cam->input); usb_make_path(dev, cam->input_physname, 56); diff --git a/include/linux/usb_input.h b/include/linux/usb_input.h new file mode 100644 index 0000000..716e0cc --- /dev/null +++ b/include/linux/usb_input.h @@ -0,0 +1,25 @@ +#ifndef __USB_INPUT_H +#define __USB_INPUT_H + +/* + * Copyright (C) 2005 Dmitry Torokhov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include + +static inline void +usb_to_input_id(const struct usb_device *dev, struct input_id *id) +{ + id->bustype = BUS_USB; + id->vendor = le16_to_cpu(dev->descriptor.idVendor); + id->product = le16_to_cpu(dev->descriptor.idProduct); + id->version = le16_to_cpu(dev->descriptor.bcdDevice); +} + +#endif -- cgit v1.1 From fb2ce3c005ede30b65b891c58ff56398df6089f8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:50:10 -0500 Subject: Sonypi: make sure that input_work is not running when unloading the module; submit/retrieve key release data into/from input_fifo in one shot. Signed-off-by: Dmitry Torokhov --- drivers/char/sonypi.c | 122 ++++++++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 59 deletions(-) diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index fd04206..983915b 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -439,6 +439,11 @@ static struct { { 0, 0 }, }; +struct sonypi_keypress { + struct input_dev *dev; + int key; +}; + static struct sonypi_device { struct pci_dev *dev; struct platform_device *pdev; @@ -710,22 +715,61 @@ static void sonypi_setbluetoothpower(u8 state) static void input_keyrelease(void *data) { - struct input_dev *input_dev; - int key; - - while (1) { - if (kfifo_get(sonypi_device.input_fifo, - (unsigned char *)&input_dev, - sizeof(input_dev)) != sizeof(input_dev)) - return; - if (kfifo_get(sonypi_device.input_fifo, - (unsigned char *)&key, - sizeof(key)) != sizeof(key)) - return; + struct sonypi_keypress kp; + while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, + sizeof(kp)) == sizeof(kp)) { msleep(10); - input_report_key(input_dev, key, 0); - input_sync(input_dev); + input_report_key(kp.dev, kp.key, 0); + input_sync(kp.dev); + } +} + +static void sonypi_report_input_event(u8 event) +{ + struct input_dev *jog_dev = &sonypi_device.input_jog_dev; + struct input_dev *key_dev = &sonypi_device.input_key_dev; + struct sonypi_keypress kp = { NULL }; + int i; + + switch (event) { + case SONYPI_EVENT_JOGDIAL_UP: + case SONYPI_EVENT_JOGDIAL_UP_PRESSED: + input_report_rel(jog_dev, REL_WHEEL, 1); + input_sync(jog_dev); + break; + + case SONYPI_EVENT_JOGDIAL_DOWN: + case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: + input_report_rel(jog_dev, REL_WHEEL, -1); + input_sync(jog_dev); + break; + + case SONYPI_EVENT_JOGDIAL_PRESSED: + kp.key = BTN_MIDDLE; + kp.dev = jog_dev; + break; + + case SONYPI_EVENT_FNKEY_RELEASED: + /* Nothing, not all VAIOs generate this event */ + break; + + default: + for (i = 0; sonypi_inputkeys[i].sonypiev; i++) + if (event == sonypi_inputkeys[i].sonypiev) { + kp.dev = key_dev; + kp.key = sonypi_inputkeys[i].inputev; + break; + } + break; + } + + if (kp.dev) { + input_report_key(kp.dev, kp.key, 1); + input_sync(kp.dev); + kfifo_put(sonypi_device.input_fifo, + (unsigned char *)&kp, sizeof(kp)); + schedule_work(&sonypi_device.input_work); } } @@ -768,51 +812,8 @@ found: printk(KERN_INFO "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2); - if (useinput) { - struct input_dev *input_jog_dev = &sonypi_device.input_jog_dev; - struct input_dev *input_key_dev = &sonypi_device.input_key_dev; - switch (event) { - case SONYPI_EVENT_JOGDIAL_UP: - case SONYPI_EVENT_JOGDIAL_UP_PRESSED: - input_report_rel(input_jog_dev, REL_WHEEL, 1); - break; - case SONYPI_EVENT_JOGDIAL_DOWN: - case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: - input_report_rel(input_jog_dev, REL_WHEEL, -1); - break; - case SONYPI_EVENT_JOGDIAL_PRESSED: { - int key = BTN_MIDDLE; - input_report_key(input_jog_dev, key, 1); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&input_jog_dev, - sizeof(input_jog_dev)); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&key, sizeof(key)); - break; - } - case SONYPI_EVENT_FNKEY_RELEASED: - /* Nothing, not all VAIOs generate this event */ - break; - } - input_sync(input_jog_dev); - - for (i = 0; sonypi_inputkeys[i].sonypiev; i++) { - int key; - - if (event != sonypi_inputkeys[i].sonypiev) - continue; - - key = sonypi_inputkeys[i].inputev; - input_report_key(input_key_dev, key, 1); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&input_key_dev, - sizeof(input_key_dev)); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&key, sizeof(key)); - } - input_sync(input_key_dev); - schedule_work(&sonypi_device.input_work); - } + if (useinput) + sonypi_report_input_event(event); kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); @@ -1337,6 +1338,9 @@ static void __devexit sonypi_remove(void) { sonypi_disable(); + synchronize_sched(); /* Allow sonypi interrupt to complete. */ + flush_scheduled_work(); + platform_device_unregister(sonypi_device.pdev); if (useinput) { -- cgit v1.1 From f96b434d3bf70845a7541ab217f525918267281e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:50:29 -0500 Subject: Input: rearrange procfs code to reduce number of #ifdefs Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 389 +++++++++++++++++++++++++------------------------- 1 file changed, 198 insertions(+), 191 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 7c4b4d3..1ea4f1a 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -48,12 +48,6 @@ static LIST_HEAD(input_handler_list); static struct input_handler *input_table[8]; -#ifdef CONFIG_PROC_FS -static struct proc_dir_entry *proc_bus_input_dir; -static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait); -static int input_devices_state; -#endif - void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct input_handle *handle; @@ -312,6 +306,7 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st return NULL; } + /* * Input hotplugging interface - loading event handlers based on * device bitfields. @@ -428,6 +423,177 @@ static void input_call_hotplug(char *verb, struct input_dev *dev) #endif +#ifdef CONFIG_PROC_FS + +static struct proc_dir_entry *proc_bus_input_dir; +static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait); +static int input_devices_state; + +static inline void input_wakeup_procfs_readers(void) +{ + input_devices_state++; + wake_up(&input_devices_poll_wait); +} + +static unsigned int input_devices_poll(struct file *file, poll_table *wait) +{ + int state = input_devices_state; + poll_wait(file, &input_devices_poll_wait, wait); + if (state != input_devices_state) + return POLLIN | POLLRDNORM; + return 0; +} + +#define SPRINTF_BIT_B(bit, name, max) \ + do { \ + len += sprintf(buf + len, "B: %s", name); \ + 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]); \ + len += sprintf(buf + len, "\n"); \ + } while (0) + +#define SPRINTF_BIT_B2(bit, name, max, ev) \ + do { \ + if (test_bit(ev, dev->evbit)) \ + SPRINTF_BIT_B(bit, name, max); \ + } while (0) + +static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) +{ + struct input_dev *dev; + struct input_handle *handle; + + off_t at = 0; + int i, len, cnt = 0; + + list_for_each_entry(dev, &input_dev_list, node) { + + len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", + dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); + + len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); + len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); + len += sprintf(buf + len, "H: Handlers="); + + list_for_each_entry(handle, &dev->h_list, d_node) + len += sprintf(buf + len, "%s ", handle->name); + + len += sprintf(buf + len, "\n"); + + SPRINTF_BIT_B(evbit, "EV=", EV_MAX); + SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY); + SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL); + SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS); + SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC); + SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED); + SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND); + SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF); + + len += sprintf(buf + len, "\n"); + + at += len; + + if (at >= pos) { + if (!*start) { + *start = buf + (pos - (at - len)); + cnt = at - pos; + } else cnt += len; + buf += len; + if (cnt >= count) + break; + } + } + + if (&dev->node == &input_dev_list) + *eof = 1; + + return (count > cnt) ? cnt : count; +} + +static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) +{ + struct input_handler *handler; + + off_t at = 0; + int len = 0, cnt = 0; + int i = 0; + + list_for_each_entry(handler, &input_handler_list, node) { + + if (handler->fops) + len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", + i++, handler->name, handler->minor); + else + len = sprintf(buf, "N: Number=%d Name=%s\n", + i++, handler->name); + + at += len; + + if (at >= pos) { + if (!*start) { + *start = buf + (pos - (at - len)); + cnt = at - pos; + } else cnt += len; + buf += len; + if (cnt >= count) + break; + } + } + if (&handler->node == &input_handler_list) + *eof = 1; + + return (count > cnt) ? cnt : count; +} + +static struct file_operations input_fileops; + +static int __init input_proc_init(void) +{ + struct proc_dir_entry *entry; + + proc_bus_input_dir = proc_mkdir("input", proc_bus); + if (!proc_bus_input_dir) + return -ENOMEM; + + proc_bus_input_dir->owner = THIS_MODULE; + + entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); + if (!entry) + goto fail1; + + entry->owner = THIS_MODULE; + input_fileops = *entry->proc_fops; + entry->proc_fops = &input_fileops; + entry->proc_fops->poll = input_devices_poll; + + entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); + if (!entry) + goto fail2; + + entry->owner = THIS_MODULE; + + return 0; + + fail2: remove_proc_entry("devices", proc_bus_input_dir); + fail1: remove_proc_entry("input", proc_bus); + return -ENOMEM; +} + +static void __exit input_proc_exit(void) +{ + remove_proc_entry("devices", proc_bus_input_dir); + remove_proc_entry("handlers", proc_bus_input_dir); + remove_proc_entry("input", proc_bus); +} + +#else /* !CONFIG_PROC_FS */ +static inline void input_wakeup_procfs_readers(void) { } +static inline int input_proc_init(void) { return 0; } +static inline void input_proc_exit(void) { } +#endif + void input_register_device(struct input_dev *dev) { struct input_handle *handle; @@ -464,10 +630,7 @@ void input_register_device(struct input_dev *dev) input_call_hotplug("add", dev); #endif -#ifdef CONFIG_PROC_FS - input_devices_state++; - wake_up(&input_devices_poll_wait); -#endif + input_wakeup_procfs_readers(); } void input_unregister_device(struct input_dev *dev) @@ -491,10 +654,7 @@ void input_unregister_device(struct input_dev *dev) list_del_init(&dev->node); -#ifdef CONFIG_PROC_FS - input_devices_state++; - wake_up(&input_devices_poll_wait); -#endif + input_wakeup_procfs_readers(); } void input_register_handler(struct input_handler *handler) @@ -518,10 +678,7 @@ void input_register_handler(struct input_handler *handler) if ((handle = handler->connect(handler, dev, id))) input_link_handle(handle); -#ifdef CONFIG_PROC_FS - input_devices_state++; - wake_up(&input_devices_poll_wait); -#endif + input_wakeup_procfs_readers(); } void input_unregister_handler(struct input_handler *handler) @@ -540,10 +697,7 @@ void input_unregister_handler(struct input_handler *handler) if (handler->fops != NULL) input_table[handler->minor >> 5] = NULL; -#ifdef CONFIG_PROC_FS - input_devices_state++; - wake_up(&input_devices_poll_wait); -#endif + input_wakeup_procfs_readers(); } static int input_open_file(struct inode *inode, struct file *file) @@ -582,190 +736,43 @@ static struct file_operations input_fops = { .open = input_open_file, }; -#ifdef CONFIG_PROC_FS - -#define SPRINTF_BIT_B(bit, name, max) \ - do { \ - len += sprintf(buf + len, "B: %s", name); \ - 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]); \ - len += sprintf(buf + len, "\n"); \ - } while (0) - -#define SPRINTF_BIT_B2(bit, name, max, ev) \ - do { \ - if (test_bit(ev, dev->evbit)) \ - SPRINTF_BIT_B(bit, name, max); \ - } while (0) - - -static unsigned int input_devices_poll(struct file *file, poll_table *wait) -{ - int state = input_devices_state; - poll_wait(file, &input_devices_poll_wait, wait); - if (state != input_devices_state) - return POLLIN | POLLRDNORM; - return 0; -} +struct class *input_class; -static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) +static int __init input_init(void) { - struct input_dev *dev; - struct input_handle *handle; - - off_t at = 0; - int i, len, cnt = 0; - - list_for_each_entry(dev, &input_dev_list, node) { - - len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", - dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); - - len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); - len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); - len += sprintf(buf + len, "H: Handlers="); - - list_for_each_entry(handle, &dev->h_list, d_node) - len += sprintf(buf + len, "%s ", handle->name); - - len += sprintf(buf + len, "\n"); - - SPRINTF_BIT_B(evbit, "EV=", EV_MAX); - SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY); - SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL); - SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS); - SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC); - SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED); - SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND); - SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF); - - len += sprintf(buf + len, "\n"); - - at += len; + int err; - if (at >= pos) { - if (!*start) { - *start = buf + (pos - (at - len)); - cnt = at - pos; - } else cnt += len; - buf += len; - if (cnt >= count) - break; - } + input_class = class_create(THIS_MODULE, "input"); + if (IS_ERR(input_class)) { + printk(KERN_ERR "input: unable to register input class\n"); + return PTR_ERR(input_class); } - if (&dev->node == &input_dev_list) - *eof = 1; - - return (count > cnt) ? cnt : count; -} - -static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) -{ - struct input_handler *handler; - - off_t at = 0; - int len = 0, cnt = 0; - int i = 0; - - list_for_each_entry(handler, &input_handler_list, node) { - - if (handler->fops) - len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", - i++, handler->name, handler->minor); - else - len = sprintf(buf, "N: Number=%d Name=%s\n", - i++, handler->name); - - at += len; + err = input_proc_init(); + if (err) + goto fail1; - if (at >= pos) { - if (!*start) { - *start = buf + (pos - (at - len)); - cnt = at - pos; - } else cnt += len; - buf += len; - if (cnt >= count) - break; - } + err = register_chrdev(INPUT_MAJOR, "input", &input_fops); + if (err) { + printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); + goto fail2; } - if (&handler->node == &input_handler_list) - *eof = 1; - - return (count > cnt) ? cnt : count; -} - -static struct file_operations input_fileops; -static int __init input_proc_init(void) -{ - struct proc_dir_entry *entry; + err = devfs_mk_dir("input"); + if (err) + goto fail3; - proc_bus_input_dir = proc_mkdir("input", proc_bus); - if (proc_bus_input_dir == NULL) - return -ENOMEM; - proc_bus_input_dir->owner = THIS_MODULE; - entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); - if (entry == NULL) { - remove_proc_entry("input", proc_bus); - return -ENOMEM; - } - entry->owner = THIS_MODULE; - input_fileops = *entry->proc_fops; - entry->proc_fops = &input_fileops; - entry->proc_fops->poll = input_devices_poll; - entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); - if (entry == NULL) { - remove_proc_entry("devices", proc_bus_input_dir); - remove_proc_entry("input", proc_bus); - return -ENOMEM; - } - entry->owner = THIS_MODULE; return 0; -} -#else /* !CONFIG_PROC_FS */ -static inline int input_proc_init(void) { return 0; } -#endif -struct class *input_class; - -static int __init input_init(void) -{ - int retval = -ENOMEM; - - input_class = class_create(THIS_MODULE, "input"); - if (IS_ERR(input_class)) - return PTR_ERR(input_class); - input_proc_init(); - retval = register_chrdev(INPUT_MAJOR, "input", &input_fops); - if (retval) { - printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); - remove_proc_entry("devices", proc_bus_input_dir); - remove_proc_entry("handlers", proc_bus_input_dir); - remove_proc_entry("input", proc_bus); - class_destroy(input_class); - return retval; - } - - retval = devfs_mk_dir("input"); - if (retval) { - remove_proc_entry("devices", proc_bus_input_dir); - remove_proc_entry("handlers", proc_bus_input_dir); - remove_proc_entry("input", proc_bus); - unregister_chrdev(INPUT_MAJOR, "input"); - class_destroy(input_class); - } - return retval; + fail3: unregister_chrdev(INPUT_MAJOR, "input"); + fail2: input_proc_exit(); + fail1: class_destroy(input_class); + return err; } static void __exit input_exit(void) { - remove_proc_entry("devices", proc_bus_input_dir); - remove_proc_entry("handlers", proc_bus_input_dir); - remove_proc_entry("input", proc_bus); - + input_proc_exit(); devfs_remove("input"); unregister_chrdev(INPUT_MAJOR, "input"); class_destroy(input_class); -- cgit v1.1 From 5b6271bda42be8edb77fbd588621cc09199fa7fb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:50:38 -0500 Subject: Input: make name, phys and uniq be 'const char *' because once set noone should attempt to change them. Signed-off-by: Dmitry Torokhov --- drivers/char/sonypi.c | 24 ++---------------------- drivers/input/misc/uinput.c | 23 ++++++++++++----------- include/linux/input.h | 6 +++--- 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 983915b..cefbe98 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1228,14 +1228,7 @@ static int __devinit sonypi_probe(void) sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE); sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL); - sonypi_device.input_jog_dev.name = - kmalloc(sizeof(SONYPI_JOG_INPUTNAME), GFP_KERNEL); - if (!sonypi_device.input_jog_dev.name) { - printk(KERN_ERR "sonypi: kmalloc failed\n"); - ret = -ENOMEM; - goto out_inkmallocinput1; - } - sprintf(sonypi_device.input_jog_dev.name, SONYPI_JOG_INPUTNAME); + sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME; sonypi_device.input_jog_dev.id.bustype = BUS_ISA; sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY; @@ -1249,14 +1242,7 @@ static int __devinit sonypi_probe(void) if (sonypi_inputkeys[i].inputev) set_bit(sonypi_inputkeys[i].inputev, sonypi_device.input_key_dev.keybit); - sonypi_device.input_key_dev.name = - kmalloc(sizeof(SONYPI_KEY_INPUTNAME), GFP_KERNEL); - if (!sonypi_device.input_key_dev.name) { - printk(KERN_ERR "sonypi: kmalloc failed\n"); - ret = -ENOMEM; - goto out_inkmallocinput2; - } - sprintf(sonypi_device.input_key_dev.name, SONYPI_KEY_INPUTNAME); + sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME; sonypi_device.input_key_dev.id.bustype = BUS_ISA; sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY; @@ -1314,11 +1300,7 @@ out_platformdev: kfifo_free(sonypi_device.input_fifo); out_infifo: input_unregister_device(&sonypi_device.input_key_dev); - kfree(sonypi_device.input_key_dev.name); -out_inkmallocinput2: input_unregister_device(&sonypi_device.input_jog_dev); - kfree(sonypi_device.input_jog_dev.name); -out_inkmallocinput1: free_irq(sonypi_device.irq, sonypi_irq); out_reqirq: release_region(sonypi_device.ioport1, sonypi_device.region_size); @@ -1345,9 +1327,7 @@ static void __devexit sonypi_remove(void) if (useinput) { input_unregister_device(&sonypi_device.input_key_dev); - kfree(sonypi_device.input_key_dev.name); input_unregister_device(&sonypi_device.input_jog_dev); - kfree(sonypi_device.input_jog_dev.name); kfifo_free(sonypi_device.input_fifo); } diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index c3eebf5..d5c5b32 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -251,6 +251,7 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz struct uinput_user_dev *user_dev; struct input_dev *dev; struct uinput_device *udev; + char *name; int size; int retval; @@ -274,13 +275,13 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz kfree(dev->name); size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; - dev->name = kmalloc(size, GFP_KERNEL); - if (!dev->name) { + dev->name = name = kmalloc(size, GFP_KERNEL); + if (!name) { retval = -ENOMEM; goto exit; } + strlcpy(name, user_dev->name, size); - strlcpy(dev->name, user_dev->name, size); dev->id.bustype = user_dev->id.bustype; dev->id.vendor = user_dev->id.vendor; dev->id.product = user_dev->id.product; @@ -397,6 +398,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd struct uinput_ff_erase ff_erase; struct uinput_request *req; int length; + char *phys; udev = file->private_data; @@ -494,20 +496,19 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd retval = -EFAULT; break; } - if (NULL != udev->dev->phys) - kfree(udev->dev->phys); - udev->dev->phys = kmalloc(length, GFP_KERNEL); - if (!udev->dev->phys) { + kfree(udev->dev->phys); + udev->dev->phys = phys = kmalloc(length, GFP_KERNEL); + if (!phys) { retval = -ENOMEM; break; } - if (copy_from_user(udev->dev->phys, p, length)) { - retval = -EFAULT; - kfree(udev->dev->phys); + if (copy_from_user(phys, p, length)) { udev->dev->phys = NULL; + kfree(phys); + retval = -EFAULT; break; } - udev->dev->phys[length - 1] = '\0'; + phys[length - 1] = '\0'; break; case UI_BEGIN_FF_UPLOAD: diff --git a/include/linux/input.h b/include/linux/input.h index b9cc0ac..bdc53c6 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -811,9 +811,9 @@ struct input_dev { void *private; - char *name; - char *phys; - char *uniq; + const char *name; + const char *phys; + const char *uniq; struct input_id id; unsigned long evbit[NBITS(EV_MAX)]; -- cgit v1.1 From beffbdc2211826b174c68307b1b48c93c05d7ded Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 1 Jul 2005 23:54:30 -0500 Subject: Input: cannot refer to __exit from within __init. Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 1ea4f1a..a275211 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -581,7 +581,7 @@ static int __init input_proc_init(void) return -ENOMEM; } -static void __exit input_proc_exit(void) +static void input_proc_exit(void) { remove_proc_entry("devices", proc_bus_input_dir); remove_proc_entry("handlers", proc_bus_input_dir); -- cgit v1.1 From dc1e97b5eaed1921f421cf56fd233f064464b300 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 11 Jul 2005 01:02:16 -0500 Subject: Input: serio_raw - link serio_raw misc device to corresponding serio port in sysfs. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio_raw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index d914e7e..47e08de 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -299,6 +299,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) serio_raw->dev.minor = PSMOUSE_MINOR; serio_raw->dev.name = serio_raw->name; + serio_raw->dev.dev = &serio->dev; serio_raw->dev.fops = &serio_raw_fops; err = misc_register(&serio_raw->dev); -- cgit v1.1 From bef5a66fd7fd8d606da5c9f210e2673f4e636f57 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 11 Jul 2005 01:05:47 -0500 Subject: Input: serio_raw - fix Kconfig help Signed-off-by: Neil Brown Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/serio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index b371073..98acf17 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -175,7 +175,7 @@ config SERIO_RAW allocating minor 1 (that historically corresponds to /dev/psaux) first. To bind this driver to a serio port use sysfs interface: - echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver + echo -n "serio_raw" > /sys/bus/serio/devices/serioX/drvctl To compile this driver as a module, choose M here: the module will be called serio_raw. -- cgit v1.1 From 865190cdbba995936700346c2daabbed97ac30ba Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 11 Jul 2005 01:06:06 -0500 Subject: Input: i8042 - add Alienware Sentia to NOMUX blacklist. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 0487ecb..66f533c 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -137,6 +137,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), }, }, + { + .ident = "Alienware Sentia", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), + }, + }, { } }; -- cgit v1.1 From 20f07944af80a2916b2f6ac1559c0a680c309c0e Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Mon, 11 Jul 2005 01:06:28 -0500 Subject: Input: i8042 - add Fujitsu T3010 to NOMUX blacklist. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 66f533c..03877c8 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -131,6 +131,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { }, }, { + .ident = "Fujitsu-Siemens Lifebook T3010", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), + }, + }, + { .ident = "Toshiba P10", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), -- cgit v1.1 From 9ba5eaafa1bff1d2dc7f6b9fb4cc6e313dcd6105 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 11 Jul 2005 01:07:20 -0500 Subject: Input: synaptics - limit rate to 40pps on Toshiba Dynabooks Toshiba Dynabooks require the same workaround as Satellites - Synaptics report rate should be lowered to 40pps (from 80), otherwise KBC starts losing keypresses. Signed-off-by: Simon Horman Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 36c7212..39cc1e5 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -608,6 +608,13 @@ static struct dmi_system_id toshiba_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME , "Satellite"), }, }, + { + .ident = "Toshiba Dynabook", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME , "dynabook"), + }, + }, { } }; #endif @@ -656,7 +663,8 @@ int synaptics_init(struct psmouse *psmouse) * thye same as rate of standard PS/2 mouse. */ if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) { - printk(KERN_INFO "synaptics: Toshiba Satellite detected, limiting rate to 40pps.\n"); + printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", + dmi_get_system_info(DMI_PRODUCT_NAME)); psmouse->rate = 40; } #endif -- cgit v1.1 From b30dc120a7471a961272aeca24ede1c0530e6455 Mon Sep 17 00:00:00 2001 From: David Moore Date: Mon, 11 Jul 2005 01:07:48 -0500 Subject: Input: ALPS - fix resume (for DualPoints) The driver would not reset pass-through mode when performing resume of a DualPoint touchpad causing it to stop working until next reboot. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a12e981..33e7198 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -358,7 +358,7 @@ static int alps_reconnect(struct psmouse *psmouse) if (!(priv->i = alps_get_model(psmouse, &version))) return -1; - if (priv->i->flags & ALPS_PASS && alps_passthrough_mode(psmouse, 1)) + if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) return -1; if (alps_get_status(psmouse, param)) @@ -372,7 +372,7 @@ static int alps_reconnect(struct psmouse *psmouse) return -1; } - if (priv->i->flags == ALPS_PASS && alps_passthrough_mode(psmouse, 0)) + if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) return -1; return 0; -- cgit v1.1 From 963f626d46d5caeeb3cff29998d8a64df5b25591 Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Mon, 11 Jul 2005 01:08:04 -0500 Subject: Input: ALPS - unconditionally enable tapping mode The condition in alps_init() was also inverted and the driver was enabling tapping mode only if it was already enabled. Signed-off-by: Peter Osterlund Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 33e7198..0d68e5e 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -2,7 +2,7 @@ * ALPS touchpad PS/2 mouse driver * * Copyright (c) 2003 Neil Brown - * Copyright (c) 2003 Peter Osterlund + * Copyright (c) 2003-2005 Peter Osterlund * Copyright (c) 2004 Dmitry Torokhov * Copyright (c) 2005 Vojtech Pavlik * @@ -350,7 +350,6 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable) static int alps_reconnect(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; - unsigned char param[4]; int version; psmouse_reset(psmouse); @@ -361,14 +360,13 @@ static int alps_reconnect(struct psmouse *psmouse) if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) return -1; - if (alps_get_status(psmouse, param)) + if (alps_tap_mode(psmouse, 1)) { + printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n"); return -1; - - if (!(param[0] & 0x04)) - alps_tap_mode(psmouse, 1); + } if (alps_absolute_mode(psmouse)) { - printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); + printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n"); return -1; } @@ -389,7 +387,6 @@ static void alps_disconnect(struct psmouse *psmouse) int alps_init(struct psmouse *psmouse) { struct alps_data *priv; - unsigned char param[4]; int version; psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL); @@ -403,16 +400,8 @@ int alps_init(struct psmouse *psmouse) if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) goto init_fail; - if (alps_get_status(psmouse, param)) { - printk(KERN_ERR "alps.c: touchpad status report request failed\n"); - goto init_fail; - } - - if (param[0] & 0x04) { - printk(KERN_INFO "alps.c: Enabling hardware tapping\n"); - if (alps_tap_mode(psmouse, 1)) - printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); - } + if (alps_tap_mode(psmouse, 1)) + printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); if (alps_absolute_mode(psmouse)) { printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); -- cgit v1.1 From 6345fdfd190659a2316d18065871245e3a1e0f84 Mon Sep 17 00:00:00 2001 From: Luca T Date: Mon, 11 Jul 2005 01:08:40 -0500 Subject: Input: HID - add a quirk for Aashima Trust (06d6:0025) gamepad Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/usb/input/hid-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 100b49bd..271f5bd 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1372,6 +1372,9 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_A4TECH 0x09da #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 +#define USB_VENDOR_ID_AASHIMA 0x06D6 +#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 + #define USB_VENDOR_ID_CYPRESS 0x04b4 #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 @@ -1524,6 +1527,7 @@ static struct hid_blacklist { { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, + { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, -- cgit v1.1 From 6f5eacfc1e9a12ffca10b4abe8e9fddf1997da6f Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 11 Jul 2005 01:08:56 -0500 Subject: Input: joydev - remove custom conversion from jiffies to msecs Replace the MSECS() macro with the jiffies_to_msecs() function provided in jiffies.h Signed-off-by: Tobias Klauser Signed-off-by: Domen Puncer Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/joydev.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index ff8e1bb..e0938d1 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -37,8 +37,6 @@ MODULE_LICENSE("GPL"); #define JOYDEV_MINORS 16 #define JOYDEV_BUFFER_SIZE 64 -#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ) - struct joydev { int exist; int open; @@ -117,7 +115,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne return; } - event.time = MSECS(jiffies); + event.time = jiffies_to_msecs(jiffies); list_for_each_entry(list, &joydev->list, node) { @@ -245,7 +243,7 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo struct js_event event; - event.time = MSECS(jiffies); + event.time = jiffies_to_msecs(jiffies); if (list->startup < joydev->nkey) { event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; -- cgit v1.1 From 153ab429cad3b585ddf1a5521cfaadb57402cd31 Mon Sep 17 00:00:00 2001 From: Michael Prokop Date: Mon, 11 Jul 2005 01:09:10 -0500 Subject: Input: elo - fix help in Kconfig (wrong module name) Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 7e99127..0489af5 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -58,7 +58,7 @@ config TOUCHSCREEN_ELO If unsure, say N. To compile this driver as a module, choose M here: the - module will be called gunze. + module will be called elo. config TOUCHSCREEN_MTOUCH tristate "MicroTouch serial touchscreens" -- cgit v1.1 From bc5d04822bd9f34ea93a681f05f5e5683935d574 Mon Sep 17 00:00:00 2001 From: Adam Kropelin Date: Mon, 11 Jul 2005 01:09:32 -0500 Subject: Input: HID - only report events coming from interrupts to hiddev Currently hid-core follows the same code path for input reports regardless of whether they are a result of interrupt transfers or control transfers. That leads to interrupt events erroneously being reported to hiddev for regular control transfers. Prior to 2.6.12 the problem was mitigated by the fact that reporting to hiddev is supressed if the field value has not changed, which is often the case. Said filtering was removed in 2.6.12-rc1 which means any input reports fetched via control transfers result in hiddev interrupt events. This behavior can quickly lead to a feedback loop where a userspace app, in response to interrupt events, issues control transfers which in turn create more interrupt events. This patch prevents input reports that arrive via control transfers from being reported to hiddev as interrupt events. Signed-off-by: Adam Kropelin Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/usb/input/hid-core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 271f5bd..30b1b2d 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -789,12 +789,12 @@ static __inline__ int search(__s32 *array, __s32 value, unsigned n) return -1; } -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) +static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs) { hid_dump_input(usage, value); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV) + if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) hiddev_hid_event(hid, field, usage, value, regs); } @@ -804,7 +804,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s * reporting to the layer). */ -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) +static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs) { unsigned n; unsigned count = field->report_count; @@ -831,19 +831,19 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u for (n = 0; n < count; n++) { if (HID_MAIN_ITEM_VARIABLE & field->flags) { - hid_process_event(hid, field, &field->usage[n], value[n], regs); + hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs); continue; } if (field->value[n] >= min && field->value[n] <= max && field->usage[field->value[n] - min].hid && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs); + hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs); if (value[n] >= min && value[n] <= max && field->usage[value[n] - min].hid && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs); + hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs); } memcpy(field->value, value, count * sizeof(__s32)); @@ -851,7 +851,7 @@ exit: kfree(value); } -static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) +static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs) { struct hid_device *hid = urb->context; struct hid_report_enum *report_enum = hid->report_enum + type; @@ -899,7 +899,7 @@ static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) hiddev_report_event(hid, report); for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, regs); + hid_input_field(hid, report->field[n], data, interrupt, regs); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_report_event(hid, report); @@ -918,7 +918,7 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs) switch (urb->status) { case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, regs); + hid_input_report(HID_INPUT_REPORT, urb, 1, regs); break; case -ECONNRESET: /* unlink */ case -ENOENT: @@ -1142,7 +1142,7 @@ static void hid_ctrl(struct urb *urb, struct pt_regs *regs) switch (urb->status) { case 0: /* success */ if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs); + hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); case -ESHUTDOWN: /* unplug */ case -EILSEQ: /* unplug timectrl on uhci */ unplug = 1; -- cgit v1.1 From 7b4019d04895de7407c9989895c3664c24ed01f7 Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Fri, 15 Jul 2005 01:50:08 -0500 Subject: Input: psmouse - wheel mice (imps, exps) always have 3rd button There are wheel mice that respond to Logitech probes and report that they have only 2 buttons (such as e-Aser mouse) and this stops the wheel from being used as a middle button. Change the driver to always report BTN_MIDDLE capability if a wheel is present. Also, never reset BTN_RIGHT capability in logips2pp code - there are no Logitech mice that have only one button and if some other mice happen to respond to Logitech's query we could do the wrong thing. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/logips2pp.c | 2 -- drivers/input/mouse/psmouse-base.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 5ab1bd7..48d2b20 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -385,8 +385,6 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) if (buttons < 3) clear_bit(BTN_MIDDLE, psmouse->dev.keybit); - if (buttons < 2) - clear_bit(BTN_RIGHT, psmouse->dev.keybit); if (model_info) ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 19785a6..2bb2fe7 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -344,6 +344,7 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties) return -1; if (set_properties) { + set_bit(BTN_MIDDLE, psmouse->dev.keybit); set_bit(REL_WHEEL, psmouse->dev.relbit); if (!psmouse->vendor) psmouse->vendor = "Generic"; @@ -376,6 +377,7 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) return -1; if (set_properties) { + set_bit(BTN_MIDDLE, psmouse->dev.keybit); set_bit(REL_WHEEL, psmouse->dev.relbit); set_bit(BTN_SIDE, psmouse->dev.keybit); set_bit(BTN_EXTRA, psmouse->dev.keybit); -- cgit v1.1 From 463a4f76a79bce00ca8964e0b2ebf7f10f376965 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 15 Jul 2005 01:51:56 -0500 Subject: Input: i8042 - don't use negation to mark AUX data Currently i8042_command() negates data coming from the AUX port of keyboard controller; this is not a very reliable indicator. Change i8042_command() to fail if response to I8042_CMD_AUX_LOOP is not coming from AUX channel and get rid of negation. Based on patch by Vojtech Pavlik. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042.c | 60 ++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index a9bf549..708a1d3 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -100,7 +100,7 @@ struct i8042_port { static struct i8042_port i8042_ports[I8042_NUM_PORTS] = { { .disable = I8042_CTR_KBDDIS, - .irqen = I8042_CTR_KBDINT, + .irqen = I8042_CTR_KBDINT, .mux = -1, .name = "KBD", }, @@ -191,41 +191,45 @@ static int i8042_flush(void) static int i8042_command(unsigned char *param, int command) { unsigned long flags; - int retval = 0, i = 0; + int i, retval, auxerr = 0; if (i8042_noloop && command == I8042_CMD_AUX_LOOP) return -1; spin_lock_irqsave(&i8042_lock, flags); - retval = i8042_wait_write(); - if (!retval) { - dbg("%02x -> i8042 (command)", command & 0xff); - i8042_write_command(command & 0xff); + if ((retval = i8042_wait_write())) + goto out; + + dbg("%02x -> i8042 (command)", command & 0xff); + i8042_write_command(command & 0xff); + + for (i = 0; i < ((command >> 12) & 0xf); i++) { + if ((retval = i8042_wait_write())) + goto out; + dbg("%02x -> i8042 (parameter)", param[i]); + i8042_write_data(param[i]); } - if (!retval) - for (i = 0; i < ((command >> 12) & 0xf); i++) { - if ((retval = i8042_wait_write())) break; - dbg("%02x -> i8042 (parameter)", param[i]); - i8042_write_data(param[i]); - } + for (i = 0; i < ((command >> 8) & 0xf); i++) { + if ((retval = i8042_wait_read())) + goto out; - if (!retval) - for (i = 0; i < ((command >> 8) & 0xf); i++) { - if ((retval = i8042_wait_read())) break; - if (i8042_read_status() & I8042_STR_AUXDATA) - param[i] = ~i8042_read_data(); - else - param[i] = i8042_read_data(); - dbg("%02x <- i8042 (return)", param[i]); + if (command == I8042_CMD_AUX_LOOP && + !(i8042_read_status() & I8042_STR_AUXDATA)) { + retval = auxerr = -1; + goto out; } - spin_unlock_irqrestore(&i8042_lock, flags); + param[i] = i8042_read_data(); + dbg("%02x <- i8042 (return)", param[i]); + } if (retval) - dbg(" -- i8042 (timeout)"); + dbg(" -- i8042 (%s)", auxerr ? "auxerr" : "timeout"); + out: + spin_unlock_irqrestore(&i8042_lock, flags); return retval; } @@ -507,17 +511,17 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version) */ param = 0xf0; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0x0f) + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xf0) return -1; param = mode ? 0x56 : 0xf6; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != (mode ? 0xa9 : 0x09)) + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != (mode ? 0x56 : 0xf6)) return -1; param = mode ? 0xa4 : 0xa5; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == (mode ? 0x5b : 0x5a)) + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == (mode ? 0xa4 : 0xa5)) return -1; if (mux_version) - *mux_version = ~param; + *mux_version = param; return 0; } @@ -619,7 +623,7 @@ static int __init i8042_check_aux(void) */ param = 0x5a; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xa5) { + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0x5a) { /* * External connection test - filters out AT-soldered PS/2 i8042's @@ -630,7 +634,7 @@ static int __init i8042_check_aux(void) */ if (i8042_command(¶m, I8042_CMD_AUX_TEST) - || (param && param != 0xfa && param != 0xff)) + || (param && param != 0xfa && param != 0xff)) return -1; } -- cgit v1.1 From 5ac7ba3ff599d66ffde182676f2e4fbcac61a2fe Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sun, 24 Jul 2005 00:50:03 -0500 Subject: Input: check keycodesize when adjusting keymaps When changing key mappings we need to make sure that the new keycode value can be stored in dev->keycodesize bytes. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 4 ++-- drivers/input/evdev.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 7b19e02..523fd3c 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -198,10 +198,10 @@ int setkeycode(unsigned int scancode, unsigned int keycode) if (scancode >= dev->keycodemax) return -EINVAL; - if (keycode > KEY_MAX) - return -EINVAL; if (keycode < 0 || keycode > KEY_MAX) return -EINVAL; + if (keycode >> (dev->keycodesize * 8)) + return -EINVAL; oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 374f404..20e3a16 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -320,6 +320,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL; if (get_user(v, ip + 1)) return -EFAULT; if (v < 0 || v > KEY_MAX) return -EINVAL; + if (v >> (dev->keycodesize * 8)) return -EINVAL; u = SET_INPUT_KEYCODE(dev, t, v); clear_bit(u, dev->keybit); set_bit(v, dev->keybit); -- cgit v1.1 From 33fdfa97f2b3aab698ef849ec50dcc5102017f0a Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Sun, 24 Jul 2005 00:53:32 -0500 Subject: Input: synaptics - fix setting packet size on passthrough port. Synaptics driver used child->type to select either 3-byte or 4-byte packet size for the pass-through port; this gives wrong results for the newer protocols. Change the check to use child->pktsize instead. Signed-off-by: Sergey Vlasov Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 39cc1e5..0293094 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -219,7 +219,7 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet serio_interrupt(ptport, packet[1], 0, NULL); serio_interrupt(ptport, packet[4], 0, NULL); serio_interrupt(ptport, packet[5], 0, NULL); - if (child->type >= PSMOUSE_GENPS) + if (child->pktsize == 4) serio_interrupt(ptport, packet[2], 0, NULL); } else serio_interrupt(ptport, packet[1], 0, NULL); @@ -233,7 +233,7 @@ static void synaptics_pt_activate(struct psmouse *psmouse) /* adjust the touchpad to child's choice of protocol */ if (child) { - if (child->type >= PSMOUSE_GENPS) + if (child->pktsize == 4) priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT; else priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; -- cgit v1.1