aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-02-10 12:58:48 -0500
committerJiri Kosina <jkosina@suse.cz>2014-02-17 08:52:51 -0500
commit4fa5a7f76cc7b6ac87f57741edd2b124851d119f (patch)
tree02f12545996a893bf29d788375b8001e27a360e0 /drivers/hid/hid-core.c
parent706daeffaf36590efc77142f6a209bfe51804f36 (diff)
HID: core: implement generic .request()
.request() can be emulated through .raw_request() we can implement this emulation in hid-core, and make .request not mandatory for transport layer drivers. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Reviewed-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 026ab0fc06f7..b6ae69711d2a 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,44 @@ 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 if (!hid->ll_driver->raw_request)
1334 return;
1335
1336 buf = hid_alloc_report_buf(report, GFP_KERNEL);
1337 if (!buf)
1338 return;
1339
1340 len = hid_report_len(report);
1341
1342 if (reqtype == HID_REQ_SET_REPORT)
1343 hid_output_report(report, buf);
1344
1345 ret = hid->ll_driver->raw_request(hid, report->id, buf, len,
1346 report->type, reqtype);
1347 if (ret < 0) {
1348 dbg_hid("unable to complete request: %d\n", ret);
1349 goto out;
1350 }
1351
1352 if (reqtype == HID_REQ_GET_REPORT)
1353 hid_input_report(hid, report->type, buf, ret, 0);
1354
1355out:
1356 kfree(buf);
1357}
1358EXPORT_SYMBOL_GPL(__hid_request);
1359
1317int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, 1360int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
1318 int interrupt) 1361 int interrupt)
1319{ 1362{