Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 305028
b: refs/heads/master
c: 734c660
h: refs/heads/master
v: v3
  • Loading branch information
Henrik Rydberg authored and Jiri Kosina committed May 1, 2012
1 parent 6936c12 commit bddbca6
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4d53b8012f1f01ddb3f24db2031b042bb4cbd0d0
refs/heads/master: 734c660931095ae165c0db6ff60558fc4173bfd0
62 changes: 62 additions & 0 deletions trunk/drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,58 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
return NULL;
}

static void hid_scan_usage(struct hid_device *hid, u32 usage)
{
}

/*
* Scan a report descriptor before the device is added to the bus.
* Sets device groups and other properties that determine what driver
* to load.
*/
static int hid_scan_report(struct hid_device *hid)
{
unsigned int page = 0, delim = 0;
__u8 *start = hid->dev_rdesc;
__u8 *end = start + hid->dev_rsize;
unsigned int u, u_min = 0, u_max = 0;
struct hid_item item;

hid->group = HID_GROUP_GENERIC;
while ((start = fetch_item(start, end, &item)) != NULL) {
if (item.format != HID_ITEM_FORMAT_SHORT)
return -EINVAL;
if (item.type == HID_ITEM_TYPE_GLOBAL) {
if (item.tag == HID_GLOBAL_ITEM_TAG_USAGE_PAGE)
page = item_udata(&item) << 16;
} else if (item.type == HID_ITEM_TYPE_LOCAL) {
if (delim > 1)
break;
u = item_udata(&item);
if (item.size <= 2)
u += page;
switch (item.tag) {
case HID_LOCAL_ITEM_TAG_DELIMITER:
delim += !!u;
break;
case HID_LOCAL_ITEM_TAG_USAGE:
hid_scan_usage(hid, u);
break;
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
u_min = u;
break;
case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
u_max = u;
for (u = u_min; u <= u_max; u++)
hid_scan_usage(hid, u);
break;
}
}
}

return 0;
}

/**
* hid_parse_report - parse device report
*
Expand Down Expand Up @@ -2171,6 +2223,16 @@ int hid_add_device(struct hid_device *hdev)
if (!hdev->dev_rdesc)
return -ENODEV;

/*
* Scan generic devices for group information
*/
if (hid_ignore_special_drivers ||
!hid_match_id(hdev, hid_have_special_driver)) {
ret = hid_scan_report(hdev);
if (ret)
hid_warn(hdev, "bad device descriptor (%d)\n", ret);
}

/* XXX hack, any other cleaner solution after the driver core
* is converted to allow more than 20 bytes as the device name? */
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/linux/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,11 @@ struct hid_item {
#define HID_QUIRK_NO_IGNORE 0x40000000
#define HID_QUIRK_NO_INPUT_SYNC 0x80000000

/*
* HID device groups
*/
#define HID_GROUP_GENERIC 0x0001

/*
* This is the global environment of the parser. This information is
* persistent for main-items. The global environment can be saved and
Expand Down

0 comments on commit bddbca6

Please sign in to comment.