mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
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: Jiri Slaby <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
This commit is contained in:
parent
fea6f1833b
commit
93c10132a7
17 changed files with 159 additions and 126 deletions
|
|
@ -107,7 +107,7 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev);
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@ static int apple_probe(struct hid_device *hdev,
|
|||
{
|
||||
unsigned long quirks = id->driver_data;
|
||||
struct apple_sc *asc;
|
||||
unsigned int connect_mask = HID_CONNECT_DEFAULT;
|
||||
int ret;
|
||||
|
||||
/* return something else or move to hid layer? device will reside
|
||||
|
|
@ -328,18 +329,18 @@ static int apple_probe(struct hid_device *hdev,
|
|||
|
||||
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);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
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) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -54,16 +54,14 @@ static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
|
||||
hid_set_drvdata(hdev, (void *)quirks);
|
||||
|
||||
if (quirks & BELKIN_HIDDEV)
|
||||
hdev->quirks |= HID_QUIRK_HIDDEV;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
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) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
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,
|
||||
const struct hid_device_id *id)
|
||||
{
|
||||
|
|
@ -1238,7 +1312,7 @@ static int hid_device_probe(struct device *dev)
|
|||
} else { /* default probe */
|
||||
ret = hid_parse(hdev);
|
||||
if (!ret)
|
||||
ret = hid_hw_start(hdev);
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
}
|
||||
if (ret)
|
||||
hdev->driver = NULL;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev);
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ static int dell_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev);
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -700,7 +700,7 @@ static void hidinput_close(struct input_dev *dev)
|
|||
* 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_input *hidinput = NULL;
|
||||
|
|
@ -708,19 +708,20 @@ int hidinput_connect(struct hid_device *hid)
|
|||
int i, j, k;
|
||||
int max_report_type = HID_OUTPUT_REPORT;
|
||||
|
||||
if (hid->quirks & HID_QUIRK_IGNORE_HIDINPUT)
|
||||
return -1;
|
||||
|
||||
INIT_LIST_HEAD(&hid->inputs);
|
||||
|
||||
for (i = 0; i < hid->maxcollection; i++)
|
||||
if (hid->collection[i].type == HID_COLLECTION_APPLICATION ||
|
||||
hid->collection[i].type == HID_COLLECTION_PHYSICAL)
|
||||
if (IS_INPUT_APPLICATION(hid->collection[i].usage))
|
||||
break;
|
||||
if (!force) {
|
||||
for (i = 0; i < hid->maxcollection; i++) {
|
||||
struct hid_collection *col = &hid->collection[i];
|
||||
if (col->type == HID_COLLECTION_APPLICATION ||
|
||||
col->type == HID_COLLECTION_PHYSICAL)
|
||||
if (IS_INPUT_APPLICATION(col->usage))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0)
|
||||
return -1;
|
||||
if (i == hid->maxcollection)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
|
||||
max_report_type = HID_INPUT_REPORT;
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev);
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -154,8 +154,6 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
|
||||
hid_set_drvdata(hdev, (void *)quirks);
|
||||
|
||||
if (quirks & MS_HIDINPUT)
|
||||
hdev->quirks |= HID_QUIRK_HIDINPUT;
|
||||
if (quirks & MS_NOGET)
|
||||
hdev->quirks |= HID_QUIRK_NOGET;
|
||||
|
||||
|
|
@ -165,7 +163,8 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
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) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev);
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -52,15 +52,14 @@ static int samsung_probe(struct hid_device *hdev,
|
|||
{
|
||||
int ret;
|
||||
|
||||
hdev->quirks |= HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
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) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -57,15 +57,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
{
|
||||
int ret;
|
||||
|
||||
hdev->quirks |= HID_QUIRK_HIDDEV;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev);
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
|
||||
HID_CONNECT_HIDDEV_FORCE);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -44,8 +44,6 @@
|
|||
#define DRIVER_DESC "USB HID core driver"
|
||||
#define DRIVER_LICENSE "GPL"
|
||||
|
||||
static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
|
||||
"Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
|
||||
/*
|
||||
* Module parameters.
|
||||
*/
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(hid->dev.parent);
|
||||
|
|
@ -923,9 +857,11 @@ static int usbhid_start(struct hid_device *hid)
|
|||
usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
|
||||
usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
|
||||
|
||||
ret = usbhid_start_finish(hid);
|
||||
if (ret)
|
||||
goto fail;
|
||||
usbhid_init_reports(hid);
|
||||
hid_dump_device(hid);
|
||||
|
||||
if (hid->quirks & HID_QUIRK_RESET_LEDS)
|
||||
usbhid_set_leds(hid);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -1000,7 +936,9 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
usb_set_intfdata(intf, hid);
|
||||
hid->ll_driver = &usb_hid_driver;
|
||||
hid->hid_output_raw_report = usbhid_output_raw_report;
|
||||
hid->ff_init = hid_ff_init;
|
||||
#ifdef CONFIG_USB_HIDDEV
|
||||
hid->hiddev_connect = hiddev_connect;
|
||||
hid->hiddev_hid_event = hiddev_hid_event;
|
||||
hid->hiddev_report_event = hiddev_report_event;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
int hiddev_connect(struct hid_device *hid)
|
||||
int hiddev_connect(struct hid_device *hid, unsigned int force)
|
||||
{
|
||||
struct hiddev *hiddev;
|
||||
struct usbhid_device *usbhid = hid->driver_data;
|
||||
int i;
|
||||
int retval;
|
||||
|
||||
for (i = 0; i < hid->maxcollection; i++)
|
||||
if (hid->collection[i].type ==
|
||||
HID_COLLECTION_APPLICATION &&
|
||||
!IS_INPUT_APPLICATION(hid->collection[i].usage))
|
||||
break;
|
||||
if (!force) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < hid->maxcollection; i++)
|
||||
if (hid->collection[i].type ==
|
||||
HID_COLLECTION_APPLICATION &&
|
||||
!IS_INPUT_APPLICATION(hid->collection[i].usage))
|
||||
break;
|
||||
|
||||
if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0)
|
||||
return -1;
|
||||
if (i == hid->maxcollection)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
|
||||
return -1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue