Commit 93c10132 authored by Jiri Slaby's avatar Jiri Slaby Committed by Jiri Kosina

HID: move connect quirks

Move connecting from usbhid to the hid layer and fix also hidp in
that manner.
This removes all the ignore/force hidinput/hiddev connecting quirks.
Signed-off-by: default avatarJiri Slaby <jirislaby@gmail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent fea6f183
...@@ -107,7 +107,7 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -107,7 +107,7 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -309,6 +309,7 @@ static int apple_probe(struct hid_device *hdev, ...@@ -309,6 +309,7 @@ static int apple_probe(struct hid_device *hdev,
{ {
unsigned long quirks = id->driver_data; unsigned long quirks = id->driver_data;
struct apple_sc *asc; struct apple_sc *asc;
unsigned int connect_mask = HID_CONNECT_DEFAULT;
int ret; int ret;
/* return something else or move to hid layer? device will reside /* return something else or move to hid layer? device will reside
...@@ -328,18 +329,18 @@ static int apple_probe(struct hid_device *hdev, ...@@ -328,18 +329,18 @@ static int apple_probe(struct hid_device *hdev,
hid_set_drvdata(hdev, asc); hid_set_drvdata(hdev, asc);
if (quirks & APPLE_HIDDEV)
hdev->quirks |= HID_QUIRK_HIDDEV;
if (quirks & APPLE_IGNORE_HIDINPUT)
hdev->quirks |= HID_QUIRK_IGNORE_HIDINPUT;
ret = hid_parse(hdev); ret = hid_parse(hdev);
if (ret) { if (ret) {
dev_err(&hdev->dev, "parse failed\n"); dev_err(&hdev->dev, "parse failed\n");
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); if (quirks & APPLE_HIDDEV)
connect_mask |= HID_CONNECT_HIDDEV_FORCE;
if (quirks & APPLE_IGNORE_HIDINPUT)
connect_mask &= ~HID_CONNECT_HIDINPUT;
ret = hid_hw_start(hdev, connect_mask);
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -54,16 +54,14 @@ static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -54,16 +54,14 @@ static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id)
hid_set_drvdata(hdev, (void *)quirks); hid_set_drvdata(hdev, (void *)quirks);
if (quirks & BELKIN_HIDDEV)
hdev->quirks |= HID_QUIRK_HIDDEV;
ret = hid_parse(hdev); ret = hid_parse(hdev);
if (ret) { if (ret) {
dev_err(&hdev->dev, "parse failed\n"); dev_err(&hdev->dev, "parse failed\n");
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0));
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -1113,6 +1113,80 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i ...@@ -1113,6 +1113,80 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
} }
EXPORT_SYMBOL_GPL(hid_input_report); EXPORT_SYMBOL_GPL(hid_input_report);
int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
{
static const char *types[] = { "Device", "Pointer", "Mouse", "Device",
"Joystick", "Gamepad", "Keyboard", "Keypad",
"Multi-Axis Controller"
};
const char *type, *bus;
char buf[64];
unsigned int i;
int len;
if (hdev->bus != BUS_USB)
connect_mask &= ~HID_CONNECT_HIDDEV;
if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev,
connect_mask & HID_CONNECT_HIDINPUT_FORCE))
hdev->claimed |= HID_CLAIMED_INPUT;
if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect &&
!hdev->hiddev_connect(hdev,
connect_mask & HID_CONNECT_HIDDEV_FORCE))
hdev->claimed |= HID_CLAIMED_HIDDEV;
if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev))
hdev->claimed |= HID_CLAIMED_HIDRAW;
if (!hdev->claimed) {
dev_err(&hdev->dev, "claimed by neither input, hiddev nor "
"hidraw\n");
return -ENODEV;
}
if ((hdev->claimed & HID_CLAIMED_INPUT) &&
(connect_mask & HID_CONNECT_FF) && hdev->ff_init)
hdev->ff_init(hdev);
len = 0;
if (hdev->claimed & HID_CLAIMED_INPUT)
len += sprintf(buf + len, "input");
if (hdev->claimed & HID_CLAIMED_HIDDEV)
len += sprintf(buf + len, "%shiddev%d", len ? "," : "",
hdev->minor);
if (hdev->claimed & HID_CLAIMED_HIDRAW)
len += sprintf(buf + len, "%shidraw%d", len ? "," : "",
((struct hidraw *)hdev->hidraw)->minor);
type = "Device";
for (i = 0; i < hdev->maxcollection; i++) {
struct hid_collection *col = &hdev->collection[i];
if (col->type == HID_COLLECTION_APPLICATION &&
(col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK &&
(col->usage & 0xffff) < ARRAY_SIZE(types)) {
type = types[col->usage & 0xffff];
break;
}
}
switch (hdev->bus) {
case BUS_USB:
bus = "USB";
break;
case BUS_BLUETOOTH:
bus = "BLUETOOTH";
break;
default:
bus = "<UNKNOWN>";
}
dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n",
buf, bus, hdev->version >> 8, hdev->version & 0xff,
type, hdev->name, hdev->phys);
return 0;
}
EXPORT_SYMBOL_GPL(hid_connect);
static bool hid_match_one_id(struct hid_device *hdev, static bool hid_match_one_id(struct hid_device *hdev,
const struct hid_device_id *id) const struct hid_device_id *id)
{ {
...@@ -1238,7 +1312,7 @@ static int hid_device_probe(struct device *dev) ...@@ -1238,7 +1312,7 @@ static int hid_device_probe(struct device *dev)
} else { /* default probe */ } else { /* default probe */
ret = hid_parse(hdev); ret = hid_parse(hdev);
if (!ret) if (!ret)
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
} }
if (ret) if (ret)
hdev->driver = NULL; hdev->driver = NULL;
......
...@@ -110,7 +110,7 @@ static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -110,7 +110,7 @@ static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -34,7 +34,7 @@ static int dell_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -34,7 +34,7 @@ static int dell_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -700,7 +700,7 @@ static void hidinput_close(struct input_dev *dev) ...@@ -700,7 +700,7 @@ static void hidinput_close(struct input_dev *dev)
* Read all reports and initialize the absolute field values. * Read all reports and initialize the absolute field values.
*/ */
int hidinput_connect(struct hid_device *hid) int hidinput_connect(struct hid_device *hid, unsigned int force)
{ {
struct hid_report *report; struct hid_report *report;
struct hid_input *hidinput = NULL; struct hid_input *hidinput = NULL;
...@@ -708,19 +708,20 @@ int hidinput_connect(struct hid_device *hid) ...@@ -708,19 +708,20 @@ int hidinput_connect(struct hid_device *hid)
int i, j, k; int i, j, k;
int max_report_type = HID_OUTPUT_REPORT; int max_report_type = HID_OUTPUT_REPORT;
if (hid->quirks & HID_QUIRK_IGNORE_HIDINPUT)
return -1;
INIT_LIST_HEAD(&hid->inputs); INIT_LIST_HEAD(&hid->inputs);
for (i = 0; i < hid->maxcollection; i++) if (!force) {
if (hid->collection[i].type == HID_COLLECTION_APPLICATION || for (i = 0; i < hid->maxcollection; i++) {
hid->collection[i].type == HID_COLLECTION_PHYSICAL) struct hid_collection *col = &hid->collection[i];
if (IS_INPUT_APPLICATION(hid->collection[i].usage)) if (col->type == HID_COLLECTION_APPLICATION ||
col->type == HID_COLLECTION_PHYSICAL)
if (IS_INPUT_APPLICATION(col->usage))
break; break;
}
if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0) if (i == hid->maxcollection)
return -1; return -1;
}
if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
max_report_type = HID_INPUT_REPORT; max_report_type = HID_INPUT_REPORT;
......
...@@ -237,7 +237,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -237,7 +237,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -154,8 +154,6 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -154,8 +154,6 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
hid_set_drvdata(hdev, (void *)quirks); hid_set_drvdata(hdev, (void *)quirks);
if (quirks & MS_HIDINPUT)
hdev->quirks |= HID_QUIRK_HIDINPUT;
if (quirks & MS_NOGET) if (quirks & MS_NOGET)
hdev->quirks |= HID_QUIRK_NOGET; hdev->quirks |= HID_QUIRK_NOGET;
...@@ -165,7 +163,8 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -165,7 +163,8 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ?
HID_CONNECT_HIDINPUT_FORCE : 0));
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -80,7 +80,7 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -80,7 +80,7 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -52,15 +52,14 @@ static int samsung_probe(struct hid_device *hdev, ...@@ -52,15 +52,14 @@ static int samsung_probe(struct hid_device *hdev,
{ {
int ret; int ret;
hdev->quirks |= HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT;
ret = hid_parse(hdev); ret = hid_parse(hdev);
if (ret) { if (ret) {
dev_err(&hdev->dev, "parse failed\n"); dev_err(&hdev->dev, "parse failed\n");
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) |
HID_CONNECT_HIDDEV_FORCE);
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -57,15 +57,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -57,15 +57,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
{ {
int ret; int ret;
hdev->quirks |= HID_QUIRK_HIDDEV;
ret = hid_parse(hdev); ret = hid_parse(hdev);
if (ret) { if (ret) {
dev_err(&hdev->dev, "parse failed\n"); dev_err(&hdev->dev, "parse failed\n");
goto err_free; goto err_free;
} }
ret = hid_hw_start(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
HID_CONNECT_HIDDEV_FORCE);
if (ret) { if (ret) {
dev_err(&hdev->dev, "hw start failed\n"); dev_err(&hdev->dev, "hw start failed\n");
goto err_free; goto err_free;
......
...@@ -44,8 +44,6 @@ ...@@ -44,8 +44,6 @@
#define DRIVER_DESC "USB HID core driver" #define DRIVER_DESC "USB HID core driver"
#define DRIVER_LICENSE "GPL" #define DRIVER_LICENSE "GPL"
static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
"Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
/* /*
* Module parameters. * Module parameters.
*/ */
...@@ -670,70 +668,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) ...@@ -670,70 +668,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
} }
static int usbhid_start_finish(struct hid_device *hid)
{
struct usb_interface *intf = to_usb_interface(hid->dev.parent);
char path[64], *type;
unsigned int i;
usbhid_init_reports(hid);
hid_dump_device(hid);
if (hid->quirks & HID_QUIRK_RESET_LEDS)
usbhid_set_leds(hid);
if (!hidinput_connect(hid))
hid->claimed |= HID_CLAIMED_INPUT;
if (!hiddev_connect(hid))
hid->claimed |= HID_CLAIMED_HIDDEV;
if (!hidraw_connect(hid))
hid->claimed |= HID_CLAIMED_HIDRAW;
if (!hid->claimed) {
printk(KERN_ERR "HID device claimed by neither input, hiddev "
"nor hidraw\n");
return -ENODEV;
}
if ((hid->claimed & HID_CLAIMED_INPUT))
hid_ff_init(hid);
printk(KERN_INFO);
if (hid->claimed & HID_CLAIMED_INPUT)
printk("input");
if ((hid->claimed & HID_CLAIMED_INPUT) &&
((hid->claimed & HID_CLAIMED_HIDDEV) ||
hid->claimed & HID_CLAIMED_HIDRAW))
printk(",");
if (hid->claimed & HID_CLAIMED_HIDDEV)
printk("hiddev%d", hid->minor);
if ((hid->claimed & HID_CLAIMED_INPUT) &&
(hid->claimed & HID_CLAIMED_HIDDEV) &&
(hid->claimed & HID_CLAIMED_HIDRAW))
printk(",");
if (hid->claimed & HID_CLAIMED_HIDRAW)
printk("hidraw%d", ((struct hidraw *)hid->hidraw)->minor);
type = "Device";
for (i = 0; i < hid->maxcollection; i++) {
if (hid->collection[i].type == HID_COLLECTION_APPLICATION &&
(hid->collection[i].usage & HID_USAGE_PAGE) ==
HID_UP_GENDESK &&
(hid->collection[i].usage & 0xffff) <
ARRAY_SIZE(hid_types)) {
type = hid_types[hid->collection[i].usage & 0xffff];
break;
}
}
usb_make_path(interface_to_usbdev(intf), path, 63);
printk(": USB HID v%x.%02x %s [%s] on %s\n",
hid->version >> 8, hid->version & 0xff, type, hid->name, path);
return 0;
}
static int usbhid_parse(struct hid_device *hid) static int usbhid_parse(struct hid_device *hid)
{ {
struct usb_interface *intf = to_usb_interface(hid->dev.parent); struct usb_interface *intf = to_usb_interface(hid->dev.parent);
...@@ -923,9 +857,11 @@ static int usbhid_start(struct hid_device *hid) ...@@ -923,9 +857,11 @@ static int usbhid_start(struct hid_device *hid)
usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
ret = usbhid_start_finish(hid); usbhid_init_reports(hid);
if (ret) hid_dump_device(hid);
goto fail;
if (hid->quirks & HID_QUIRK_RESET_LEDS)
usbhid_set_leds(hid);
return 0; return 0;
...@@ -1000,7 +936,9 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1000,7 +936,9 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_set_intfdata(intf, hid); usb_set_intfdata(intf, hid);
hid->ll_driver = &usb_hid_driver; hid->ll_driver = &usb_hid_driver;
hid->hid_output_raw_report = usbhid_output_raw_report; hid->hid_output_raw_report = usbhid_output_raw_report;
hid->ff_init = hid_ff_init;
#ifdef CONFIG_USB_HIDDEV #ifdef CONFIG_USB_HIDDEV
hid->hiddev_connect = hiddev_connect;
hid->hiddev_hid_event = hiddev_hid_event; hid->hiddev_hid_event = hiddev_hid_event;
hid->hiddev_report_event = hiddev_report_event; hid->hiddev_report_event = hiddev_report_event;
#endif #endif
......
...@@ -790,21 +790,23 @@ static struct usb_class_driver hiddev_class = { ...@@ -790,21 +790,23 @@ static struct usb_class_driver hiddev_class = {
/* /*
* This is where hid.c calls us to connect a hid device to the hiddev driver * This is where hid.c calls us to connect a hid device to the hiddev driver
*/ */
int hiddev_connect(struct hid_device *hid) int hiddev_connect(struct hid_device *hid, unsigned int force)
{ {
struct hiddev *hiddev; struct hiddev *hiddev;
struct usbhid_device *usbhid = hid->driver_data; struct usbhid_device *usbhid = hid->driver_data;
int i;
int retval; int retval;
if (!force) {
unsigned int i;
for (i = 0; i < hid->maxcollection; i++) for (i = 0; i < hid->maxcollection; i++)
if (hid->collection[i].type == if (hid->collection[i].type ==
HID_COLLECTION_APPLICATION && HID_COLLECTION_APPLICATION &&
!IS_INPUT_APPLICATION(hid->collection[i].usage)) !IS_INPUT_APPLICATION(hid->collection[i].usage))
break; break;
if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0) if (i == hid->maxcollection)
return -1; return -1;
}
if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
return -1; return -1;
......
...@@ -246,6 +246,19 @@ struct hid_item { ...@@ -246,6 +246,19 @@ struct hid_item {
#define HID_OUTPUT_REPORT 1 #define HID_OUTPUT_REPORT 1
#define HID_FEATURE_REPORT 2 #define HID_FEATURE_REPORT 2
/*
* HID connect requests
*/
#define HID_CONNECT_HIDINPUT 0x01
#define HID_CONNECT_HIDINPUT_FORCE 0x02
#define HID_CONNECT_HIDRAW 0x04
#define HID_CONNECT_HIDDEV 0x08
#define HID_CONNECT_HIDDEV_FORCE 0x10
#define HID_CONNECT_FF 0x20
#define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \
HID_CONNECT_HIDDEV|HID_CONNECT_FF)
/* /*
* HID device quirks. * HID device quirks.
*/ */
...@@ -258,13 +271,10 @@ struct hid_item { ...@@ -258,13 +271,10 @@ struct hid_item {
#define HID_QUIRK_INVERT 0x00000001 #define HID_QUIRK_INVERT 0x00000001
#define HID_QUIRK_NOTOUCH 0x00000002 #define HID_QUIRK_NOTOUCH 0x00000002
#define HID_QUIRK_NOGET 0x00000008 #define HID_QUIRK_NOGET 0x00000008
#define HID_QUIRK_HIDDEV 0x00000010
#define HID_QUIRK_BADPAD 0x00000020 #define HID_QUIRK_BADPAD 0x00000020
#define HID_QUIRK_MULTI_INPUT 0x00000040 #define HID_QUIRK_MULTI_INPUT 0x00000040
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
#define HID_QUIRK_RESET_LEDS 0x00100000 #define HID_QUIRK_RESET_LEDS 0x00100000
#define HID_QUIRK_HIDINPUT 0x00200000
#define HID_QUIRK_IGNORE_HIDINPUT 0x01000000
#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
/* /*
...@@ -439,7 +449,11 @@ struct hid_device { /* device report descriptor */ ...@@ -439,7 +449,11 @@ struct hid_device { /* device report descriptor */
void *driver_data; void *driver_data;
/* temporary hid_ff handling (until moved to the drivers) */
int (*ff_init)(struct hid_device *);
/* hiddev event handler */ /* hiddev event handler */
int (*hiddev_connect)(struct hid_device *, unsigned int);
void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
struct hid_usage *, __s32); struct hid_usage *, __s32);
void (*hiddev_report_event) (struct hid_device *, struct hid_report *); void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
...@@ -610,7 +624,7 @@ extern void hid_unregister_driver(struct hid_driver *); ...@@ -610,7 +624,7 @@ extern void hid_unregister_driver(struct hid_driver *);
extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
extern int hidinput_connect(struct hid_device *); extern int hidinput_connect(struct hid_device *hid, unsigned int force);
extern void hidinput_disconnect(struct hid_device *); extern void hidinput_disconnect(struct hid_device *);
int hid_set_field(struct hid_field *, unsigned, __s32); int hid_set_field(struct hid_field *, unsigned, __s32);
...@@ -619,6 +633,7 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int ...@@ -619,6 +633,7 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
void hid_output_report(struct hid_report *report, __u8 *data); void hid_output_report(struct hid_report *report, __u8 *data);
struct hid_device *hid_allocate_device(void); struct hid_device *hid_allocate_device(void);
int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
int hid_connect(struct hid_device *hid, unsigned int connect_mask);
/** /**
* hid_map_usage - map usage input bits * hid_map_usage - map usage input bits
...@@ -700,14 +715,22 @@ static inline int __must_check hid_parse(struct hid_device *hdev) ...@@ -700,14 +715,22 @@ static inline int __must_check hid_parse(struct hid_device *hdev)
* hid_hw_start - start underlaying HW * hid_hw_start - start underlaying HW
* *
* @hdev: hid device * @hdev: hid device
* @connect_mask: which outputs to connect, see HID_CONNECT_*
* *
* Call this in probe function *after* hid_parse. This will setup HW buffers * Call this in probe function *after* hid_parse. This will setup HW buffers
* and start the device (if not deffered to device open). hid_hw_stop must be * and start the device (if not deffered to device open). hid_hw_stop must be
* called if this was successfull. * called if this was successfull.
*/ */
static inline int __must_check hid_hw_start(struct hid_device *hdev) static inline int __must_check hid_hw_start(struct hid_device *hdev,
unsigned int connect_mask)
{ {
return hdev->ll_driver->start(hdev); int ret = hdev->ll_driver->start(hdev);
if (ret || !connect_mask)
return ret;
ret = hid_connect(hdev, connect_mask);
if (ret)
hdev->ll_driver->stop(hdev);
return ret;
} }
/** /**
...@@ -749,7 +772,7 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; } ...@@ -749,7 +772,7 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
#endif #endif
#else #else
static inline int hid_ff_init(struct hid_device *hid) { return -1; } #define hid_ff_init NULL
#endif #endif
#ifdef CONFIG_HID_DEBUG #ifdef CONFIG_HID_DEBUG
......
...@@ -217,7 +217,7 @@ struct hid_field; ...@@ -217,7 +217,7 @@ struct hid_field;
struct hid_report; struct hid_report;
#ifdef CONFIG_USB_HIDDEV #ifdef CONFIG_USB_HIDDEV
int hiddev_connect(struct hid_device *); int hiddev_connect(struct hid_device *hid, unsigned int force);
void hiddev_disconnect(struct hid_device *); void hiddev_disconnect(struct hid_device *);
void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value); struct hid_usage *usage, __s32 value);
...@@ -225,7 +225,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report); ...@@ -225,7 +225,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report);
int __init hiddev_init(void); int __init hiddev_init(void);
void hiddev_exit(void); void hiddev_exit(void);
#else #else
static inline int hiddev_connect(struct hid_device *hid) { return -1; } static inline int hiddev_connect(struct hid_device *hid,
unsigned int force)
{ return -1; }
static inline void hiddev_disconnect(struct hid_device *hid) { } static inline void hiddev_disconnect(struct hid_device *hid) { }
static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value) { } struct hid_usage *usage, __s32 value) { }
......
...@@ -724,9 +724,6 @@ static int hidp_start(struct hid_device *hid) ...@@ -724,9 +724,6 @@ static int hidp_start(struct hid_device *hid)
report_list, list) report_list, list)
hidp_send_report(session, report); hidp_send_report(session, report);
if (hidinput_connect(hid) == 0)
hid->claimed |= HID_CLAIMED_INPUT;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment