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
This commit is contained in:
Linus Torvalds 2007-05-11 09:56:05 -07:00
commit 5884c40668
13 changed files with 171 additions and 39 deletions

View file

@ -240,11 +240,94 @@ static inline void hidinput_pb_setup(struct input_dev *input)
} }
#endif #endif
static inline int match_scancode(int code, int scancode)
{
if (scancode == 0)
return 1;
return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode);
}
static inline int match_keycode(int code, int keycode)
{
if (keycode == 0)
return 1;
return (code == keycode);
}
static struct hid_usage *hidinput_find_key(struct hid_device *hid,
int scancode, int keycode)
{
int i, j, k;
struct hid_report *report;
struct hid_usage *usage;
for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
for (i = 0; i < report->maxfield; i++) {
for ( j = 0; j < report->field[i]->maxusage; j++) {
usage = report->field[i]->usage + j;
if (usage->type == EV_KEY &&
match_scancode(usage->hid, scancode) &&
match_keycode(usage->code, keycode))
return usage;
}
}
}
}
return NULL;
}
static int hidinput_getkeycode(struct input_dev *dev, int scancode,
int *keycode)
{
struct hid_device *hid = dev->private;
struct hid_usage *usage;
usage = hidinput_find_key(hid, scancode, 0);
if (usage) {
*keycode = usage->code;
return 0;
}
return -EINVAL;
}
static int hidinput_setkeycode(struct input_dev *dev, int scancode,
int keycode)
{
struct hid_device *hid = dev->private;
struct hid_usage *usage;
int old_keycode;
if (keycode < 0 || keycode > KEY_MAX)
return -EINVAL;
usage = hidinput_find_key(hid, scancode, 0);
if (usage) {
old_keycode = usage->code;
usage->code = keycode;
clear_bit(old_keycode, dev->keybit);
set_bit(usage->code, dev->keybit);
#ifdef CONFIG_HID_DEBUG
printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
#endif
/* Set the keybit for the old keycode if the old keycode is used
* by another key */
if (hidinput_find_key (hid, 0, old_keycode))
set_bit(old_keycode, dev->keybit);
return 0;
}
return -EINVAL;
}
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage) struct hid_usage *usage)
{ {
struct input_dev *input = hidinput->input; struct input_dev *input = hidinput->input;
struct hid_device *device = input->private; struct hid_device *device = input_get_drvdata(input);
int max = 0, code; int max = 0, code;
unsigned long *bit = NULL; unsigned long *bit = NULL;
@ -553,6 +636,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x1015: map_key_clear(KEY_RECORD); break; case 0x1015: map_key_clear(KEY_RECORD); break;
case 0x1016: map_key_clear(KEY_PLAYER); break; case 0x1016: map_key_clear(KEY_PLAYER); break;
case 0x1017: map_key_clear(KEY_EJECTCD); break; case 0x1017: map_key_clear(KEY_EJECTCD); break;
case 0x1018: map_key_clear(KEY_MEDIA); break;
case 0x1019: map_key_clear(KEY_PROG1); break; case 0x1019: map_key_clear(KEY_PROG1); break;
case 0x101a: map_key_clear(KEY_PROG2); break; case 0x101a: map_key_clear(KEY_PROG2); break;
case 0x101b: map_key_clear(KEY_PROG3); break; case 0x101b: map_key_clear(KEY_PROG3); break;
@ -560,9 +644,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x1020: map_key_clear(KEY_ZOOMOUT); break; case 0x1020: map_key_clear(KEY_ZOOMOUT); break;
case 0x1021: map_key_clear(KEY_ZOOMRESET); break; case 0x1021: map_key_clear(KEY_ZOOMRESET); break;
case 0x1023: map_key_clear(KEY_CLOSE); break; case 0x1023: map_key_clear(KEY_CLOSE); break;
case 0x1027: map_key_clear(KEY_MENU); break;
/* this one is marked as 'Rotate' */ /* this one is marked as 'Rotate' */
case 0x1028: map_key_clear(KEY_ANGLE); break; case 0x1028: map_key_clear(KEY_ANGLE); break;
case 0x1029: map_key_clear(KEY_SHUFFLE); break; case 0x1029: map_key_clear(KEY_SHUFFLE); break;
case 0x102a: map_key_clear(KEY_BACK); break;
case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break;
case 0x1041: map_key_clear(KEY_BATTERY); break; case 0x1041: map_key_clear(KEY_BATTERY); break;
case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break;
case 0x1043: map_key_clear(KEY_SPREADSHEET); break; case 0x1043: map_key_clear(KEY_SPREADSHEET); break;
@ -855,13 +942,15 @@ EXPORT_SYMBOL_GPL(hidinput_find_field);
static int hidinput_open(struct input_dev *dev) static int hidinput_open(struct input_dev *dev)
{ {
struct hid_device *hid = dev->private; struct hid_device *hid = input_get_drvdata(dev);
return hid->hid_open(hid); return hid->hid_open(hid);
} }
static void hidinput_close(struct input_dev *dev) static void hidinput_close(struct input_dev *dev)
{ {
struct hid_device *hid = dev->private; struct hid_device *hid = input_get_drvdata(dev);
hid->hid_close(hid); hid->hid_close(hid);
} }
@ -909,10 +998,12 @@ int hidinput_connect(struct hid_device *hid)
return -1; return -1;
} }
input_dev->private = hid; input_set_drvdata(input_dev, hid);
input_dev->event = hid->hidinput_input_event; input_dev->event = hid->hidinput_input_event;
input_dev->open = hidinput_open; input_dev->open = hidinput_open;
input_dev->close = hidinput_close; input_dev->close = hidinput_close;
input_dev->setkeycode = hidinput_setkeycode;
input_dev->getkeycode = hidinput_getkeycode;
input_dev->name = hid->name; input_dev->name = hid->name;
input_dev->phys = hid->phys; input_dev->phys = hid->phys;
@ -921,7 +1012,7 @@ int hidinput_connect(struct hid_device *hid)
input_dev->id.vendor = hid->vendor; input_dev->id.vendor = hid->vendor;
input_dev->id.product = hid->product; input_dev->id.product = hid->product;
input_dev->id.version = hid->version; input_dev->id.version = hid->version;
input_dev->cdev.dev = hid->dev; input_dev->dev.parent = hid->dev;
hidinput->input = input_dev; hidinput->input = input_dev;
list_add_tail(&hidinput->list, &hid->inputs); list_add_tail(&hidinput->list, &hid->inputs);
} }

