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); |
