diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hid/hid-core.c | 33 |
1 files changed, 33 insertions, 0 deletions
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) |