diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 09:56:05 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 09:56:05 -0700 |
commit | 5884c40668a928bba017eaf54e2eb3c01c8a98e6 (patch) | |
tree | 240bdf1b015f0bc2ce8c1811bd0b528c1ef386c2 /drivers/hid/usbhid | |
parent | ee54d2d87a8158d14434c1a3274bd7f713105836 (diff) | |
parent | cdcb44e87bedcf5070eece61f89f9373a3810031 (diff) |
Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jikos/hid
* 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jikos/hid:
USB HID: hiddev - fix race between hiddev_send_event() and hiddev_release()
HID: add hooks for getkeycode() and setkeycode() methods
HID: switch to using input_dev->dev.parent
USB HID: Logitech wheel 0x046d/0xc294 needs HID_QUIRK_NOGET quirk
USB HID: usb_buffer_free() cleanup
USB HID: report descriptor of Cypress USB barcode readers needs fixup
Bluetooth HID: HIDP - don't initialize force feedback
USB HID: update CONFIG_USB_HIDINPUT_POWERBOOK description
HID: add input mappings for non-working keys on Logitech S510 remote
Diffstat (limited to 'drivers/hid/usbhid')
-rw-r--r-- | drivers/hid/usbhid/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 41 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-lgff.c | 2 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-plff.c | 2 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 7 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-tmff.c | 2 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-zpff.c | 2 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 14 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbkbd.c | 21 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbmouse.c | 9 |
10 files changed, 73 insertions, 31 deletions
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig index 7c87bdc538b..1b4b572f899 100644 --- a/drivers/hid/usbhid/Kconfig +++ b/drivers/hid/usbhid/Kconfig @@ -25,12 +25,12 @@ comment "Input core support is needed for USB HID input layer or HIDBP support" depends on USB_HID && INPUT=n config USB_HIDINPUT_POWERBOOK - bool "Enable support for iBook/PowerBook special keys" + bool "Enable support for iBook/PowerBook/MacBook/MacBookPro special keys" default n depends on USB_HID help Say Y here if you want support for the special keys (Fn, Numlock) on - Apple iBooks and PowerBooks. + Apple iBooks, PowerBooks, MacBooks and MacBook Pros. If unsure, say N. diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 91d610358d5..d91b9dac6df 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -446,7 +446,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct hid_device *hid = dev->private; + struct hid_device *hid = input_get_drvdata(dev); struct hid_field *field; int offset; @@ -626,14 +626,10 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) { struct usbhid_device *usbhid = hid->driver_data; - if (usbhid->inbuf) - usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma); - if (usbhid->outbuf) - usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma); - if (usbhid->cr) - usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma); - if (usbhid->ctrlbuf) - usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); + usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma); + usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma); + usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma); + usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); } /* @@ -692,6 +688,30 @@ static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize) } } +/* + * Some USB barcode readers from cypress have usage min and usage max in + * the wrong order + */ +static void hid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize) +{ + short fixed = 0; + int i; + + for (i = 0; i < rsize - 4; i++) { + if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) { + unsigned char tmp; + + rdesc[i] = 0x19; rdesc[i+2] = 0x29; + tmp = rdesc[i+3]; + rdesc[i+3] = rdesc[i+1]; + rdesc[i+1] = tmp; + } + } + + if (fixed) + info("Fixing up Cypress report descriptor"); +} + static struct hid_device *usb_hid_configure(struct usb_interface *intf) { struct usb_host_interface *interface = intf->cur_altsetting; @@ -758,6 +778,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR) hid_fixup_logitech_descriptor(rdesc, rsize); + if (quirks & HID_QUIRK_SWAPPED_MIN_MAX) + hid_fixup_cypress_descriptor(rdesc, rsize); + #ifdef CONFIG_HID_DEBUG printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); for (n = 0; n < rsize; n++) diff --git a/drivers/hid/usbhid/hid-lgff.c b/drivers/hid/usbhid/hid-lgff.c index 92d2553f17b..c5cd4107d6a 100644 --- a/drivers/hid/usbhid/hid-lgff.c +++ b/drivers/hid/usbhid/hid-lgff.c @@ -60,7 +60,7 @@ static const struct dev_type devices[] = { static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect) { - struct hid_device *hid = dev->private; + struct hid_device *hid = input_get_drvdata(dev); struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; struct hid_report *report = list_entry(report_list->next, struct hid_report, list); int x, y; diff --git a/drivers/hid/usbhid/hid-plff.c b/drivers/hid/usbhid/hid-plff.c index 76d2e6e14db..d6a8f2b49bd 100644 --- a/drivers/hid/usbhid/hid-plff.c +++ b/drivers/hid/usbhid/hid-plff.c @@ -37,7 +37,7 @@ struct plff_device { static int hid_plff_play(struct input_dev *dev, void *data, struct ff_effect *effect) { - struct hid_device *hid = dev->private; + struct hid_device *hid = input_get_drvdata(dev); struct plff_device *plff = data; int left, right; diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 17a87555e32..f6c4145dc20 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -92,6 +92,8 @@ #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 +#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 +#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 #define USB_VENDOR_ID_DELL 0x413c #define USB_DEVICE_ID_DELL_W7658 0x2005 @@ -193,6 +195,7 @@ #define USB_VENDOR_ID_LOGITECH 0x046d #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 +#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 #define USB_DEVICE_ID_S510_RECEIVER 0xc50c #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 #define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 @@ -422,6 +425,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, @@ -445,6 +449,9 @@ static const struct hid_blacklist { { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_SWAPPED_MIN_MAX }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_SWAPPED_MIN_MAX }, + { 0, 0 } }; diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c index ab67331620d..ab5ba6ef891 100644 --- a/drivers/hid/usbhid/hid-tmff.c +++ b/drivers/hid/usbhid/hid-tmff.c @@ -59,7 +59,7 @@ static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum) static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect) { - struct hid_device *hid = dev->private; + struct hid_device *hid = input_get_drvdata(dev); struct tmff_device *tmff = data; int left, right; /* Rumbling */ diff --git a/drivers/hid/usbhid/hid-zpff.c b/drivers/hid/usbhid/hid-zpff.c index 7bd8238ca21..a7fbffcdaf3 100644 --- a/drivers/hid/usbhid/hid-zpff.c +++ b/drivers/hid/usbhid/hid-zpff.c @@ -37,7 +37,7 @@ struct zpff_device { static int hid_zpff_play(struct input_dev *dev, void *data, struct ff_effect *effect) { - struct hid_device *hid = dev->private; + struct hid_device *hid = input_get_drvdata(dev); struct zpff_device *zpff = data; int left, right; diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index a8b3d66cd49..488d61bdbf2 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -51,6 +51,7 @@ struct hiddev { wait_queue_head_t wait; struct hid_device *hid; struct list_head list; + spinlock_t list_lock; }; struct hiddev_list { @@ -161,7 +162,9 @@ static void hiddev_send_event(struct hid_device *hid, { struct hiddev *hiddev = hid->hiddev; struct hiddev_list *list; + unsigned long flags; + spin_lock_irqsave(&hiddev->list_lock, flags); list_for_each_entry(list, &hiddev->list, node) { if (uref->field_index != HID_FIELD_INDEX_NONE || (list->flags & HIDDEV_FLAG_REPORT) != 0) { @@ -171,6 +174,7 @@ static void hiddev_send_event(struct hid_device *hid, kill_fasync(&list->fasync, SIGIO, POLL_IN); } } + spin_unlock_irqrestore(&hiddev->list_lock, flags); wake_up_interruptible(&hiddev->wait); } @@ -235,9 +239,13 @@ static int hiddev_fasync(int fd, struct file *file, int on) static int hiddev_release(struct inode * inode, struct file * file) { struct hiddev_list *list = file->private_data; + unsigned long flags; hiddev_fasync(-1, file, 0); + + spin_lock_irqsave(&list->hiddev->list_lock, flags); list_del(&list->node); + spin_unlock_irqrestore(&list->hiddev->list_lock, flags); if (!--list->hiddev->open) { if (list->hiddev->exist) @@ -257,6 +265,7 @@ static int hiddev_release(struct inode * inode, struct file * file) static int hiddev_open(struct inode *inode, struct file *file) { struct hiddev_list *list; + unsigned long flags; int i = iminor(inode) - HIDDEV_MINOR_BASE; @@ -267,7 +276,11 @@ static int hiddev_open(struct inode *inode, struct file *file) return -ENOMEM; list->hiddev = hiddev_table[i]; + + spin_lock_irqsave(&list->hiddev->list_lock, flags); list_add_tail(&list->node, &hiddev_table[i]->list); + spin_unlock_irqrestore(&list->hiddev->list_lock, flags); + file->private_data = list; if (!list->hiddev->open++) @@ -773,6 +786,7 @@ int hiddev_connect(struct hid_device *hid) init_waitqueue_head(&hiddev->wait); INIT_LIST_HEAD(&hiddev->list); + spin_lock_init(&hiddev->list_lock); hiddev->hid = hid; hiddev->exist = 1; diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index 65aa12e8d7b..13097878071 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c @@ -133,12 +133,11 @@ resubmit: static int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct usb_kbd *kbd = dev->private; + struct usb_kbd *kbd = input_get_drvdata(dev); if (type != EV_LED) return -1; - kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) | (!!test_bit(LED_NUML, dev->led)); @@ -175,7 +174,7 @@ static void usb_kbd_led(struct urb *urb) static int usb_kbd_open(struct input_dev *dev) { - struct usb_kbd *kbd = dev->private; + struct usb_kbd *kbd = input_get_drvdata(dev); kbd->irq->dev = kbd->usbdev; if (usb_submit_urb(kbd->irq, GFP_KERNEL)) @@ -186,7 +185,7 @@ static int usb_kbd_open(struct input_dev *dev) static void usb_kbd_close(struct input_dev *dev) { - struct usb_kbd *kbd = dev->private; + struct usb_kbd *kbd = input_get_drvdata(dev); usb_kill_urb(kbd->irq); } @@ -211,12 +210,9 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd) { usb_free_urb(kbd->irq); usb_free_urb(kbd->led); - if (kbd->new) - usb_buffer_free(dev, 8, kbd->new, kbd->new_dma); - if (kbd->cr) - usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma); - if (kbd->leds) - usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma); + usb_buffer_free(dev, 8, kbd->new, kbd->new_dma); + usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma); + usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma); } static int usb_kbd_probe(struct usb_interface *iface, @@ -274,8 +270,9 @@ static int usb_kbd_probe(struct usb_interface *iface, input_dev->name = kbd->name; input_dev->phys = kbd->phys; usb_to_input_id(dev, &input_dev->id); - input_dev->cdev.dev = &iface->dev; - input_dev->private = kbd; + input_dev->dev.parent = &iface->dev; + + input_set_drvdata(input_dev, kbd); input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c index 573776d865e..5345c73bcf6 100644 --- a/drivers/hid/usbhid/usbmouse.c +++ b/drivers/hid/usbhid/usbmouse.c @@ -96,7 +96,7 @@ resubmit: static int usb_mouse_open(struct input_dev *dev) { - struct usb_mouse *mouse = dev->private; + struct usb_mouse *mouse = input_get_drvdata(dev); mouse->irq->dev = mouse->usbdev; if (usb_submit_urb(mouse->irq, GFP_KERNEL)) @@ -107,7 +107,7 @@ static int usb_mouse_open(struct input_dev *dev) static void usb_mouse_close(struct input_dev *dev) { - struct usb_mouse *mouse = dev->private; + struct usb_mouse *mouse = input_get_drvdata(dev); usb_kill_urb(mouse->irq); } @@ -171,7 +171,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i input_dev->name = mouse->name; input_dev->phys = mouse->phys; usb_to_input_id(dev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; + input_dev->dev.parent = &intf->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); @@ -179,7 +179,8 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->private = mouse; + input_set_drvdata(input_dev, mouse); + input_dev->open = usb_mouse_open; input_dev->close = usb_mouse_close; |