0001 ==============
0002 USB Raw Gadget
0003 ==============
0004
0005 USB Raw Gadget is a gadget driver that gives userspace low-level control over
0006 the gadget's communication process.
0007
0008 Like any other gadget driver, Raw Gadget implements USB devices via the
0009 USB gadget API. Unlike most gadget drivers, Raw Gadget does not implement
0010 any concrete USB functions itself but requires userspace to do that.
0011
0012 Raw Gadget is currently a strictly debugging feature and should not be used
0013 in production. Use GadgetFS instead.
0014
0015 Enabled with CONFIG_USB_RAW_GADGET.
0016
0017 Comparison to GadgetFS
0018 ~~~~~~~~~~~~~~~~~~~~~~
0019
0020 Raw Gadget is similar to GadgetFS but provides more direct access to the
0021 USB gadget layer for userspace. The key differences are:
0022
0023 1. Raw Gadget passes every USB request to userspace to get a response, while
0024 GadgetFS responds to some USB requests internally based on the provided
0025 descriptors. Note that the UDC driver might respond to some requests on
0026 its own and never forward them to the gadget layer.
0027
0028 2. Raw Gadget allows providing arbitrary data as responses to USB requests,
0029 while GadgetFS performs sanity checks on the provided USB descriptors.
0030 This makes Raw Gadget suitable for fuzzing by providing malformed data as
0031 responses to USB requests.
0032
0033 3. Raw Gadget provides a way to select a UDC device/driver to bind to,
0034 while GadgetFS currently binds to the first available UDC. This allows
0035 having multiple Raw Gadget instances bound to different UDCs.
0036
0037 4. Raw Gadget explicitly exposes information about endpoints addresses and
0038 capabilities. This allows the user to write UDC-agnostic gadgets.
0039
0040 5. Raw Gadget has an ioctl-based interface instead of a filesystem-based
0041 one.
0042
0043 Userspace interface
0044 ~~~~~~~~~~~~~~~~~~~
0045
0046 The user can interact with Raw Gadget by opening ``/dev/raw-gadget`` and
0047 issuing ioctl calls; see the comments in include/uapi/linux/usb/raw_gadget.h
0048 for details. Multiple Raw Gadget instances (bound to different UDCs) can be
0049 used at the same time.
0050
0051 A typical usage scenario of Raw Gadget:
0052
0053 1. Create a Raw Gadget instance by opening ``/dev/raw-gadget``.
0054 2. Initialize the instance via ``USB_RAW_IOCTL_INIT``.
0055 3. Launch the instance with ``USB_RAW_IOCTL_RUN``.
0056 4. In a loop issue ``USB_RAW_IOCTL_EVENT_FETCH`` to receive events from
0057 Raw Gadget and react to those depending on what kind of USB gadget must
0058 be implemented.
0059
0060 Note that some UDC drivers have fixed addresses assigned to endpoints, and
0061 therefore arbitrary endpoint addresses cannot be used in the descriptors.
0062 Nevertheless, Raw Gadget provides a UDC-agnostic way to write USB gadgets.
0063 Once ``USB_RAW_EVENT_CONNECT`` is received via ``USB_RAW_IOCTL_EVENT_FETCH``,
0064 ``USB_RAW_IOCTL_EPS_INFO`` can be used to find out information about the
0065 endpoints that the UDC driver has. Based on that, userspace must choose UDC
0066 endpoints for the gadget and assign addresses in the endpoint descriptors
0067 correspondingly.
0068
0069 Raw Gadget usage examples and a test suite:
0070
0071 https://github.com/xairy/raw-gadget
0072
0073 Internal details
0074 ~~~~~~~~~~~~~~~~
0075
0076 Every Raw Gadget endpoint read/write ioctl submits a USB request and waits
0077 until its completion. This is done deliberately to assist with coverage-guided
0078 fuzzing by having a single syscall fully process a single USB request. This
0079 feature must be kept in the implementation.
0080
0081 Potential future improvements
0082 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0083
0084 - Report more events (suspend, resume, etc.) through
0085 ``USB_RAW_IOCTL_EVENT_FETCH``.
0086
0087 - Support ``O_NONBLOCK`` I/O. This would be another mode of operation, where
0088 Raw Gadget would not wait until the completion of each USB request.
0089
0090 - Support USB 3 features (accept SS endpoint companion descriptor when
0091 enabling endpoints; allow providing ``stream_id`` for bulk transfers).
0092
0093 - Support ISO transfer features (expose ``frame_number`` for completed
0094 requests).