diff options
| -rw-r--r-- | Documentation/hid/hid-transport.txt | 316 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 45 | ||||
| -rw-r--r-- | drivers/hid/hid-input.c | 12 | ||||
| -rw-r--r-- | drivers/hid/hid-lg.c | 6 | ||||
| -rw-r--r-- | drivers/hid/hid-logitech-dj.c | 111 | ||||
| -rw-r--r-- | drivers/hid/hid-magicmouse.c | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-sony.c | 9 | ||||
| -rw-r--r-- | drivers/hid/hid-thingm.c | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-wacom.c | 28 | ||||
| -rw-r--r-- | drivers/hid/hid-wiimote-core.c | 4 | ||||
| -rw-r--r-- | drivers/hid/hidraw.c | 9 | ||||
| -rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 81 | ||||
| -rw-r--r-- | drivers/hid/uhid.c | 24 | ||||
| -rw-r--r-- | drivers/hid/usbhid/hid-core.c | 107 | ||||
| -rw-r--r-- | include/linux/hid.h | 87 | ||||
| -rw-r--r-- | net/bluetooth/hidp/core.c | 107 |
16 files changed, 714 insertions, 240 deletions
diff --git a/Documentation/hid/hid-transport.txt b/Documentation/hid/hid-transport.txt new file mode 100644 index 000000000000..9dbbceaef4f3 --- /dev/null +++ b/Documentation/hid/hid-transport.txt | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | HID I/O Transport Drivers | ||
| 2 | =========================== | ||
| 3 | |||
| 4 | The HID subsystem is independent of the underlying transport driver. Initially, | ||
| 5 | only USB was supported, but other specifications adopted the HID design and | ||
| 6 | provided new transport drivers. The kernel includes at least support for USB, | ||
| 7 | Bluetooth, I2C and user-space I/O drivers. | ||
| 8 | |||
| 9 | 1) HID Bus | ||
| 10 | ========== | ||
| 11 | |||
| 12 | The HID subsystem is designed as a bus. Any I/O subsystem may provide HID | ||
| 13 | devices and register them with the HID bus. HID core then loads generic device | ||
| 14 | drivers on top of it. The transport drivers are responsible of raw data | ||
| 15 | transport and device setup/management. HID core is responsible of | ||
| 16 | report-parsing, report interpretation and the user-space API. Device specifics | ||
| 17 | and quirks are handled by all layers depending on the quirk. | ||
| 18 | |||
| 19 | +-----------+ +-----------+ +-----------+ +-----------+ | ||
| 20 | | Device #1 | | Device #i | | Device #j | | Device #k | | ||
| 21 | +-----------+ +-----------+ +-----------+ +-----------+ | ||
| 22 | \\ // \\ // | ||
| 23 | +------------+ +------------+ | ||
| 24 | | I/O Driver | | I/O Driver | | ||
| 25 | +------------+ +------------+ | ||
| 26 | || || | ||
| 27 | +------------------+ +------------------+ | ||
| 28 | | Transport Driver | | Transport Driver | | ||
| 29 | +------------------+ +------------------+ | ||
| 30 | \___ ___/ | ||
| 31 | \ / | ||
| 32 | +----------------+ | ||
| 33 | | HID Core | | ||
| 34 | +----------------+ | ||
| 35 | / | | \ | ||
| 36 | / | | \ | ||
| 37 | ____________/ | | \_________________ | ||
| 38 | / | | \ | ||
| 39 | / | | \ | ||
| 40 | +----------------+ +-----------+ +------------------+ +------------------+ | ||
| 41 | | Generic Driver | | MT Driver | | Custom Driver #1 | | Custom Driver #2 | | ||
| 42 | +----------------+ +-----------+ +------------------+ +------------------+ | ||
| 43 | |||
| 44 | Example Drivers: | ||
| 45 | I/O: USB, I2C, Bluetooth-l2cap | ||
| 46 | Transport: USB-HID, I2C-HID, BT-HIDP | ||
| 47 | |||
| 48 | Everything below "HID Core" is simplified in this graph as it is only of | ||
| 49 | interest to HID device drivers. Transport drivers do not need to know the | ||
| 50 | specifics. | ||
| 51 | |||
| 52 | 1.1) Device Setup | ||
| 53 | ----------------- | ||
| 54 | |||
| 55 | I/O drivers normally provide hotplug detection or device enumeration APIs to the | ||
| 56 | transport drivers. Transport drivers use this to find any suitable HID device. | ||
| 57 | They allocate HID device objects and register them with HID core. Transport | ||
| 58 | drivers are not required to register themselves with HID core. HID core is never | ||
| 59 | aware of which transport drivers are available and is not interested in it. It | ||
| 60 | is only interested in devices. | ||
| 61 | |||
| 62 | Transport drivers attach a constant "struct hid_ll_driver" object with each | ||
| 63 | device. Once a device is registered with HID core, the callbacks provided via | ||
| 64 | this struct are used by HID core to communicate with the device. | ||
| 65 | |||
| 66 | Transport drivers are responsible of detecting device failures and unplugging. | ||
| 67 | HID core will operate a device as long as it is registered regardless of any | ||
| 68 | device failures. Once transport drivers detect unplug or failure events, they | ||
| 69 | must unregister the device from HID core and HID core will stop using the | ||
| 70 | provided callbacks. | ||
| 71 | |||
| 72 | 1.2) Transport Driver Requirements | ||
| 73 | ---------------------------------- | ||
| 74 | |||
| 75 | The terms "asynchronous" and "synchronous" in this document describe the | ||
| 76 | transmission behavior regarding acknowledgements. An asynchronous channel must | ||
| 77 | not perform any synchronous operations like waiting for acknowledgements or | ||
| 78 | verifications. Generally, HID calls operating on asynchronous channels must be | ||
| 79 | running in atomic-context just fine. | ||
| 80 | On the other hand, synchronous channels can be implemented by the transport | ||
| 81 | driver in whatever way they like. They might just be the same as asynchronous | ||
| 82 | channels, but they can also provide acknowledgement reports, automatic | ||
| 83 | retransmission on failure, etc. in a blocking manner. If such functionality is | ||
| 84 | required on asynchronous channels, a transport-driver must implement that via | ||
| 85 | its own worker threads. | ||
| 86 | |||
| 87 | HID core requires transport drivers to follow a given design. A Transport | ||
| 88 | driver must provide two bi-directional I/O channels to each HID device. These | ||
| 89 | channels must not necessarily be bi-directional in the hardware itself. A | ||
| 90 | transport driver might just provide 4 uni-directional channels. Or it might | ||
| 91 | multiplex all four on a single physical channel. However, in this document we | ||
| 92 | will describe them as two bi-directional channels as they have several | ||
| 93 | properties in common. | ||
| 94 | |||
| 95 | - Interrupt Channel (intr): The intr channel is used for asynchronous data | ||
| 96 | reports. No management commands or data acknowledgements are sent on this | ||
| 97 | channel. Any unrequested incoming or outgoing data report must be sent on | ||
| 98 | this channel and is never acknowledged by the remote side. Devices usually | ||
| 99 | send their input events on this channel. Outgoing events are normally | ||
| 100 | not send via intr, except if high throughput is required. | ||
| 101 | - Control Channel (ctrl): The ctrl channel is used for synchronous requests and | ||
| 102 | device management. Unrequested data input events must not be sent on this | ||
| 103 | channel and are normally ignored. Instead, devices only send management | ||
| 104 | events or answers to host requests on this channel. | ||
| 105 | The control-channel is used for direct blocking queries to the device | ||
| 106 | independent of any events on the intr-channel. | ||
| 107 | Outgoing reports are usually sent on the ctrl channel via synchronous | ||
| 108 | SET_REPORT requests. | ||
| 109 | |||
| 110 | Communication between devices and HID core is mostly done via HID reports. A | ||
| 111 | report can be of one of three types: | ||
| 112 | |||
| 113 | - INPUT Report: Input reports provide data from device to host. This | ||
| 114 | data may include button events, axis events, battery status or more. This | ||
| 115 | data is generated by the device and sent to the host with or without | ||
| 116 | requiring explicit requests. Devices can choose to send data continuously or | ||
| 117 | only on change. | ||
| 118 | - OUTPUT Report: Output reports change device states. They are sent from host | ||
| 119 | to device and may include LED requests, rumble requests or more. Output | ||
| 120 | reports are never sent from device to host, but a host can retrieve their | ||
| 121 | current state. | ||
| 122 | Hosts may choose to send output reports either continuously or only on | ||
| 123 | change. | ||
| 124 | - FEATURE Report: Feature reports are used for specific static device features | ||
| 125 | and never reported spontaneously. A host can read and/or write them to access | ||
| 126 | data like battery-state or device-settings. | ||
| 127 | Feature reports are never sent without requests. A host must explicitly set | ||
| 128 | or retrieve a feature report. This also means, feature reports are never sent | ||
| 129 | on the intr channel as this channel is asynchronous. | ||
| 130 | |||
| 131 | INPUT and OUTPUT reports can be sent as pure data reports on the intr channel. | ||
| 132 | For INPUT reports this is the usual operational mode. But for OUTPUT reports, | ||
| 133 | this is rarely done as OUTPUT reports are normally quite scarce. But devices are | ||
| 134 | free to make excessive use of asynchronous OUTPUT reports (for instance, custom | ||
| 135 | HID audio speakers make great use of it). | ||
| 136 | |||
| 137 | Plain reports must not be sent on the ctrl channel, though. Instead, the ctrl | ||
| 138 | channel provides synchronous GET/SET_REPORT requests. Plain reports are only | ||
| 139 | allowed on the intr channel and are the only means of data there. | ||
| 140 | |||
| 141 | - GET_REPORT: A GET_REPORT request has a report ID as payload and is sent | ||
| 142 | from host to device. The device must answer with a data report for the | ||
| 143 | requested report ID on the ctrl channel as a synchronous acknowledgement. | ||
| 144 | Only one GET_REPORT request can be pending for each device. This restriction | ||
| 145 | is enforced by HID core as several transport drivers don't allow multiple | ||
| 146 | simultaneous GET_REPORT requests. | ||
| 147 | Note that data reports which are sent as answer to a GET_REPORT request are | ||
| 148 | not handled as generic device events. That is, if a device does not operate | ||
| 149 | in continuous data reporting mode, an answer to GET_REPORT does not replace | ||
| 150 | the raw data report on the intr channel on state change. | ||
| 151 | GET_REPORT is only used by custom HID device drivers to query device state. | ||
| 152 | Normally, HID core caches any device state so this request is not necessary | ||
| 153 | on devices that follow the HID specs except during device initialization to | ||
| 154 | retrieve the current state. | ||
| 155 | GET_REPORT requests can be sent for any of the 3 report types and shall | ||
| 156 | return the current report state of the device. However, OUTPUT reports as | ||
| 157 | payload may be blocked by the underlying transport driver if the | ||
| 158 | specification does not allow them. | ||
| 159 | - SET_REPORT: A SET_REPORT request has a report ID plus data as payload. It is | ||
| 160 | sent from host to device and a device must update it's current report state | ||
| 161 | according to the given data. Any of the 3 report types can be used. However, | ||
| 162 | INPUT reports as payload might be blocked by the underlying transport driver | ||
| 163 | if the specification does not allow them. | ||
| 164 | A device must answer with a synchronous acknowledgement. However, HID core | ||
| 165 | does not require transport drivers to forward this acknowledgement to HID | ||
| 166 | core. | ||
| 167 | Same as for GET_REPORT, only one SET_REPORT can be pending at a time. This | ||
| 168 | restriction is enforced by HID core as some transport drivers do not support | ||
| 169 | multiple synchronous SET_REPORT requests. | ||
| 170 | |||
| 171 | Other ctrl-channel requests are supported by USB-HID but are not available | ||
| 172 | (or deprecated) in most other transport level specifications: | ||
| 173 | |||
| 174 | - GET/SET_IDLE: Only used by USB-HID and I2C-HID. | ||
| 175 | - GET/SET_PROTOCOL: Not used by HID core. | ||
| 176 | - RESET: Used by I2C-HID, not hooked up in HID core. | ||
| 177 | - SET_POWER: Used by I2C-HID, not hooked up in HID core. | ||
| 178 | |||
| 179 | 2) HID API | ||
| 180 | ========== | ||
| 181 | |||
| 182 | 2.1) Initialization | ||
| 183 | ------------------- | ||
| 184 | |||
| 185 | Transport drivers normally use the following procedure to register a new device | ||
| 186 | with HID core: | ||
| 187 | |||
| 188 | struct hid_device *hid; | ||
| 189 | int ret; | ||
| 190 | |||
| 191 | hid = hid_allocate_device(); | ||
| 192 | if (IS_ERR(hid)) { | ||
| 193 | ret = PTR_ERR(hid); | ||
| 194 | goto err_<...>; | ||
| 195 | } | ||
| 196 | |||
| 197 | strlcpy(hid->name, <device-name-src>, 127); | ||
| 198 | strlcpy(hid->phys, <device-phys-src>, 63); | ||
| 199 | strlcpy(hid->uniq, <device-uniq-src>, 63); | ||
| 200 | |||
| 201 | hid->ll_driver = &custom_ll_driver; | ||
| 202 | hid->bus = <device-bus>; | ||
| 203 | hid->vendor = <device-vendor>; | ||
| 204 | hid->product = <device-product>; | ||
| 205 | hid->version = <device-version>; | ||
| 206 | hid->country = <device-country>; | ||
| 207 | hid->dev.parent = <pointer-to-parent-device>; | ||
| 208 | hid->driver_data = <transport-driver-data-field>; | ||
| 209 | |||
| 210 | ret = hid_add_device(hid); | ||
| 211 | if (ret) | ||
| 212 | goto err_<...>; | ||
| 213 | |||
| 214 | Once hid_add_device() is entered, HID core might use the callbacks provided in | ||
| 215 | "custom_ll_driver". Note that fields like "country" can be ignored by underlying | ||
| 216 | transport-drivers if not supported. | ||
| 217 | |||
| 218 | To unregister a device, use: | ||
| 219 | |||
| 220 | hid_destroy_device(hid); | ||
| 221 | |||
| 222 | Once hid_destroy_device() returns, HID core will no longer make use of any | ||
| 223 | driver callbacks. | ||
| 224 | |||
| 225 | 2.2) hid_ll_driver operations | ||
| 226 | ----------------------------- | ||
| 227 | |||
| 228 | The available HID callbacks are: | ||
| 229 | - int (*start) (struct hid_device *hdev) | ||
| 230 | Called from HID device drivers once they want to use the device. Transport | ||
| 231 | drivers can choose to setup their device in this callback. However, normally | ||
| 232 | devices are already set up before transport drivers register them to HID core | ||
| 233 | so this is mostly only used by USB-HID. | ||
| 234 | |||
| 235 | - void (*stop) (struct hid_device *hdev) | ||
| 236 | Called from HID device drivers once they are done with a device. Transport | ||
| 237 | drivers can free any buffers and deinitialize the device. But note that | ||
| 238 | ->start() might be called again if another HID device driver is loaded on the | ||
| 239 | device. | ||
| 240 | Transport drivers are free to ignore it and deinitialize devices after they | ||
| 241 | destroyed them via hid_destroy_device(). | ||
| 242 | |||
| 243 | - int (*open) (struct hid_device *hdev) | ||
| 244 | Called from HID device drivers once they are interested in data reports. | ||
| 245 | Usually, while user-space didn't open any input API/etc., device drivers are | ||
| 246 | not interested in device data and transport drivers can put devices asleep. | ||
| 247 | However, once ->open() is called, transport drivers must be ready for I/O. | ||
| 248 | ->open() calls are nested for each client that opens the HID device. | ||
| 249 | |||
| 250 | - void (*close) (struct hid_device *hdev) | ||
| 251 | Called from HID device drivers after ->open() was called but they are no | ||
| 252 | longer interested in device reports. (Usually if user-space closed any input | ||
| 253 | devices of the driver). | ||
| 254 | Transport drivers can put devices asleep and terminate any I/O of all | ||
| 255 | ->open() calls have been followed by a ->close() call. However, ->start() may | ||
| 256 | be called again if the device driver is interested in input reports again. | ||
| 257 | |||
| 258 | - int (*parse) (struct hid_device *hdev) | ||
| 259 | Called once during device setup after ->start() has been called. Transport | ||
| 260 | drivers must read the HID report-descriptor from the device and tell HID core | ||
| 261 | about it via hid_parse_report(). | ||
| 262 | |||
| 263 | - int (*power) (struct hid_device *hdev, int level) | ||
| 264 | Called by HID core to give PM hints to transport drivers. Usually this is | ||
| 265 | analogical to the ->open() and ->close() hints and redundant. | ||
| 266 | |||
| 267 | - void (*request) (struct hid_device *hdev, struct hid_report *report, | ||
| 268 | int reqtype) | ||
| 269 | Send an HID request on the ctrl channel. "report" contains the report that | ||
| 270 | should be sent and "reqtype" the request type. Request-type can be | ||
| 271 | HID_REQ_SET_REPORT or HID_REQ_GET_REPORT. | ||
| 272 | This callback is optional. If not provided, HID core will assemble a raw | ||
| 273 | report following the HID specs and send it via the ->raw_request() callback. | ||
| 274 | The transport driver is free to implement this asynchronously. | ||
| 275 | |||
| 276 | - int (*wait) (struct hid_device *hdev) | ||
| 277 | Used by HID core before calling ->request() again. A transport driver can use | ||
| 278 | it to wait for any pending requests to complete if only one request is | ||
| 279 | allowed at a time. | ||
| 280 | |||
| 281 | - int (*raw_request) (struct hid_device *hdev, unsigned char reportnum, | ||
| 282 | __u8 *buf, size_t count, unsigned char rtype, | ||
| 283 | int reqtype) | ||
| 284 | Same as ->request() but provides the report as raw buffer. This request shall | ||
| 285 | be synchronous. A transport driver must not use ->wait() to complete such | ||
| 286 | requests. | ||
| 287 | |||
| 288 | - int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len) | ||
| 289 | Send raw output report via intr channel. Used by some HID device drivers | ||
| 290 | which require high throughput for outgoing requests on the intr channel. This | ||
| 291 | must not cause SET_REPORT calls! This must be implemented as asynchronous | ||
| 292 | output report on the intr channel! | ||
| 293 | |||
| 294 | - int (*idle) (struct hid_device *hdev, int report, int idle, int reqtype) | ||
| 295 | Perform SET/GET_IDLE request. Only used by USB-HID, do not implement! | ||
| 296 | |||
| 297 | 2.3) Data Path | ||
| 298 | -------------- | ||
| 299 | |||
| 300 | Transport drivers are responsible of reading data from I/O devices. They must | ||
| 301 | handle any I/O-related state-tracking themselves. HID core does not implement | ||
| 302 | protocol handshakes or other management commands which can be required by the | ||
| 303 | given HID transport specification. | ||
| 304 | |||
| 305 | Every raw data packet read from a device must be fed into HID core via | ||
| 306 | hid_input_report(). You must specify the channel-type (intr or ctrl) and report | ||
| 307 | type (input/output/feature). Under normal conditions, only input reports are | ||
| 308 | provided via this API. | ||
| 309 | |||
| 310 | Responses to GET_REPORT requests via ->request() must also be provided via this | ||
| 311 | API. Responses to ->raw_request() are synchronous and must be intercepted by the | ||
| 312 | transport driver and not passed to hid_input_report(). | ||
| 313 | Acknowledgements to SET_REPORT requests are not of interest to HID core. | ||
| 314 | |||
| 315 | ---------------------------------------------------- | ||
| 316 | Written 2013, David Herrmann <dh.herrmann@gmail.com> | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5ca6fe7a1a36..2011136cb35f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1248,6 +1248,11 @@ void hid_output_report(struct hid_report *report, __u8 *data) | |||
| 1248 | } | 1248 | } |
| 1249 | EXPORT_SYMBOL_GPL(hid_output_report); | 1249 | EXPORT_SYMBOL_GPL(hid_output_report); |
| 1250 | 1250 | ||
| 1251 | static int hid_report_len(struct hid_report *report) | ||
| 1252 | { | ||
| 1253 | return ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7; | ||
| 1254 | } | ||
| 1255 | |||
| 1251 | /* | 1256 | /* |
| 1252 | * Allocator for buffer that is going to be passed to hid_output_report() | 1257 | * Allocator for buffer that is going to be passed to hid_output_report() |
| 1253 | */ | 1258 | */ |
| @@ -1258,7 +1263,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) | |||
| 1258 | * of implement() working on 8 byte chunks | 1263 | * of implement() working on 8 byte chunks |
| 1259 | */ | 1264 | */ |
| 1260 | 1265 | ||
| 1261 | int len = ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7; | 1266 | int len = hid_report_len(report); |
| 1262 | 1267 | ||
| 1263 | return kmalloc(len, flags); | 1268 | return kmalloc(len, flags); |
| 1264 | } | 1269 | } |
| @@ -1314,6 +1319,44 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, | |||
| 1314 | return report; | 1319 | return report; |
| 1315 | } | 1320 | } |
| 1316 | 1321 | ||
| 1322 | /* | ||
| 1323 | * Implement a generic .request() callback, using .raw_request() | ||
| 1324 | * DO NOT USE in hid drivers directly, but through hid_hw_request instead. | ||
| 1325 | */ | ||
| 1326 | void __hid_request(struct hid_device *hid, struct hid_report *report, | ||
| 1327 | int reqtype) | ||
| 1328 | { | ||
| 1329 | char *buf; | ||
| 1330 | int ret; | ||
| 1331 | int len; | ||
| 1332 | |||
| 1333 | if (!hid->ll_driver->raw_request) | ||
| 1334 | return; | ||
| 1335 | |||
| 1336 | buf = hid_alloc_report_buf(report, GFP_KERNEL); | ||
| 1337 | if (!buf) | ||
| 1338 | return; | ||
| 1339 | |||
| 1340 | len = hid_report_len(report); | ||
| 1341 | |||
| 1342 | if (reqtype == HID_REQ_SET_REPORT) | ||
| 1343 | hid_output_report(report, buf); | ||
| 1344 | |||
| 1345 | ret = hid->ll_driver->raw_request(hid, report->id, buf, len, | ||
| 1346 | report->type, reqtype); | ||
| 1347 | if (ret < 0) { | ||
| 1348 | dbg_hid("unable to complete request: %d\n", ret); | ||
| 1349 | goto out; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | if (reqtype == HID_REQ_GET_REPORT) | ||
| 1353 | hid_input_report(hid, report->type, buf, ret, 0); | ||
| 1354 | |||
| 1355 | out: | ||
| 1356 | kfree(buf); | ||
| 1357 | } | ||
| 1358 | EXPORT_SYMBOL_GPL(__hid_request); | ||
| 1359 | |||
| 1317 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 1360 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
| 1318 | int interrupt) | 1361 | int interrupt) |
| 1319 | { | 1362 | { |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index d50e7313b171..15959fbae268 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -350,9 +350,9 @@ static int hidinput_get_battery_property(struct power_supply *psy, | |||
| 350 | ret = -ENOMEM; | 350 | ret = -ENOMEM; |
| 351 | break; | 351 | break; |
| 352 | } | 352 | } |
| 353 | ret = dev->hid_get_raw_report(dev, dev->battery_report_id, | 353 | ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 2, |
| 354 | buf, 2, | 354 | dev->battery_report_type, |
| 355 | dev->battery_report_type); | 355 | HID_REQ_GET_REPORT); |
| 356 | 356 | ||
| 357 | if (ret != 2) { | 357 | if (ret != 2) { |
| 358 | ret = -ENODATA; | 358 | ret = -ENODATA; |
| @@ -1184,7 +1184,7 @@ static void hidinput_led_worker(struct work_struct *work) | |||
| 1184 | 1184 | ||
| 1185 | hid_output_report(report, buf); | 1185 | hid_output_report(report, buf); |
| 1186 | /* synchronous output report */ | 1186 | /* synchronous output report */ |
| 1187 | hid->hid_output_raw_report(hid, buf, len, HID_OUTPUT_REPORT); | 1187 | hid_output_raw_report(hid, buf, len, HID_OUTPUT_REPORT); |
| 1188 | kfree(buf); | 1188 | kfree(buf); |
| 1189 | } | 1189 | } |
| 1190 | 1190 | ||
| @@ -1263,9 +1263,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid) | |||
| 1263 | } | 1263 | } |
| 1264 | 1264 | ||
| 1265 | input_set_drvdata(input_dev, hid); | 1265 | input_set_drvdata(input_dev, hid); |
| 1266 | if (hid->ll_driver->hidinput_input_event) | 1266 | if (hid->ll_driver->request || hid->hid_output_raw_report) |
| 1267 | input_dev->event = hid->ll_driver->hidinput_input_event; | ||
| 1268 | else if (hid->ll_driver->request || hid->hid_output_raw_report) | ||
| 1269 | input_dev->event = hidinput_input_event; | 1267 | input_dev->event = hidinput_input_event; |
| 1270 | input_dev->open = hidinput_open; | 1268 | input_dev->open = hidinput_open; |
| 1271 | input_dev->close = hidinput_close; | 1269 | input_dev->close = hidinput_close; |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 9fe9d4ac3114..a976f48263f6 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
| @@ -692,7 +692,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 692 | if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) { | 692 | if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) { |
| 693 | unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 693 | unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
| 694 | 694 | ||
| 695 | ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | 695 | ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), |
| 696 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | ||
| 696 | 697 | ||
| 697 | if (ret >= 0) { | 698 | if (ret >= 0) { |
| 698 | /* insert a little delay of 10 jiffies ~ 40ms */ | 699 | /* insert a little delay of 10 jiffies ~ 40ms */ |
| @@ -704,7 +705,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 704 | buf[1] = 0xB2; | 705 | buf[1] = 0xB2; |
| 705 | get_random_bytes(&buf[2], 2); | 706 | get_random_bytes(&buf[2], 2); |
| 706 | 707 | ||
| 707 | ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | 708 | ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), |
| 709 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | ||
| 708 | } | 710 | } |
| 709 | } | 711 | } |
| 710 | 712 | ||
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index f45279c3b11a..486dbde2ba2d 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
| @@ -44,14 +44,6 @@ static const char kbd_descriptor[] = { | |||
| 44 | 0x19, 0xE0, /* USAGE_MINIMUM (Left Control) */ | 44 | 0x19, 0xE0, /* USAGE_MINIMUM (Left Control) */ |
| 45 | 0x29, 0xE7, /* USAGE_MAXIMUM (Right GUI) */ | 45 | 0x29, 0xE7, /* USAGE_MAXIMUM (Right GUI) */ |
| 46 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ | 46 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ |
| 47 | 0x95, 0x05, /* REPORT COUNT (5) */ | ||
| 48 | 0x05, 0x08, /* USAGE PAGE (LED page) */ | ||
| 49 | 0x19, 0x01, /* USAGE MINIMUM (1) */ | ||
| 50 | 0x29, 0x05, /* USAGE MAXIMUM (5) */ | ||
| 51 | 0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */ | ||
| 52 | 0x95, 0x01, /* REPORT COUNT (1) */ | ||
| 53 | 0x75, 0x03, /* REPORT SIZE (3) */ | ||
| 54 | 0x91, 0x01, /* OUTPUT (Constant) */ | ||
| 55 | 0x95, 0x06, /* REPORT_COUNT (6) */ | 47 | 0x95, 0x06, /* REPORT_COUNT (6) */ |
| 56 | 0x75, 0x08, /* REPORT_SIZE (8) */ | 48 | 0x75, 0x08, /* REPORT_SIZE (8) */ |
| 57 | 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ | 49 | 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ |
| @@ -60,6 +52,18 @@ static const char kbd_descriptor[] = { | |||
| 60 | 0x19, 0x00, /* USAGE_MINIMUM (no event) */ | 52 | 0x19, 0x00, /* USAGE_MINIMUM (no event) */ |
| 61 | 0x2A, 0xFF, 0x00, /* USAGE_MAXIMUM (reserved) */ | 53 | 0x2A, 0xFF, 0x00, /* USAGE_MAXIMUM (reserved) */ |
| 62 | 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ | 54 | 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ |
| 55 | 0x85, 0x0e, /* REPORT_ID (14) */ | ||
| 56 | 0x05, 0x08, /* USAGE PAGE (LED page) */ | ||
| 57 | 0x95, 0x05, /* REPORT COUNT (5) */ | ||
| 58 | 0x75, 0x01, /* REPORT SIZE (1) */ | ||
| 59 | 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ | ||
| 60 | 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ | ||
| 61 | 0x19, 0x01, /* USAGE MINIMUM (1) */ | ||
| 62 | 0x29, 0x05, /* USAGE MAXIMUM (5) */ | ||
| 63 | 0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */ | ||
| 64 | 0x95, 0x01, /* REPORT COUNT (1) */ | ||
| 65 | 0x75, 0x03, /* REPORT SIZE (3) */ | ||
| 66 | 0x91, 0x01, /* OUTPUT (Constant) */ | ||
| 63 | 0xC0 | 67 | 0xC0 |
| 64 | }; | 68 | }; |
| 65 | 69 | ||
| @@ -189,9 +193,6 @@ static const u8 hid_reportid_size_map[NUMBER_OF_HID_REPORTS] = { | |||
| 189 | 193 | ||
| 190 | static struct hid_ll_driver logi_dj_ll_driver; | 194 | static struct hid_ll_driver logi_dj_ll_driver; |
| 191 | 195 | ||
| 192 | static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, | ||
| 193 | size_t count, | ||
| 194 | unsigned char report_type); | ||
| 195 | static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev); | 196 | static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev); |
| 196 | 197 | ||
| 197 | static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev, | 198 | static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev, |
| @@ -258,7 +259,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
| 258 | } | 259 | } |
| 259 | 260 | ||
| 260 | dj_hiddev->ll_driver = &logi_dj_ll_driver; | 261 | dj_hiddev->ll_driver = &logi_dj_ll_driver; |
| 261 | dj_hiddev->hid_output_raw_report = logi_dj_output_hidraw_report; | ||
| 262 | 262 | ||
| 263 | dj_hiddev->dev.parent = &djrcv_hdev->dev; | 263 | dj_hiddev->dev.parent = &djrcv_hdev->dev; |
| 264 | dj_hiddev->bus = BUS_USB; | 264 | dj_hiddev->bus = BUS_USB; |
| @@ -540,14 +540,35 @@ static void logi_dj_ll_close(struct hid_device *hid) | |||
| 540 | dbg_hid("%s:%s\n", __func__, hid->phys); | 540 | dbg_hid("%s:%s\n", __func__, hid->phys); |
| 541 | } | 541 | } |
| 542 | 542 | ||
| 543 | static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, | 543 | static int logi_dj_ll_raw_request(struct hid_device *hid, |
| 544 | size_t count, | 544 | unsigned char reportnum, __u8 *buf, |
| 545 | unsigned char report_type) | 545 | size_t count, unsigned char report_type, |
| 546 | int reqtype) | ||
| 546 | { | 547 | { |
| 547 | /* Called by hid raw to send data */ | 548 | struct dj_device *djdev = hid->driver_data; |
| 548 | dbg_hid("%s\n", __func__); | 549 | struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev; |
| 550 | u8 *out_buf; | ||
| 551 | int ret; | ||
| 549 | 552 | ||
| 550 | return 0; | 553 | if (buf[0] != REPORT_TYPE_LEDS) |
| 554 | return -EINVAL; | ||
| 555 | |||
| 556 | out_buf = kzalloc(DJREPORT_SHORT_LENGTH, GFP_ATOMIC); | ||
| 557 | if (!out_buf) | ||
| 558 | return -ENOMEM; | ||
| 559 | |||
| 560 | if (count < DJREPORT_SHORT_LENGTH - 2) | ||
| 561 | count = DJREPORT_SHORT_LENGTH - 2; | ||
| 562 | |||
| 563 | out_buf[0] = REPORT_ID_DJ_SHORT; | ||
| 564 | out_buf[1] = djdev->device_index; | ||
| 565 | memcpy(out_buf + 2, buf, count); | ||
| 566 | |||
| 567 | ret = hid_hw_raw_request(djrcv_dev->hdev, out_buf[0], out_buf, | ||
| 568 | DJREPORT_SHORT_LENGTH, report_type, reqtype); | ||
| 569 | |||
| 570 | kfree(out_buf); | ||
| 571 | return ret; | ||
| 551 | } | 572 | } |
| 552 | 573 | ||
| 553 | static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size) | 574 | static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size) |
| @@ -613,58 +634,6 @@ static int logi_dj_ll_parse(struct hid_device *hid) | |||
| 613 | return retval; | 634 | return retval; |
| 614 | } | 635 | } |
| 615 | 636 | ||
| 616 | static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, | ||
| 617 | unsigned int code, int value) | ||
| 618 | { | ||
| 619 | /* Sent by the input layer to handle leds and Force Feedback */ | ||
| 620 | struct hid_device *dj_hiddev = input_get_drvdata(dev); | ||
| 621 | struct dj_device *dj_dev = dj_hiddev->driver_data; | ||
| 622 | |||
| 623 | struct dj_receiver_dev *djrcv_dev = | ||
| 624 | dev_get_drvdata(dj_hiddev->dev.parent); | ||
| 625 | struct hid_device *dj_rcv_hiddev = djrcv_dev->hdev; | ||
| 626 | struct hid_report_enum *output_report_enum; | ||
| 627 | |||
| 628 | struct hid_field *field; | ||
| 629 | struct hid_report *report; | ||
| 630 | unsigned char *data; | ||
| 631 | int offset; | ||
| 632 | |||
| 633 | dbg_hid("%s: %s, type:%d | code:%d | value:%d\n", | ||
| 634 | __func__, dev->phys, type, code, value); | ||
| 635 | |||
| 636 | if (type != EV_LED) | ||
| 637 | return -1; | ||
| 638 | |||
| 639 | offset = hidinput_find_field(dj_hiddev, type, code, &field); | ||
| 640 | |||
| 641 | if (offset == -1) { | ||
| 642 | dev_warn(&dev->dev, "event field not found\n"); | ||
| 643 | return -1; | ||
| 644 | } | ||
| 645 | hid_set_field(field, offset, value); | ||
| 646 | |||
| 647 | data = hid_alloc_report_buf(field->report, GFP_ATOMIC); | ||
| 648 | if (!data) { | ||
| 649 | dev_warn(&dev->dev, "failed to allocate report buf memory\n"); | ||
| 650 | return -1; | ||
| 651 | } | ||
| 652 | |||
| 653 | hid_output_report(field->report, &data[0]); | ||
| 654 | |||
| 655 | output_report_enum = &dj_rcv_hiddev->report_enum[HID_OUTPUT_REPORT]; | ||
| 656 | report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT]; | ||
| 657 | hid_set_field(report->field[0], 0, dj_dev->device_index); | ||
| 658 | hid_set_field(report->field[0], 1, REPORT_TYPE_LEDS); | ||
| 659 | hid_set_field(report->field[0], 2, data[1]); | ||
| 660 | |||
| 661 | hid_hw_request(dj_rcv_hiddev, report, HID_REQ_SET_REPORT); | ||
| 662 | |||
| 663 | kfree(data); | ||
| 664 | |||
| 665 | return 0; | ||
| 666 | } | ||
| 667 | |||
| 668 | static int logi_dj_ll_start(struct hid_device *hid) | 637 | static int logi_dj_ll_start(struct hid_device *hid) |
| 669 | { | 638 | { |
| 670 | dbg_hid("%s\n", __func__); | 639 | dbg_hid("%s\n", __func__); |
| @@ -683,7 +652,7 @@ static struct hid_ll_driver logi_dj_ll_driver = { | |||
| 683 | .stop = logi_dj_ll_stop, | 652 | .stop = logi_dj_ll_stop, |
| 684 | .open = logi_dj_ll_open, | 653 | .open = logi_dj_ll_open, |
| 685 | .close = logi_dj_ll_close, | 654 | .close = logi_dj_ll_close, |
| 686 | .hidinput_input_event = logi_dj_ll_input_event, | 655 | .raw_request = logi_dj_ll_raw_request, |
| 687 | }; | 656 | }; |
| 688 | 657 | ||
| 689 | 658 | ||
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 3b43d1cfa936..ecc2cbf300cc 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c | |||
| @@ -538,8 +538,8 @@ static int magicmouse_probe(struct hid_device *hdev, | |||
| 538 | * but there seems to be no other way of switching the mode. | 538 | * but there seems to be no other way of switching the mode. |
| 539 | * Thus the super-ugly hacky success check below. | 539 | * Thus the super-ugly hacky success check below. |
| 540 | */ | 540 | */ |
| 541 | ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), | 541 | ret = hid_hw_raw_request(hdev, feature[0], feature, sizeof(feature), |
| 542 | HID_FEATURE_REPORT); | 542 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 543 | if (ret != -EIO && ret != sizeof(feature)) { | 543 | if (ret != -EIO && ret != sizeof(feature)) { |
| 544 | hid_err(hdev, "unable to request touch data (%d)\n", ret); | 544 | hid_err(hdev, "unable to request touch data (%d)\n", ret); |
| 545 | goto err_stop_hw; | 545 | goto err_stop_hw; |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 12354055d474..e3e89b6a41c2 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
| @@ -706,7 +706,8 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) | |||
| 706 | if (!buf) | 706 | if (!buf) |
| 707 | return -ENOMEM; | 707 | return -ENOMEM; |
| 708 | 708 | ||
| 709 | ret = hdev->hid_get_raw_report(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT); | 709 | ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, |
| 710 | HID_REQ_GET_REPORT); | ||
| 710 | 711 | ||
| 711 | if (ret < 0) | 712 | if (ret < 0) |
| 712 | hid_err(hdev, "can't set operational mode\n"); | 713 | hid_err(hdev, "can't set operational mode\n"); |
| @@ -719,7 +720,8 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) | |||
| 719 | static int sixaxis_set_operational_bt(struct hid_device *hdev) | 720 | static int sixaxis_set_operational_bt(struct hid_device *hdev) |
| 720 | { | 721 | { |
| 721 | unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; | 722 | unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; |
| 722 | return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | 723 | return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), |
| 724 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | ||
| 723 | } | 725 | } |
| 724 | 726 | ||
| 725 | static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) | 727 | static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) |
| @@ -941,8 +943,7 @@ static void sixaxis_state_worker(struct work_struct *work) | |||
| 941 | buf[10] |= sc->led_state[2] << 3; | 943 | buf[10] |= sc->led_state[2] << 3; |
| 942 | buf[10] |= sc->led_state[3] << 4; | 944 | buf[10] |= sc->led_state[3] << 4; |
| 943 | 945 | ||
| 944 | sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf), | 946 | hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT); |
| 945 | HID_OUTPUT_REPORT); | ||
| 946 | } | 947 | } |
| 947 | 948 | ||
| 948 | static void dualshock4_state_worker(struct work_struct *work) | 949 | static void dualshock4_state_worker(struct work_struct *work) |
diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 99342cfa0ea2..a97c78845f7b 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c | |||
| @@ -48,8 +48,8 @@ static int blink1_send_command(struct blink1_data *data, | |||
| 48 | buf[0], buf[1], buf[2], buf[3], buf[4], | 48 | buf[0], buf[1], buf[2], buf[3], buf[4], |
| 49 | buf[5], buf[6], buf[7], buf[8]); | 49 | buf[5], buf[6], buf[7], buf[8]); |
| 50 | 50 | ||
| 51 | ret = data->hdev->hid_output_raw_report(data->hdev, buf, | 51 | ret = hid_hw_raw_request(data->hdev, buf[0], buf, BLINK1_CMD_SIZE, |
| 52 | BLINK1_CMD_SIZE, HID_FEATURE_REPORT); | 52 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 53 | 53 | ||
| 54 | return ret < 0 ? ret : 0; | 54 | return ret < 0 ? ret : 0; |
| 55 | } | 55 | } |
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 60c75dcbbdb8..902013ec041b 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
| @@ -128,8 +128,8 @@ static void wacom_set_image(struct hid_device *hdev, const char *image, | |||
| 128 | 128 | ||
| 129 | rep_data[0] = WAC_CMD_ICON_START_STOP; | 129 | rep_data[0] = WAC_CMD_ICON_START_STOP; |
| 130 | rep_data[1] = 0; | 130 | rep_data[1] = 0; |
| 131 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | 131 | ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2, |
| 132 | HID_FEATURE_REPORT); | 132 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 133 | if (ret < 0) | 133 | if (ret < 0) |
| 134 | goto err; | 134 | goto err; |
| 135 | 135 | ||
| @@ -143,15 +143,15 @@ static void wacom_set_image(struct hid_device *hdev, const char *image, | |||
| 143 | rep_data[j + 3] = p[(i << 6) + j]; | 143 | rep_data[j + 3] = p[(i << 6) + j]; |
| 144 | 144 | ||
| 145 | rep_data[2] = i; | 145 | rep_data[2] = i; |
| 146 | ret = hdev->hid_output_raw_report(hdev, rep_data, 67, | 146 | ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 67, |
| 147 | HID_FEATURE_REPORT); | 147 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | rep_data[0] = WAC_CMD_ICON_START_STOP; | 150 | rep_data[0] = WAC_CMD_ICON_START_STOP; |
| 151 | rep_data[1] = 0; | 151 | rep_data[1] = 0; |
| 152 | 152 | ||
| 153 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | 153 | ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2, |
| 154 | HID_FEATURE_REPORT); | 154 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 155 | 155 | ||
| 156 | err: | 156 | err: |
| 157 | return; | 157 | return; |
| @@ -183,7 +183,8 @@ static void wacom_leds_set_brightness(struct led_classdev *led_dev, | |||
| 183 | buf[3] = value; | 183 | buf[3] = value; |
| 184 | /* use fixed brightness for OLEDs */ | 184 | /* use fixed brightness for OLEDs */ |
| 185 | buf[4] = 0x08; | 185 | buf[4] = 0x08; |
| 186 | hdev->hid_output_raw_report(hdev, buf, 9, HID_FEATURE_REPORT); | 186 | hid_hw_raw_request(hdev, buf[0], buf, 9, HID_FEATURE_REPORT, |
| 187 | HID_REQ_SET_REPORT); | ||
| 187 | kfree(buf); | 188 | kfree(buf); |
| 188 | } | 189 | } |
| 189 | 190 | ||
| @@ -339,8 +340,8 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed) | |||
| 339 | rep_data[0] = 0x03 ; rep_data[1] = 0x00; | 340 | rep_data[0] = 0x03 ; rep_data[1] = 0x00; |
| 340 | limit = 3; | 341 | limit = 3; |
| 341 | do { | 342 | do { |
| 342 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | 343 | ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2, |
| 343 | HID_FEATURE_REPORT); | 344 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 344 | } while (ret < 0 && limit-- > 0); | 345 | } while (ret < 0 && limit-- > 0); |
| 345 | 346 | ||
| 346 | if (ret >= 0) { | 347 | if (ret >= 0) { |
| @@ -352,8 +353,9 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed) | |||
| 352 | rep_data[1] = 0x00; | 353 | rep_data[1] = 0x00; |
| 353 | limit = 3; | 354 | limit = 3; |
| 354 | do { | 355 | do { |
| 355 | ret = hdev->hid_output_raw_report(hdev, | 356 | ret = hid_hw_raw_request(hdev, rep_data[0], |
| 356 | rep_data, 2, HID_FEATURE_REPORT); | 357 | rep_data, 2, HID_FEATURE_REPORT, |
| 358 | HID_REQ_SET_REPORT); | ||
| 357 | } while (ret < 0 && limit-- > 0); | 359 | } while (ret < 0 && limit-- > 0); |
| 358 | 360 | ||
| 359 | if (ret >= 0) { | 361 | if (ret >= 0) { |
| @@ -378,8 +380,8 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed) | |||
| 378 | rep_data[0] = 0x03; | 380 | rep_data[0] = 0x03; |
| 379 | rep_data[1] = wdata->features; | 381 | rep_data[1] = wdata->features; |
| 380 | 382 | ||
| 381 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | 383 | ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2, |
| 382 | HID_FEATURE_REPORT); | 384 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 383 | if (ret >= 0) | 385 | if (ret >= 0) |
| 384 | wdata->high_speed = speed; | 386 | wdata->high_speed = speed; |
| 385 | break; | 387 | break; |
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index abb20db2b443..d00391418d1a 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c | |||
| @@ -28,14 +28,14 @@ static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, | |||
| 28 | __u8 *buf; | 28 | __u8 *buf; |
| 29 | int ret; | 29 | int ret; |
| 30 | 30 | ||
| 31 | if (!hdev->hid_output_raw_report) | 31 | if (!hdev->ll_driver->output_report) |
| 32 | return -ENODEV; | 32 | return -ENODEV; |
| 33 | 33 | ||
| 34 | buf = kmemdup(buffer, count, GFP_KERNEL); | 34 | buf = kmemdup(buffer, count, GFP_KERNEL); |
| 35 | if (!buf) | 35 | if (!buf) |
| 36 | return -ENOMEM; | 36 | return -ENOMEM; |
| 37 | 37 | ||
| 38 | ret = hdev->hid_output_raw_report(hdev, buf, count, HID_OUTPUT_REPORT); | 38 | ret = hid_hw_output_report(hdev, buf, count); |
| 39 | 39 | ||
| 40 | kfree(buf); | 40 | kfree(buf); |
| 41 | return ret; | 41 | return ret; |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index cb0137b3718d..f8708c93f85c 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
| @@ -153,7 +153,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, | |||
| 153 | goto out_free; | 153 | goto out_free; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | ret = dev->hid_output_raw_report(dev, buf, count, report_type); | 156 | ret = hid_output_raw_report(dev, buf, count, report_type); |
| 157 | out_free: | 157 | out_free: |
| 158 | kfree(buf); | 158 | kfree(buf); |
| 159 | out: | 159 | out: |
| @@ -189,7 +189,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t | |||
| 189 | 189 | ||
| 190 | dev = hidraw_table[minor]->hid; | 190 | dev = hidraw_table[minor]->hid; |
| 191 | 191 | ||
| 192 | if (!dev->hid_get_raw_report) { | 192 | if (!dev->ll_driver->raw_request) { |
| 193 | ret = -ENODEV; | 193 | ret = -ENODEV; |
| 194 | goto out; | 194 | goto out; |
| 195 | } | 195 | } |
| @@ -216,14 +216,15 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t | |||
| 216 | 216 | ||
| 217 | /* | 217 | /* |
| 218 | * Read the first byte from the user. This is the report number, | 218 | * Read the first byte from the user. This is the report number, |
| 219 | * which is passed to dev->hid_get_raw_report(). | 219 | * which is passed to hid_hw_raw_request(). |
| 220 | */ | 220 | */ |
| 221 | if (copy_from_user(&report_number, buffer, 1)) { | 221 | if (copy_from_user(&report_number, buffer, 1)) { |
| 222 | ret = -EFAULT; | 222 | ret = -EFAULT; |
| 223 | goto out_free; | 223 | goto out_free; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | ret = dev->hid_get_raw_report(dev, report_number, buf, count, report_type); | 226 | ret = hid_hw_raw_request(dev, report_number, buf, count, report_type, |
| 227 | HID_REQ_GET_REPORT); | ||
| 227 | 228 | ||
| 228 | if (ret < 0) | 229 | if (ret < 0) |
| 229 | goto out_free; | 230 | goto out_free; |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index e914f2755491..1a955317d05f 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -256,18 +256,27 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType, | |||
| 256 | return 0; | 256 | return 0; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | 259 | /** |
| 260 | u8 reportID, unsigned char *buf, size_t data_len) | 260 | * i2c_hid_set_or_send_report: forward an incoming report to the device |
| 261 | * @client: the i2c_client of the device | ||
| 262 | * @reportType: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT | ||
| 263 | * @reportID: the report ID | ||
| 264 | * @buf: the actual data to transfer, without the report ID | ||
| 265 | * @len: size of buf | ||
| 266 | * @use_data: true: use SET_REPORT HID command, false: send plain OUTPUT report | ||
| 267 | */ | ||
| 268 | static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, | ||
| 269 | u8 reportID, unsigned char *buf, size_t data_len, bool use_data) | ||
| 261 | { | 270 | { |
| 262 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 271 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
| 263 | u8 *args = ihid->argsbuf; | 272 | u8 *args = ihid->argsbuf; |
| 264 | const struct i2c_hid_cmd * hidcmd = &hid_set_report_cmd; | 273 | const struct i2c_hid_cmd *hidcmd; |
| 265 | int ret; | 274 | int ret; |
| 266 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); | 275 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); |
| 267 | u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister); | 276 | u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister); |
| 268 | u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength); | 277 | u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength); |
| 269 | 278 | ||
| 270 | /* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */ | 279 | /* hid_hw_* already checked that data_len < HID_MAX_BUFFER_SIZE */ |
| 271 | u16 size = 2 /* size */ + | 280 | u16 size = 2 /* size */ + |
| 272 | (reportID ? 1 : 0) /* reportID */ + | 281 | (reportID ? 1 : 0) /* reportID */ + |
| 273 | data_len /* buf */; | 282 | data_len /* buf */; |
| @@ -278,6 +287,9 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | |||
| 278 | 287 | ||
| 279 | i2c_hid_dbg(ihid, "%s\n", __func__); | 288 | i2c_hid_dbg(ihid, "%s\n", __func__); |
| 280 | 289 | ||
| 290 | if (!use_data && maxOutputLength == 0) | ||
| 291 | return -ENOSYS; | ||
| 292 | |||
| 281 | if (reportID >= 0x0F) { | 293 | if (reportID >= 0x0F) { |
| 282 | args[index++] = reportID; | 294 | args[index++] = reportID; |
| 283 | reportID = 0x0F; | 295 | reportID = 0x0F; |
| @@ -287,9 +299,10 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | |||
| 287 | * use the data register for feature reports or if the device does not | 299 | * use the data register for feature reports or if the device does not |
| 288 | * support the output register | 300 | * support the output register |
| 289 | */ | 301 | */ |
| 290 | if (reportType == 0x03 || maxOutputLength == 0) { | 302 | if (use_data) { |
| 291 | args[index++] = dataRegister & 0xFF; | 303 | args[index++] = dataRegister & 0xFF; |
| 292 | args[index++] = dataRegister >> 8; | 304 | args[index++] = dataRegister >> 8; |
| 305 | hidcmd = &hid_set_report_cmd; | ||
| 293 | } else { | 306 | } else { |
| 294 | args[index++] = outputRegister & 0xFF; | 307 | args[index++] = outputRegister & 0xFF; |
| 295 | args[index++] = outputRegister >> 8; | 308 | args[index++] = outputRegister >> 8; |
| @@ -550,7 +563,7 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, | |||
| 550 | } | 563 | } |
| 551 | 564 | ||
| 552 | static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, | 565 | static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, |
| 553 | size_t count, unsigned char report_type) | 566 | size_t count, unsigned char report_type, bool use_data) |
| 554 | { | 567 | { |
| 555 | struct i2c_client *client = hid->driver_data; | 568 | struct i2c_client *client = hid->driver_data; |
| 556 | int report_id = buf[0]; | 569 | int report_id = buf[0]; |
| @@ -564,9 +577,9 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, | |||
| 564 | count--; | 577 | count--; |
| 565 | } | 578 | } |
| 566 | 579 | ||
| 567 | ret = i2c_hid_set_report(client, | 580 | ret = i2c_hid_set_or_send_report(client, |
| 568 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, | 581 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, |
| 569 | report_id, buf, count); | 582 | report_id, buf, count, use_data); |
| 570 | 583 | ||
| 571 | if (report_id && ret >= 0) | 584 | if (report_id && ret >= 0) |
| 572 | ret++; /* add report_id to the number of transfered bytes */ | 585 | ret++; /* add report_id to the number of transfered bytes */ |
| @@ -574,34 +587,40 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, | |||
| 574 | return ret; | 587 | return ret; |
| 575 | } | 588 | } |
| 576 | 589 | ||
| 577 | static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep, | 590 | static int __i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, |
| 578 | int reqtype) | 591 | size_t count, unsigned char report_type) |
| 579 | { | 592 | { |
| 580 | struct i2c_client *client = hid->driver_data; | 593 | struct i2c_client *client = hid->driver_data; |
| 581 | char *buf; | 594 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
| 582 | int ret; | 595 | bool data = true; /* SET_REPORT */ |
| 583 | int len = i2c_hid_get_report_length(rep) - 2; | ||
| 584 | 596 | ||
| 585 | buf = kzalloc(len, GFP_KERNEL); | 597 | if (report_type == HID_OUTPUT_REPORT) |
| 586 | if (!buf) | 598 | data = le16_to_cpu(ihid->hdesc.wMaxOutputLength) == 0; |
| 587 | return; | 599 | |
| 600 | return i2c_hid_output_raw_report(hid, buf, count, report_type, data); | ||
| 601 | } | ||
| 588 | 602 | ||
| 603 | static int i2c_hid_output_report(struct hid_device *hid, __u8 *buf, | ||
| 604 | size_t count) | ||
| 605 | { | ||
| 606 | return i2c_hid_output_raw_report(hid, buf, count, HID_OUTPUT_REPORT, | ||
| 607 | false); | ||
| 608 | } | ||
| 609 | |||
| 610 | static int i2c_hid_raw_request(struct hid_device *hid, unsigned char reportnum, | ||
| 611 | __u8 *buf, size_t len, unsigned char rtype, | ||
| 612 | int reqtype) | ||
| 613 | { | ||
| 589 | switch (reqtype) { | 614 | switch (reqtype) { |
| 590 | case HID_REQ_GET_REPORT: | 615 | case HID_REQ_GET_REPORT: |
| 591 | ret = i2c_hid_get_raw_report(hid, rep->id, buf, len, rep->type); | 616 | return i2c_hid_get_raw_report(hid, reportnum, buf, len, rtype); |
| 592 | if (ret < 0) | ||
| 593 | dev_err(&client->dev, "%s: unable to get report: %d\n", | ||
| 594 | __func__, ret); | ||
| 595 | else | ||
| 596 | hid_input_report(hid, rep->type, buf, ret, 0); | ||
| 597 | break; | ||
| 598 | case HID_REQ_SET_REPORT: | 617 | case HID_REQ_SET_REPORT: |
| 599 | hid_output_report(rep, buf); | 618 | if (buf[0] != reportnum) |
| 600 | i2c_hid_output_raw_report(hid, buf, len, rep->type); | 619 | return -EINVAL; |
| 601 | break; | 620 | return i2c_hid_output_raw_report(hid, buf, len, rtype, true); |
| 621 | default: | ||
| 622 | return -EIO; | ||
| 602 | } | 623 | } |
| 603 | |||
| 604 | kfree(buf); | ||
| 605 | } | 624 | } |
| 606 | 625 | ||
| 607 | static int i2c_hid_parse(struct hid_device *hid) | 626 | static int i2c_hid_parse(struct hid_device *hid) |
| @@ -760,7 +779,8 @@ static struct hid_ll_driver i2c_hid_ll_driver = { | |||
| 760 | .open = i2c_hid_open, | 779 | .open = i2c_hid_open, |
| 761 | .close = i2c_hid_close, | 780 | .close = i2c_hid_close, |
| 762 | .power = i2c_hid_power, | 781 | .power = i2c_hid_power, |
| 763 | .request = i2c_hid_request, | 782 | .output_report = i2c_hid_output_report, |
| 783 | .raw_request = i2c_hid_raw_request, | ||
| 764 | }; | 784 | }; |
| 765 | 785 | ||
| 766 | static int i2c_hid_init_irq(struct i2c_client *client) | 786 | static int i2c_hid_init_irq(struct i2c_client *client) |
| @@ -1005,8 +1025,7 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
| 1005 | 1025 | ||
| 1006 | hid->driver_data = client; | 1026 | hid->driver_data = client; |
| 1007 | hid->ll_driver = &i2c_hid_ll_driver; | 1027 | hid->ll_driver = &i2c_hid_ll_driver; |
| 1008 | hid->hid_get_raw_report = i2c_hid_get_raw_report; | 1028 | hid->hid_output_raw_report = __i2c_hid_output_raw_report; |
| 1009 | hid->hid_output_raw_report = i2c_hid_output_raw_report; | ||
| 1010 | hid->dev.parent = &client->dev; | 1029 | hid->dev.parent = &client->dev; |
| 1011 | ACPI_COMPANION_SET(&hid->dev, ACPI_COMPANION(&client->dev)); | 1030 | ACPI_COMPANION_SET(&hid->dev, ACPI_COMPANION(&client->dev)); |
| 1012 | hid->bus = BUS_I2C; | 1031 | hid->bus = BUS_I2C; |
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index cedc6da93c19..60acee422fdc 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
| @@ -244,12 +244,35 @@ static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, | |||
| 244 | return count; | 244 | return count; |
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf, | ||
| 248 | size_t count) | ||
| 249 | { | ||
| 250 | return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT); | ||
| 251 | } | ||
| 252 | |||
| 253 | static int uhid_raw_request(struct hid_device *hid, unsigned char reportnum, | ||
| 254 | __u8 *buf, size_t len, unsigned char rtype, | ||
| 255 | int reqtype) | ||
| 256 | { | ||
| 257 | switch (reqtype) { | ||
| 258 | case HID_REQ_GET_REPORT: | ||
| 259 | return uhid_hid_get_raw(hid, reportnum, buf, len, rtype); | ||
| 260 | case HID_REQ_SET_REPORT: | ||
| 261 | /* TODO: implement proper SET_REPORT functionality */ | ||
| 262 | return -ENOSYS; | ||
| 263 | default: | ||
| 264 | return -EIO; | ||
| 265 | } | ||
| 266 | } | ||
| 267 | |||
| 247 | static struct hid_ll_driver uhid_hid_driver = { | 268 | static struct hid_ll_driver uhid_hid_driver = { |
| 248 | .start = uhid_hid_start, | 269 | .start = uhid_hid_start, |
| 249 | .stop = uhid_hid_stop, | 270 | .stop = uhid_hid_stop, |
| 250 | .open = uhid_hid_open, | 271 | .open = uhid_hid_open, |
| 251 | .close = uhid_hid_close, | 272 | .close = uhid_hid_close, |
| 252 | .parse = uhid_hid_parse, | 273 | .parse = uhid_hid_parse, |
| 274 | .output_report = uhid_hid_output_report, | ||
| 275 | .raw_request = uhid_raw_request, | ||
| 253 | }; | 276 | }; |
| 254 | 277 | ||
| 255 | #ifdef CONFIG_COMPAT | 278 | #ifdef CONFIG_COMPAT |
| @@ -377,7 +400,6 @@ static int uhid_dev_create(struct uhid_device *uhid, | |||
| 377 | hid->uniq[63] = 0; | 400 | hid->uniq[63] = 0; |
| 378 | 401 | ||
| 379 | hid->ll_driver = &uhid_hid_driver; | 402 | hid->ll_driver = &uhid_hid_driver; |
| 380 | hid->hid_get_raw_report = uhid_hid_get_raw; | ||
| 381 | hid->hid_output_raw_report = uhid_hid_output_raw; | 403 | hid->hid_output_raw_report = uhid_hid_output_raw; |
| 382 | hid->bus = ev->u.create.bus; | 404 | hid->bus = ev->u.create.bus; |
| 383 | hid->vendor = ev->u.create.vendor; | 405 | hid->vendor = ev->u.create.vendor; |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 44df131d390a..0d1d87533f48 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
| @@ -884,58 +884,78 @@ static int usbhid_get_raw_report(struct hid_device *hid, | |||
| 884 | return ret; | 884 | return ret; |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, | 887 | static int usbhid_set_raw_report(struct hid_device *hid, unsigned int reportnum, |
| 888 | unsigned char report_type) | 888 | __u8 *buf, size_t count, unsigned char rtype) |
| 889 | { | 889 | { |
| 890 | struct usbhid_device *usbhid = hid->driver_data; | 890 | struct usbhid_device *usbhid = hid->driver_data; |
| 891 | struct usb_device *dev = hid_to_usb_dev(hid); | 891 | struct usb_device *dev = hid_to_usb_dev(hid); |
| 892 | struct usb_interface *intf = usbhid->intf; | 892 | struct usb_interface *intf = usbhid->intf; |
| 893 | struct usb_host_interface *interface = intf->cur_altsetting; | 893 | struct usb_host_interface *interface = intf->cur_altsetting; |
| 894 | int ret; | 894 | int ret, skipped_report_id = 0; |
| 895 | 895 | ||
| 896 | if (usbhid->urbout && report_type != HID_FEATURE_REPORT) { | 896 | /* Byte 0 is the report number. Report data starts at byte 1.*/ |
| 897 | int actual_length; | 897 | buf[0] = reportnum; |
| 898 | int skipped_report_id = 0; | 898 | if (buf[0] == 0x0) { |
| 899 | /* Don't send the Report ID */ | ||
| 900 | buf++; | ||
| 901 | count--; | ||
| 902 | skipped_report_id = 1; | ||
| 903 | } | ||
| 899 | 904 | ||
| 900 | if (buf[0] == 0x0) { | 905 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
| 901 | /* Don't send the Report ID */ | ||
| 902 | buf++; | ||
| 903 | count--; | ||
| 904 | skipped_report_id = 1; | ||
| 905 | } | ||
| 906 | ret = usb_interrupt_msg(dev, usbhid->urbout->pipe, | ||
| 907 | buf, count, &actual_length, | ||
| 908 | USB_CTRL_SET_TIMEOUT); | ||
| 909 | /* return the number of bytes transferred */ | ||
| 910 | if (ret == 0) { | ||
| 911 | ret = actual_length; | ||
| 912 | /* count also the report id */ | ||
| 913 | if (skipped_report_id) | ||
| 914 | ret++; | ||
| 915 | } | ||
| 916 | } else { | ||
| 917 | int skipped_report_id = 0; | ||
| 918 | int report_id = buf[0]; | ||
| 919 | if (buf[0] == 0x0) { | ||
| 920 | /* Don't send the Report ID */ | ||
| 921 | buf++; | ||
| 922 | count--; | ||
| 923 | skipped_report_id = 1; | ||
| 924 | } | ||
| 925 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
| 926 | HID_REQ_SET_REPORT, | 906 | HID_REQ_SET_REPORT, |
| 927 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 907 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
| 928 | ((report_type + 1) << 8) | report_id, | 908 | ((rtype + 1) << 8) | reportnum, |
| 929 | interface->desc.bInterfaceNumber, buf, count, | 909 | interface->desc.bInterfaceNumber, buf, count, |
| 930 | USB_CTRL_SET_TIMEOUT); | 910 | USB_CTRL_SET_TIMEOUT); |
| 931 | /* count also the report id, if this was a numbered report. */ | 911 | /* count also the report id, if this was a numbered report. */ |
| 932 | if (ret > 0 && skipped_report_id) | 912 | if (ret > 0 && skipped_report_id) |
| 913 | ret++; | ||
| 914 | |||
| 915 | return ret; | ||
| 916 | } | ||
| 917 | |||
| 918 | static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count) | ||
| 919 | { | ||
| 920 | struct usbhid_device *usbhid = hid->driver_data; | ||
| 921 | struct usb_device *dev = hid_to_usb_dev(hid); | ||
| 922 | int actual_length, skipped_report_id = 0, ret; | ||
| 923 | |||
| 924 | if (!usbhid->urbout) | ||
| 925 | return -ENOSYS; | ||
| 926 | |||
| 927 | if (buf[0] == 0x0) { | ||
| 928 | /* Don't send the Report ID */ | ||
| 929 | buf++; | ||
| 930 | count--; | ||
| 931 | skipped_report_id = 1; | ||
| 932 | } | ||
| 933 | |||
| 934 | ret = usb_interrupt_msg(dev, usbhid->urbout->pipe, | ||
| 935 | buf, count, &actual_length, | ||
| 936 | USB_CTRL_SET_TIMEOUT); | ||
| 937 | /* return the number of bytes transferred */ | ||
| 938 | if (ret == 0) { | ||
| 939 | ret = actual_length; | ||
| 940 | /* count also the report id */ | ||
| 941 | if (skipped_report_id) | ||
| 933 | ret++; | 942 | ret++; |
| 934 | } | 943 | } |
| 935 | 944 | ||
| 936 | return ret; | 945 | return ret; |
| 937 | } | 946 | } |
| 938 | 947 | ||
| 948 | static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, | ||
| 949 | size_t count, unsigned char report_type) | ||
| 950 | { | ||
| 951 | struct usbhid_device *usbhid = hid->driver_data; | ||
| 952 | |||
| 953 | if (usbhid->urbout && report_type != HID_FEATURE_REPORT) | ||
| 954 | return usbhid_output_report(hid, buf, count); | ||
| 955 | |||
| 956 | return usbhid_set_raw_report(hid, buf[0], buf, count, report_type); | ||
| 957 | } | ||
| 958 | |||
| 939 | static void usbhid_restart_queues(struct usbhid_device *usbhid) | 959 | static void usbhid_restart_queues(struct usbhid_device *usbhid) |
| 940 | { | 960 | { |
| 941 | if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) | 961 | if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) |
| @@ -1200,6 +1220,20 @@ static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int r | |||
| 1200 | } | 1220 | } |
| 1201 | } | 1221 | } |
| 1202 | 1222 | ||
| 1223 | static int usbhid_raw_request(struct hid_device *hid, unsigned char reportnum, | ||
| 1224 | __u8 *buf, size_t len, unsigned char rtype, | ||
| 1225 | int reqtype) | ||
| 1226 | { | ||
| 1227 | switch (reqtype) { | ||
| 1228 | case HID_REQ_GET_REPORT: | ||
| 1229 | return usbhid_get_raw_report(hid, reportnum, buf, len, rtype); | ||
| 1230 | case HID_REQ_SET_REPORT: | ||
| 1231 | return usbhid_set_raw_report(hid, reportnum, buf, len, rtype); | ||
| 1232 | default: | ||
| 1233 | return -EIO; | ||
| 1234 | } | ||
| 1235 | } | ||
| 1236 | |||
| 1203 | static int usbhid_idle(struct hid_device *hid, int report, int idle, | 1237 | static int usbhid_idle(struct hid_device *hid, int report, int idle, |
| 1204 | int reqtype) | 1238 | int reqtype) |
| 1205 | { | 1239 | { |
| @@ -1223,6 +1257,8 @@ static struct hid_ll_driver usb_hid_driver = { | |||
| 1223 | .power = usbhid_power, | 1257 | .power = usbhid_power, |
| 1224 | .request = usbhid_request, | 1258 | .request = usbhid_request, |
| 1225 | .wait = usbhid_wait_io, | 1259 | .wait = usbhid_wait_io, |
| 1260 | .raw_request = usbhid_raw_request, | ||
| 1261 | .output_report = usbhid_output_report, | ||
| 1226 | .idle = usbhid_idle, | 1262 | .idle = usbhid_idle, |
| 1227 | }; | 1263 | }; |
| 1228 | 1264 | ||
| @@ -1253,7 +1289,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * | |||
| 1253 | 1289 | ||
| 1254 | usb_set_intfdata(intf, hid); | 1290 | usb_set_intfdata(intf, hid); |
| 1255 | hid->ll_driver = &usb_hid_driver; | 1291 | hid->ll_driver = &usb_hid_driver; |
| 1256 | hid->hid_get_raw_report = usbhid_get_raw_report; | ||
| 1257 | hid->hid_output_raw_report = usbhid_output_raw_report; | 1292 | hid->hid_output_raw_report = usbhid_output_raw_report; |
| 1258 | hid->ff_init = hid_pidff_init; | 1293 | hid->ff_init = hid_pidff_init; |
| 1259 | #ifdef CONFIG_USB_HIDDEV | 1294 | #ifdef CONFIG_USB_HIDDEV |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 31b9d299ef6c..60f3ff762376 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -508,9 +508,6 @@ struct hid_device { /* device report descriptor */ | |||
| 508 | struct hid_usage *, __s32); | 508 | struct hid_usage *, __s32); |
| 509 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); | 509 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); |
| 510 | 510 | ||
| 511 | /* handler for raw input (Get_Report) data, used by hidraw */ | ||
| 512 | int (*hid_get_raw_report) (struct hid_device *, unsigned char, __u8 *, size_t, unsigned char); | ||
| 513 | |||
| 514 | /* handler for raw output data, used by hidraw */ | 511 | /* handler for raw output data, used by hidraw */ |
| 515 | int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char); | 512 | int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char); |
| 516 | 513 | ||
| @@ -675,11 +672,12 @@ struct hid_driver { | |||
| 675 | * @stop: called on remove | 672 | * @stop: called on remove |
| 676 | * @open: called by input layer on open | 673 | * @open: called by input layer on open |
| 677 | * @close: called by input layer on close | 674 | * @close: called by input layer on close |
| 678 | * @hidinput_input_event: event input event (e.g. ff or leds) | ||
| 679 | * @parse: this method is called only once to parse the device data, | 675 | * @parse: this method is called only once to parse the device data, |
| 680 | * shouldn't allocate anything to not leak memory | 676 | * shouldn't allocate anything to not leak memory |
| 681 | * @request: send report request to device (e.g. feature report) | 677 | * @request: send report request to device (e.g. feature report) |
| 682 | * @wait: wait for buffered io to complete (send/recv reports) | 678 | * @wait: wait for buffered io to complete (send/recv reports) |
| 679 | * @raw_request: send raw report request to device (e.g. feature report) | ||
| 680 | * @output_report: send output report to device | ||
| 683 | * @idle: send idle request to device | 681 | * @idle: send idle request to device |
| 684 | */ | 682 | */ |
| 685 | struct hid_ll_driver { | 683 | struct hid_ll_driver { |
| @@ -691,17 +689,20 @@ struct hid_ll_driver { | |||
| 691 | 689 | ||
| 692 | int (*power)(struct hid_device *hdev, int level); | 690 | int (*power)(struct hid_device *hdev, int level); |
| 693 | 691 | ||
| 694 | int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, | ||
| 695 | unsigned int code, int value); | ||
| 696 | |||
| 697 | int (*parse)(struct hid_device *hdev); | 692 | int (*parse)(struct hid_device *hdev); |
| 698 | 693 | ||
| 699 | void (*request)(struct hid_device *hdev, | 694 | void (*request)(struct hid_device *hdev, |
| 700 | struct hid_report *report, int reqtype); | 695 | struct hid_report *report, int reqtype); |
| 701 | 696 | ||
| 702 | int (*wait)(struct hid_device *hdev); | 697 | int (*wait)(struct hid_device *hdev); |
| 703 | int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); | ||
| 704 | 698 | ||
| 699 | int (*raw_request) (struct hid_device *hdev, unsigned char reportnum, | ||
| 700 | __u8 *buf, size_t len, unsigned char rtype, | ||
| 701 | int reqtype); | ||
| 702 | |||
| 703 | int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len); | ||
| 704 | |||
| 705 | int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); | ||
| 705 | }; | 706 | }; |
| 706 | 707 | ||
| 707 | #define PM_HINT_FULLON 1<<5 | 708 | #define PM_HINT_FULLON 1<<5 |
| @@ -752,6 +753,7 @@ struct hid_field *hidinput_get_led_field(struct hid_device *hid); | |||
| 752 | unsigned int hidinput_count_leds(struct hid_device *hid); | 753 | unsigned int hidinput_count_leds(struct hid_device *hid); |
| 753 | __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code); | 754 | __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code); |
| 754 | void hid_output_report(struct hid_report *report, __u8 *data); | 755 | void hid_output_report(struct hid_report *report, __u8 *data); |
| 756 | void __hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype); | ||
| 755 | u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags); | 757 | u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags); |
| 756 | struct hid_device *hid_allocate_device(void); | 758 | struct hid_device *hid_allocate_device(void); |
| 757 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); | 759 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); |
| @@ -964,7 +966,74 @@ static inline void hid_hw_request(struct hid_device *hdev, | |||
| 964 | struct hid_report *report, int reqtype) | 966 | struct hid_report *report, int reqtype) |
| 965 | { | 967 | { |
| 966 | if (hdev->ll_driver->request) | 968 | if (hdev->ll_driver->request) |
| 967 | hdev->ll_driver->request(hdev, report, reqtype); | 969 | return hdev->ll_driver->request(hdev, report, reqtype); |
| 970 | |||
| 971 | __hid_request(hdev, report, reqtype); | ||
| 972 | } | ||
| 973 | |||
| 974 | /** | ||
| 975 | * hid_hw_raw_request - send report request to device | ||
| 976 | * | ||
| 977 | * @hdev: hid device | ||
| 978 | * @reportnum: report ID | ||
| 979 | * @buf: in/out data to transfer | ||
| 980 | * @len: length of buf | ||
| 981 | * @rtype: HID report type | ||
| 982 | * @reqtype: HID_REQ_GET_REPORT or HID_REQ_SET_REPORT | ||
| 983 | * | ||
| 984 | * @return: count of data transfered, negative if error | ||
| 985 | * | ||
| 986 | * Same behavior as hid_hw_request, but with raw buffers instead. | ||
| 987 | */ | ||
| 988 | static inline int hid_hw_raw_request(struct hid_device *hdev, | ||
| 989 | unsigned char reportnum, __u8 *buf, | ||
| 990 | size_t len, unsigned char rtype, int reqtype) | ||
| 991 | { | ||
| 992 | if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf) | ||
| 993 | return -EINVAL; | ||
| 994 | |||
| 995 | if (hdev->ll_driver->raw_request) | ||
| 996 | return hdev->ll_driver->raw_request(hdev, reportnum, buf, len, | ||
| 997 | rtype, reqtype); | ||
| 998 | |||
| 999 | return -ENOSYS; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | /** | ||
| 1003 | * hid_hw_output_report - send output report to device | ||
| 1004 | * | ||
| 1005 | * @hdev: hid device | ||
| 1006 | * @buf: raw data to transfer | ||
| 1007 | * @len: length of buf | ||
| 1008 | * | ||
| 1009 | * @return: count of data transfered, negative if error | ||
| 1010 | */ | ||
| 1011 | static inline int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, | ||
| 1012 | size_t len) | ||
| 1013 | { | ||
| 1014 | if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf) | ||
| 1015 | return -EINVAL; | ||
| 1016 | |||
| 1017 | if (hdev->ll_driver->output_report) | ||
| 1018 | return hdev->ll_driver->output_report(hdev, buf, len); | ||
| 1019 | |||
| 1020 | return -ENOSYS; | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | /** | ||
| 1024 | * hid_output_raw_report - send an output or a feature report to the device | ||
| 1025 | * | ||
| 1026 | * @hdev: hid device | ||
| 1027 | * @buf: raw data to transfer | ||
| 1028 | * @len: length of buf | ||
| 1029 | * @report_type: HID_FEATURE_REPORT or HID_OUTPUT_REPORT | ||
| 1030 | * | ||
| 1031 | * @return: count of data transfered, negative if error | ||
| 1032 | */ | ||
| 1033 | static inline int hid_output_raw_report(struct hid_device *hdev, __u8 *buf, | ||
| 1034 | size_t len, unsigned char report_type) | ||
| 1035 | { | ||
| 1036 | return hdev->hid_output_raw_report(hdev, buf, len, report_type); | ||
| 968 | } | 1037 | } |
| 969 | 1038 | ||
| 970 | /** | 1039 | /** |
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 | ||
| 226 | static 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 | |||
| 246 | static 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 | |||
| 271 | static int hidp_get_raw_report(struct hid_device *hid, | 226 | static 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 | ||
| 356 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, | 311 | static 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 | ||
| 376 | static 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 | |||
| 385 | static 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 | |||
| 397 | static 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 | |||
| 414 | static void hidp_idle_timeout(unsigned long arg) | 411 | static 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 */ |
