问题
有客户使用Linux中的USB Gadget功能,把MPSoC器件做USB从设备。在执行“mkdir functions/.”时,得到错误“Device or resource busy”。
代码语言:javascript复制mkdir: can't create directory 'functions/ffs.usb0': Device or resource busy
分析
根据配置项CONFIG_USB_F_FS分析对应的代码drivers/usb/gadget/function/f_fs.c, 使能其中的调试信息,并增加额外的调试信息,发现_ffs_alloc_dev中的_ffs_get_single_dev得到了有效指针,就会返回EBUSY。_ffs_get_single_dev返回的指针,从链表ffs_devices中获取。
代码语言:javascript复制static struct ffs_dev *_ffs_alloc_dev(void)
{
struct ffs_dev *dev;
int ret;
if (_ffs_get_single_dev()) {
return ERR_PTR(-EBUSY);
}
......
return dev;
}
继续跟踪代码,发现drivers/usb/gadget/legacy/g_ffs.c中向链表ffs_devices添加了设备。
因此禁止g_ffs.c对应的配置CONFIG_USB_FUNCTIONFS,再次使用USB gadget功能,没有错误“Device or resource busy”。
创建USB gadget功能的脚本
代码语言:javascript复制#!/bin/sh
echo "USB ffs init"
uname -a
CONFIGFS_HOME=/sys/kernel/config
echo $CONFIGFS_HOME
modprobe libcomposite
mount none $CONFIGFS_HOME -t configfs
ls -l $CONFIGFS_HOME
mkdir $CONFIGFS_HOME/usb_gadget/hkug
ls -l $CONFIGFS_HOME/usb_gadget/hkug
cd $CONFIGFS_HOME/usb_gadget/hkug
pwd
echo 0x0104 > idProduct
echo 0x1d6b > idVendor
mkdir strings/0x409
ls -l strings/0x409
echo hkug12345678 > strings/0x409/serialnumber
echo hkug > strings/0x409/manufacturer
echo hkugtester > strings/0x409/product
mkdir configs/hkugcfgname.1
ls -l configs/hkugcfgname.1
mkdir configs/hkugcfgname.1/strings/0x409
ls -l configs/hkugcfgname.1/strings/0x409
echo hkugtcfg > configs/hkugcfgname.1/strings/0x409/configuration
echo 120 > configs/hkugcfgname.1/MaxPower
echo "functions/ffs.usb0"
mkdir functions/ffs.usb0
ls -l functions/ffs.usb0
ln -s functions/ffs.usb0 configs/c.1
echo "UDC"
# echo <udc name> > UDC
echo hkug > UDC
ls /sys/class/udc/
ls /sys/class/udc/ > UDC
其它
CONFIG_USB_F_FS(USB_F_FS)的定义在文件drivers/usb/gadget/Kconfig:
代码语言:javascript复制config USB_F_FS
tristate
CONFIG_USB_FUNCTIONFS(USB_FUNCTIONFS)的定义在文件drivers/usb/gadget/Kconfig:
代码语言:javascript复制config USB_FUNCTIONFS
tristate "Function Filesystem"
select USB_LIBCOMPOSITE
select USB_F_FS
select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS)
help
The Function Filesystem (FunctionFS) lets one create USB
composite functions in user space in the same way GadgetFS
lets one create USB gadgets in user space. This allows creation
of composite gadgets such that some of the functions are
implemented in kernel space (for instance Ethernet, serial or
mass storage) and other are implemented in user space.
If you say "y" or "m" here you will be able what kind of
configurations the gadget will provide.
Say "y" to link the driver statically, or "m" to build
a dynamically linked module called "g_ffs".
奇怪的是,会主动选择CONFIG_USB_F_FS。
参考文档
Linux USB gadget configured through configfs
USB 协议核心概念与实践