aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2014-04-01 13:05:09 -0400
committerJiri Kosina <jkosina@suse.cz>2014-04-01 13:05:09 -0400
commitad295b6d5739ab24880a31be403bbc8fab62e177 (patch)
treecd760a18bcfa6e59b8b63fc71e333ba394b1cd9c /drivers/hid/hid-core.c
parentba04a57b4acd05a764471b2accd02000f6641881 (diff)
parentc3d77fab51f40821de91a744e4b514e9e4e76a7c (diff)
Merge branch 'for-3.15/hid-core-ll-transport-cleanup' into for-linus
Conflicts: drivers/hid/hid-ids.h drivers/hid/hid-sony.c drivers/hid/i2c-hid/i2c-hid.c
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f36b3524caf1..3736f6a121b7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1248,6 +1248,11 @@ void hid_output_report(struct hid_report *report, __u8 *data)
1248} 1248}
1249EXPORT_SYMBOL_GPL(hid_output_report); 1249EXPORT_SYMBOL_GPL(hid_output_report);
1250 1250
1251static int hid_report_len(struct hid_report *report)
1252{
1253 return ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7;
1254}
1255
1251/* 1256/*
1252 * Allocator for buffer that is going to be passed to hid_output_report() 1257 * Allocator for buffer that is going to be passed to hid_output_report()
1253 */ 1258 */
@@ -1258,7 +1263,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
1258 * of implement() working on 8 byte chunks 1263 * of implement() working on 8 byte chunks
1259 */ 1264 */
1260 1265
1261 int len = ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7; 1266 int len = hid_report_len(report);
1262 1267
1263 return kmalloc(len, flags); 1268 return kmalloc(len, flags);
1264} 1269}
@@ -1314,6 +1319,41 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
1314 return report; 1319 return report;
1315} 1320}
1316 1321
1322/*
1323 * Implement a generic .request() callback, using .raw_request()
1324 * DO NOT USE in hid drivers directly, but through hid_hw_request instead.
1325 */
1326void __hid_request(struct hid_device *hid, struct hid_report *report,
1327 int reqtype)
1328{
1329 char *buf;
1330 int ret;
1331 int len;
1332
1333 buf = hid_alloc_report_buf(report, GFP_KERNEL);
1334 if (!buf)
1335 return;
1336
1337 len = hid_report_len(report);
1338
1339 if (reqtype == HID_REQ_SET_REPORT)
1340 hid_output_report(report, buf);
1341
1342 ret = hid->ll_driver->raw_request(hid, report->id, buf, len,
1343 report->type, reqtype);
1344 if (ret < 0) {
1345 dbg_hid("unable to complete request: %d\n", ret);
1346 goto out;
1347 }
1348
1349 if (reqtype == HID_REQ_GET_REPORT)
1350 hid_input_report(hid, report->type, buf, ret, 0);
1351
1352out:
1353 kfree(buf);
1354}
1355EXPORT_SYMBOL_GPL(__hid_request);
1356
1317int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, 1357int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
1318 int interrupt) 1358 int interrupt)
1319{ 1359{
@@ -1693,6 +1733,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1693 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, 1733 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
1694 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, 1734 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
1695 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, 1735 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
1736 { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) },
1696 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, 1737 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
1697 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, 1738 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
1698 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, 1739 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
@@ -2432,6 +2473,14 @@ int hid_add_device(struct hid_device *hdev)
2432 return -ENODEV; 2473 return -ENODEV;
2433 2474
2434 /* 2475 /*
2476 * Check for the mandatory transport channel.
2477 */
2478 if (!hdev->ll_driver->raw_request) {
2479 hid_err(hdev, "transport driver missing .raw_request()\n");
2480 return -EINVAL;
2481 }
2482
2483 /*
2435 * Read the device report descriptor once and use as template 2484 * Read the device report descriptor once and use as template
2436 * for the driver-specific modifications. 2485 * for the driver-specific modifications.
2437 */ 2486 */