Skip to content

Commit

Permalink
HID: move connect quirks
Browse files Browse the repository at this point in the history
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 <jirislaby@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
  • Loading branch information
Jiri Slaby authored and Jiri Kosina committed Oct 14, 2008
1 parent fea6f18 commit 93c1013
Show file tree
Hide file tree
Showing 17 changed files with 159 additions and 126 deletions.
2 changes: 1 addition & 1 deletion drivers/hid/hid-a4tech.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
13 changes: 7 additions & 6 deletions drivers/hid/hid-apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
6 changes: 2 additions & 4 deletions drivers/hid/hid-belkin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
76 changes: 75 additions & 1 deletion drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/hid/hid-cypress.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/hid/hid-dell.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 12 additions & 11 deletions drivers/hid/hid-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,27 +700,28 @@ 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;
struct input_dev *input_dev;
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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/hid/hid-logitech.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions drivers/hid/hid-microsoft.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/hid/hid-petalynx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions drivers/hid/hid-samsung.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions drivers/hid/hid-sony.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
76 changes: 7 additions & 69 deletions drivers/hid/usbhid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 93c1013

Please sign in to comment.