diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-02 19:24:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-02 19:24:28 -0400 |
commit | 0f1b1e6d73cb989ce2c071edc57deade3b084dfe (patch) | |
tree | 1bd8f2d3ea66dbc3fadd9a9ca522caa99d9b5277 /net | |
parent | 159d8133d0b54a501a41a66fe3a0e7d16405e36d (diff) | |
parent | 3ae821effdfea47dcb36b52e0a8dffd9757a96a6 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
- substantial cleanup of the generic and transport layers, in the
direction of an ultimate goal of making struct hid_device completely
transport independent, by Benjamin Tissoires
- cp2112 driver from David Barksdale
- a lot of fixes and new hardware support (Dualshock 4) to hid-sony
driver, by Frank Praznik
- support for Win 8.1 multitouch protocol by Andrew Duggan
- other smaller fixes / device ID additions
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (75 commits)
HID: sony: fix force feedback mismerge
HID: sony: Set the quriks flag for Bluetooth controllers
HID: sony: Fix Sixaxis cable state detection
HID: uhid: Add UHID_CREATE2 + UHID_INPUT2
HID: hyperv: fix _raw_request() prototype
HID: hyperv: Implement a stub raw_request() entry point
HID: hid-sensor-hub: fix sleeping function called from invalid context
HID: multitouch: add support for Win 8.1 multitouch touchpads
HID: remove hid_output_raw_report transport implementations
HID: sony: do not rely on hid_output_raw_report
HID: cp2112: remove the last hid_output_raw_report() call
HID: cp2112: remove various hid_out_raw_report calls
HID: multitouch: add support of other generic collections in hid-mt
HID: multitouch: remove pen special handling
HID: multitouch: remove registered devices with default behavior
HID: hidp: Add a comment that some devices depend on the current behavior of uniq
HID: sony: Prevent duplicate controller connections.
HID: sony: Perform a boundry check on the sixaxis battery level index.
HID: sony: Fix work queue issues
HID: sony: Fix multi-line comment styling
...
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hidp/core.c | 100 |
1 files changed, 43 insertions, 57 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index d9fb93451442..8181ea4bc2f2 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -223,51 +223,6 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) | |||
223 | input_sync(dev); | 223 | input_sync(dev); |
224 | } | 224 | } |
225 | 225 | ||
226 | static int hidp_send_report(struct hidp_session *session, struct hid_report *report) | ||
227 | { | ||
228 | unsigned char hdr; | ||
229 | u8 *buf; | ||
230 | int rsize, ret; | ||
231 | |||
232 | buf = hid_alloc_report_buf(report, GFP_ATOMIC); | ||
233 | if (!buf) | ||
234 | return -EIO; | ||
235 | |||
236 | hid_output_report(report, buf); | ||
237 | hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; | ||
238 | |||
239 | rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); | ||
240 | ret = hidp_send_intr_message(session, hdr, buf, rsize); | ||
241 | |||
242 | kfree(buf); | ||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, | ||
247 | unsigned int code, int value) | ||
248 | { | ||
249 | struct hid_device *hid = input_get_drvdata(dev); | ||
250 | struct hidp_session *session = hid->driver_data; | ||
251 | struct hid_field *field; | ||
252 | int offset; | ||
253 | |||
254 | BT_DBG("session %p type %d code %d value %d", | ||
255 | session, type, code, value); | ||
256 | |||
257 | if (type != EV_LED) | ||
258 | return -1; | ||
259 | |||
260 | offset = hidinput_find_field(hid, type, code, &field); | ||
261 | if (offset == -1) { | ||
262 | hid_warn(dev, "event field not found\n"); | ||
263 | return -1; | ||
264 | } | ||
265 | |||
266 | hid_set_field(field, offset, value); | ||
267 | |||
268 | return hidp_send_report(session, field->report); | ||
269 | } | ||
270 | |||
271 | static int hidp_get_raw_report(struct hid_device *hid, | 226 | static int hidp_get_raw_report(struct hid_device *hid, |
272 | unsigned char report_number, | 227 | unsigned char report_number, |
273 | unsigned char *data, size_t count, | 228 | unsigned char *data, size_t count, |
@@ -353,17 +308,24 @@ err: | |||
353 | return ret; | 308 | return ret; |
354 | } | 309 | } |
355 | 310 | ||
356 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, | 311 | static int hidp_set_raw_report(struct hid_device *hid, unsigned char reportnum, |
357 | unsigned char report_type) | 312 | unsigned char *data, size_t count, |
313 | unsigned char report_type) | ||
358 | { | 314 | { |
359 | struct hidp_session *session = hid->driver_data; | 315 | struct hidp_session *session = hid->driver_data; |
360 | int ret; | 316 | int ret; |
361 | 317 | ||
362 | if (report_type == HID_OUTPUT_REPORT) { | 318 | switch (report_type) { |
363 | report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; | 319 | case HID_FEATURE_REPORT: |
364 | return hidp_send_intr_message(session, report_type, | 320 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; |
365 | data, count); | 321 | break; |
366 | } else if (report_type != HID_FEATURE_REPORT) { | 322 | case HID_INPUT_REPORT: |
323 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_INPUT; | ||
324 | break; | ||
325 | case HID_OUTPUT_REPORT: | ||
326 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT; | ||
327 | break; | ||
328 | default: | ||
367 | return -EINVAL; | 329 | return -EINVAL; |
368 | } | 330 | } |
369 | 331 | ||
@@ -371,8 +333,8 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s | |||
371 | return -ERESTARTSYS; | 333 | return -ERESTARTSYS; |
372 | 334 | ||
373 | /* Set up our wait, and send the report request to the device. */ | 335 | /* Set up our wait, and send the report request to the device. */ |
336 | data[0] = reportnum; | ||
374 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | 337 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); |
375 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; | ||
376 | ret = hidp_send_ctrl_message(session, report_type, data, count); | 338 | ret = hidp_send_ctrl_message(session, report_type, data, count); |
377 | if (ret) | 339 | if (ret) |
378 | goto err; | 340 | goto err; |
@@ -411,6 +373,29 @@ err: | |||
411 | return ret; | 373 | return ret; |
412 | } | 374 | } |
413 | 375 | ||
376 | static int hidp_output_report(struct hid_device *hid, __u8 *data, size_t count) | ||
377 | { | ||
378 | struct hidp_session *session = hid->driver_data; | ||
379 | |||
380 | return hidp_send_intr_message(session, | ||
381 | HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT, | ||
382 | data, count); | ||
383 | } | ||
384 | |||
385 | static int hidp_raw_request(struct hid_device *hid, unsigned char reportnum, | ||
386 | __u8 *buf, size_t len, unsigned char rtype, | ||
387 | int reqtype) | ||
388 | { | ||
389 | switch (reqtype) { | ||
390 | case HID_REQ_GET_REPORT: | ||
391 | return hidp_get_raw_report(hid, reportnum, buf, len, rtype); | ||
392 | case HID_REQ_SET_REPORT: | ||
393 | return hidp_set_raw_report(hid, reportnum, buf, len, rtype); | ||
394 | default: | ||
395 | return -EIO; | ||
396 | } | ||
397 | } | ||
398 | |||
414 | static void hidp_idle_timeout(unsigned long arg) | 399 | static void hidp_idle_timeout(unsigned long arg) |
415 | { | 400 | { |
416 | struct hidp_session *session = (struct hidp_session *) arg; | 401 | struct hidp_session *session = (struct hidp_session *) arg; |
@@ -739,7 +724,8 @@ static struct hid_ll_driver hidp_hid_driver = { | |||
739 | .stop = hidp_stop, | 724 | .stop = hidp_stop, |
740 | .open = hidp_open, | 725 | .open = hidp_open, |
741 | .close = hidp_close, | 726 | .close = hidp_close, |
742 | .hidinput_input_event = hidp_hidinput_event, | 727 | .raw_request = hidp_raw_request, |
728 | .output_report = hidp_output_report, | ||
743 | }; | 729 | }; |
744 | 730 | ||
745 | /* This function sets up the hid device. It does not add it | 731 | /* This function sets up the hid device. It does not add it |
@@ -781,15 +767,15 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
781 | snprintf(hid->phys, sizeof(hid->phys), "%pMR", | 767 | snprintf(hid->phys, sizeof(hid->phys), "%pMR", |
782 | &l2cap_pi(session->ctrl_sock->sk)->chan->src); | 768 | &l2cap_pi(session->ctrl_sock->sk)->chan->src); |
783 | 769 | ||
770 | /* NOTE: Some device modules depend on the dst address being stored in | ||
771 | * uniq. Please be aware of this before making changes to this behavior. | ||
772 | */ | ||
784 | snprintf(hid->uniq, sizeof(hid->uniq), "%pMR", | 773 | snprintf(hid->uniq, sizeof(hid->uniq), "%pMR", |
785 | &l2cap_pi(session->ctrl_sock->sk)->chan->dst); | 774 | &l2cap_pi(session->ctrl_sock->sk)->chan->dst); |
786 | 775 | ||
787 | hid->dev.parent = &session->conn->hcon->dev; | 776 | hid->dev.parent = &session->conn->hcon->dev; |
788 | hid->ll_driver = &hidp_hid_driver; | 777 | hid->ll_driver = &hidp_hid_driver; |
789 | 778 | ||
790 | hid->hid_get_raw_report = hidp_get_raw_report; | ||
791 | hid->hid_output_raw_report = hidp_output_raw_report; | ||
792 | |||
793 | /* True if device is blacklisted in drivers/hid/hid-core.c */ | 779 | /* True if device is blacklisted in drivers/hid/hid-core.c */ |
794 | if (hid_ignore(hid)) { | 780 | if (hid_ignore(hid)) { |
795 | hid_destroy_device(session->hid); | 781 | hid_destroy_device(session->hid); |