mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-24 07:46:48 +00:00
package: new package for usb gadget setup
Setting up usb gadgets using g_* kernel modules are considered a legacy approach, but the usb_gadget configfs is a bit annoying to use directly. The usb_gadget configfs works by creating magic directories and writing to magic files under /sys/kernel/config/usbgadget. This new package is an init script to setup usb_gadget configfs using uci. In the config file, gadget/configuration/function sections create corresponding directories. UCI options are magic files available in the configfs and strings/0x409 directories, grabbed with a 'find' command. UDC option in gadget writes the UDC file under the 'gadget' directory to attach the generated gadget config. It's also possible to apply pre-made config templates under /usr/share/usbgadget. The templates use the same UCI config format, with the 'gadget' entry named 'g1'. Currently, there are templates for CDC-ACM and CDC-NCM gadgets written based on existing g_*.ko module code. Certain SBCs come with only a USB device port (e.g. Raspberry Pi Zero). With this script, it's now possible to perform initial setup on them by adding a default NCM gadget. Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
This commit is contained in:
parent
b799dd3c70
commit
b196a9f6ce
54
package/utils/usbgadget/Makefile
Normal file
54
package/utils/usbgadget/Makefile
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=usbgadget
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
|
PKG_LICENSE:=BSD-2-Clause
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Chuanhong Guo <gch981213@gmail.com>
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/$(PKG_NAME)
|
||||||
|
SECTION:=utils
|
||||||
|
CATEGORY:=Utilities
|
||||||
|
DEPENDS:=@USB_GADGET_SUPPORT +kmod-usb-gadget +kmod-usb-lib-composite
|
||||||
|
TITLE:=init script to create USB gadgets
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(PKG_NAME)/install
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d
|
||||||
|
$(INSTALL_CONF) ./files/usbgadget.conf $(1)/etc/config/usbgadget
|
||||||
|
$(INSTALL_BIN) ./files/usbgadget.init $(1)/etc/init.d/usbgadget
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||||
|
|
||||||
|
# 1: short name
|
||||||
|
# 2: description
|
||||||
|
# 3: dependencies on other packages
|
||||||
|
define GadgetPreset
|
||||||
|
define Package/$(PKG_NAME)-$(1)
|
||||||
|
SECTION:=utils
|
||||||
|
CATEGORY:=Utilities
|
||||||
|
TITLE+= $(2) gadget preset
|
||||||
|
DEPENDS+= $(3)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(PKG_NAME)-$(1)/description
|
||||||
|
This package contains the USB gadget preset for $(3).
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(PKG_NAME)-$(1)/install
|
||||||
|
$(INSTALL_DIR) $$(1)/usr/share/usbgadget
|
||||||
|
$(INSTALL_CONF) ./files/presets/$(1) $$(1)/usr/share/usbgadget
|
||||||
|
endef
|
||||||
|
|
||||||
|
$$(eval $$(call BuildPackage,$(PKG_NAME)-$(1)))
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call GadgetPreset,ncm,CDC-NCM,+kmod-usb-gadget-ncm))
|
||||||
|
$(eval $(call GadgetPreset,acm,CDC-ACM,+kmod-usb-gadget-serial))
|
13
package/utils/usbgadget/files/presets/acm
Normal file
13
package/utils/usbgadget/files/presets/acm
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
config gadget 'g1'
|
||||||
|
option idVendor '0x0525'
|
||||||
|
option idProduct '0xa4a7'
|
||||||
|
option bDeviceClass '2'
|
||||||
|
option product 'Gadget Serial v2.4'
|
||||||
|
|
||||||
|
config configuration 'cfg1'
|
||||||
|
option configuration 'ACM'
|
||||||
|
option gadget 'g1'
|
||||||
|
|
||||||
|
config function 'acm1'
|
||||||
|
option function 'acm'
|
||||||
|
option configuration 'cfg1'
|
13
package/utils/usbgadget/files/presets/ncm
Normal file
13
package/utils/usbgadget/files/presets/ncm
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
config gadget 'g1'
|
||||||
|
option idVendor '0x0525'
|
||||||
|
option idProduct '0xa4a1'
|
||||||
|
option bDeviceClass '2'
|
||||||
|
option product 'NCM Gadget'
|
||||||
|
|
||||||
|
config configuration 'cfg1'
|
||||||
|
option configuration 'NCM'
|
||||||
|
option gadget 'g1'
|
||||||
|
|
||||||
|
config function 'ncm1'
|
||||||
|
option function 'ncm'
|
||||||
|
option configuration 'cfg1'
|
12
package/utils/usbgadget/files/usbgadget.conf
Normal file
12
package/utils/usbgadget/files/usbgadget.conf
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# apply a preset under /usr/share/usbgadget
|
||||||
|
config preset
|
||||||
|
option name 'ncm'
|
||||||
|
# specify a UDC to enable this gadget:
|
||||||
|
# option UDC 'musb-hdrc.2.auto'
|
||||||
|
|
||||||
|
# or create a custom gadget here following the content of presets:
|
||||||
|
#config gadget 'g1'
|
||||||
|
# option idVendor ...
|
||||||
|
# ...
|
||||||
|
# and add an UDC under the gadget section to enable it:
|
||||||
|
# option UDC 'musb-hdrc.2.auto'
|
144
package/utils/usbgadget/files/usbgadget.init
Normal file
144
package/utils/usbgadget/files/usbgadget.init
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
|
||||||
|
START=19
|
||||||
|
|
||||||
|
GADGET_FS=/sys/kernel/config/usb_gadget
|
||||||
|
GADGET_PRESETS_DIR=/usr/share/usbgadget
|
||||||
|
GADGET_PREFIX=owrt_
|
||||||
|
|
||||||
|
log() {
|
||||||
|
logger -t usbgadget "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_configs() {
|
||||||
|
local fs_path="$1"
|
||||||
|
local cfg="$2"
|
||||||
|
for param in $(find "$fs_path" -maxdepth 1 -type f -exec basename '{}' ';'); do
|
||||||
|
[ "$param" = "UDC" ] && continue
|
||||||
|
|
||||||
|
config_get val "$cfg" "$param"
|
||||||
|
[ -n "$val" ] && echo "$val" > "${fs_path}/${param}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_gadget() {
|
||||||
|
local cfg="$1"
|
||||||
|
local gadget_path="${GADGET_FS}/${GADGET_PREFIX}${cfg}"
|
||||||
|
local param udc
|
||||||
|
|
||||||
|
config_get udc "$cfg" UDC
|
||||||
|
[ -z "$udc" ] && return
|
||||||
|
|
||||||
|
mkdir "$gadget_path" || return
|
||||||
|
apply_configs "$gadget_path" "$cfg"
|
||||||
|
|
||||||
|
local strings_path="${gadget_path}/strings/0x409"
|
||||||
|
mkdir "$strings_path"
|
||||||
|
apply_configs "$strings_path" "$cfg"
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_configuration() {
|
||||||
|
local cfg="$1"
|
||||||
|
local gadget
|
||||||
|
config_get gadget "$cfg" gadget
|
||||||
|
local cfgs_path="${GADGET_FS}/${GADGET_PREFIX}${gadget}/configs"
|
||||||
|
[ -d "${cfgs_path}" ] || return
|
||||||
|
local cfg_path="${cfgs_path}/${cfg}.1"
|
||||||
|
mkdir "$cfg_path" || {
|
||||||
|
log "failed to create configuration ${cfg}"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_configs "$cfg_path" "$cfg"
|
||||||
|
|
||||||
|
local strings_path="${cfg_path}/strings/0x409"
|
||||||
|
mkdir "$strings_path"
|
||||||
|
apply_configs "$strings_path" "$cfg"
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_function() {
|
||||||
|
local cfg="$1"
|
||||||
|
local usbcfg gadget usbfun
|
||||||
|
|
||||||
|
config_get usbcfg "$cfg" configuration
|
||||||
|
[ -z "$usbcfg" ] && return
|
||||||
|
config_get usbfun "$cfg" function
|
||||||
|
[ -z "$usbfun" ] && return
|
||||||
|
|
||||||
|
config_get gadget "$usbcfg" gadget
|
||||||
|
local gadget_path="${GADGET_FS}/${GADGET_PREFIX}${gadget}"
|
||||||
|
local cfg_path="${gadget_path}/configs/${usbcfg}.1"
|
||||||
|
[ -d "${cfg_path}" ] || return
|
||||||
|
|
||||||
|
local fun_path="${gadget_path}/functions/${usbfun}.${cfg}"
|
||||||
|
mkdir "$fun_path" || {
|
||||||
|
log "failed to create function ${usbfun}.${cfg}"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_configs "$fun_path" "$cfg"
|
||||||
|
|
||||||
|
ln -s "$fun_path" "$cfg_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
attach_gadget() {
|
||||||
|
local cfg="$1"
|
||||||
|
local gadget_path="${GADGET_FS}/${GADGET_PREFIX}${cfg}"
|
||||||
|
local param udc
|
||||||
|
|
||||||
|
config_get udc "$cfg" UDC
|
||||||
|
[ -z "$udc" ] && return
|
||||||
|
|
||||||
|
echo "$udc" > "$gadget_path/UDC"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_gadget() {
|
||||||
|
config_foreach setup_gadget gadget
|
||||||
|
config_foreach setup_configuration configuration
|
||||||
|
config_foreach setup_function function
|
||||||
|
config_foreach attach_gadget gadget
|
||||||
|
}
|
||||||
|
|
||||||
|
# use subshell for isolated env
|
||||||
|
apply_preset() (
|
||||||
|
local preset="$1"
|
||||||
|
local gadget="$2"
|
||||||
|
UCI_CONFIG_DIR=$GADGET_PRESETS_DIR config_load "$1"
|
||||||
|
config_set g1 UDC "$2"
|
||||||
|
load_gadget
|
||||||
|
)
|
||||||
|
|
||||||
|
load_preset() {
|
||||||
|
local cfg="$1"
|
||||||
|
config_get name "$cfg" name
|
||||||
|
config_get udc "$cfg" UDC
|
||||||
|
[ -z "$udc" ] && return
|
||||||
|
apply_preset $name $udc
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
grep -q /sys/kernel/config /proc/mounts || \
|
||||||
|
mount -t configfs configfs /sys/kernel/config
|
||||||
|
|
||||||
|
[ -d /sys/kernel/config/usb_gadget ] || {
|
||||||
|
log "usb_gadget support not found."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
config_load usbgadget
|
||||||
|
config_foreach load_preset preset
|
||||||
|
load_gadget
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
for gadget_path in ${GADGET_FS}/${GADGET_PREFIX}* ; do
|
||||||
|
[ -d "$gadget_path" ] || continue
|
||||||
|
echo "" > ${gadget_path}/UDC
|
||||||
|
find ${gadget_path}/configs -maxdepth 2 -type l -exec rm '{}' ';'
|
||||||
|
rmdir ${gadget_path}/configs/*/strings/*
|
||||||
|
rmdir ${gadget_path}/configs/*
|
||||||
|
rmdir ${gadget_path}/functions/*
|
||||||
|
rmdir ${gadget_path}/strings/*
|
||||||
|
rmdir $gadget_path
|
||||||
|
done
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user