Skip to content

Commit

Permalink
usb: gadget: add raw-gadget interface
Browse files Browse the repository at this point in the history
USB Raw Gadget is a kernel module that provides a userspace interface for
the USB Gadget subsystem. Essentially it allows to emulate USB devices
from userspace. Enabled with CONFIG_USB_RAW_GADGET. Raw Gadget is
currently a strictly debugging feature and shouldn't be used in
production.

Raw Gadget is similar to GadgetFS, but provides a more low-level and
direct access to the USB Gadget layer for the userspace. The key
differences are:

1. Every USB request is passed to the userspace to get a response, while
   GadgetFS responds to some USB requests internally based on the provided
   descriptors. However note, that the UDC driver might respond to some
   requests on its own and never forward them to the Gadget layer.

2. GadgetFS performs some sanity checks on the provided USB descriptors,
   while Raw Gadget allows you to provide arbitrary data as responses to
   USB requests.

3. Raw Gadget provides a way to select a UDC device/driver to bind to,
   while GadgetFS currently binds to the first available UDC.

4. Raw Gadget uses predictable endpoint names (handles) across different
   UDCs (as long as UDCs have enough endpoints of each required transfer
   type).

5. Raw Gadget has ioctl-based interface instead of a filesystem-based one.

Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Change-Id: If35d66c52119c76ba27787ada23b3c00c7208975
  • Loading branch information
xairy committed Nov 29, 2019
1 parent e5a1f73 commit 32b5e2b
Show file tree
Hide file tree
Showing 6 changed files with 1,294 additions and 0 deletions.
1 change: 1 addition & 0 deletions Documentation/usb/index.rst
Expand Up @@ -22,6 +22,7 @@ USB support
misc_usbsevseg
mtouchusb
ohci
raw-gadget
rio
usbip_protocol
usbmon
Expand Down
60 changes: 60 additions & 0 deletions Documentation/usb/raw-gadget.rst
@@ -0,0 +1,60 @@
==============
USB Raw Gadget
==============

USB Raw Gadget is a kernel module that provides a userspace interface for
the USB Gadget subsystem. Essentially it allows to emulate USB devices
from userspace. Enabled with CONFIG_USB_RAW_GADGET. Raw Gadget is
currently a strictly debugging feature and shouldn't be used in
production, use GadgetFS instead.

Comparison to GadgetFS
~~~~~~~~~~~~~~~~~~~~~~

Raw Gadget is similar to GadgetFS, but provides a more low-level and
direct access to the USB Gadget layer for the userspace. The key
differences are:

1. Every USB request is passed to the userspace to get a response, while
GadgetFS responds to some USB requests internally based on the provided
descriptors. However note, that the UDC driver might respond to some
requests on its own and never forward them to the Gadget layer.

2. GadgetFS performs some sanity checks on the provided USB descriptors,
while Raw Gadget allows you to provide arbitrary data as responses to
USB requests.

3. Raw Gadget provides a way to select a UDC device/driver to bind to,
while GadgetFS currently binds to the first available UDC.

4. Raw Gadget uses predictable endpoint names (handles) across different
UDCs (as long as UDCs have enough endpoints of each required transfer
type).

5. Raw Gadget has ioctl-based interface instead of a filesystem-based one.

Userspace interface
~~~~~~~~~~~~~~~~~~~

To create a Raw Gadget instance open /sys/kernel/debug/usb/raw-gadget
(debugfs should be enabled and mounted). Multiple raw-gadget instances
(bound to different UDCs) can be used at the same time. The interaction
with the opened file happens through the ioctl() calls, see comments in
include/uapi/linux/usb/raw_gadget.h for details.

The typical usage of Raw Gadget looks like:

1. Open Raw Gadget instance via /sys/kernel/debug/usb/raw-gadget.
2. Initialize the instance via USB_RAW_IOCTL_INIT.
3. Launch the instance with USB_RAW_IOCTL_RUN.
4. In a loop issue USB_RAW_IOCTL_EVENT_FETCH calls to receive events from
Raw Gadget and react to those depending on what kind of USB device
needs to be emulated.

Potential future improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- Implement ioctl's for setting/clearing halt status on endpoints.

- Reporting more events (suspend, resume, etc.) through
USB_RAW_IOCTL_EVENT_FETCH.
8 changes: 8 additions & 0 deletions drivers/usb/gadget/legacy/Kconfig
Expand Up @@ -489,3 +489,11 @@ config USB_G_WEBCAM

Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "g_webcam".

config USB_RAW_GADGET
tristate "USB Raw Gadget"
help
USB Raw Gadget is a kernel module that provides a userspace interface
for the USB Gadget subsystem. Essentially it allows to emulate USB
devices from userspace. See Documentation/usb/raw-gadget.rst for
details.
1 change: 1 addition & 0 deletions drivers/usb/gadget/legacy/Makefile
Expand Up @@ -43,3 +43,4 @@ obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o
obj-$(CONFIG_USB_G_NCM) += g_ncm.o
obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o
obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o
obj-$(CONFIG_USB_RAW_GADGET) += raw.o

0 comments on commit 32b5e2b

Please sign in to comment.