aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-01-29 09:03:36 -0500
committerJiri Kosina <jkosina@suse.cz>2010-02-03 09:41:52 -0500
commitd4bfa033ed84e0ae446eff445d107ffd5ee78df3 (patch)
tree20e76bfa4d6249e1d51dcca7aa29deb4f0cf8673
parentc80d292f137275a1ed88e6ed515ecb457051f1a4 (diff)
HID: make raw reports possible for both feature and output reports
In commit 2da31939a42 ("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 6bf8268f9a91f1 ("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>
-rw-r--r--drivers/hid/hidraw.c2
-rw-r--r--drivers/hid/usbhid/hid-core.c5
-rw-r--r--include/linux/hid.h2
-rw-r--r--net/bluetooth/hidp/core.c17
4 files changed, 19 insertions, 7 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index cdd136942bca..d04476700b7b 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -134,7 +134,7 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
134 goto out; 134 goto out;
135 } 135 }
136 136
137 ret = dev->hid_output_raw_report(dev, buf, count); 137 ret = dev->hid_output_raw_report(dev, buf, count, HID_OUTPUT_REPORT);
138out: 138out:
139 kfree(buf); 139 kfree(buf);
140 return ret; 140 return ret;
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index e2997a8d5e1b..caa16c057ce2 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -774,7 +774,8 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
774 return 0; 774 return 0;
775} 775}
776 776
777static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count) 777static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
778 unsigned char report_type)
778{ 779{
779 struct usbhid_device *usbhid = hid->driver_data; 780 struct usbhid_device *usbhid = hid->driver_data;
780 struct usb_device *dev = hid_to_usb_dev(hid); 781 struct usb_device *dev = hid_to_usb_dev(hid);
@@ -785,7 +786,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
785 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 786 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
786 HID_REQ_SET_REPORT, 787 HID_REQ_SET_REPORT,
787 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 788 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
788 ((HID_OUTPUT_REPORT + 1) << 8) | *buf, 789 ((report_type + 1) << 8) | *buf,
789 interface->desc.bInterfaceNumber, buf + 1, count - 1, 790 interface->desc.bInterfaceNumber, buf + 1, count - 1,
790 USB_CTRL_SET_TIMEOUT); 791 USB_CTRL_SET_TIMEOUT);
791 792
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 87093652dda8..3661a626941d 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -501,7 +501,7 @@ struct hid_device { /* device report descriptor */
501 void (*hiddev_report_event) (struct hid_device *, struct hid_report *); 501 void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
502 502
503 /* handler for raw output data, used by hidraw */ 503 /* handler for raw output data, used by hidraw */
504 int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t); 504 int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char);
505 505
506 /* debugging support via debugfs */ 506 /* debugging support via debugfs */
507 unsigned short debug; 507 unsigned short debug;
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 6cf526d06e21..37ba153c4cd4 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -313,10 +313,21 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
313 return hidp_queue_report(session, buf, rsize); 313 return hidp_queue_report(session, buf, rsize);
314} 314}
315 315
316static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count) 316static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
317 unsigned char report_type)
317{ 318{
318 if (hidp_send_ctrl_message(hid->driver_data, 319 switch (report_type) {
319 HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE, 320 case HID_FEATURE_REPORT:
321 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
322 break;
323 case HID_OUTPUT_REPORT:
324 report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
325 break;
326 default:
327 return -EINVAL;
328 }
329
330 if (hidp_send_ctrl_message(hid->driver_data, report_type,
320 data, count)) 331 data, count))
321 return -ENOMEM; 332 return -ENOMEM;
322 return count; 333 return count;