brintos

brintos / linux-shallow public Read only

0
0
Text · 9.3 KiB · 2243a6b Raw
194 lines · plain
1======================================================2UHID - User-space I/O driver support for HID subsystem3======================================================4 5UHID allows user-space to implement HID transport drivers. Please see6hid-transport.rst for an introduction into HID transport drivers. This document7relies heavily on the definitions declared there.8 9With UHID, a user-space transport driver can create kernel hid-devices for each10device connected to the user-space controlled bus. The UHID API defines the I/O11events provided from the kernel to user-space and vice versa.12 13There is an example user-space application in ./samples/uhid/uhid-example.c14 15The UHID API16------------17 18UHID is accessed through a character misc-device. The minor number is allocated19dynamically so you need to rely on udev (or similar) to create the device node.20This is /dev/uhid by default.21 22If a new device is detected by your HID I/O Driver and you want to register this23device with the HID subsystem, then you need to open /dev/uhid once for each24device you want to register. All further communication is done by read()'ing or25write()'ing "struct uhid_event" objects. Non-blocking operations are supported26by setting O_NONBLOCK::27 28  struct uhid_event {29        __u32 type;30        union {31                struct uhid_create2_req create2;32                struct uhid_output_req output;33                struct uhid_input2_req input2;34                ...35        } u;36  };37 38The "type" field contains the ID of the event. Depending on the ID different39payloads are sent. You must not split a single event across multiple read()'s or40multiple write()'s. A single event must always be sent as a whole. Furthermore,41only a single event can be sent per read() or write(). Pending data is ignored.42If you want to handle multiple events in a single syscall, then use vectored43I/O with readv()/writev().44The "type" field defines the payload. For each type, there is a45payload-structure available in the union "u" (except for empty payloads). This46payload contains management and/or device data.47 48The first thing you should do is send a UHID_CREATE2 event. This will49register the device. UHID will respond with a UHID_START event. You can now50start sending data to and reading data from UHID. However, unless UHID sends the51UHID_OPEN event, the internally attached HID Device Driver has no user attached.52That is, you might put your device asleep unless you receive the UHID_OPEN53event. If you receive the UHID_OPEN event, you should start I/O. If the last54user closes the HID device, you will receive a UHID_CLOSE event. This may be55followed by a UHID_OPEN event again and so on. There is no need to perform56reference-counting in user-space. That is, you will never receive multiple57UHID_OPEN events without a UHID_CLOSE event. The HID subsystem performs58ref-counting for you.59You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even60though the device may have no users.61 62If you want to send data on the interrupt channel to the HID subsystem, you send63a HID_INPUT2 event with your raw data payload. If the kernel wants to send data64on the interrupt channel to the device, you will read a UHID_OUTPUT event.65Data requests on the control channel are currently limited to GET_REPORT and66SET_REPORT (no other data reports on the control channel are defined so far).67Those requests are always synchronous. That means, the kernel sends68UHID_GET_REPORT and UHID_SET_REPORT events and requires you to forward them to69the device on the control channel. Once the device responds, you must forward70the response via UHID_GET_REPORT_REPLY and UHID_SET_REPORT_REPLY to the kernel.71The kernel blocks internal driver-execution during such round-trips (times out72after a hard-coded period).73 74If your device disconnects, you should send a UHID_DESTROY event. This will75unregister the device. You can now send UHID_CREATE2 again to register a new76device.77If you close() the fd, the device is automatically unregistered and destroyed78internally.79 80write()81-------82write() allows you to modify the state of the device and feed input data into83the kernel. The kernel will parse the event immediately and if the event ID is84not supported, it will return -EOPNOTSUPP. If the payload is invalid, then85-EINVAL is returned, otherwise, the amount of data that was read is returned and86the request was handled successfully. O_NONBLOCK does not affect write() as87writes are always handled immediately in a non-blocking fashion. Future requests88might make use of O_NONBLOCK, though.89 90UHID_CREATE2:91  This creates the internal HID device. No I/O is possible until you send this92  event to the kernel. The payload is of type struct uhid_create2_req and93  contains information about your device. You can start I/O now.94 95UHID_DESTROY:96  This destroys the internal HID device. No further I/O will be accepted. There97  may still be pending messages that you can receive with read() but no further98  UHID_INPUT events can be sent to the kernel.99  You can create a new device by sending UHID_CREATE2 again. There is no need to100  reopen the character device.101 102UHID_INPUT2:103  You must send UHID_CREATE2 before sending input to the kernel! This event104  contains a data-payload. This is the raw data that you read from your device105  on the interrupt channel. The kernel will parse the HID reports.106 107UHID_GET_REPORT_REPLY:108  If you receive a UHID_GET_REPORT request you must answer with this request.109  You  must copy the "id" field from the request into the answer. Set the "err"110  field to 0 if no error occurred or to EIO if an I/O error occurred.111  If "err" is 0 then you should fill the buffer of the answer with the results112  of the GET_REPORT request and set "size" correspondingly.113 114UHID_SET_REPORT_REPLY:115  This is the SET_REPORT equivalent of UHID_GET_REPORT_REPLY. Unlike GET_REPORT,116  SET_REPORT never returns a data buffer, therefore, it's sufficient to set the117  "id" and "err" fields correctly.118 119read()120------121read() will return a queued output report. No reaction is required to any of122them but you should handle them according to your needs.123 124UHID_START:125  This is sent when the HID device is started. Consider this as an answer to126  UHID_CREATE2. This is always the first event that is sent. Note that this127  event might not be available immediately after write(UHID_CREATE2) returns.128  Device drivers might require delayed setups.129  This event contains a payload of type uhid_start_req. The "dev_flags" field130  describes special behaviors of a device. The following flags are defined:131 132      - UHID_DEV_NUMBERED_FEATURE_REPORTS133      - UHID_DEV_NUMBERED_OUTPUT_REPORTS134      - UHID_DEV_NUMBERED_INPUT_REPORTS135 136          Each of these flags defines whether a given report-type uses numbered137          reports. If numbered reports are used for a type, all messages from138          the kernel already have the report-number as prefix. Otherwise, no139          prefix is added by the kernel.140          For messages sent by user-space to the kernel, you must adjust the141          prefixes according to these flags.142 143UHID_STOP:144  This is sent when the HID device is stopped. Consider this as an answer to145  UHID_DESTROY.146 147  If you didn't destroy your device via UHID_DESTROY, but the kernel sends an148  UHID_STOP event, this should usually be ignored. It means that the kernel149  reloaded/changed the device driver loaded on your HID device (or some other150  maintenance actions happened).151 152  You can usually ignore any UHID_STOP events safely.153 154UHID_OPEN:155  This is sent when the HID device is opened. That is, the data that the HID156  device provides is read by some other process. You may ignore this event but157  it is useful for power-management. As long as you haven't received this event158  there is actually no other process that reads your data so there is no need to159  send UHID_INPUT2 events to the kernel.160 161UHID_CLOSE:162  This is sent when there are no more processes which read the HID data. It is163  the counterpart of UHID_OPEN and you may as well ignore this event.164 165UHID_OUTPUT:166  This is sent if the HID device driver wants to send raw data to the I/O167  device on the interrupt channel. You should read the payload and forward it to168  the device. The payload is of type "struct uhid_output_req".169  This may be received even though you haven't received UHID_OPEN yet.170 171UHID_GET_REPORT:172  This event is sent if the kernel driver wants to perform a GET_REPORT request173  on the control channel as described in the HID specs. The report-type and174  report-number are available in the payload.175  The kernel serializes GET_REPORT requests so there will never be two in176  parallel. However, if you fail to respond with a UHID_GET_REPORT_REPLY, the177  request might silently time out.178  Once you read a GET_REPORT request, you shall forward it to the HID device and179  remember the "id" field in the payload. Once your HID device responds to the180  GET_REPORT (or if it fails), you must send a UHID_GET_REPORT_REPLY to the181  kernel with the exact same "id" as in the request. If the request already182  timed out, the kernel will ignore the response silently. The "id" field is183  never re-used, so conflicts cannot happen.184 185UHID_SET_REPORT:186  This is the SET_REPORT equivalent of UHID_GET_REPORT. On receipt, you shall187  send a SET_REPORT request to your HID device. Once it replies, you must tell188  the kernel about it via UHID_SET_REPORT_REPLY.189  The same restrictions as for UHID_GET_REPORT apply.190 191----------------------------------------------------192 193Written 2012, David Herrmann <dh.herrmann@gmail.com>194