diff options
| -rw-r--r-- | drivers/hid/usbhid/hid-core.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 44df131d390a..f8ca312bae1b 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
| @@ -884,6 +884,38 @@ static int usbhid_get_raw_report(struct hid_device *hid, | |||
| 884 | return ret; | 884 | return ret; |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | static int usbhid_set_raw_report(struct hid_device *hid, unsigned int reportnum, | ||
| 888 | __u8 *buf, size_t count, unsigned char rtype) | ||
| 889 | { | ||
| 890 | struct usbhid_device *usbhid = hid->driver_data; | ||
| 891 | struct usb_device *dev = hid_to_usb_dev(hid); | ||
| 892 | struct usb_interface *intf = usbhid->intf; | ||
| 893 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
| 894 | int ret, skipped_report_id = 0; | ||
| 895 | |||
| 896 | /* Byte 0 is the report number. Report data starts at byte 1.*/ | ||
| 897 | buf[0] = reportnum; | ||
| 898 | if (buf[0] == 0x0) { | ||
| 899 | /* Don't send the Report ID */ | ||
| 900 | buf++; | ||
| 901 | count--; | ||
| 902 | skipped_report_id = 1; | ||
| 903 | } | ||
| 904 | |||
| 905 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
| 906 | HID_REQ_SET_REPORT, | ||
| 907 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
| 908 | ((rtype + 1) << 8) | reportnum, | ||
| 909 | interface->desc.bInterfaceNumber, buf, count, | ||
| 910 | USB_CTRL_SET_TIMEOUT); | ||
| 911 | /* count also the report id, if this was a numbered report. */ | ||
| 912 | if (ret > 0 && skipped_report_id) | ||
| 913 | ret++; | ||
| 914 | |||
| 915 | return ret; | ||
| 916 | } | ||
| 917 | |||
| 918 | |||
| 887 | static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, | 919 | static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, |
| 888 | unsigned char report_type) | 920 | unsigned char report_type) |
| 889 | { | 921 | { |
| @@ -936,6 +968,36 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co | |||
| 936 | return ret; | 968 | return ret; |
| 937 | } | 969 | } |
| 938 | 970 | ||
| 971 | static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count) | ||
| 972 | { | ||
| 973 | struct usbhid_device *usbhid = hid->driver_data; | ||
| 974 | struct usb_device *dev = hid_to_usb_dev(hid); | ||
| 975 | int actual_length, skipped_report_id = 0, ret; | ||
| 976 | |||
| 977 | if (!usbhid->urbout) | ||
| 978 | return -EIO; | ||
| 979 | |||
| 980 | if (buf[0] == 0x0) { | ||
| 981 | /* Don't send the Report ID */ | ||
| 982 | buf++; | ||
| 983 | count--; | ||
| 984 | skipped_report_id = 1; | ||
| 985 | } | ||
| 986 | |||
| 987 | ret = usb_interrupt_msg(dev, usbhid->urbout->pipe, | ||
| 988 | buf, count, &actual_length, | ||
| 989 | USB_CTRL_SET_TIMEOUT); | ||
| 990 | /* return the number of bytes transferred */ | ||
| 991 | if (ret == 0) { | ||
| 992 | ret = actual_length; | ||
| 993 | /* count also the report id */ | ||
| 994 | if (skipped_report_id) | ||
| 995 | ret++; | ||
| 996 | } | ||
| 997 | |||
| 998 | return ret; | ||
| 999 | } | ||
| 1000 | |||
| 939 | static void usbhid_restart_queues(struct usbhid_device *usbhid) | 1001 | static void usbhid_restart_queues(struct usbhid_device *usbhid) |
| 940 | { | 1002 | { |
| 941 | if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) | 1003 | if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) |
| @@ -1200,6 +1262,20 @@ static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int r | |||
| 1200 | } | 1262 | } |
| 1201 | } | 1263 | } |
| 1202 | 1264 | ||
| 1265 | static int usbhid_raw_request(struct hid_device *hid, unsigned char reportnum, | ||
| 1266 | __u8 *buf, size_t len, unsigned char rtype, | ||
| 1267 | int reqtype) | ||
| 1268 | { | ||
| 1269 | switch (reqtype) { | ||
| 1270 | case HID_REQ_GET_REPORT: | ||
| 1271 | return usbhid_get_raw_report(hid, reportnum, buf, len, rtype); | ||
| 1272 | case HID_REQ_SET_REPORT: | ||
| 1273 | return usbhid_set_raw_report(hid, reportnum, buf, len, rtype); | ||
| 1274 | default: | ||
| 1275 | return -EIO; | ||
| 1276 | } | ||
| 1277 | } | ||
| 1278 | |||
| 1203 | static int usbhid_idle(struct hid_device *hid, int report, int idle, | 1279 | static int usbhid_idle(struct hid_device *hid, int report, int idle, |
| 1204 | int reqtype) | 1280 | int reqtype) |
| 1205 | { | 1281 | { |
| @@ -1223,6 +1299,8 @@ static struct hid_ll_driver usb_hid_driver = { | |||
| 1223 | .power = usbhid_power, | 1299 | .power = usbhid_power, |
| 1224 | .request = usbhid_request, | 1300 | .request = usbhid_request, |
| 1225 | .wait = usbhid_wait_io, | 1301 | .wait = usbhid_wait_io, |
| 1302 | .raw_request = usbhid_raw_request, | ||
| 1303 | .output_report = usbhid_output_report, | ||
| 1226 | .idle = usbhid_idle, | 1304 | .idle = usbhid_idle, |
| 1227 | }; | 1305 | }; |
| 1228 | 1306 | ||
