02 Oct, 2014

1 commit

  • When uhid_get_report() or uhid_set_report() are called, they emit on the
    char device a UHID_GET_REPORT or UHID_SET_REPORT message. Then, the
    protocol says that the user space asnwers with UHID_GET_REPORT_REPLY
    or UHID_SET_REPORT_REPLY.

    Unfortunatelly, the current code waits for an event of type UHID_GET_REPORT
    or UHID_SET_REPORT instead of the reply one.
    Add 1 to UHID_GET_REPORT or UHID_SET_REPORT to actually wait for the
    reply, and validate the reply.

    Signed-off-by: Benjamin Tissoires
    Reviewed-by: David Herrmann
    Signed-off-by: Jiri Kosina

    Benjamin Tissoires
     

25 Aug, 2014

10 commits

  • This makes UHID_START include a "dev_flags" field that describes details
    of the hid-device in the kernel. The first flags we introduce describe
    whether a given report-type uses numbered reports. This is useful for
    transport layers that force report-numbers and therefore might have to
    prefix kernel-provided HID-messages with the report-number.

    Currently, only HoG needs this and the spec only talks about "global
    report numbers". That is, it's a global boolean not a per-type boolean.
    However, given the quirks we already have in kernel-space, a per-type
    value seems much more appropriate.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • We so far lacked support for hid_hw_raw_request(..., HID_REQ_SET_REPORT);
    Add support for it and simply forward the request to user-space. Note that
    SET_REPORT is synchronous, just like GET_REPORT, even though it does not
    provide any data back besides an error code.

    If a transport layer does SET_REPORT asynchronously, they can just ACK it
    immediately by writing an uhid_set_report_reply to uhid.

    This patch re-uses the synchronous uhid-report infrastructure to query
    user-space. Note that this means you cannot run SET_REPORT and GET_REPORT
    in parallel. However, that has always been a restriction of HID and due to
    its blocking nature, this is just fine. Maybe some future transport layer
    supports parallel requests (very unlikely), however, until then lets not
    over-complicate things and avoid request-lookup-tables.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • We use strict prefixed in uhid.c:
    uhid_char_*: implement char-dev callbacks
    uhid_dev_*: implement uhid device management and runtime
    uhid_hid_*: implement hid-dev callbacks

    uhid_raw_request is an hid callback, so rename it to uhid_hid_raw_request.

    While at it, move it closer to it's extracted helpers and keep the same
    order as in "struct hid_driver".

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • The old hdev->hid_get_raw_report() was broken by design. It was never
    clear what kind of HW request it should trigger. Benjamin fixed that with
    the core HID cleanup, though we never really adjusted uhid.

    Unfortunately, our old UHID_FEATURE command was modelled around the broken
    hid_get_raw_report(). We converted it silently to the new GET_REPORT and
    nothing broke. Make this explicit by renaming UHID_FEATURE to
    UHID_GET_REPORT and UHID_FEATURE_ANSWER to UHID_GET_REPORT_REPLY.

    Note that this is 100% ABI compatible to UHID_FEATURE. This is just a
    rename. But we have to keep the old definitions around to not break API.

    >From now on, UHID_GET_REPORT must trigger a GET_REPORT request on the
    user-space hardware layer. All the ambiguity due to the weird "feature"
    name should be gone now.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • All accesses to @report_done are protected by qlock (or report-contexts).
    No need to use an atomic.

    While at it, invert the logic and call it "report_running". This is
    similar to the uhid->running field and easier to read.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • All accesses to @report_id are protected by @qlock. No need to use an
    atomic.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Avoid hard-coding the target buffer sizes and use sizeof() instead. This
    also makes us future-proof to buffer-extensions later on.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Avoid keeping uhid->rd_data and uhid->rd_size set in case
    uhid_dev_create2() fails. This is non-critical as we never flip
    uhid->running and thus never enter uhid_dev_destroy(). However, it's much
    nicer for debugging if pointers are only set if they point to valid data.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Instead of hard-coding the uhid_dev_create() function twice, copy any
    create_req into a create2_req structure and forward it.

    We allocate uhid_create_req on the stack here, but that should be fine.
    Unlike uhid_create2_req it is fairly small (
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • The report-query is blocking, so when user-space destroys a device we have
    to wake up any blocking kernel context that is currently in the report-cb.
    We used some broken correlation between @report_done and @running so far.
    Replace it by a much more obvious use.

    We now wake up the report-cb if either @report_done or @running is set.
    wake_up() and wait_event() serve as implicit barriers (as they always do)
    so no need to use smp_rmb/wmb directly.

    Note that @report_done is never reset by anyone but the report-cb, thus
    it cannot flip twice while we wait for it. And whenever we set @running,
    we afterwards synchronously remove the HID device. Therefore, we wait for
    all report-cbs to finish before we return. This way, @running can never
    flip to true while we wait for it.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     

27 May, 2014

1 commit


02 Apr, 2014

1 commit

  • UHID_CREATE2:
    HID report descriptor data (rd_data) is an array in struct uhid_create2_req,
    instead of a pointer. Enables use from languages that don't support pointers,
    e.g. Python.

    UHID_INPUT2:
    Data array is the last field of struct uhid_input2_req. Enables userspace to
    write only the required bytes to kernel (ev.type + ev.u.input2.size + the part
    of the data array that matters), instead of the entire struct uhid_input2_req.

    Note:
    UHID_CREATE2 increases the total size of struct uhid_event slightly, thus
    increasing the size of messages that are queued for userspace. However, this
    won't affect the userspace processing of these events.

    [Jiri Kosina : adjust to hid_get_raw_report() and
    hid_output_raw_report() API changes]

    Signed-off-by: Petri Gynther
    Reviewed-by: David Herrmann
    Signed-off-by: Jiri Kosina

    Petri Gynther
     

14 Mar, 2014

1 commit


17 Feb, 2014

5 commits


29 Jan, 2014

1 commit


27 Nov, 2013

1 commit

  • UHID allows short writes so user-space can omit unused fields. We
    automatically set them to 0 in the kernel. However, the 64/32 bit
    compat-handler didn't do that in the UHID_CREATE fallback. This will
    reveal random kernel heap data (of random size, even) to user-space.

    Fixes: befde0226a59 ('HID: uhid: make creating devices work on 64/32 systems')

    Reported-by: Ben Hutchings
    Signed-off-by: David Herrmann
    Cc: stable@vger.kernel.org
    Signed-off-by: Jiri Kosina

    David Herrmann
     

26 Sep, 2013

1 commit

  • udev has this nice feature of creating "dead" /dev/ device-nodes if
    it finds a devnode: modalias. Once the node is accessed, the kernel
    automatically loads the module that provides the node. However, this
    requires udev to know the major:minor code to use for the node. This
    feature was introduced by:

    commit 578454ff7eab61d13a26b568f99a89a2c9edc881
    Author: Kay Sievers
    Date: Thu May 20 18:07:20 2010 +0200

    driver core: add devname module aliases to allow module on-demand auto-loading

    However, uhid uses dynamic minor numbers so this doesn't actually work. We
    need to load uhid to know which minor it's going to use.

    Hence, allocate a static minor (just like uinput does) and we're good
    to go.

    Reported-by: Tom Gundersen
    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     

06 Sep, 2013

1 commit


02 Sep, 2013

1 commit


31 Jul, 2013

1 commit

  • HID core provides the same functionality and can convert the input event
    to a raw output report. We can thus drop UHID_OUTPUT_EV and rely on the
    mandatory UHID_OUTPUT.

    User-space wasn't able to do anything with UHID_OUTPUT_EV, anyway. They
    don't have access to the report fields.

    Signed-off-by: David Herrmann
    Acked-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    David Herrmann
     

18 Feb, 2013

1 commit

  • Unfortunately UHID interface, as it was introduced, is broken with 32 bit
    userspace running on 64 bit kernels as it uses a pointer in its userspace
    facing API.

    Fix it by checking if we are executing compat task and munge the request
    appropriately.

    Reported-by: Kirill A. Shutemov
    Acked-by: Kirill A. Shutemov
    Signed-off-by: Dmitry Torokhov
    Signed-off-by: Jiri Kosina

    Dmitry Torokhov
     

20 Jul, 2012

1 commit


18 Jun, 2012

13 commits

  • gcc is giving me:

    drivers/hid/uhid.c: In function ‘uhid_hid_get_raw’:
    drivers/hid/uhid.c:157: warning: ‘len’ may be used uninitialized in this function

    which is clearly bogus, as

    - when used as memcpy() argument, it's initialized properly
    - the code is structured in a way that either 'ret' or 'len'
    is always initialized, so the return statement always has
    an initialized value.

    Signed-off-by: Jiri Kosina

    Jiri Kosina
     
  • HID standard allows sending a feature request to the device which is
    answered by an HID report. uhid implements this by sending a UHID_FEATURE
    event to user-space which then must answer with UHID_FEATURE_ANSWER. If it
    doesn't do this in a timely manner, the request is discarded silently.

    We serialize the feature requests, that is, there is always only a single
    active feature-request sent to user-space, other requests have to wait.
    HIDP and USB-HID do it the same way.

    Because we discard feature-requests silently, we must make sure to match
    a response to the corresponding request. We use sequence-IDs for this so
    user-space must copy the ID from the request into the answer.
    Feature-answers are ignored if they do not contain the same ID as the
    currently pending feature request.

    Internally, we must make sure that feature-requests are synchronized with
    UHID_DESTROY and close() events. We must not dead-lock when closing the
    HID device, either, so we have to use separate locks.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Some drivers that use non-standard HID features require raw output reports
    sent to the device. We now forward these requests directly to user-space
    so the transport-level driver can correctly send it to the device or
    handle it correspondingly.

    There is no way to signal back whether the transmission was successful,
    moreover, there might be lots of messages coming out from the driver
    flushing the output-queue. However, there is currently no driver that
    causes this so we are safe. If some drivers need to transmit lots of data
    this way, we need a method to synchronize this and can implement another
    UHID_OUTPUT_SYNC event.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • If the hid-driver wants to send standardized data to the device it uses a
    linux input_event. We forward this to the user-space transport-level
    driver so they can perform the requested action on the device.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • HID core notifies us with *_open/*_close callbacks when there is an actual
    user of our device. We forward these to user-space so they can react on
    this. This allows user-space to skip I/O unless they receive an OPEN
    event. When they receive a CLOSE event they can stop I/O again to save
    energy.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • We send UHID_START and UHID_STOP events to user-space when the HID core
    starts/stops the device. This notifies user-space about driver readiness
    and data-I/O can start now.

    This directly forwards the callbacks from hid-core to user-space.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • When the uhid_hid_parse callback is called we simply forward it to
    hid_parse_report() with the data that we got in the UHID_CREATE event.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • This adds a new event type UHID_INPUT which allows user-space to feed raw
    HID reports into the HID subsystem. We copy the data into kernel memory
    and directly feed it into the HID core.

    There is no error handling of the events couldn't be parsed so user-space
    should consider all events successfull unless read() returns an error.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • UHID_CREATE and UHID_DESTROY are used to create and destroy a device on an
    open uhid char-device. Internally, we allocate and register an HID device
    with the HID core and immediately start the device. From now on events may
    be received or sent to the device.

    The UHID_CREATE event has a payload similar to the data used by
    Bluetooth-HIDP when creating a new connection.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Similar to read() you can only write() a single event with one call to an
    uhid device. To write multiple events use writev() which is supported by
    uhid.

    We currently always return -EOPNOTSUPP but other events will be added in
    later patches.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • User-space can use read() to get a single event from uhid devices. read()
    does never return multiple events. This allows us to extend the event
    structure and still keep backwards compatibility.

    If user-space wants to get multiple events in one syscall, they should use
    the readv()/writev() syscalls which are supported by uhid.

    This introduces a new lock which helps us synchronizing simultaneous reads
    from user-space. We also correctly return -EINVAL/-EFAULT only on errors
    and retry the read() when some other thread captured the event faster than
    we did.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • As long as the internal buffer is not empty, we return POLLIN to
    user-space.

    uhid->head and uhid->tail are no atomics so the comparison may return
    inexact results. However, this doesn't matter here as user-space would
    need to poll() in two threads simultaneously to trigger this. And in this
    case it doesn't matter if a cached result is returned or the exact new
    result as user-space does not know which thread returns first from poll()
    and the following read(). So it is safe to compare the values without
    locking.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • When receiving messages from the HID subsystem, we need to process them
    and store them in an internal buffer so user-space can read() on the char
    device to retrieve the messages.

    This adds a static buffer for 32 messages to each uhid device. Each
    message is dynamically allocated so the uhid_device structure does not get
    too big.

    uhid_queue() adds a message to the buffer. If the buffer is full, the
    message is discarded. uhid_queue_event() is an helper for messages without
    payload.

    This also adds a public header: uhid.h. It contains the declarations for
    the user-space API. It is built around "struct uhid_event" which contains
    a type field which specifies the event type and each event can then add a
    variable-length payload. For now, there is only a dummy event but later
    patches will add new event types and payloads.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann