linux 4.4 USB Gadget Mass Stroage
硬件平台: licheepi nano衍生
调试记录
驱动信息
│ This driver is a replacement for now removed File-backed │
│ Storage Gadget (g_file_storage). │
│ │
│ Say "y" to link the driver statically, or "m" to build │
│ a dynamically linked module called "g_mass_storage". │
│ │
│ Symbol: USB_MASS_STORAGE [=m] │
│ Type : tristate │
│ Prompt: Mass Storage Gadget │
│ Location: │
│ -> Device Drivers │
│ -> USB support (USB_SUPPORT [=y]) │
│ -> USB Gadget Support (USB_GADGET [=m]) │
│ -> USB Gadget precomposed configurations (<choice> [=m]) │
│ Defined at drivers/usb/gadget/legacy/Kconfig:240 │
│ Depends on: <choice> && BLOCK [=y] │
│ Selects: USB_LIBCOMPOSITE [=m] && USB_F_MASS_STORAGE [=m]
config位置
[*] Device drivers
[*] USB Support
[M] USB Gadget Support
[M] Mass Storage Gadget
dt node信息
// suniv.dtsi
usb_otg: usb@1c13000 {
compatible = "allwinner,suniv-f1c100s-musb";
reg = <0x01c13000 0x0400>;
clocks = <&ccu CLK_BUS_OTG>;
resets = <&ccu RST_BUS_OTG>;
interrupts = <26>;
interrupt-names = "mc";
phys = <&usbphy 0>;
phy-names = "usb";
extcon = <&usbphy 0>;
allwinner,sram = <&otg_sram 1>;
status = "disabled";
};
// suniv-f1c100s-lichee-nano.dts
&usb_otg {
dr_mode = "peripheral";
status = "okay";
};
err log
[ 40.564794] musb-sunxi 1c13000.usb: Invalid or missing \'dr_mode\' property
[ 40.578424] musb-sunxi: probe of 1c13000.usb failed with error -22
err log相关代码
// drivers/usb/musb/sunxi.c sunxi.ko
static int sunxi_musb_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data pdata;
struct platform_device_info pinfo;
struct sunxi_glue *glue;
struct device_node *np = pdev->dev.of_node;
int ret;
if (!np) {
dev_err(&pdev->dev, "Error no device tree node found\n");
return -EINVAL;
}
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
if (!glue)
return -ENOMEM;
memset(&pdata, 0, sizeof(pdata));
switch (usb_get_dr_mode(&pdev->dev)) {
#if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST
case USB_DR_MODE_HOST:
pdata.mode = MUSB_PORT_MODE_HOST;
glue->phy_mode = PHY_MODE_USB_HOST;
break;
#endif
#if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_GADGET
case USB_DR_MODE_PERIPHERAL:
pdata.mode = MUSB_PORT_MODE_GADGET;
glue->phy_mode = PHY_MODE_USB_DEVICE;
break;
#endif
#ifdef CONFIG_USB_MUSB_DUAL_ROLE
case USB_DR_MODE_OTG:
pdata.mode = MUSB_PORT_MODE_DUAL_ROLE;
glue->phy_mode = PHY_MODE_USB_OTG;
break;
#endif
default:
dev_err(&pdev->dev, "Invalid or missing \'dr_mode\' property\n");
return -EINVAL;
}
查看 usb_get_dr_mode代码
dr_mode match代码
static const char *const usb_dr_modes[] = {
[USB_DR_MODE_UNKNOWN] = "",
[USB_DR_MODE_HOST] = "host",
[USB_DR_MODE_PERIPHERAL] = "peripheral",
[USB_DR_MODE_OTG] = "otg",
};
static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str)
{
int ret;
ret = match_string(usb_dr_modes, ARRAY_SIZE(usb_dr_modes), str);
return (ret < 0) ? USB_DR_MODE_UNKNOWN : ret;
}
enum usb_dr_mode usb_get_dr_mode(struct device *dev)
{
const char *dr_mode;
int err;
err = device_property_read_string(dev, "dr_mode", &dr_mode);
if (err < 0)
return USB_DR_MODE_UNKNOWN;
return usb_get_dr_mode_from_string(dr_mode);
}
EXPORT_SYMBOL_GPL(usb_get_dr_mode);
dt配置应该没问题
usb_get_dr_mode返回了0,导致sunxi.c return -EINVAL;
看起来没什么问题,需要修改代码进行调试。
修改打印usb dr mode序号,位于default中
[ 40.909639] USB_DR_MODE: 2
[ 40.915745] musb-sunxi 1c13000.usb: Invalid or missing \'dr_mode\' property
[ 40.929251] musb-sunxi: probe of 1c13000.usb failed with error -22
dr_mode序号是2 对应"peripheral",看来问题出在宏上
//CONFIG_USB_MUSB_DUAL_ROLE
//CONFIG_USB_MUSB_GADGET
#if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_GADGET
case USB_DR_MODE_PERIPHERAL:
pdata.mode = MUSB_PORT_MODE_GADGET;
glue->phy_mode = PHY_MODE_USB_DEVICE;
break;
#endif
menuconfig中搜索相关宏
Symbol: USB_MUSB_DUAL_ROLE [=n] │
│ Type : boolean │
│ Prompt: Dual Role mode │
│ Location: │
│ -> Device Drivers │
│ -> USB support (USB_SUPPORT [=y]) │
│ -> Inventra Highspeed Dual Role Controller (TI, ADI, AW, ...) (USB_MUSB_HDRC [=y]) │
│ (1) -> MUSB Mode Selection (<choice> [=y]) │
│ Defined at drivers/usb/musb/Kconfig:54 │
│ Depends on: <choice> && (USB [=y]=y || USB [=y]=USB_MUSB_HDRC [=y]) && (USB_GADGET [=m]=y || USB_GADGET [=m]=USB_MUSB_HDRC [=y]) && HAS_DMA [=y]
Symbol: USB_MUSB_GADGET [=n] │
│ Type : boolean │
│ Prompt: Gadget only mode │
│ Location: │
│ -> Device Drivers │
│ -> USB support (USB_SUPPORT [=y]) │
│ -> Inventra Highspeed Dual Role Controller (TI, ADI, AW, ...) (USB_MUSB_HDRC [=y]) │
│ (1) -> MUSB Mode Selection (<choice> [=y]) │
│ Defined at drivers/usb/musb/Kconfig:46 │
│ Depends on: <choice> && (USB_GADGET [=m]=y || USB_GADGET [=m]=USB_MUSB_HDRC [=y]) && HAS_DMA [=y]
根据依赖关系可以得知,若要产生USB_MUSB_GADGET选项,需要满足USB_GADGET [=m]=y || USB_GADGET [=m]=USB_MUSB_HDRC [=y]) && HAS_DMA [=y]
将CONFIG_USB_GADGET 设为y后,菜单中已经可以进行设置
dr_mode=host, peripheral, otg
( ) Host only mode
( ) Gadget only mode
(X) Dual Role mode
修改后编译测试,加载sunxi.ko
内核崩溃栈
[ 1499.715055] usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not found, using dummy regulator
[ 1499.743415] ------------[ cut here ]------------
[ 1499.753896] WARNING: CPU: 0 PID: 153 at drivers/usb/musb/sunxi.c:411 sunxi_musb_ep_offset+0x3c/0x54 [sunxi]
[ 1499.774726] sunxi_musb_ep_offset called with non 0 offset
[ 1499.785728] Modules linked in: sunxi(+) usbmon phy_generic [last unloaded: sunxi]
[ 1499.804191] CPU: 0 PID: 153 Comm: insmod Tainted: G W 4.14.0-licheepi-nano+ #2
[ 1499.823454] Hardware name: Allwinner suniv Family
[ 1499.833761] [
[ 1499.852350] [
[ 1499.870000] [
[ 1499.888369] [
[ 1499.908727] [
[ 1499.929141] [
[ 1499.948017] [
[ 1499.966756] [
[ 1499.986551] [
[ 1500.006014] [
[ 1500.025248] [
[ 1500.044407] [
[ 1500.063286] [
[ 1500.082484] [
[ 1500.103345] [
[ 1500.124773] [
[ 1500.145073] [
[ 1500.165139] [
[ 1500.184808] [
[ 1500.204238] [
[ 1500.223736] [
[ 1500.242947] [
[ 1500.262353] [
[ 1500.281664] [
[ 1500.300874] [
[ 1500.319945] [
[ 1500.339308] ---[ end trace 2ff972a0dfd621b1 ]---
[ 1500.349620] musb-sunxi 1c13000.usb: Error unknown readb offset 128
[ 1500.366938] musb-hdrc musb-hdrc.1.auto: musb_init_controller failed with status -22
[ 1500.385854] musb-hdrc: probe of musb-hdrc.1.auto failed with error -22