View file

@ -25,12 +25,12 @@ comment "Input core support is needed for USB HID input layer or HIDBP support"
depends on USB_HID && INPUT=n depends on USB_HID && INPUT=n
config USB_HIDINPUT_POWERBOOK config USB_HIDINPUT_POWERBOOK
bool "Enable support for iBook/PowerBook special keys" bool "Enable support for iBook/PowerBook/MacBook/MacBookPro special keys"
default n default n
depends on USB_HID depends on USB_HID
help help
Say Y here if you want support for the special keys (Fn, Numlock) on 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. If unsure, say N.

View file

@ -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) 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; struct hid_field *field;
int offset; 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; struct usbhid_device *usbhid = hid->driver_data;
if (usbhid->inbuf) usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma); usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
if (usbhid->outbuf) usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma); usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_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);
} }
/* /*
@ -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) static struct hid_device *usb_hid_configure(struct usb_interface *intf)
{ {
struct usb_host_interface *interface = intf->cur_altsetting; 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) if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR)
hid_fixup_logitech_descriptor(rdesc, rsize); hid_fixup_logitech_descriptor(rdesc, rsize);
if (quirks & HID_QUIRK_SWAPPED_MIN_MAX)
hid_fixup_cypress_descriptor(rdesc, rsize);
#ifdef CONFIG_HID_DEBUG #ifdef CONFIG_HID_DEBUG
printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
for (n = 0; n < rsize; n++) for (n = 0; n < rsize; n++)

View file

@ -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) 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 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); struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
int x, y; int x, y;

View file

@ -37,7 +37,7 @@ struct plff_device {
static int hid_plff_play(struct input_dev *dev, void *data, static int hid_plff_play(struct input_dev *dev, void *data,
struct ff_effect *effect) struct ff_effect *effect)
{ {
struct hid_device *hid = dev->private; struct hid_device *hid = input_get_drvdata(dev);
struct plff_device *plff = data; struct plff_device *plff = data;
int left, right; int left, right;

View file

@ -92,6 +92,8 @@
#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 #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_VENDOR_ID_DELL 0x413c
#define USB_DEVICE_ID_DELL_W7658 0x2005 #define USB_DEVICE_ID_DELL_W7658 0x2005
@ -193,6 +195,7 @@
#define USB_VENDOR_ID_LOGITECH 0x046d #define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 #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 0xc50c
#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 #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_2PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, 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_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_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_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 }, { 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_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 } { 0, 0 }
}; };

View file

@ -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) 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; struct tmff_device *tmff = data;
int left, right; /* Rumbling */ int left, right; /* Rumbling */

