diff options
| author | Alan Ott <alan@signal11.us> | 2011-01-23 22:50:18 -0500 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2011-02-17 07:23:14 -0500 |
| commit | 6d3bfb74341c2c1454fcf5ec9c4dd707011f78e5 (patch) | |
| tree | a39633616655a75caeb15eb8a69c8609b7c0469c | |
| parent | 8ef395310852710bb4237d918bbac53b22622ef0 (diff) | |
HID: Add HID Report Descriptor to sysfs
Add a new binary sysfs entry called report_descriptor which contains
the HID report descriptor.
Signed-off-by: Alan Ott <alan@signal11.us>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
| -rw-r--r-- | Documentation/ABI/testing/sysfs-driver-hid | 10 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 33 |
2 files changed, 43 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid b/Documentation/ABI/testing/sysfs-driver-hid new file mode 100644 index 000000000000..b6490e14fe83 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | What: For USB devices : /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/report_descriptor | ||
| 2 | For BT devices : /sys/class/bluetooth/hci<addr>/<hid-bus>:<vendor-id>:<product-id>.<num>/report_descriptor | ||
| 3 | Symlink : /sys/class/hidraw/hidraw<num>/device/report_descriptor | ||
| 4 | Date: Jan 2011 | ||
| 5 | KernelVersion: 2.0.39 | ||
| 6 | Contact: Alan Ott <alan@signal11.us> | ||
| 7 | Description: When read, this file returns the device's raw binary HID | ||
| 8 | report descriptor. | ||
| 9 | This file cannot be written. | ||
| 10 | Users: HIDAPI library (http://www.signal11.us/oss/hidapi) | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 2dcdf9ff02ea..5e0e4eea7065 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1159,6 +1159,32 @@ static bool hid_hiddev(struct hid_device *hdev) | |||
| 1159 | return !!hid_match_id(hdev, hid_hiddev_list); | 1159 | return !!hid_match_id(hdev, hid_hiddev_list); |
| 1160 | } | 1160 | } |
| 1161 | 1161 | ||
| 1162 | |||
| 1163 | static ssize_t | ||
| 1164 | read_report_descriptor(struct file *filp, struct kobject *kobj, | ||
| 1165 | struct bin_attribute *attr, | ||
| 1166 | char *buf, loff_t off, size_t count) | ||
| 1167 | { | ||
| 1168 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 1169 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 1170 | |||
| 1171 | if (off >= hdev->rsize) | ||
| 1172 | return 0; | ||
| 1173 | |||
| 1174 | if (off + count > hdev->rsize) | ||
| 1175 | count = hdev->rsize - off; | ||
| 1176 | |||
| 1177 | memcpy(buf, hdev->rdesc + off, count); | ||
| 1178 | |||
| 1179 | return count; | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | static struct bin_attribute dev_bin_attr_report_desc = { | ||
| 1183 | .attr = { .name = "report_descriptor", .mode = 0444 }, | ||
| 1184 | .read = read_report_descriptor, | ||
| 1185 | .size = HID_MAX_DESCRIPTOR_SIZE, | ||
| 1186 | }; | ||
| 1187 | |||
| 1162 | int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | 1188 | int hid_connect(struct hid_device *hdev, unsigned int connect_mask) |
| 1163 | { | 1189 | { |
| 1164 | static const char *types[] = { "Device", "Pointer", "Mouse", "Device", | 1190 | static const char *types[] = { "Device", "Pointer", "Mouse", "Device", |
| @@ -1169,6 +1195,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | |||
| 1169 | char buf[64]; | 1195 | char buf[64]; |
| 1170 | unsigned int i; | 1196 | unsigned int i; |
| 1171 | int len; | 1197 | int len; |
| 1198 | int ret; | ||
| 1172 | 1199 | ||
| 1173 | if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE) | 1200 | if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE) |
| 1174 | connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV); | 1201 | connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV); |
| @@ -1230,6 +1257,11 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | |||
| 1230 | bus = "<UNKNOWN>"; | 1257 | bus = "<UNKNOWN>"; |
| 1231 | } | 1258 | } |
| 1232 | 1259 | ||
| 1260 | ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc); | ||
| 1261 | if (ret) | ||
| 1262 | hid_warn(hdev, | ||
| 1263 | "can't create sysfs report descriptor attribute err: %d\n", ret); | ||
| 1264 | |||
| 1233 | hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n", | 1265 | hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n", |
| 1234 | buf, bus, hdev->version >> 8, hdev->version & 0xff, | 1266 | buf, bus, hdev->version >> 8, hdev->version & 0xff, |
| 1235 | type, hdev->name, hdev->phys); | 1267 | type, hdev->name, hdev->phys); |
| @@ -1240,6 +1272,7 @@ EXPORT_SYMBOL_GPL(hid_connect); | |||
| 1240 | 1272 | ||
| 1241 | void hid_disconnect(struct hid_device *hdev) | 1273 | void hid_disconnect(struct hid_device *hdev) |
| 1242 | { | 1274 | { |
| 1275 | device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc); | ||
| 1243 | if (hdev->claimed & HID_CLAIMED_INPUT) | 1276 | if (hdev->claimed & HID_CLAIMED_INPUT) |
| 1244 | hidinput_disconnect(hdev); | 1277 | hidinput_disconnect(hdev); |
| 1245 | if (hdev->claimed & HID_CLAIMED_HIDDEV) | 1278 | if (hdev->claimed & HID_CLAIMED_HIDDEV) |
