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设备。
结构互联
- 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;
};