소스 검색

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
Linus Torvalds 18 년 전
부모
커밋
5884c40668

+ 96 - 5
drivers/hid/hid-input.c

@@ -240,11 +240,94 @@ static inline void hidinput_pb_setup(struct input_dev *input)
 }
 #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,
 				     struct hid_usage *usage)
 {
 	struct input_dev *input = hidinput->input;
-	struct hid_device *device = input->private;
+	struct hid_device *device = input_get_drvdata(input);
 	int max = 0, code;
 	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 0x1016: map_key_clear(KEY_PLAYER);		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 0x101a: map_key_clear(KEY_PROG2);		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 0x1021: map_key_clear(KEY_ZOOMRESET);	break;
 				case 0x1023: map_key_clear(KEY_CLOSE);		break;
+				case 0x1027: map_key_clear(KEY_MENU);           break;
 				/* this one is marked as 'Rotate' */
 				case 0x1028: map_key_clear(KEY_ANGLE);		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 0x1042: map_key_clear(KEY_WORDPROCESSOR);	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)
 {
-	struct hid_device *hid = dev->private;
+	struct hid_device *hid = input_get_drvdata(dev);
+
 	return hid->hid_open(hid);
 }
 
 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);
 }
 
@@ -909,10 +998,12 @@ int hidinput_connect(struct hid_device *hid)
 					return -1;
 				}
 
-				input_dev->private = hid;
+				input_set_drvdata(input_dev, hid);
 				input_dev->event = hid->hidinput_input_event;
 				input_dev->open = hidinput_open;
 				input_dev->close = hidinput_close;
+				input_dev->setkeycode = hidinput_setkeycode;
+				input_dev->getkeycode = hidinput_getkeycode;
 
 				input_dev->name = hid->name;
 				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.product = hid->product;
 				input_dev->id.version = hid->version;
-				input_dev->cdev.dev = hid->dev;
+				input_dev->dev.parent = hid->dev;
 				hidinput->input = input_dev;
 				list_add_tail(&hidinput->list, &hid->inputs);
 			}

+ 2 - 2
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.
 

+ 32 - 9
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++)

+ 1 - 1
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;

+ 1 - 1
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;
 

+ 7 - 0
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 }
 };
 

+ 1 - 1
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 */
 

+ 1 - 1
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;
 

+ 14 - 0
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;
 

+ 9 - 12
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);

+ 5 - 4
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;
 

+ 1 - 0
include/linux/hid.h

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

+ 1 - 3
net/bluetooth/hidp/core.c

@@ -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)
 		hidp_send_report(session, report);
 
-	if (hidinput_connect(hid) == 0) {
+	if (hidinput_connect(hid) == 0)
 		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)