作者:付汉杰 hankf@amd.com
问题
有客户使用Linux中的USB Gadget功能,把MPSoC器件做USB从设备。在执行“mkdir functions/
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中获取。
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功能的脚本
#!/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:
config USB_F_FS tristate
CONFIG_USB_FUNCTIONFS(USB_FUNCTIONFS)的定义在文件drivers/usb/gadget/Kconfig:
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。
参考文档