From fe65b97a5885a84baa103d7213754ff29e8f872f Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Mon, 5 Jun 2006 00:18:21 -0400 Subject: Input: iforce - use ENOSPC instead of ENOMEM Use -ENOSPC instead of -ENOMEM when the iforce device doesn't have enough free memory for the new effect. All other drivers are using -ENOSPC, so this makes the behaviour coherent. Signed-off-by: Anssi Hannula Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/iforce/iforce-ff.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index 2b8e8456c9fa..50c90765aee1 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c @@ -47,7 +47,7 @@ static int make_magnitude_modifier(struct iforce* iforce, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { mutex_unlock(&iforce->mem_mutex); - return -ENOMEM; + return -ENOSPC; } mutex_unlock(&iforce->mem_mutex); } @@ -80,7 +80,7 @@ static int make_period_modifier(struct iforce* iforce, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { mutex_unlock(&iforce->mem_mutex); - return -ENOMEM; + return -ENOSPC; } mutex_unlock(&iforce->mem_mutex); } @@ -120,7 +120,7 @@ static int make_envelope_modifier(struct iforce* iforce, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { mutex_unlock(&iforce->mem_mutex); - return -ENOMEM; + return -ENOSPC; } mutex_unlock(&iforce->mem_mutex); } @@ -157,7 +157,7 @@ static int make_condition_modifier(struct iforce* iforce, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { mutex_unlock(&iforce->mem_mutex); - return -ENOMEM; + return -ENOSPC; } mutex_unlock(&iforce->mem_mutex); } -- cgit v1.2.3 From 5fa28ea42f28342ca6efaa2d23789f3fec5adff6 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Fri, 23 Jun 2006 02:04:56 -0700 Subject: [PATCH] m68k: restore amikbd compatibility with 2.4 Dump the extra mapping in the amikbd interrupt handler, so old Amiga keymaps work again. Amigas need a special keymap anyway, standard keymaps are not usable and recreating all keymaps is simply not worth the trouble. Signed-off-by: Roman Zippel Cc: Dmitry Torokhov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/keyboard/amikbd.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 4c8fb1f8631f..f1f9db9d282c 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,7 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Amiga keyboard driver"); MODULE_LICENSE("GPL"); -static unsigned char amikbd_keycode[0x78] = { +static unsigned char amikbd_keycode[0x78] __initdata = { [0] = KEY_GRAVE, [1] = KEY_1, [2] = KEY_2, @@ -170,12 +171,9 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp) scancode >>= 1; if (scancode < 0x78) { /* scancodes < 0x78 are keys */ - - scancode = amikbd_keycode[scancode]; - input_regs(amikbd_dev, fp); - if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ + if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ input_report_key(amikbd_dev, scancode, 1); input_report_key(amikbd_dev, scancode, 0); } else { @@ -191,7 +189,7 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp) static int __init amikbd_init(void) { - int i; + int i, j; if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) return -EIO; @@ -214,14 +212,26 @@ static int __init amikbd_init(void) amikbd_dev->id.version = 0x0100; amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - amikbd_dev->keycode = amikbd_keycode; - amikbd_dev->keycodesize = sizeof(unsigned char); - amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode); for (i = 0; i < 0x78; i++) - if (amikbd_keycode[i]) - set_bit(amikbd_keycode[i], amikbd_dev->keybit); - + set_bit(i, amikbd_dev->keybit); + + for (i = 0; i < MAX_NR_KEYMAPS; i++) { + static u_short temp_map[NR_KEYS] __initdata; + if (!key_maps[i]) + continue; + memset(temp_map, 0, sizeof(temp_map)); + for (j = 0; j < 0x78; j++) { + if (!amikbd_keycode[j]) + continue; + temp_map[j] = key_maps[i][amikbd_keycode[j]]; + } + for (j = 0; j < NR_KEYS; j++) { + if (!temp_map[j]) + temp_map[j] = 0xf200; + } + memcpy(key_maps[i], temp_map, sizeof(temp_map)); + } ciaa.cra &= ~0x41; /* serial data in, turn off TA */ request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt); -- cgit v1.2.3 From 75e1fcc0b18df0a65ab113198e9dc0e98999a08c Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 23 Jun 2006 02:05:12 -0700 Subject: [PATCH] vfs: add lock owner argument to flush operation Pass the POSIX lock owner ID to the flush operation. This is useful for filesystems which don't want to store any locking state in inode->i_flock but want to handle locking/unlocking POSIX locks internally. FUSE is one such filesystem but I think it possible that some network filesystems would need this also. Also add a flag to indicate that a POSIX locking request was generated by close(), so filesystems using the above feature won't send an extra locking request in this case. Signed-off-by: Miklos Szeredi Cc: Trond Myklebust Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/evdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index ba325f16d077..5f561fce32d8 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -82,7 +82,7 @@ static int evdev_fasync(int fd, struct file *file, int on) return retval < 0 ? retval : 0; } -static int evdev_flush(struct file * file) +static int evdev_flush(struct file * file, fl_owner_t id) { struct evdev_list *list = file->private_data; if (!list->evdev->exist) return -ENODEV; -- cgit v1.2.3 From 690c8fd31f1e35985d0f35772fde514da59ec9d1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 22 Jun 2006 19:12:03 -0700 Subject: [SPARC64]: Use in-kernel PROM tree for EBUS and ISA. Signed-off-by: David S. Miller --- drivers/input/misc/sparcspkr.c | 4 ++-- drivers/input/serio/i8042-sparcio.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index f0fd2c4740f1..ed95dc9420dd 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -199,7 +199,7 @@ static int __init sparcspkr_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "beep")) { + if (!strcmp(edev->prom_node->name, "beep")) { beep_name = "Sparc EBUS Speaker"; beep_event = ebus_spkr_event; beep_iobase = edev->resource[0].start; @@ -213,7 +213,7 @@ static int __init sparcspkr_init(void) /* A hack, the beep device's base lives in * the DMA isa node. */ - if (!strcmp(isa_dev->prom_name, "dma")) { + if (!strcmp(isa_dev->prom_node->name, "dma")) { beep_name = "Sparc ISA Speaker"; beep_event = isa_spkr_event, beep_iobase = isa_dev->resource.start; diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index ed9446f6d7e3..6d66351805a2 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -74,7 +74,7 @@ static int __init i8042_platform_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "8042")) + if (!strcmp(edev->prom_node->name, "8042")) goto edev_found; } } @@ -82,14 +82,14 @@ static int __init i8042_platform_init(void) edev_found: for_each_edevchild(edev, child) { - if (!strcmp(child->prom_name, OBP_PS2KBD_NAME1) || - !strcmp(child->prom_name, OBP_PS2KBD_NAME2)) { + if (!strcmp(child->prom_node->name, OBP_PS2KBD_NAME1) || + !strcmp(child->prom_node->name, OBP_PS2KBD_NAME2)) { i8042_kbd_irq = child->irqs[0]; kbd_iobase = ioremap(child->resource[0].start, 8); } - if (!strcmp(child->prom_name, OBP_PS2MS_NAME1) || - !strcmp(child->prom_name, OBP_PS2MS_NAME2)) + if (!strcmp(child->prom_node->name, OBP_PS2MS_NAME1) || + !strcmp(child->prom_node->name, OBP_PS2MS_NAME2)) i8042_aux_irq = child->irqs[0]; } if (i8042_kbd_irq == -1 || -- cgit v1.2.3 From a2bd4fd17926d715a470fbe0ebe05128ba410984 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 23 Jun 2006 01:44:10 -0700 Subject: [SPARC64]: Add of_device layer and make ebus/isa use it. Sparcspkr and power drivers are converted, to make sure it works. Eventually the SBUS device layer will use this as a sub-class. I really cannot cut loose on that bit until sparc32 is given the same infrastructure. Signed-off-by: David S. Miller --- drivers/input/misc/Kconfig | 2 +- drivers/input/misc/sparcspkr.c | 218 +++++++++++++++++++++++------------------ 2 files changed, 124 insertions(+), 96 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 4bad588d0e5d..a6dfc7455733 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -26,7 +26,7 @@ config INPUT_PCSPKR config INPUT_SPARCSPKR tristate "SPARC Speaker support" - depends on PCI && SPARC + depends on PCI && SPARC64 help Say Y here if you want the standard Speaker on Sparc PCI systems to be used for bells and whistles. diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index ed95dc9420dd..42c11fbf3c79 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -2,7 +2,7 @@ * Driver for PC-speaker like devices found on various Sparc systems. * * Copyright (c) 2002 Vojtech Pavlik - * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * Copyright (c) 2002, 2006 David S. Miller (davem@davemloft.net) */ #include #include @@ -13,21 +13,23 @@ #include #include -#ifdef CONFIG_SPARC64 #include -#endif -MODULE_AUTHOR("David S. Miller "); +MODULE_AUTHOR("David S. Miller "); MODULE_DESCRIPTION("Sparc Speaker beeper driver"); MODULE_LICENSE("GPL"); -const char *beep_name; -static unsigned long beep_iobase; -static int (*beep_event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); -static DEFINE_SPINLOCK(beep_lock); +struct sparcspkr_state { + const char *name; + unsigned long iobase; + int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); + spinlock_t lock; + struct input_dev *input_dev; +}; static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { + struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); unsigned int count = 0; unsigned long flags; @@ -43,24 +45,24 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in if (value > 20 && value < 32767) count = 1193182 / value; - spin_lock_irqsave(&beep_lock, flags); + spin_lock_irqsave(&state->lock, flags); /* EBUS speaker only has on/off state, the frequency does not * appear to be programmable. */ - if (beep_iobase & 0x2UL) - outb(!!count, beep_iobase); + if (state->iobase & 0x2UL) + outb(!!count, state->iobase); else - outl(!!count, beep_iobase); + outl(!!count, state->iobase); - spin_unlock_irqrestore(&beep_lock, flags); + spin_unlock_irqrestore(&state->lock, flags); return 0; } -#ifdef CONFIG_SPARC64 static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { + struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); unsigned int count = 0; unsigned long flags; @@ -76,29 +78,29 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int if (value > 20 && value < 32767) count = 1193182 / value; - spin_lock_irqsave(&beep_lock, flags); + spin_lock_irqsave(&state->lock, flags); if (count) { /* enable counter 2 */ - outb(inb(beep_iobase + 0x61) | 3, beep_iobase + 0x61); + outb(inb(state->iobase + 0x61) | 3, state->iobase + 0x61); /* set command for counter 2, 2 byte write */ - outb(0xB6, beep_iobase + 0x43); + outb(0xB6, state->iobase + 0x43); /* select desired HZ */ - outb(count & 0xff, beep_iobase + 0x42); - outb((count >> 8) & 0xff, beep_iobase + 0x42); + outb(count & 0xff, state->iobase + 0x42); + outb((count >> 8) & 0xff, state->iobase + 0x42); } else { /* disable counter 2 */ - outb(inb_p(beep_iobase + 0x61) & 0xFC, beep_iobase + 0x61); + outb(inb_p(state->iobase + 0x61) & 0xFC, state->iobase + 0x61); } - spin_unlock_irqrestore(&beep_lock, flags); + spin_unlock_irqrestore(&state->lock, flags); return 0; } -#endif -static int __devinit sparcspkr_probe(struct platform_device *dev) +static int __devinit sparcspkr_probe(struct device *dev) { + struct sparcspkr_state *state = dev_get_drvdata(dev); struct input_dev *input_dev; int error; @@ -106,18 +108,18 @@ static int __devinit sparcspkr_probe(struct platform_device *dev) if (!input_dev) return -ENOMEM; - input_dev->name = beep_name; + input_dev->name = state->name; input_dev->phys = "sparc/input0"; input_dev->id.bustype = BUS_ISA; input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &dev->dev; + input_dev->cdev.dev = dev; input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - input_dev->event = beep_event; + input_dev->event = state->event; error = input_register_device(input_dev); if (error) { @@ -125,111 +127,137 @@ static int __devinit sparcspkr_probe(struct platform_device *dev) return error; } - platform_set_drvdata(dev, input_dev); + state->input_dev = input_dev; return 0; } -static int __devexit sparcspkr_remove(struct platform_device *dev) +static int __devexit sparcspkr_remove(struct of_device *dev) { - struct input_dev *input_dev = platform_get_drvdata(dev); + struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); + struct input_dev *input_dev = state->input_dev; - input_unregister_device(input_dev); - platform_set_drvdata(dev, NULL); /* turn off the speaker */ - beep_event(NULL, EV_SND, SND_BELL, 0); + state->event(input_dev, EV_SND, SND_BELL, 0); + + input_unregister_device(input_dev); + + dev_set_drvdata(&dev->dev, NULL); + kfree(state); return 0; } -static void sparcspkr_shutdown(struct platform_device *dev) +static int sparcspkr_shutdown(struct of_device *dev) { + struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); + struct input_dev *input_dev = state->input_dev; + /* turn off the speaker */ - beep_event(NULL, EV_SND, SND_BELL, 0); + state->event(input_dev, EV_SND, SND_BELL, 0); + + return 0; +} + +static int __devinit ebus_beep_probe(struct of_device *dev, const struct of_device_id *match) +{ + struct linux_ebus_device *edev = to_ebus_device(&dev->dev); + struct sparcspkr_state *state; + int err; + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + state->name = "Sparc EBUS Speaker"; + state->iobase = edev->resource[0].start; + state->event = ebus_spkr_event; + spin_lock_init(&state->lock); + + dev_set_drvdata(&dev->dev, state); + + err = sparcspkr_probe(&dev->dev); + if (err) { + dev_set_drvdata(&dev->dev, NULL); + kfree(state); + } + + return 0; } -static struct platform_driver sparcspkr_platform_driver = { - .driver = { - .name = "sparcspkr", - .owner = THIS_MODULE, +static struct of_device_id ebus_beep_match[] = { + { + .name = "beep", }, - .probe = sparcspkr_probe, - .remove = __devexit_p(sparcspkr_remove), - .shutdown = sparcspkr_shutdown, + {}, }; -static struct platform_device *sparcspkr_platform_device; +static struct of_platform_driver ebus_beep_driver = { + .name = "beep", + .match_table = ebus_beep_match, + .probe = ebus_beep_probe, + .remove = sparcspkr_remove, + .shutdown = sparcspkr_shutdown, +}; -static int __init sparcspkr_drv_init(void) +static int __devinit isa_beep_probe(struct of_device *dev, const struct of_device_id *match) { - int error; + struct sparc_isa_device *idev = to_isa_device(&dev->dev); + struct sparcspkr_state *state; + int err; - error = platform_driver_register(&sparcspkr_platform_driver); - if (error) - return error; + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; - sparcspkr_platform_device = platform_device_alloc("sparcspkr", -1); - if (!sparcspkr_platform_device) { - error = -ENOMEM; - goto err_unregister_driver; - } + state->name = "Sparc ISA Speaker"; + state->iobase = idev->resource.start; + state->event = isa_spkr_event; + spin_lock_init(&state->lock); + + dev_set_drvdata(&dev->dev, state); - error = platform_device_add(sparcspkr_platform_device); - if (error) - goto err_free_device; + err = sparcspkr_probe(&dev->dev); + if (err) { + dev_set_drvdata(&dev->dev, NULL); + kfree(state); + } return 0; +} - err_free_device: - platform_device_put(sparcspkr_platform_device); - err_unregister_driver: - platform_driver_unregister(&sparcspkr_platform_driver); +static struct of_device_id isa_beep_match[] = { + { + .name = "dma", + }, + {}, +}; - return error; -} +static struct of_platform_driver isa_beep_driver = { + .name = "beep", + .match_table = isa_beep_match, + .probe = isa_beep_probe, + .remove = sparcspkr_remove, + .shutdown = sparcspkr_shutdown, +}; static int __init sparcspkr_init(void) { - struct linux_ebus *ebus; - struct linux_ebus_device *edev; -#ifdef CONFIG_SPARC64 - struct sparc_isa_bridge *isa_br; - struct sparc_isa_device *isa_dev; -#endif - - for_each_ebus(ebus) { - for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, "beep")) { - beep_name = "Sparc EBUS Speaker"; - beep_event = ebus_spkr_event; - beep_iobase = edev->resource[0].start; - return sparcspkr_drv_init(); - } - } - } -#ifdef CONFIG_SPARC64 - for_each_isa(isa_br) { - for_each_isadev(isa_dev, isa_br) { - /* A hack, the beep device's base lives in - * the DMA isa node. - */ - if (!strcmp(isa_dev->prom_node->name, "dma")) { - beep_name = "Sparc ISA Speaker"; - beep_event = isa_spkr_event, - beep_iobase = isa_dev->resource.start; - return sparcspkr_drv_init(); - } - } + int err = of_register_driver(&ebus_beep_driver, &ebus_bus_type); + + if (!err) { + err = of_register_driver(&isa_beep_driver, &isa_bus_type); + if (err) + of_unregister_driver(&ebus_beep_driver); } -#endif - return -ENODEV; + return err; } static void __exit sparcspkr_exit(void) { - platform_device_unregister(sparcspkr_platform_device); - platform_driver_unregister(&sparcspkr_platform_driver); + of_unregister_driver(&ebus_beep_driver); + of_unregister_driver(&isa_beep_driver); } module_init(sparcspkr_init); -- cgit v1.2.3 From 6ceab8a936c302c0cea2bfe55617c76e2f5746fa Mon Sep 17 00:00:00 2001 From: Matt Mackall Date: Sun, 25 Jun 2006 05:47:13 -0700 Subject: [PATCH] random: remove redundant SA_SAMPLE_RANDOM from touchscreen drivers The core input layer is already calling add_input_randomness. Signed-off-by: Matt Mackall Cc: Dmitry Torokhov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/touchscreen/ads7846.c | 3 +-- drivers/input/touchscreen/h3600_ts_input.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 161afddd0f44..386023c594d7 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -773,8 +773,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->last_msg = m; - if (request_irq(spi->irq, ads7846_irq, - SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, + if (request_irq(spi->irq, ads7846_irq, SA_TRIGGER_FALLING, spi->dev.driver->name, ts)) { dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); err = -EBUSY; diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index a18d56bdafd9..a595d386312f 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c @@ -399,16 +399,14 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE); if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, - SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, - "h3600_action", &ts->dev)) { + SA_SHIRQ | SA_INTERRUPT, "h3600_action", &ts->dev)) { printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); err = -EBUSY; goto fail2; } if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, - SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, - "h3600_suspend", &ts->dev)) { + SA_SHIRQ | SA_INTERRUPT, "h3600_suspend", &ts->dev)) { printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); err = -EBUSY; goto fail3; -- cgit v1.2.3 From 08ffce4560e0133e10634b0dd85eecee11257a1c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Jun 2006 01:45:10 -0400 Subject: Input: fix potential overflows in driver/input/mouse Change all sprintfs into snprintfs to make sure we won't stomp on data adjacent to our buffers. Noticed by Wouter Paesen Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 2 +- drivers/input/mouse/psmouse-base.c | 6 +++--- drivers/input/mouse/sermouse.c | 2 +- drivers/input/mouse/vsxxxaa.c | 22 +++++++++++++--------- 4 files changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a0e2e797c6d5..070d75330afd 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -470,7 +470,7 @@ int alps_init(struct psmouse *psmouse) dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); } - sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys); + snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); dev2->phys = priv->phys; dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; dev2->id.bustype = BUS_I8042; diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 136321a2cfdb..5f21532c24ff 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1057,8 +1057,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto if (psmouse->resync_time && psmouse->poll(psmouse)) psmouse->resync_time = 0; - sprintf(psmouse->devname, "%s %s %s", - psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); + snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", + psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); input_dev->name = psmouse->devname; input_dev->phys = psmouse->phys; @@ -1099,7 +1099,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) ps2_init(&psmouse->ps2dev, serio); INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse); psmouse->dev = input_dev; - sprintf(psmouse->phys, "%s/input0", serio->phys); + snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 2f9a04ae725f..a89742431717 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -254,7 +254,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) goto fail; sermouse->dev = input_dev; - sprintf(sermouse->phys, "%s/input0", serio->phys); + snprintf(sermouse->phys, sizeof(sermouse->phys), "%s/input0", serio->phys); sermouse->type = serio->id.proto; input_dev->name = sermouse_protocols[sermouse->type]; diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 36e9442a16b2..7b85bc21ae4a 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -153,22 +153,25 @@ vsxxxaa_detection_done (struct vsxxxaa *mouse) { switch (mouse->type) { case 0x02: - sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse"); + strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse", + sizeof (mouse->name)); break; case 0x04: - sprintf (mouse->name, "DEC VSXXX-AB digitizer"); + strlcpy (mouse->name, "DEC VSXXX-AB digitizer", + sizeof (mouse->name)); break; default: - sprintf (mouse->name, "unknown DEC pointer device " - "(type = 0x%02x)", mouse->type); + snprintf (mouse->name, sizeof (mouse->name), + "unknown DEC pointer device (type = 0x%02x)", + mouse->type); break; } - printk (KERN_INFO "Found %s version 0x%02x from country 0x%02x " - "on port %s\n", mouse->name, mouse->version, - mouse->country, mouse->phys); + printk (KERN_INFO + "Found %s version 0x%02x from country 0x%02x on port %s\n", + mouse->name, mouse->version, mouse->country, mouse->phys); } /* @@ -503,8 +506,9 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) mouse->dev = input_dev; mouse->serio = serio; - sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer"); - sprintf (mouse->phys, "%s/input0", serio->phys); + strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer", + sizeof (mouse->name)); + snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys); input_dev->name = mouse->name; input_dev->phys = mouse->phys; -- cgit v1.2.3 From 10ca4c0a622a942e55dc8a6d57ebd441089c9e38 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Jun 2006 01:45:48 -0400 Subject: Input: fix potential overflows in driver/input/joystick Change all sprintfs into snprintfs to make sure we won't stomp on data adjacent to our buffers. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/a3d.c | 2 +- drivers/input/joystick/analog.c | 23 +++++++++++++---------- drivers/input/joystick/cobra.c | 3 ++- drivers/input/joystick/db9.c | 3 ++- drivers/input/joystick/gamecon.c | 3 ++- drivers/input/joystick/gf2k.c | 2 +- drivers/input/joystick/grip.c | 3 ++- drivers/input/joystick/guillemot.c | 2 +- drivers/input/joystick/interact.c | 2 +- drivers/input/joystick/magellan.c | 2 +- drivers/input/joystick/sidewinder.c | 15 +++++++++------ drivers/input/joystick/spaceball.c | 2 +- drivers/input/joystick/spaceorb.c | 2 +- drivers/input/joystick/stinger.c | 2 +- drivers/input/joystick/twidjoy.c | 2 +- drivers/input/joystick/warrior.c | 2 +- 16 files changed, 40 insertions(+), 30 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 4612d13ea756..b11a4bbc84c4 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -306,7 +306,7 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) gameport_set_poll_handler(gameport, a3d_poll); gameport_set_poll_interval(gameport, 20); - sprintf(a3d->phys, "%s/input0", gameport->phys); + snprintf(a3d->phys, sizeof(a3d->phys), "%s/input0", gameport->phys); input_dev->name = a3d_names[a3d->mode]; input_dev->phys = a3d->phys; diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 3121961e3e7c..01dc0b195d59 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -408,21 +408,23 @@ static void analog_calibrate_timer(struct analog_port *port) static void analog_name(struct analog *analog) { - sprintf(analog->name, "Analog %d-axis %d-button", - hweight8(analog->mask & ANALOG_AXES_STD), - hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 + - hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); + snprintf(analog->name, sizeof(analog->name), "Analog %d-axis %d-button", + hweight8(analog->mask & ANALOG_AXES_STD), + hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 + + hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); if (analog->mask & ANALOG_HATS_ALL) - sprintf(analog->name, "%s %d-hat", - analog->name, hweight16(analog->mask & ANALOG_HATS_ALL)); + snprintf(analog->name, sizeof(analog->name), "%s %d-hat", + analog->name, hweight16(analog->mask & ANALOG_HATS_ALL)); if (analog->mask & ANALOG_HAT_FCS) - strcat(analog->name, " FCS"); + strlcat(analog->name, " FCS", sizeof(analog->name)); if (analog->mask & ANALOG_ANY_CHF) - strcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF"); + strlcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF", + sizeof(analog->name)); - strcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick"); + strlcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick", + sizeof(analog->name)); } /* @@ -435,7 +437,8 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i int i, j, t, v, w, x, y, z; analog_name(analog); - sprintf(analog->phys, "%s/input%d", port->gameport->phys, index); + snprintf(analog->phys, sizeof(analog->phys), + "%s/input%d", port->gameport->phys, index); analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn; analog->dev = input_dev = input_allocate_device(); diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 1909f7ef340c..d5e42eb88a20 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -202,7 +202,8 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) goto fail3; } - sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i); + snprintf(cobra->phys[i], sizeof(cobra->phys[i]), + "%s/input%d", gameport->phys, i); input_dev->name = "Creative Labs Blaster GamePad Cobra"; input_dev->phys = cobra->phys[i]; diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index e61894685cb1..6f31f054d1bb 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -620,7 +620,8 @@ static struct db9 __init *db9_probe(int parport, int mode) goto err_unreg_devs; } - sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i); + snprintf(db9->phys[i], sizeof(db9->phys[i]), + "%s/input%d", db9->pd->port->name, i); input_dev->name = db9_mode->name; input_dev->phys = db9->phys[i]; diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index ecbdb6b9bbd6..fe12aa37393d 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -761,7 +761,8 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) if (!pads[i]) continue; - sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i); + snprintf(gc->phys[i], sizeof(gc->phys[i]), + "%s/input%d", gc->pd->port->name, i); err = gc_setup_pad(gc, i, pads[i]); if (err) goto err_unreg_devs; diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 8a3ad455eb38..e4a699f6ec87 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -298,7 +298,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) gameport_set_poll_handler(gameport, gf2k_poll); gameport_set_poll_interval(gameport, 20); - sprintf(gf2k->phys, "%s/input0", gameport->phys); + snprintf(gf2k->phys, sizeof(gf2k->phys), "%s/input0", gameport->phys); gf2k->length = gf2k_lens[gf2k->id]; diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index 20cb98ac2d79..17a90c436de8 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -354,7 +354,8 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) goto fail3; } - sprintf(grip->phys[i], "%s/input%d", gameport->phys, i); + snprintf(grip->phys[i], sizeof(grip->phys[i]), + "%s/input%d", gameport->phys, i); input_dev->name = grip_name[grip->mode[i]]; input_dev->phys = grip->phys[i]; diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 6e2c721c26ba..840ed9b512b2 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -222,7 +222,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * gameport_set_poll_handler(gameport, guillemot_poll); gameport_set_poll_interval(gameport, 20); - sprintf(guillemot->phys, "%s/input0", gameport->phys); + snprintf(guillemot->phys, sizeof(guillemot->phys), "%s/input0", gameport->phys); guillemot->type = guillemot_type + i; input_dev->name = guillemot_type[i].name; diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index c4ed01758226..bbfeb9c59b87 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -251,7 +251,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d gameport_set_poll_handler(gameport, interact_poll); gameport_set_poll_interval(gameport, 20); - sprintf(interact->phys, "%s/input0", gameport->phys); + snprintf(interact->phys, sizeof(interact->phys), "%s/input0", gameport->phys); interact->type = i; interact->length = interact_type[i].length; diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index ca3cc2319d6a..168b1061a03b 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -162,7 +162,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) goto fail; magellan->dev = input_dev; - sprintf(magellan->phys, "%s/input0", serio->phys); + snprintf(magellan->phys, sizeof(magellan->phys), "%s/input0", serio->phys); input_dev->name = "LogiCad3D Magellan / SpaceMouse"; input_dev->phys = magellan->phys; diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 95c0de7964a0..e58b22c018e4 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -541,7 +541,7 @@ static void sw_print_packet(char *name, int length, unsigned char *buf, char bit * Unfortunately I don't know how to do this for the other SW types. */ -static void sw_3dp_id(unsigned char *buf, char *comment) +static void sw_3dp_id(unsigned char *buf, char *comment, size_t size) { int i; char pnp[8], rev[9]; @@ -554,7 +554,7 @@ static void sw_3dp_id(unsigned char *buf, char *comment) pnp[7] = rev[8] = 0; - sprintf(comment, " [PnP %d.%02d id %s rev %s]", + snprintf(comment, size, " [PnP %d.%02d id %s rev %s]", (int) ((sw_get_bits(buf, 8, 6, 1) << 6) | /* Two 6-bit values */ sw_get_bits(buf, 16, 6, 1)) / 100, (int) ((sw_get_bits(buf, 8, 6, 1) << 6) | @@ -695,7 +695,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) sw->type = SW_ID_FFP; sprintf(comment, " [AC %s]", sw_get_bits(idbuf,38,1,3) ? "off" : "on"); } else - sw->type = SW_ID_PP; + sw->type = SW_ID_PP; break; case 66: sw->bits = 3; @@ -703,7 +703,8 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) sw->length = 22; case 64: sw->type = SW_ID_3DP; - if (j == 160) sw_3dp_id(idbuf, comment); + if (j == 160) + sw_3dp_id(idbuf, comment, sizeof(comment)); break; } } @@ -733,8 +734,10 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) for (i = 0; i < sw->number; i++) { int bits, code; - sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]); - sprintf(sw->phys[i], "%s/input%d", gameport->phys, i); + snprintf(sw->name, sizeof(sw->name), + "Microsoft SideWinder %s", sw_name[sw->type]); + snprintf(sw->phys[i], sizeof(sw->phys[i]), + "%s/input%d", gameport->phys, i); sw->dev[i] = input_dev = input_allocate_device(); if (!input_dev) { diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index d6f8db8ec3fd..75eb5ca59992 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -220,7 +220,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) goto fail; spaceball->dev = input_dev; - sprintf(spaceball->phys, "%s/input0", serio->phys); + snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys); input_dev->name = spaceball_names[id]; input_dev->phys = spaceball->phys; diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index 7c123a01c58e..3e2782e79834 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -177,7 +177,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) goto fail; spaceorb->dev = input_dev; - sprintf(spaceorb->phys, "%s/input0", serio->phys); + snprintf(spaceorb->phys, sizeof(spaceorb->phys), "%s/input0", serio->phys); input_dev->name = "SpaceTec SpaceOrb 360 / Avenger"; input_dev->phys = spaceorb->phys; diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index 0a9ed1d30636..011ec4858e15 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -148,7 +148,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) goto fail; stinger->dev = input_dev; - sprintf(stinger->phys, "%s/serio0", serio->phys); + snprintf(stinger->phys, sizeof(stinger->phys), "%s/serio0", serio->phys); input_dev->name = "Gravis Stinger"; input_dev->phys = stinger->phys; diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 7f8b0093c5bc..076f237d9654 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -199,7 +199,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) goto fail; twidjoy->dev = input_dev; - sprintf(twidjoy->phys, "%s/input0", serio->phys); + snprintf(twidjoy->phys, sizeof(twidjoy->phys), "%s/input0", serio->phys); input_dev->name = "Handykey Twiddler"; input_dev->phys = twidjoy->phys; diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 1849b176cf18..f9c1a03214eb 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -154,7 +154,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) goto fail; warrior->dev = input_dev; - sprintf(warrior->phys, "%s/input0", serio->phys); + snprintf(warrior->phys, sizeof(warrior->phys), "%s/input0", serio->phys); input_dev->name = "Logitech WingMan Warrior"; input_dev->phys = warrior->phys; -- cgit v1.2.3 From a21466cc77b25dc2afd1292c79c7fc8fd454a1a7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Jun 2006 01:46:04 -0400 Subject: Input: fix potential overflows in driver/input/touchscreen Change all sprintfs into snprintfs to make sure we won't stomp on data adjacent to our buffers. Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/gunze.c | 2 +- drivers/input/touchscreen/h3600_ts_input.c | 2 +- drivers/input/touchscreen/mtouch.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 466da190ceec..b769b21973b7 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -129,7 +129,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) gunze->serio = serio; gunze->dev = input_dev; - sprintf(gunze->phys, "%s/input0", serio->phys); + snprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys); input_dev->private = gunze; input_dev->name = "Gunze AHL-51S TouchScreen"; diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index a595d386312f..2de2139f2fed 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c @@ -363,7 +363,7 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) ts->serio = serio; ts->dev = input_dev; - sprintf(ts->phys, "%s/input0", serio->phys); + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", serio->phys); input_dev->name = "H3600 TouchScreen"; input_dev->phys = ts->phys; diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index 1d0d37eeef6e..8647a905df80 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c @@ -143,7 +143,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) mtouch->serio = serio; mtouch->dev = input_dev; - sprintf(mtouch->phys, "%s/input0", serio->phys); + snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys); input_dev->private = mtouch; input_dev->name = "MicroTouch Serial TouchScreen"; -- cgit v1.2.3 From ea08c6faa0a8dc93b016663de55e49822ed0b33f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Jun 2006 01:46:17 -0400 Subject: Input: fix potential overflows in driver/input/keyboard Change all sprintfs into snprintfs to make sure we won't stomp on data adjacent to our buffers. Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 11 +++++++---- drivers/input/keyboard/lkkbd.c | 9 ++++++--- drivers/input/keyboard/newtonkbd.c | 2 +- drivers/input/keyboard/sunkbd.c | 2 +- drivers/input/keyboard/xtkbd.c | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index fad04b66d268..0eb955ddc654 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -776,12 +776,15 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) int i; if (atkbd->extra) - sprintf(atkbd->name, "AT Set 2 Extra keyboard"); + snprintf(atkbd->name, sizeof(atkbd->name), + "AT Set 2 Extra keyboard"); else - sprintf(atkbd->name, "AT %s Set %d keyboard", - atkbd->translated ? "Translated" : "Raw", atkbd->set); + snprintf(atkbd->name, sizeof(atkbd->name), + "AT %s Set %d keyboard", + atkbd->translated ? "Translated" : "Raw", atkbd->set); - sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys); + snprintf(atkbd->phys, sizeof(atkbd->phys), + "%s/input0", atkbd->ps2dev.serio->phys); input_dev->name = atkbd->name; input_dev->phys = atkbd->phys; diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 77c4d9669ad0..5174224cadb4 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -384,18 +384,21 @@ lkkbd_detection_done (struct lkkbd *lk) */ switch (lk->id[4]) { case 1: - sprintf (lk->name, "DEC LK201 keyboard"); + strlcpy (lk->name, "DEC LK201 keyboard", + sizeof (lk->name)); if (lk201_compose_is_alt) lk->keycode[0xb1] = KEY_LEFTALT; break; case 2: - sprintf (lk->name, "DEC LK401 keyboard"); + strlcpy (lk->name, "DEC LK401 keyboard", + sizeof (lk->name)); break; default: - sprintf (lk->name, "Unknown DEC keyboard"); + strlcpy (lk->name, "Unknown DEC keyboard", + sizeof (lk->name)); printk (KERN_ERR "lkkbd: keyboard on %s is unknown, " "please report to Jan-Benedict Glaw " "\n", lk->phys); diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index d10983c521e6..40a3f551247e 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c @@ -96,7 +96,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) nkbd->serio = serio; nkbd->dev = input_dev; - sprintf(nkbd->phys, "%s/input0", serio->phys); + snprintf(nkbd->phys, sizeof(nkbd->phys), "%s/input0", serio->phys); memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode)); input_dev->name = "Newton Keyboard"; diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index b15b6d8d4f83..9dbd7b85686d 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -263,7 +263,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) goto fail; } - sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type); + snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type); memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode)); input_dev->name = sunkbd->name; diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index 4135e3e16c51..0821d53cf0c1 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c @@ -100,7 +100,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) xtkbd->serio = serio; xtkbd->dev = input_dev; - sprintf(xtkbd->phys, "%s/input0", serio->phys); + snprintf(xtkbd->phys, sizeof(xtkbd->phys), "%s/input0", serio->phys); memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode)); input_dev->name = "XT Keyboard"; -- cgit v1.2.3 From 8a3cf456adbde8317a15fc038cfe82c630512f2e Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 26 Jun 2006 01:48:21 -0400 Subject: Input: return correct size when reading modalias attribute Signed-off-by: Richard Purdie Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index 3038c268917d..b149c9434849 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -629,7 +629,7 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) len = input_print_modalias(buf, PAGE_SIZE, id, 1); - return max_t(int, len, PAGE_SIZE); + return min_t(int, len, PAGE_SIZE); } static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); -- cgit v1.2.3 From f60d2b111cd55c335c2b70e50d66a612d2b10856 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Jun 2006 01:48:36 -0400 Subject: Input: reset name, phys and uniq when unregistering Name, phys and uniq are quite often constant strings in moules implementing particular input device. If a module unregisters input device and then gets unloaded, the device could still be present in memory (pinned via sysfs), but aforementioned members would point to some random memory. Set them all to NULL when unregistering so sysfs handlers won't try dereferencing them. Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index b149c9434849..d3cdb139e962 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -29,6 +29,7 @@ MODULE_DESCRIPTION("Input core"); MODULE_LICENSE("GPL"); EXPORT_SYMBOL(input_allocate_device); +EXPORT_SYMBOL(input_free_device); EXPORT_SYMBOL(input_register_device); EXPORT_SYMBOL(input_unregister_device); EXPORT_SYMBOL(input_register_handler); @@ -872,6 +873,7 @@ struct input_dev *input_allocate_device(void) dev->dynalloc = 1; dev->cdev.class = &input_class; class_device_initialize(&dev->cdev); + mutex_init(&dev->mutex); INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->node); } @@ -879,6 +881,18 @@ struct input_dev *input_allocate_device(void) return dev; } +void input_free_device(struct input_dev *dev) +{ + if (dev) { + + mutex_lock(&dev->mutex); + dev->name = dev->phys = dev->uniq = NULL; + mutex_unlock(&dev->mutex); + + input_put_device(dev); + } +} + int input_register_device(struct input_dev *dev) { static atomic_t input_no = ATOMIC_INIT(0); @@ -895,7 +909,6 @@ int input_register_device(struct input_dev *dev) return -EINVAL; } - mutex_init(&dev->mutex); set_bit(EV_SYN, dev->evbit); /* @@ -979,6 +992,10 @@ void input_unregister_device(struct input_dev *dev) sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); class_device_unregister(&dev->cdev); + mutex_lock(&dev->mutex); + dev->name = dev->phys = dev->uniq = NULL; + mutex_unlock(&dev->mutex); + input_wakeup_procfs_readers(); } -- cgit v1.2.3 From 1e0afb288e56d469ca1c583342bb9782d49333c6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Jun 2006 01:48:47 -0400 Subject: Input: fix formatting to better follow CodingStyle Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 10 +++++-- drivers/input/input.c | 37 +++++++++++++++++--------- drivers/input/joydev.c | 69 +++++++++++++++++++++++++++++++----------------- drivers/input/mousedev.c | 42 ++++++++++++++++++----------- drivers/input/tsdev.c | 22 +++++++++------ 5 files changed, 119 insertions(+), 61 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 5f561fce32d8..a29d5ceb00cf 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -78,14 +78,19 @@ static int evdev_fasync(int fd, struct file *file, int on) { int retval; struct evdev_list *list = file->private_data; + retval = fasync_helper(fd, file, on, &list->fasync); + return retval < 0 ? retval : 0; } -static int evdev_flush(struct file * file, fl_owner_t id) +static int evdev_flush(struct file *file, fl_owner_t id) { struct evdev_list *list = file->private_data; - if (!list->evdev->exist) return -ENODEV; + + if (!list->evdev->exist) + return -ENODEV; + return input_flush_device(&list->evdev->handle, file); } @@ -300,6 +305,7 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count static unsigned int evdev_poll(struct file *file, poll_table *wait) { struct evdev_list *list = file->private_data; + poll_wait(file, &list->evdev->wait, wait); return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); diff --git a/drivers/input/input.c b/drivers/input/input.c index d3cdb139e962..7570a3f52f18 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -64,11 +64,13 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in case EV_SYN: switch (code) { case SYN_CONFIG: - if (dev->event) dev->event(dev, type, code, value); + if (dev->event) + dev->event(dev, type, code, value); break; case SYN_REPORT: - if (dev->sync) return; + if (dev->sync) + return; dev->sync = 1; break; } @@ -137,7 +139,8 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in if (code > MSC_MAX || !test_bit(code, dev->mscbit)) return; - if (dev->event) dev->event(dev, type, code, value); + if (dev->event) + dev->event(dev, type, code, value); break; @@ -147,7 +150,9 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in return; change_bit(code, dev->led); - if (dev->event) dev->event(dev, type, code, value); + + if (dev->event) + dev->event(dev, type, code, value); break; @@ -159,21 +164,25 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in if (!!test_bit(code, dev->snd) != !!value) change_bit(code, dev->snd); - if (dev->event) dev->event(dev, type, code, value); + if (dev->event) + dev->event(dev, type, code, value); break; case EV_REP: - if (code > REP_MAX || value < 0 || dev->rep[code] == value) return; + if (code > REP_MAX || value < 0 || dev->rep[code] == value) + return; dev->rep[code] = value; - if (dev->event) dev->event(dev, type, code, value); + if (dev->event) + dev->event(dev, type, code, value); break; case EV_FF: - if (dev->event) dev->event(dev, type, code, value); + if (dev->event) + dev->event(dev, type, code, value); break; } @@ -336,9 +345,11 @@ static inline void input_wakeup_procfs_readers(void) static unsigned int input_proc_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; } @@ -972,9 +983,10 @@ int input_register_device(struct input_dev *dev) void input_unregister_device(struct input_dev *dev) { - struct list_head * node, * next; + struct list_head *node, *next; - if (!dev) return; + if (!dev) + return; del_timer_sync(&dev->timer); @@ -1005,7 +1017,8 @@ void input_register_handler(struct input_handler *handler) struct input_handle *handle; struct input_device_id *id; - if (!handler) return; + if (!handler) + return; INIT_LIST_HEAD(&handler->h_list); @@ -1025,7 +1038,7 @@ void input_register_handler(struct input_handler *handler) void input_unregister_handler(struct input_handler *handler) { - struct list_head * node, * next; + struct list_head *node, *next; list_for_each_safe(node, next, &handler->h_list) { struct input_handle * handle = to_handle_h(node); diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 949bdcef8c2b..d67157513bf7 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -81,10 +81,7 @@ static int joydev_correct(int value, struct js_corr *corr) return 0; } - if (value < -32767) return -32767; - if (value > 32767) return 32767; - - return value; + return value < -32767 ? -32767 : (value > 32767 ? 32767 : value); } static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) @@ -96,7 +93,8 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne switch (type) { case EV_KEY: - if (code < BTN_MISC || value == 2) return; + if (code < BTN_MISC || value == 2) + return; event.type = JS_EVENT_BUTTON; event.number = joydev->keymap[code - BTN_MISC]; event.value = value; @@ -106,7 +104,8 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne event.type = JS_EVENT_AXIS; event.number = joydev->absmap[code]; event.value = joydev_correct(value, joydev->corr + event.number); - if (event.value == joydev->abs[event.number]) return; + if (event.value == joydev->abs[event.number]) + return; joydev->abs[event.number] = event.value; break; @@ -134,7 +133,9 @@ static int joydev_fasync(int fd, struct file *file, int on) { int retval; struct joydev_list *list = file->private_data; + retval = fasync_helper(fd, file, on, &list->fasync); + return retval < 0 ? retval : 0; } @@ -222,12 +223,12 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo return sizeof(struct JS_DATA_TYPE); } - if (list->startup == joydev->nabs + joydev->nkey - && list->head == list->tail && (file->f_flags & O_NONBLOCK)) - return -EAGAIN; + if (list->startup == joydev->nabs + joydev->nkey && + list->head == list->tail && (file->f_flags & O_NONBLOCK)) + return -EAGAIN; retval = wait_event_interruptible(list->joydev->wait, - !list->joydev->exist || + !list->joydev->exist || list->startup < joydev->nabs + joydev->nkey || list->head != list->tail); @@ -276,8 +277,9 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo static unsigned int joydev_poll(struct file *file, poll_table *wait) { struct joydev_list *list = file->private_data; + poll_wait(file, &list->joydev->wait, wait); - return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? + return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); } @@ -291,20 +293,26 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u case JS_SET_CAL: return copy_from_user(&joydev->glue.JS_CORR, argp, sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; + case JS_GET_CAL: return copy_to_user(argp, &joydev->glue.JS_CORR, sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; + case JS_SET_TIMEOUT: return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); + case JS_GET_TIMEOUT: return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); case JSIOCGVERSION: return put_user(JS_VERSION, (__u32 __user *) argp); + case JSIOCGAXES: return put_user(joydev->nabs, (__u8 __user *) argp); + case JSIOCGBUTTONS: return put_user(joydev->nkey, (__u8 __user *) argp); + case JSIOCSCORR: if (copy_from_user(joydev->corr, argp, sizeof(joydev->corr[0]) * joydev->nabs)) @@ -314,38 +322,49 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); } return 0; + case JSIOCGCORR: return copy_to_user(argp, joydev->corr, sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0; + case JSIOCSAXMAP: if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1))) return -EFAULT; for (i = 0; i < joydev->nabs; i++) { - if (joydev->abspam[i] > ABS_MAX) return -EINVAL; + if (joydev->abspam[i] > ABS_MAX) + return -EINVAL; joydev->absmap[joydev->abspam[i]] = i; } return 0; + case JSIOCGAXMAP: return copy_to_user(argp, joydev->abspam, sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0; + case JSIOCSBTNMAP: if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1))) return -EFAULT; for (i = 0; i < joydev->nkey; i++) { - if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL; + if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) + return -EINVAL; joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; } return 0; + case JSIOCGBTNMAP: return copy_to_user(argp, joydev->keypam, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0; + default: if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) { int len; - if (!dev->name) return 0; + if (!dev->name) + return 0; len = strlen(dev->name) + 1; - if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - if (copy_to_user(argp, dev->name, len)) return -EFAULT; + if (len > _IOC_SIZE(cmd)) + len = _IOC_SIZE(cmd); + if (copy_to_user(argp, dev->name, len)) + return -EFAULT; return len; } } @@ -362,7 +381,9 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo struct JS_DATA_SAVE_TYPE_32 ds32; int err; - if (!joydev->exist) return -ENODEV; + if (!joydev->exist) + return -ENODEV; + switch(cmd) { case JS_SET_TIMELIMIT: err = get_user(tmp32, (s32 __user *) arg); @@ -395,8 +416,7 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo ds32.JS_SAVE = joydev->glue.JS_SAVE; ds32.JS_CORR = joydev->glue.JS_CORR; - err = copy_to_user(argp, &ds32, - sizeof(ds32)) ? -EFAULT : 0; + err = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0; break; default: @@ -412,7 +432,8 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd struct joydev *joydev = list->joydev; void __user *argp = (void __user *)arg; - if (!joydev->exist) return -ENODEV; + if (!joydev->exist) + return -ENODEV; switch(cmd) { case JS_SET_TIMELIMIT: @@ -546,8 +567,8 @@ static struct input_device_id joydev_blacklist[] = { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, .evbit = { BIT(EV_KEY) }, .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, - }, /* Avoid itouchpads, touchscreens and tablets */ - { }, /* Terminating entry */ + }, /* Avoid itouchpads, touchscreens and tablets */ + { } /* Terminating entry */ }; static struct input_device_id joydev_ids[] = { @@ -566,7 +587,7 @@ static struct input_device_id joydev_ids[] = { .evbit = { BIT(EV_ABS) }, .absbit = { BIT(ABS_THROTTLE) }, }, - { }, /* Terminating entry */ + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(input, joydev_ids); @@ -579,7 +600,7 @@ static struct input_handler joydev_handler = { .minor = JOYDEV_MINOR_BASE, .name = "joydev", .id_table = joydev_ids, - .blacklist = joydev_blacklist, + .blacklist = joydev_blacklist, }; static int __init joydev_init(void) diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index b685a507955d..eb721b11ff37 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -123,7 +123,9 @@ static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mous if (mousedev->touch) { size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; - if (size == 0) size = 256 * 2; + if (size == 0) + size = 256 * 2; + switch (code) { case ABS_X: fx(0) = value; @@ -155,18 +157,24 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, switch (code) { case ABS_X: size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; - if (size == 0) size = xres ? : 1; - if (value > dev->absmax[ABS_X]) value = dev->absmax[ABS_X]; - if (value < dev->absmin[ABS_X]) value = dev->absmin[ABS_X]; + if (size == 0) + size = xres ? : 1; + if (value > dev->absmax[ABS_X]) + value = dev->absmax[ABS_X]; + if (value < dev->absmin[ABS_X]) + value = dev->absmin[ABS_X]; mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size; mousedev->packet.abs_event = 1; break; case ABS_Y: size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; - if (size == 0) size = yres ? : 1; - if (value > dev->absmax[ABS_Y]) value = dev->absmax[ABS_Y]; - if (value < dev->absmin[ABS_Y]) value = dev->absmin[ABS_Y]; + if (size == 0) + size = yres ? : 1; + if (value > dev->absmax[ABS_Y]) + value = dev->absmax[ABS_Y]; + if (value < dev->absmin[ABS_Y]) + value = dev->absmin[ABS_Y]; mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size; mousedev->packet.abs_event = 1; break; @@ -202,7 +210,7 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int case BTN_SIDE: index = 3; break; case BTN_4: case BTN_EXTRA: index = 4; break; - default: return; + default: return; } if (value) { @@ -285,10 +293,9 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value) mousedev->touch = mousedev->pkt_count = 0; mousedev->frac_dx = 0; mousedev->frac_dy = 0; - } - else - if (!mousedev->touch) - mousedev->touch = jiffies; + + } else if (!mousedev->touch) + mousedev->touch = jiffies; } static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) @@ -327,7 +334,7 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig mousedev->pkt_count++; /* Input system eats duplicate events, but we need all of them * to do correct averaging so apply present one forward - */ + */ fx(0) = fx(1); fy(0) = fy(1); } @@ -346,7 +353,9 @@ static int mousedev_fasync(int fd, struct file *file, int on) { int retval; struct mousedev_list *list = file->private_data; + retval = fasync_helper(fd, file, on, &list->fasync); + return retval < 0 ? retval : 0; } @@ -507,14 +516,16 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si list->imexseq = 0; list->mode = MOUSEDEV_EMUL_EXPS; } - } else list->imexseq = 0; + } else + list->imexseq = 0; if (c == mousedev_imps_seq[list->impsseq]) { if (++list->impsseq == MOUSEDEV_SEQ_LEN) { list->impsseq = 0; list->mode = MOUSEDEV_EMUL_IMPS; } - } else list->impsseq = 0; + } else + list->impsseq = 0; list->ps2[0] = 0xfa; @@ -598,6 +609,7 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co static unsigned int mousedev_poll(struct file *file, poll_table *wait) { struct mousedev_list *list = file->private_data; + poll_wait(file, &list->mousedev->wait, wait); return ((list->ready || list->buffer) ? (POLLIN | POLLRDNORM) : 0) | (list->mousedev->exist ? 0 : (POLLHUP | POLLERR)); diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index d678d144bbf8..5f9ecad2ca75 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -35,7 +35,7 @@ * e-mail - mail your message to . */ -#define TSDEV_MINOR_BASE 128 +#define TSDEV_MINOR_BASE 128 #define TSDEV_MINORS 32 /* First 16 devices are h3600_ts compatible; second 16 are h3600_tsraw */ #define TSDEV_MINOR_MASK 15 @@ -230,6 +230,7 @@ static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, static unsigned int tsdev_poll(struct file *file, poll_table * wait) { struct tsdev_list *list = file->private_data; + poll_wait(file, &list->tsdev->wait, wait); return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | (list->tsdev->exist ? 0 : (POLLHUP | POLLERR)); @@ -248,11 +249,13 @@ static int tsdev_ioctl(struct inode *inode, struct file *file, sizeof (struct ts_calibration))) retval = -EFAULT; break; + case TS_SET_CAL: if (copy_from_user (&tsdev->cal, (void __user *)arg, sizeof (struct ts_calibration))) retval = -EFAULT; break; + default: retval = -EINVAL; break; @@ -284,9 +287,11 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, case ABS_X: tsdev->x = value; break; + case ABS_Y: tsdev->y = value; break; + case ABS_PRESSURE: if (value > handle->dev->absmax[ABS_PRESSURE]) value = handle->dev->absmax[ABS_PRESSURE]; @@ -307,6 +312,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, else if (tsdev->x > xres) tsdev->x = xres; break; + case REL_Y: tsdev->y += value; if (tsdev->y < 0) @@ -323,6 +329,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, case 0: tsdev->pressure = 0; break; + case 1: if (!tsdev->pressure) tsdev->pressure = 1; @@ -370,9 +377,8 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, struct class_device *cdev; int minor, delta; - for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor]; - minor++); - if (minor >= TSDEV_MINORS/2) { + for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++); + if (minor >= TSDEV_MINORS / 2) { printk(KERN_ERR "tsdev: You have way too many touchscreens\n"); return NULL; @@ -444,22 +450,22 @@ static struct input_device_id tsdev_ids[] = { .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, .relbit = { BIT(REL_X) | BIT(REL_Y) }, - },/* A mouse like device, at least one button, two relative axes */ + }, /* A mouse like device, at least one button, two relative axes */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, - },/* A tablet like device, at least touch detection, two absolute axes */ + }, /* A tablet like device, at least touch detection, two absolute axes */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, .evbit = { BIT(EV_ABS) }, .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) }, - },/* A tablet like device with several gradations of pressure */ + }, /* A tablet like device with several gradations of pressure */ - {},/* Terminating entry */ + {} /* Terminating entry */ }; MODULE_DEVICE_TABLE(input, tsdev_ids); -- cgit v1.2.3 From ca56fe07f46e1c174b544e714be183f1476fecea Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Jun 2006 01:49:21 -0400 Subject: Input: rearrange exports New style is to mark symbol as exported right after its definition. Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index 7570a3f52f18..de2e7546b491 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -28,21 +28,6 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input core"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(input_allocate_device); -EXPORT_SYMBOL(input_free_device); -EXPORT_SYMBOL(input_register_device); -EXPORT_SYMBOL(input_unregister_device); -EXPORT_SYMBOL(input_register_handler); -EXPORT_SYMBOL(input_unregister_handler); -EXPORT_SYMBOL(input_grab_device); -EXPORT_SYMBOL(input_release_device); -EXPORT_SYMBOL(input_open_device); -EXPORT_SYMBOL(input_close_device); -EXPORT_SYMBOL(input_accept_process); -EXPORT_SYMBOL(input_flush_device); -EXPORT_SYMBOL(input_event); -EXPORT_SYMBOL_GPL(input_class); - #define INPUT_DEVICES 256 static LIST_HEAD(input_dev_list); @@ -196,6 +181,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in if (handle->open) handle->handler->event(handle, type, code, value); } +EXPORT_SYMBOL(input_event); static void input_repeat_key(unsigned long data) { @@ -218,6 +204,7 @@ int input_accept_process(struct input_handle *handle, struct file *file) return 0; } +EXPORT_SYMBOL(input_accept_process); int input_grab_device(struct input_handle *handle) { @@ -227,12 +214,14 @@ int input_grab_device(struct input_handle *handle) handle->dev->grab = handle; return 0; } +EXPORT_SYMBOL(input_grab_device); void input_release_device(struct input_handle *handle) { if (handle->dev->grab == handle) handle->dev->grab = NULL; } +EXPORT_SYMBOL(input_release_device); int input_open_device(struct input_handle *handle) { @@ -255,6 +244,7 @@ int input_open_device(struct input_handle *handle) return err; } +EXPORT_SYMBOL(input_open_device); int input_flush_device(struct input_handle* handle, struct file* file) { @@ -263,6 +253,7 @@ int input_flush_device(struct input_handle* handle, struct file* file) return 0; } +EXPORT_SYMBOL(input_flush_device); void input_close_device(struct input_handle *handle) { @@ -278,6 +269,7 @@ void input_close_device(struct input_handle *handle) mutex_unlock(&dev->mutex); } +EXPORT_SYMBOL(input_close_device); static void input_link_handle(struct input_handle *handle) { @@ -874,6 +866,7 @@ struct class input_class = { .release = input_dev_release, .uevent = input_dev_uevent, }; +EXPORT_SYMBOL_GPL(input_class); struct input_dev *input_allocate_device(void) { @@ -891,6 +884,7 @@ struct input_dev *input_allocate_device(void) return dev; } +EXPORT_SYMBOL(input_allocate_device); void input_free_device(struct input_dev *dev) { @@ -903,6 +897,7 @@ void input_free_device(struct input_dev *dev) input_put_device(dev); } } +EXPORT_SYMBOL(input_free_device); int input_register_device(struct input_dev *dev) { @@ -980,6 +975,7 @@ int input_register_device(struct input_dev *dev) fail1: class_device_del(&dev->cdev); return error; } +EXPORT_SYMBOL(input_register_device); void input_unregister_device(struct input_dev *dev) { @@ -1010,6 +1006,7 @@ void input_unregister_device(struct input_dev *dev) input_wakeup_procfs_readers(); } +EXPORT_SYMBOL(input_unregister_device); void input_register_handler(struct input_handler *handler) { @@ -1035,6 +1032,7 @@ void input_register_handler(struct input_handler *handler) input_wakeup_procfs_readers(); } +EXPORT_SYMBOL(input_register_handler); void input_unregister_handler(struct input_handler *handler) { @@ -1054,6 +1052,7 @@ void input_unregister_handler(struct input_handler *handler) input_wakeup_procfs_readers(); } +EXPORT_SYMBOL(input_unregister_handler); static int input_open_file(struct inode *inode, struct file *file) { -- cgit v1.2.3 From b9ab58dd8e771d30df110c56e785db1ae5e073df Mon Sep 17 00:00:00 2001 From: Jerome Pinot Date: Mon, 26 Jun 2006 01:51:23 -0400 Subject: Input: fix misspelling of Hangeul key Fix a mispelling of the korean alphabet name in the input subsystem. See http://en.wikipedia.org/wiki/Hangeul#Names for more details. KEY_HANGUEL left to not break people Signed-off-by: Jerome Pinot Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 0eb955ddc654..1bf61f00cbd2 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -150,7 +150,7 @@ static unsigned char atkbd_unxlate_table[128] = { #define ATKBD_RET_EMUL0 0xe0 #define ATKBD_RET_EMUL1 0xe1 #define ATKBD_RET_RELEASE 0xf0 -#define ATKBD_RET_HANGUEL 0xf1 +#define ATKBD_RET_HANGEUL 0xf1 #define ATKBD_RET_HANJA 0xf2 #define ATKBD_RET_ERR 0xff @@ -304,7 +304,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, if (atkbd->emul || (code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 && - code != ATKBD_RET_HANGUEL && code != ATKBD_RET_HANJA && + code != ATKBD_RET_HANGEUL && code != ATKBD_RET_HANJA && (code != ATKBD_RET_ERR || atkbd->err_xl) && (code != ATKBD_RET_BAT || atkbd->bat_xl))) { atkbd->release = code >> 7; @@ -333,8 +333,8 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, case ATKBD_RET_RELEASE: atkbd->release = 1; goto out; - case ATKBD_RET_HANGUEL: - atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3); + case ATKBD_RET_HANGEUL: + atkbd_report_key(atkbd->dev, regs, KEY_HANGEUL, 3); goto out; case ATKBD_RET_HANJA: atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3); -- cgit v1.2.3 From 0ae051a19092d36112b5ba60ff8b5df7a5d5d23b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Jun 2006 01:52:34 -0400 Subject: Input: atkbd - fix HANGEUL/HANJA keys Make atkbd report HANGEUL/HANJA keys by default and use correct scan codes for these keys (they were swapped). Also make sure their scancodes reported as EV_MSC/MSC_SCAN events. Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 208 ++++++++++++++++++++++++++--------------- 1 file changed, 131 insertions(+), 77 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 1bf61f00cbd2..ffde8f86e0fb 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -55,7 +55,7 @@ static int atkbd_softraw = 1; module_param_named(softraw, atkbd_softraw, bool, 0); MODULE_PARM_DESC(softraw, "Use software generated rawmode"); -static int atkbd_scroll = 0; +static int atkbd_scroll; module_param_named(scroll, atkbd_scroll, bool, 0); MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); @@ -150,8 +150,8 @@ static unsigned char atkbd_unxlate_table[128] = { #define ATKBD_RET_EMUL0 0xe0 #define ATKBD_RET_EMUL1 0xe1 #define ATKBD_RET_RELEASE 0xf0 -#define ATKBD_RET_HANGEUL 0xf1 -#define ATKBD_RET_HANJA 0xf2 +#define ATKBD_RET_HANJA 0xf1 +#define ATKBD_RET_HANGEUL 0xf2 #define ATKBD_RET_ERR 0xff #define ATKBD_KEY_UNKNOWN 0 @@ -170,6 +170,13 @@ static unsigned char atkbd_unxlate_table[128] = { #define ATKBD_LED_EVENT_BIT 0 #define ATKBD_REP_EVENT_BIT 1 +#define ATKBD_XL_ERR 0x01 +#define ATKBD_XL_BAT 0x02 +#define ATKBD_XL_ACK 0x04 +#define ATKBD_XL_NAK 0x08 +#define ATKBD_XL_HANGEUL 0x10 +#define ATKBD_XL_HANJA 0x20 + static struct { unsigned char keycode; unsigned char set2; @@ -211,8 +218,7 @@ struct atkbd { unsigned char emul; unsigned char resend; unsigned char release; - unsigned char bat_xl; - unsigned char err_xl; + unsigned long xl_bit; unsigned int last; unsigned long time; @@ -245,17 +251,65 @@ ATKBD_DEFINE_ATTR(set); ATKBD_DEFINE_ATTR(softrepeat); ATKBD_DEFINE_ATTR(softraw); +static const unsigned int xl_table[] = { + ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, + ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, +}; -static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value) +/* + * Checks if we should mangle the scancode to extract 'release' bit + * in translated mode. + */ +static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code) { - input_regs(dev, regs); - if (value == 3) { - input_report_key(dev, code, 1); - input_sync(dev); - input_report_key(dev, code, 0); - } else - input_event(dev, EV_KEY, code, value); - input_sync(dev); + int i; + + if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) + return 0; + + for (i = 0; i < ARRAY_SIZE(xl_table); i++) + if (code == xl_table[i]) + return test_bit(i, &xl_bit); + + return 1; +} + +/* + * Calculates new value of xl_bit so the driver can distinguish + * between make/break pair of scancodes for select keys and PS/2 + * protocol responses. + */ +static void atkbd_calculate_xl_bit(struct atkbd *atkbd, unsigned char code) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(xl_table); i++) { + if (!((code ^ xl_table[i]) & 0x7f)) { + if (code & 0x80) + __clear_bit(i, &atkbd->xl_bit); + else + __set_bit(i, &atkbd->xl_bit); + break; + } + } +} + +/* + * Encode the scancode, 0xe0 prefix, and high bit into a single integer, + * keeping kernel 2.4 compatibility for set 2 + */ +static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code) +{ + if (atkbd->set == 3) { + if (atkbd->emul == 1) + code |= 0x100; + } else { + code = (code & 0x7f) | ((code & 0x80) << 1); + if (atkbd->emul == 1) + code |= 0x80; + } + + return code; } /* @@ -267,9 +321,11 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct atkbd *atkbd = serio_get_drvdata(serio); + struct input_dev *dev = atkbd->dev; unsigned int code = data; - int scroll = 0, hscroll = 0, click = -1; + int scroll = 0, hscroll = 0, click = -1, add_release_event = 0; int value; + unsigned char keycode; #ifdef ATKBD_DEBUG printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); @@ -298,25 +354,17 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, if (!atkbd->enabled) goto out; - input_event(atkbd->dev, EV_MSC, MSC_RAW, code); + input_event(dev, EV_MSC, MSC_RAW, code); if (atkbd->translated) { - if (atkbd->emul || - (code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 && - code != ATKBD_RET_HANGEUL && code != ATKBD_RET_HANJA && - (code != ATKBD_RET_ERR || atkbd->err_xl) && - (code != ATKBD_RET_BAT || atkbd->bat_xl))) { + if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) { atkbd->release = code >> 7; code &= 0x7f; } - if (!atkbd->emul) { - if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f)) - atkbd->bat_xl = !(data >> 7); - if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f)) - atkbd->err_xl = !(data >> 7); - } + if (!atkbd->emul) + atkbd_calculate_xl_bit(atkbd, data); } switch (code) { @@ -333,47 +381,48 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, case ATKBD_RET_RELEASE: atkbd->release = 1; goto out; - case ATKBD_RET_HANGEUL: - atkbd_report_key(atkbd->dev, regs, KEY_HANGEUL, 3); + case ATKBD_RET_ACK: + case ATKBD_RET_NAK: + printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " + "Some program might be trying access hardware directly.\n", + data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); goto out; + case ATKBD_RET_HANGEUL: case ATKBD_RET_HANJA: - atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3); - goto out; + /* + * These keys do not report release and thus need to be + * flagged properly + */ + add_release_event = 1; + break; case ATKBD_RET_ERR: printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); goto out; } - if (atkbd->set != 3) - code = (code & 0x7f) | ((code & 0x80) << 1); - if (atkbd->emul) { - if (--atkbd->emul) - goto out; - code |= (atkbd->set != 3) ? 0x80 : 0x100; - } + code = atkbd_compat_scancode(atkbd, code); + + if (atkbd->emul && --atkbd->emul) + goto out; + + keycode = atkbd->keycode[code]; - if (atkbd->keycode[code] != ATKBD_KEY_NULL) - input_event(atkbd->dev, EV_MSC, MSC_SCAN, code); + if (keycode != ATKBD_KEY_NULL) + input_event(dev, EV_MSC, MSC_SCAN, code); - switch (atkbd->keycode[code]) { + switch (keycode) { case ATKBD_KEY_NULL: break; case ATKBD_KEY_UNKNOWN: - if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) { - printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, " - "like XFree86, might be trying access hardware directly.\n", - data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); - } else { - printk(KERN_WARNING "atkbd.c: Unknown key %s " - "(%s set %d, code %#x on %s).\n", - atkbd->release ? "released" : "pressed", - atkbd->translated ? "translated" : "raw", - atkbd->set, code, serio->phys); - printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x ' " - "to make it known.\n", - code & 0x80 ? "e0" : "", code & 0x7f); - } - input_sync(atkbd->dev); + printk(KERN_WARNING + "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", + atkbd->release ? "released" : "pressed", + atkbd->translated ? "translated" : "raw", + atkbd->set, code, serio->phys); + printk(KERN_WARNING + "atkbd.c: Use 'setkeycodes %s%02x ' to make it known.\n", + code & 0x80 ? "e0" : "", code & 0x7f); + input_sync(dev); break; case ATKBD_SCR_1: scroll = 1 - atkbd->release * 2; @@ -397,33 +446,35 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, hscroll = 1; break; default: - value = atkbd->release ? 0 : - (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key))); - - switch (value) { /* Workaround Toshiba laptop multiple keypress */ - case 0: - atkbd->last = 0; - break; - case 1: - atkbd->last = code; - atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2; - break; - case 2: - if (!time_after(jiffies, atkbd->time) && atkbd->last == code) - value = 1; - break; + if (atkbd->release) { + value = 0; + atkbd->last = 0; + } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { + /* Workaround Toshiba laptop multiple keypress */ + value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; + } else { + value = 1; + atkbd->last = code; + atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; } - atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value); + input_regs(dev, regs); + input_report_key(dev, keycode, value); + input_sync(dev); + + if (value && add_release_event) { + input_report_key(dev, keycode, 0); + input_sync(dev); + } } if (atkbd->scroll) { - input_regs(atkbd->dev, regs); + input_regs(dev, regs); if (click != -1) - input_report_key(atkbd->dev, BTN_MIDDLE, click); - input_report_rel(atkbd->dev, REL_WHEEL, scroll); - input_report_rel(atkbd->dev, REL_HWHEEL, hscroll); - input_sync(atkbd->dev); + input_report_key(dev, BTN_MIDDLE, click); + input_report_rel(dev, REL_WHEEL, scroll); + input_report_rel(dev, REL_HWHEEL, hscroll); + input_sync(dev); } atkbd->release = 0; @@ -764,6 +815,9 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++) atkbd->keycode[atkbd_scroll_keys[i].set2] = atkbd_scroll_keys[i].keycode; } + + atkbd->keycode[atkbd_compat_scancode(atkbd, ATKBD_RET_HANGEUL)] = KEY_HANGUEL; + atkbd->keycode[atkbd_compat_scancode(atkbd, ATKBD_RET_HANJA)] = KEY_HANJA; } /* -- cgit v1.2.3 From b0c9ad8e0ff154f8c4730b8c4383f49b846c97c4 Mon Sep 17 00:00:00 2001 From: Pozsar Balazs Date: Mon, 26 Jun 2006 01:56:08 -0400 Subject: Input: psmouse - add support for Intellimouse 4.0 Add support for the H-Wheel present on Microsoft Intellimouse 4.0 (AKA "tilt mouse") Signed-off-by: Pozsar Balazs Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 5f21532c24ff..8bc9f51ae6c2 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -150,9 +150,20 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg */ if (psmouse->type == PSMOUSE_IMEX) { - input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); - input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); - input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); + switch (packet[3] & 0xC0) { + case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ + input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); + break; + case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ + input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); + break; + case 0x00: + case 0xC0: + input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); + input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); + input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); + break; + } } /* @@ -466,9 +477,25 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) if (param[0] != 4) return -1; +/* Magic to enable horizontal scrolling on IntelliMouse 4.0 */ + param[0] = 200; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 80; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 40; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + + param[0] = 200; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 200; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 60; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (set_properties) { set_bit(BTN_MIDDLE, psmouse->dev->keybit); set_bit(REL_WHEEL, psmouse->dev->relbit); + set_bit(REL_HWHEEL, psmouse->dev->relbit); set_bit(BTN_SIDE, psmouse->dev->keybit); set_bit(BTN_EXTRA, psmouse->dev->keybit); -- cgit v1.2.3 From e2e8115b54aa6f159ac3dfec8d3d23b0af5fbfa0 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 26 Jun 2006 01:59:52 -0400 Subject: Input: iforce - remove some pointless casts The 'private' member of struct input_dev is a void*, so no need to cast it when assigning it to a struct iforce* variable. Signed-off-by: Jesper Juhl Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/iforce/iforce-main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index ab0a26b924ca..6d99e3c37884 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -86,7 +86,7 @@ static struct iforce_device iforce_device[] = { static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct iforce* iforce = (struct iforce*)(dev->private); + struct iforce* iforce = dev->private; unsigned char data[3]; if (type != EV_FF) @@ -138,7 +138,7 @@ static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned */ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) { - struct iforce* iforce = (struct iforce*)(dev->private); + struct iforce* iforce = dev->private; int id; int ret; int is_update; @@ -218,7 +218,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) */ static int iforce_erase_effect(struct input_dev *dev, int effect_id) { - struct iforce* iforce = (struct iforce*)(dev->private); + struct iforce* iforce = dev->private; int err = 0; struct iforce_core_effect* core_effect; -- cgit v1.2.3 From 9000195bb7ea959939b1e5fdad336e5bac59c9e9 Mon Sep 17 00:00:00 2001 From: Frank de Lange Date: Tue, 27 Jun 2006 01:48:24 -0400 Subject: Input: wistron - add mapping for Wistron MS 2111 Wistron MS 2111 (aka Medion 'Titanium' MD 9783, aka ALDI PC, aka Fujitsu-Siemens AMILO D7800, aka ...) has 5 extra buttons, map them. Unfortunately we only have DMI data for the Medion box. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/wistron_btns.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index e4e5be111c96..ccf0faeee5c1 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -285,6 +285,15 @@ static struct key_entry keymap_fujitsu_n3510[] = { { KE_END, 0 } }; +static struct key_entry keymap_wistron_ms2111[] = { + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_KEY, 0x13, KEY_PROG3 }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, + { KE_END, 0 } +}; + static struct key_entry keymap_wistron_ms2141[] = { { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, @@ -326,6 +335,7 @@ static struct key_entry keymap_aopen_1559as[] = { { KE_WIFI, 0x30, 0 }, { KE_KEY, 0x31, KEY_MAIL }, { KE_KEY, 0x36, KEY_WWW }, + { KE_END, 0 }, }; /* @@ -388,6 +398,15 @@ static struct dmi_system_id dmi_ids[] = { }, .driver_data = keymap_aopen_1559as }, + { + .callback = dmi_matched, + .ident = "Medion MD 9783", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), + DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), + }, + .driver_data = keymap_wistron_ms2111 + }, { NULL, } }; -- cgit v1.2.3 From e29419fffceb8ec36def3c922040e1ca7bcd3de5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 12 Jun 2006 15:20:16 -0700 Subject: [PATCH] 64bit resource: fix up printks for resources in misc drivers This is needed if we wish to change the size of the resource structures. Based on an original patch from Vivek Goyal Cc: Vivek Goyal Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/input/serio/ct82c710.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 096b6a0b5cca..1ac739ef2ffa 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -189,7 +189,7 @@ static int __devinit ct82c710_probe(struct platform_device *dev) strlcpy(ct82c710_port->name, "C&T 82c710 mouse port", sizeof(ct82c710_port->name)); snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys), - "isa%04lx/serio0", CT82C710_DATA); + "isa%16llx/serio0", (unsigned long long)CT82C710_DATA); serio_register_port(ct82c710_port); @@ -241,8 +241,8 @@ static int __init ct82c710_init(void) serio_register_port(ct82c710_port); - printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n", - CT82C710_DATA, CT82C710_IRQ); + printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", + (unsigned long long)CT82C710_DATA, CT82C710_IRQ); return 0; -- cgit v1.2.3 From e7374e48009a15a680d53bd1f9828b9b79a8aac9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 27 Jun 2006 08:30:31 -0400 Subject: Input: fix resetting name, phys and uniq when unregistering device It should be done before calling class_device_unregister() because it will destroy the device and free memory if there are no other references to the device. Signed-off-by: Dmitry Torokhov Signed-off-by: Linus Torvalds --- drivers/input/input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index de2e7546b491..a90486f5e491 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -998,12 +998,13 @@ void input_unregister_device(struct input_dev *dev) sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); - class_device_unregister(&dev->cdev); mutex_lock(&dev->mutex); dev->name = dev->phys = dev->uniq = NULL; mutex_unlock(&dev->mutex); + class_device_unregister(&dev->cdev); + input_wakeup_procfs_readers(); } EXPORT_SYMBOL(input_unregister_device); -- cgit v1.2.3 From f8b4c46c0c3667a56148a59bca54d945d246a3f3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 27 Jun 2006 23:42:17 -0400 Subject: Input: atkbd - fix hardware autorepeat Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index ffde8f86e0fb..ce1f10e8984b 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -459,7 +459,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, } input_regs(dev, regs); - input_report_key(dev, keycode, value); + input_event(dev, EV_KEY, keycode, value); input_sync(dev); if (value && add_release_event) { -- cgit v1.2.3 From 0a3a6d69b7e9f1d7fa5add7db528e7b81cbd422e Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn Date: Tue, 27 Jun 2006 23:42:33 -0400 Subject: Input: db9 - fix potential buffer overrun Fixes Coverity #id 483 Signed-off-by: Eric Sesterhenn Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/db9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 6f31f054d1bb..5080e15c6d30 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -584,7 +584,7 @@ static struct db9 __init *db9_probe(int parport, int mode) goto err_out; } - if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { + if (db9_mode->bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { printk(KERN_ERR "db9.c: specified parport is not bidirectional\n"); err = -EINVAL; goto err_put_pp; -- cgit v1.2.3