Skip to content

Commit

Permalink
HID: make raw reports possible for both feature and output reports
Browse files Browse the repository at this point in the history
In commit 2da3193 ("Bluetooth: Implement raw output support for HIDP
layer"), support for Bluetooth hid_output_raw_report was added, but it
pushes the data to the intr socket instead of the ctrl one. This has been
fixed by 6bf8268 ("Bluetooth: Use the control channel for raw HID reports")

Still, it is necessary to distinguish whether the report in question should be
either FEATURE or OUTPUT. For this, we have to extend the generic HID API,
so that hid_output_raw_report() callback provides means to specify this
value so that it can be passed down to lower level hardware drivers (currently
Bluetooth and USB).

Based on original patch by Bastien Nocera <hadess@hadess.net>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
  • Loading branch information
Jiri Kosina committed Feb 3, 2010
1 parent c80d292 commit d4bfa03
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 7 deletions.
2 changes: 1 addition & 1 deletion drivers/hid/hidraw.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
goto out;
}

ret = dev->hid_output_raw_report(dev, buf, count);
ret = dev->hid_output_raw_report(dev, buf, count, HID_OUTPUT_REPORT);
out:
kfree(buf);
return ret;
Expand Down
5 changes: 3 additions & 2 deletions drivers/hid/usbhid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,8 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
return 0;
}

static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count)
static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
unsigned char report_type)
{
struct usbhid_device *usbhid = hid->driver_data;
struct usb_device *dev = hid_to_usb_dev(hid);
Expand All @@ -785,7 +786,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
HID_REQ_SET_REPORT,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
((HID_OUTPUT_REPORT + 1) << 8) | *buf,
((report_type + 1) << 8) | *buf,
interface->desc.bInterfaceNumber, buf + 1, count - 1,
USB_CTRL_SET_TIMEOUT);

Expand Down
2 changes: 1 addition & 1 deletion include/linux/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ struct hid_device { /* device report descriptor */
void (*hiddev_report_event) (struct hid_device *, struct hid_report *);

/* handler for raw output data, used by hidraw */
int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char);

/* debugging support via debugfs */
unsigned short debug;
Expand Down
17 changes: 14 additions & 3 deletions net/bluetooth/hidp/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,21 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
return hidp_queue_report(session, buf, rsize);
}

static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count)
static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
unsigned char report_type)
{
if (hidp_send_ctrl_message(hid->driver_data,
HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE,
switch (report_type) {
case HID_FEATURE_REPORT:
report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
break;
case HID_OUTPUT_REPORT:
report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
break;
default:
return -EINVAL;
}

if (hidp_send_ctrl_message(hid->driver_data, report_type,
data, count))
return -ENOMEM;
return count;
Expand Down

0 comments on commit d4bfa03

Please sign in to comment.