aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hidp/core.c107
1 files changed, 52 insertions, 55 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 292e619db896..77c4badb3e9d 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
226static 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
246static 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
271static int hidp_get_raw_report(struct hid_device *hid, 226static 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
356static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, 311static 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,41 @@ err:
411 return ret; 373 return ret;
412} 374}
413 375
376static 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
385static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data,
386 size_t count, unsigned char report_type)
387{
388 if (report_type == HID_OUTPUT_REPORT) {
389 return hidp_output_report(hid, data, count);
390 } else if (report_type != HID_FEATURE_REPORT) {
391 return -EINVAL;
392 }
393
394 return hidp_set_raw_report(hid, data[0], data, count, report_type);
395}
396
397static int hidp_raw_request(struct hid_device *hid, unsigned char reportnum,
398 __u8 *buf, size_t len, unsigned char rtype,
399 int reqtype)
400{
401 switch (reqtype) {
402 case HID_REQ_GET_REPORT:
403 return hidp_get_raw_report(hid, reportnum, buf, len, rtype);
404 case HID_REQ_SET_REPORT:
405 return hidp_set_raw_report(hid, reportnum, buf, len, rtype);
406 default:
407 return -EIO;
408 }
409}
410
414static void hidp_idle_timeout(unsigned long arg) 411static void hidp_idle_timeout(unsigned long arg)
415{ 412{
416 struct hidp_session *session = (struct hidp_session *) arg; 413 struct hidp_session *session = (struct hidp_session *) arg;
@@ -727,7 +724,8 @@ static struct hid_ll_driver hidp_hid_driver = {
727 .stop = hidp_stop, 724 .stop = hidp_stop,
728 .open = hidp_open, 725 .open = hidp_open,
729 .close = hidp_close, 726 .close = hidp_close,
730 .hidinput_input_event = hidp_hidinput_event, 727 .raw_request = hidp_raw_request,
728 .output_report = hidp_output_report,
731}; 729};
732 730
733/* 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
@@ -775,7 +773,6 @@ static int hidp_setup_hid(struct hidp_session *session,
775 hid->dev.parent = &session->conn->hcon->dev; 773 hid->dev.parent = &session->conn->hcon->dev;
776 hid->ll_driver = &hidp_hid_driver; 774 hid->ll_driver = &hidp_hid_driver;
777 775
778 hid->hid_get_raw_report = hidp_get_raw_report;
779 hid->hid_output_raw_report = hidp_output_raw_report; 776 hid->hid_output_raw_report = hidp_output_raw_report;
780 777
781 /* True if device is blacklisted in drivers/hid/hid-core.c */ 778 /* True if device is blacklisted in drivers/hid/hid-core.c */