View file

@ -37,7 +37,7 @@ struct zpff_device {
static int hid_zpff_play(struct input_dev *dev, void *data, static int hid_zpff_play(struct input_dev *dev, void *data,
struct ff_effect *effect) struct ff_effect *effect)
{ {
struct hid_device *hid = dev->private; struct hid_device *hid = input_get_drvdata(dev);
struct zpff_device *zpff = data; struct zpff_device *zpff = data;
int left, right; int left, right;

View file

@ -51,6 +51,7 @@ struct hiddev {
wait_queue_head_t wait; wait_queue_head_t wait;
struct hid_device *hid; struct hid_device *hid;
struct list_head list; struct list_head list;
spinlock_t list_lock;
}; };
struct hiddev_list { struct hiddev_list {
@ -161,7 +162,9 @@ static void hiddev_send_event(struct hid_device *hid,
{ {
struct hiddev *hiddev = hid->hiddev; struct hiddev *hiddev = hid->hiddev;
struct hiddev_list *list; struct hiddev_list *list;
unsigned long flags;
spin_lock_irqsave(&hiddev->list_lock, flags);
list_for_each_entry(list, &hiddev->list, node) { list_for_each_entry(list, &hiddev->list, node) {
if (uref->field_index != HID_FIELD_INDEX_NONE || if (uref->field_index != HID_FIELD_INDEX_NONE ||
(list->flags & HIDDEV_FLAG_REPORT) != 0) { (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); kill_fasync(&list->fasync, SIGIO, POLL_IN);
} }
} }
spin_unlock_irqrestore(&hiddev->list_lock, flags);
wake_up_interruptible(&hiddev->wait); 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) static int hiddev_release(struct inode * inode, struct file * file)
{ {
struct hiddev_list *list = file->private_data; struct hiddev_list *list = file->private_data;
unsigned long flags;
hiddev_fasync(-1, file, 0); hiddev_fasync(-1, file, 0);
spin_lock_irqsave(&list->hiddev->list_lock, flags);
list_del(&list->node); list_del(&list->node);
spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
if (!--list->hiddev->open) { if (!--list->hiddev->open) {
if (list->hiddev->exist) 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) static int hiddev_open(struct inode *inode, struct file *file)
{ {
struct hiddev_list *list; struct hiddev_list *list;
unsigned long flags;
int i = iminor(inode) - HIDDEV_MINOR_BASE; int i = iminor(inode) - HIDDEV_MINOR_BASE;
@ -267,7 +276,11 @@ static int hiddev_open(struct inode *inode, struct file *file)
return -ENOMEM; return -ENOMEM;
list->hiddev = hiddev_table[i]; list->hiddev = hiddev_table[i];
spin_lock_irqsave(&list->hiddev->list_lock, flags);
list_add_tail(&list->node, &hiddev_table[i]->list); list_add_tail(&list->node, &hiddev_table[i]->list);
spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
file->private_data = list; file->private_data = list;
if (!list->hiddev->open++) if (!list->hiddev->open++)
@ -773,6 +786,7 @@ int hiddev_connect(struct hid_device *hid)
init_waitqueue_head(&hiddev->wait); init_waitqueue_head(&hiddev->wait);
INIT_LIST_HEAD(&hiddev->list); INIT_LIST_HEAD(&hiddev->list);
spin_lock_init(&hiddev->list_lock);
hiddev->hid = hid; hiddev->hid = hid;
hiddev->exist = 1; hiddev->exist = 1;

View file

@ -133,12 +133,11 @@ static void usb_kbd_irq(struct urb *urb)
static int usb_kbd_event(struct input_dev *dev, unsigned int type, static int usb_kbd_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value) unsigned int code, int value)
{ {
struct usb_kbd *kbd = dev->private; struct usb_kbd *kbd = input_get_drvdata(dev);
if (type != EV_LED) if (type != EV_LED)
return -1; return -1;
kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) | 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_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) |
(!!test_bit(LED_NUML, dev->led)); (!!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) 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; kbd->irq->dev = kbd->usbdev;
if (usb_submit_urb(kbd->irq, GFP_KERNEL)) 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) 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); 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->irq);
usb_free_urb(kbd->led); usb_free_urb(kbd->led);
if (kbd->new) usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
usb_buffer_free(dev, 8, kbd->new, kbd->new_dma); usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
if (kbd->cr) usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
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);
} }
static int usb_kbd_probe(struct usb_interface *iface, 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->name = kbd->name;
input_dev->phys = kbd->phys; input_dev->phys = kbd->phys;
usb_to_input_id(dev, &input_dev->id); usb_to_input_id(dev, &input_dev->id);
input_dev->cdev.dev = &iface->dev; input_dev->dev.parent = &iface->dev;
input_dev->private = kbd;
input_set_drvdata(input_dev, kbd);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); 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); input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);

View file

@ -96,7 +96,7 @@ static void usb_mouse_irq(struct urb *urb)
static int usb_mouse_open(struct input_dev *dev) 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; mouse->irq->dev = mouse->usbdev;
if (usb_submit_urb(mouse->irq, GFP_KERNEL)) 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) 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); 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->name = mouse->name;
input_dev->phys = mouse->phys; input_dev->phys = mouse->phys;
usb_to_input_id(dev, &input_dev->id); 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->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); 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->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
input_dev->relbit[0] |= BIT(REL_WHEEL); 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->open = usb_mouse_open;
input_dev->close = usb_mouse_close; input_dev->close = usb_mouse_close;

View file

@ -275,6 +275,7 @@ struct hid_item {
#define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000 #define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000
#define HID_QUIRK_DUPLICATE_USAGES 0x00200000 #define HID_QUIRK_DUPLICATE_USAGES 0x00200000
#define HID_QUIRK_RESET_LEDS 0x00400000 #define HID_QUIRK_RESET_LEDS 0x00400000
#define HID_QUIRK_SWAPPED_MIN_MAX 0x00800000
/* /*
* This is the global environment of the parser. This information is * This is the global environment of the parser. This information is

View file

@ -737,10 +737,8 @@ static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_conn
list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
hidp_send_report(session, report); hidp_send_report(session, report);
if (hidinput_connect(hid) == 0) { if (hidinput_connect(hid) == 0)
hid->claimed |= HID_CLAIMED_INPUT; hid->claimed |= HID_CLAIMED_INPUT;
hid_ff_init(hid);
}
} }
int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)