[Trusty] UBUNTU: SAUCE: (no-up) Bluetooth: HIDP: Add back missing HID operations

Keng-Yu Lin kengyu at canonical.com
Fri Nov 14 12:40:00 UTC 2014


Due to a previous patch, hid_device no longer has hid_get_raw_report()
in its struct.

    commit aa6c390c4d59c9ff4fffd887e15783b2b793951b
    Author: Benjamin Tissoires <benjamin.tissoires at redhat.com>
    Date:   Wed Feb 5 16:33:22 2014 -0500

        HID: remove hid_get_raw_report in struct hid_device

        BugLink: http://bugs.launchpad.net/bugs/1305522

        dev->hid_get_raw_report(X) and hid_hw_raw_request(X, HID_REQ_GET_REPORT)
        are strictly equivalent. Switch the hid subsystem to the hid_hw notation
        and remove the field .hid_get_raw_report in struct hid_device.

        Reviewed-by: David Herrmann <dh.herrmann at gmail.com>
        Signed-off-by: Benjamin Tissoires <benjamin.tissoires at redhat.com>
        Signed-off-by: Jiri Kosina <jkosina at suse.cz>
        (cherry picked from commit cafebc058bf86e63fff5354864781d3de11e41d3)
        Acked-by: Brad Figg <brad.figg at canonical.com>
        Signed-off-by: Chia-Lin Kao <acelan.kao at canonical.com>
        Signed-off-by: Tim Gardner <tim.gardner at canonical.com>

And the net/bluetooth/hidp/core.c in Trusty tree has some mysterious changes
(I could not trace them back with git blame)
such as no .raw_request assignment in struct hid_ll_driver.
This broke things such as the battery strenth in hid-input.c.

This patch added back the missing HID operations and copied the necessary
code snippet from mainline.

The patch was tested on my Lenovo Thinkpad X240 and HP K4000 Bluetooth
keyboard.

Signed-off-by: Keng-Yu Lin <kengyu at canonical.com>
---
 net/bluetooth/hidp/core.c | 50 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 10 deletions(-)

diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index f41f637..6b73b86 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -353,17 +353,24 @@ err:
 	return ret;
 }
 
-static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
-		unsigned char report_type)
+static int hidp_set_raw_report(struct hid_device *hid, unsigned char reportnum,
+			       unsigned char *data, size_t count,
+			       unsigned char report_type)
 {
 	struct hidp_session *session = hid->driver_data;
 	int ret;
 
-	if (report_type == HID_OUTPUT_REPORT) {
-		report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
-		return hidp_send_intr_message(session, report_type,
-					      data, count);
-	} else if (report_type != HID_FEATURE_REPORT) {
+	switch (report_type) {
+	case HID_FEATURE_REPORT:
+		report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
+		break;
+	case HID_INPUT_REPORT:
+		report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_INPUT;
+		break;
+	case HID_OUTPUT_REPORT:
+		report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT;
+		break;
+	default:
 		return -EINVAL;
 	}
 
@@ -371,8 +378,8 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
 		return -ERESTARTSYS;
 
 	/* Set up our wait, and send the report request to the device. */
+	data[0] = reportnum;
 	set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
-	report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
 	ret = hidp_send_ctrl_message(session, report_type, data, count);
 	if (ret)
 		goto err;
@@ -411,6 +418,29 @@ err:
 	return ret;
 }
 
+static int hidp_output_report(struct hid_device *hid, __u8 *data, size_t count)
+{
+	struct hidp_session *session = hid->driver_data;
+
+	return hidp_send_intr_message(session,
+				      HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT,
+				      data, count);
+}
+
+static int hidp_raw_request(struct hid_device *hid, unsigned char reportnum,
+			    __u8 *buf, size_t len, unsigned char rtype,
+			    int reqtype)
+{
+	switch (reqtype) {
+	case HID_REQ_GET_REPORT:
+		return hidp_get_raw_report(hid, reportnum, buf, len, rtype);
+	case HID_REQ_SET_REPORT:
+		return hidp_set_raw_report(hid, reportnum, buf, len, rtype);
+	default:
+		return -EIO;
+	}
+}
+
 static void hidp_idle_timeout(unsigned long arg)
 {
 	struct hidp_session *session = (struct hidp_session *) arg;
@@ -740,6 +770,8 @@ static struct hid_ll_driver hidp_hid_driver = {
 	.open  = hidp_open,
 	.close = hidp_close,
 	.hidinput_input_event = hidp_hidinput_event,
+	.raw_request = hidp_raw_request,
+	.output_report = hidp_output_report,
 };
 
 /* This function sets up the hid device. It does not add it
@@ -787,8 +819,6 @@ static int hidp_setup_hid(struct hidp_session *session,
 	hid->dev.parent = &session->conn->hcon->dev;
 	hid->ll_driver = &hidp_hid_driver;
 
-	hid->hid_output_raw_report = hidp_output_raw_report;
-
 	/* True if device is blacklisted in drivers/hid/hid-core.c */
 	if (hid_ignore(hid)) {
 		hid_destroy_device(session->hid);
-- 
2.1.0





More information about the kernel-team mailing list