Linux USB驱动源代码分析
+ -

Linux Gadget驱动结构关系图

2025-08-13 0 0

Linux Gadget驱动层级如下:

  • Gadget Function驱动/gadget legacy驱动
  • Gadget Compoiste驱动
  • USB UDC驱动(USB Device Control)

Gadget Function驱动/gadget legacy驱动

  • function, 更加现代化和结构化的 USB 设备功能配置方式,它依赖于 configfs 接口
  • legacy, 传统的 USB 设备功能配置方,主要依赖于 gadgetfs 接口

Gadget Compoiste驱动

Gadget Compoiste驱动依赖于usbstring.o config.o epautoconf.o composite.o functions.o configfs.o u_f.o

obj-$(CONFIG_USB_LIBCOMPOSITE)    += libcomposite.o
libcomposite-y            := usbstring.o config.o epautoconf.o
libcomposite-y            += composite.o functions.o configfs.o u_f.o

USB设备控制器UDC驱动

UDC驱动是USB硬件设备的驱动,其用于驱动设备树DTS中描述的USB设备。

结构互联

165232972172
152418392578

  • usb_udc
  • usb_gadget
  • usb_composite_dev
struct usb_udc {
    struct usb_gadget_driver    *driver;
    struct usb_gadget        *gadget;
    struct device            dev;//device tree
    struct list_head        list;//to udc_list
...
};

struct usb_gadget {
...
    struct usb_udc            *udc;
    const struct usb_gadget_ops    *ops;
    struct usb_ep            *ep0;
    struct list_head        ep_list;    /* of usb_ep */
    struct device            dev; //device tree,driver data指向usb_composite
}

struct usb_composite_dev {
    struct usb_gadget        *gadget;
    struct usb_composite_driver    *driver;
}

usb_gadget与usb_udc

udc驱动如dwc2,dwc3等调用usb_add_gadget_udc(usb_add_gadget_udc_release)

int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
        void (*release)(struct device *dev))
{
    struct usb_udc    * udc;
    ...
    udc = kzalloc(sizeof(*udc), GFP_KERNEL);
    device_initialize(&udc->dev);
    udc->dev.release = usb_udc_release;
    udc->dev.class = udc_class;
    udc->dev.groups = usb_udc_attr_groups;
    udc->dev.parent = parent;

    ret = device_add(&gadget->dev);
    udc->gadget = gadget;
    gadget->udc = udc;

    list_add_tail(&udc->list, &udc_list);  //udc_list global list
    ret = device_add(&udc->dev);
    ...
}

usb_gadget与usb_composite_dev

static int composite_bind(struct usb_gadget *gadget,struct usb_gadget_driver *gdriver)
{
    struct usb_composite_dev *cdev;

    cdev = kzalloc(sizeof *cdev, GFP_KERNEL);

    cdev->gadget = gadget;
    set_gadget_data(gadget, cdev);
}

static inline void set_gadget_data(struct usb_gadget *gadget, void *data)
{ 
    dev_set_drvdata(&gadget->dev, data); 
}
static inline void dev_set_drvdata(struct device *dev, void *data)
{
    dev->driver_data = data;
}

usb_gadget

usb_gadget是承上启下的一个结构

struct usb_composite_dev    *cdev = get_gadget_data(gadget);

static inline void *get_gadget_data(struct usb_gadget *gadget)
{ 
    return dev_get_drvdata(&gadget->dev);
}
static inline void *dev_get_drvdata(const struct device *dev)
{
    return dev->driver_data;
}

驱动

struct usb_composite_driver {
    const char                *name;
    const struct usb_device_descriptor    *dev;
    struct usb_gadget_strings        **strings;
    enum usb_device_speed            max_speed;
    unsigned        needs_serial:1;

    int            (*bind)(struct usb_composite_dev *cdev);
    int            (*unbind)(struct usb_composite_dev *);

    void            (*disconnect)(struct usb_composite_dev *);

    /* global suspend hooks */
    void            (*suspend)(struct usb_composite_dev *);
    void            (*resume)(struct usb_composite_dev *);
    struct usb_gadget_driver        gadget_driver;
};

struct usb_gadget_driver {
    char            *function;
    enum usb_device_speed    max_speed;
    int            (*bind)(struct usb_gadget *gadget,
                    struct usb_gadget_driver *driver);
    void            (*unbind)(struct usb_gadget *);
    int            (*setup)(struct usb_gadget *,
                    const struct usb_ctrlrequest *);
    void            (*disconnect)(struct usb_gadget *);
    void            (*suspend)(struct usb_gadget *);
    void            (*resume)(struct usb_gadget *);
    void            (*reset)(struct usb_gadget *);

    /* FIXME support safe rmmod */
    struct device_driver    driver;

    char            *udc_name;
    struct list_head    pending;
    unsigned                match_existing_only:1;
};

0 篇笔记 写笔记

Linux Gadget驱动结构关系图
Linux Gadget驱动层级如下:Gadget Function驱动/gadget legacy驱动Gadget Compoiste驱动USB UDC驱动(USB Device Control)Gadget Function驱动/gadget legacy驱动function, 更加现代......
gadget probe过程-以g_audio为例
g_audio中通过如下代码调用usb_composite_probe,其中入参为audio_driverstatic struct usb_composite_driver audio_driver = { .name = "g_audio", ......
关注公众号
  • HID人机交互
  • Linux&USB
  • UAC音频
  • CDC
  • TYPE-C
  • USB规范
  • USB大容量存储
  • USB百科
  • USB周边
  • UVC摄像头
  • Windows系统USB
  • 音视频博客
  • 取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

    打开支付宝扫一扫,即可进行扫码打赏哦

    您的支持,是我们前进的动力!