环境
- Linux Kernel 5.0
- Source Insight 3.5
1 USB总线初始化
1.1 usb_init()函数
在usb_init()函数中主要有如下的三个主要函数,分别注册usb总线,初始化usb hub驱动,注册usb设备通用驱动.
static int __init usb_init(void)
{
int retval;
retval = bus_register(&usb_bus_type);
retval = usb_hub_init();
retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);
}
1.1.1 bus_register()函数
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
.need_parent_lock = true,
};
int bus_register(struct bus_type *bus)
{
struct subsys_private *priv;
priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);
priv->bus = bus;
bus->p = priv;
//初始化usb kset
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
priv->subsys.kobj.kset = bus_kset;
priv->subsys.kobj.ktype = &bus_ktype;
priv->drivers_autoprobe = 1;
//注册usb kset
retval = kset_register(&priv->subsys);
//初始化devices kset并注册在usb kset下
priv->devices_kset = kset_create_and_add("devices", NULL,
&priv->subsys.kobj);
//初始化drivers kset并注册在usb kset下
priv->drivers_kset = kset_create_and_add("drivers", NULL,
&priv->subsys.kobj);
}
- 注册usb类型的kset, 然后在usb类型的kset下添加devices和drivers两个kset.
1.1.2 usb_hub_init()函数
static struct usb_driver hub_driver = {
.name = "hub",
.probe = hub_probe,
...
.id_table = hub_id_table,
.supports_autosuspend = 1,
};
int usb_hub_init(void)
{
//#define usb_register(driver) usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
usb_register(&hub_driver)
hub_wq = alloc_workqueue("usb_hub_wq", WQ_FREEZABLE, 0);
}
int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
const char *mod_name)
{
//@for_devices: Non-zero for device drivers, 0 for interface drivers.
new_driver->drvwrap.for_devices = 0;
new_driver->drvwrap.driver.name = new_driver->name;
new_driver->drvwrap.driver.bus = &usb_bus_type;
new_driver->drvwrap.driver.probe = usb_probe_interface;
...
retval = driver_register(&new_driver->drvwrap.driver);
//klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
}
- 注册hub_driver和创建hub_wq工作队列.
- 初始化hub中drvwrap中driver的name,bus类型,和probe函数,并注册driver到usb总线klist_drivers链表上.
1.1.3 usb_register_device_driver()函数
struct usb_device_driver usb_generic_driver = {
.name = "usb",
.probe = generic_probe,
.disconnect = generic_disconnect,
.supports_autosuspend = 1,
};
int usb_register_device_driver(struct usb_device_driver *new_udriver,
struct module *owner)
{
//@for_devices: Non-zero for device drivers, 0 for interface drivers.
new_udriver->drvwrap.for_devices = 1;
new_udriver->drvwrap.driver.name = new_udriver->name;
new_udriver->drvwrap.driver.bus = &usb_bus_type;
new_udriver->drvwrap.driver.probe = usb_probe_device;
retval = driver_register(&new_udriver->drvwrap.driver);
//klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
}
初始化usb_generic_driver 中drvwrap中driver的name, bus类型,以及probe函数,并注册到usb总线klist_drivers链表上.
总结:USB总线初始化完后,分别在总线上注册了名为"usb"和“hub"的两个驱动,分别对应着usb_probe_device
和 usb_probe_interface
的probe函数.
2 USB Host 设备初始化
- 常用的USB Host主要有OHCI, UHCI, EHCI, xHCI。
- 这里选择PCI方式的xHCI, 即挂接在PCI总线的xHCI设备PCI-xHCI。
- 对于PCI-xHCI而言,既然是PCI设备,那么就需要注册PCI驱动。
- 这里我们不讨论PCI相关的代码。
2.1 xhci_pci_init()函数
static const char hcd_name[] = "xhci_hcd";
static const struct pci_device_id pci_ids[] = { {
/* handle any USB 3.0 xHCI controller */
PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0),
.driver_data = (unsigned long) &xhci_pci_hc_driver,
},
};
static struct pci_driver xhci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
.probe = xhci_pci_probe,
...
};
static int __init xhci_pci_init(void)
{
xhci_init_driver(&xhci_pci_hc_driver, &xhci_pci_overrides);
return pci_register_driver(&xhci_pci_driver);
}
xhci_pci_init函数主要是初始化xhci_pci_hc_driver,注册xhci_pci_driver.
2.1.1 xhci_init_driver()函数
static const struct hc_driver xhci_hc_driver = {
.description = "xhci-hcd",
.product_desc = "xHCI Host Controller",
.hcd_priv_size = sizeof(struct xhci_hcd),
.irq = xhci_irq,
.flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED,
.urb_enqueue = xhci_urb_enqueue,
...
}
void xhci_init_driver(struct hc_driver *drv, const struct xhci_driver_overrides *over)
{
*drv = xhci_hc_driver;
}
初始化xhci_pci_hc_driver为xhci_hc_driver
。
2.1.2 pci_register_driver()函数
#define pci_register_driver(driver) __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
int __pci_register_driver(struct pci_driver *drv, struct module *owner,
const char *mod_name)
{
/* initialize common driver fields */
drv->driver.name = drv->name;
drv->driver.bus = &pci_bus_type;
drv->driver.owner = owner;
drv->driver.mod_name = mod_name;
drv->driver.groups = drv->groups;
/* register with core */
return driver_register(&drv->driver);
}
当系统中存在PCI-xHCI设备时,就会调用pci_driver形式的xhci_pci_driver中的probe()函数.即xhci_pci_probe()函数
2.2 xhci_pci_probe()函数
static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int retval;
struct xhci_hcd *xhci;
struct hc_driver *driver;
struct usb_hcd *hcd;
//获取之前存在id_table中的driver->xhci_hc_driver
driver = (struct hc_driver *)id->driver_data;
retval = usb_hcd_pci_probe(dev, id);
//创建共享的hcd(TODO), 其流程下面已经分析完了.
xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev,pci_name(dev), hcd);
retval = usb_add_hcd(xhci->shared_hcd, dev->irq, IRQF_SHARED);
}
2.2.1 usb_hcd_pci_probe()函数
int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct hc_driver *driver;
struct usb_hcd *hcd;
int retval;
int hcd_irq = 0;
//获取PCI类型的xHCI设备
pci_enable_device(dev)
//driver = xhci_hc_driver
driver = (struct hc_driver *)id->driver_data;
//__usb_create_hcd(driver, &dev->dev, pci_name(dev));
hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
usb_add_hcd(hcd, hcd_irq, IRQF_SHARED);
...
}
2.2.1.2 __usb_create_hcd()函数
struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
struct device *sysdev, struct device *dev, const char *bus_name,
struct usb_hcd *primary_hcd)
{
struct usb_hcd *hcd;
hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);
if (primary_hcd == NULL) {
//dev->driver_data = data;
dev_set_drvdata(dev, hcd);
}
//初始化HCD对应的USB BUS.
usb_bus_init(&hcd->self);
hcd->self.controller = dev;
hcd->self.bus_name = bus_name;
timer_setup(&hcd->rh_timer, rh_timer_func, 0);
hcd->driver = driver;
hcd->product_desc = (driver->product_desc) ? driver->product_desc :"USB Host Controller";
return hcd;
}
__usb_create_hcd
创建并初始化了hcd
.
2.2.1.3 usb_add_hcd()函数
int usb_add_hcd(struct usb_hcd *hcd,unsigned int irqnum, unsigned long irqflags)
{
int retval;
struct usb_device *rhdev;
retval = hcd_buffer_create(hcd);
//bus->busnum = busnum;
retval = usb_register_bus(&hcd->self);
rhdev = usb_alloc_dev(NULL, &hcd->self, 0);
hcd->self.root_hub = rhdev;
/* initialize tasklets */
init_giveback_urb_bh(&hcd->high_prio_bh);
init_giveback_urb_bh(&hcd->low_prio_bh);
/* starting here, usbcore will pay attention to this root hub */
retval = register_root_hub(hcd);
return retval;
}
继续初始化HCD,这里初始化了两个tasklets
, 有什么用呢?(答案后面揭晓)
然后初始化并注册root hub, 对于HCD而言,root hub也是一种USB 设备.
2.2.1.3.1 usb_alloc_dev()函数
struct usb_device *usb_alloc_dev(struct usb_device *parent,
struct usb_bus *bus, unsigned port1)
{
struct usb_device *dev;
struct usb_hcd *usb_hcd = bus_to_hcd(bus);
unsigned root_hub = 0;
unsigned raw_port = port1;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
device_initialize(&dev->dev);
dev->dev.bus = &usb_bus_type;
dev->dev.type = &usb_device_type;
dev->dev.dma_mask = bus->sysdev->dma_mask;
dev->dev.dma_pfn_offset = bus->sysdev->dma_pfn_offset;
set_dev_node(&dev->dev, dev_to_node(bus->sysdev));
dev->state = USB_STATE_ATTACHED;
dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
/* ep0 maxpacket comes later, from device descriptor */
usb_enable_endpoint(dev, &dev->ep0, false);
dev->can_submit = 1;
if (unlikely(!parent)) {
dev->devpath[0] = '0';
dev->route = 0;
dev->dev.parent = bus->controller;
device_set_of_node_from_dev(&dev->dev, bus->sysdev);
dev_set_name(&dev->dev, "usb%d", bus->busnum);
root_hub = 1;
} else {
..
dev->dev.parent = &parent->dev;
dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
}
dev->portnum = port1;
dev->bus = bus;
dev->parent = parent;
}
2.2.1.3.2 register_root_hub()函数
static int register_root_hub(struct usb_hcd *hcd)
{
struct device *parent_dev = hcd->self.controller;
struct usb_device *usb_dev = hcd->self.root_hub;
const int devnum = 1;
int retval;
usb_dev->devnum = devnum;
usb_dev->bus->devnum_next = devnum + 1;
set_bit (devnum, usb_dev->bus->devmap.devicemap);
usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
retval = usb_new_device (usb_dev);
return retval;
}
2.2.1.3.2.1 usb_new_device ()函数
int usb_new_device(struct usb_device *udev)
{
int err;
//usb_enumerate_device - Read device configs/intfs
err = usb_enumerate_device(udev); /* Read descriptors */
/* export the usbdev device-node for libusb */
udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
/* Register the device. The device driver is responsible
* for configuring the device and invoking the add-device
* notifier chain (used by usbfs and possibly others).
*/
err = device_add(&udev->dev);
//klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
//bus_probe_device(dev);
}
通过device_add就注册到了USB 总线klist_devices中, 然后调用到driver_match_device()和driver_probe_device()函数
bus_probe_device(dev)-->device_initial_probe(dev)-->__device_attach(dev, true)-->bus_for_each_drv(...)-->__device_attach_driver(...)
static int __device_attach_driver(struct device_driver *drv, void *_data)
{
struct device_attach_data *data = _data;
struct device *dev = data->dev;
//return drv->bus->match ? drv->bus->match(dev, drv) : 1; -->usb_device_match(dev, drv)
ret = driver_match_device(drv, dev);
return driver_probe_device(drv, dev);
}
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
//return dev->type == &usb_device_type;
if (is_usb_device(dev)) {
//return container_of(drv, struct usbdrv_wrap, driver)->for_devices
if (!is_usb_device_driver(drv))
return 0;
return 1;
//return dev->type == &usb_if_device_type;
} else if (is_usb_interface(dev)) {
struct usb_interface *intf;
struct usb_driver *usb_drv;
const struct usb_device_id *id;
//return container_of(drv, struct usbdrv_wrap, driver)->for_devices;
if (is_usb_device_driver(drv))
return 0;
intf = to_usb_interface(dev);
usb_drv = to_usb_driver(drv);
id = usb_match_id(intf, usb_drv->id_table);
if (id)
return 1;
id = usb_match_dynamic_id(intf, usb_drv);
if (id)
return 1;
}
return 0;
}
根据以上分析会调用usb_device_match(…)来匹配驱动. 由于在2.2.1.3.1
中dev->type == &usb_device_type
;然后又会判断for_devices,在1.1.3
中for_devices=1
的,所以满足条件驱动的probe函数为usb_probe_device()
,其最后会调用到usb_generic_driver
中的 probe
函数generic_probe()
static int usb_probe_device(struct device *dev)
{
//udriver = usb_generic_driver;
struct usb_device_driver *udriver = to_usb_device_driver(dev->driver);
struct usb_device *udev = to_usb_device(dev);
error = udriver->probe(udev);
}
2.3 generic_probe()函数
static int generic_probe(struct usb_device *udev)
{
int err, c;
//获取coniguration
c = usb_choose_configuration(udev);
err = usb_set_configuration(udev, c);
/* USB device state == configured ... usable */
usb_notify_add_device(udev);
return 0;
}
int usb_set_configuration(struct usb_device *dev, int configuration)
{
int i, ret;
struct usb_host_config *cp = NULL;
struct usb_interface **new_interfaces = NULL;
struct usb_hcd *hcd = bus_to_hcd(dev->bus);
int n, nintf;
n = nintf = 0;
if (cp) {
nintf = cp->desc.bNumInterfaces;
new_interfaces = kmalloc_array(nintf, sizeof(*new_interfaces), GFP_NOIO);
for (; n < nintf; ++n)
new_interfaces[n] = kzalloc(sizeof(struct usb_interface),GFP_NOIO);
}
for (i = 0; i < nintf; ++i) {
struct usb_interface_cache *intfc;
struct usb_interface *intf;
struct usb_host_interface *alt;
u8 ifnum;
cp->interface[i] = intf = new_interfaces[i];
intfc = cp->intf_cache[i];
intf->altsetting = intfc->altsetting;
intf->num_altsetting = intfc->num_altsetting;
intf->authorized = !!HCD_INTF_AUTHORIZED(hcd);
ifnum = alt->desc.bInterfaceNumber;
intf->intf_assoc = find_iad(dev, cp, ifnum);
intf->cur_altsetting = alt;
usb_enable_interface(dev, intf, true);
intf->dev.parent = &dev->dev;
intf->dev.driver = NULL;
intf->dev.bus = &usb_bus_type;
intf->dev.type = &usb_if_device_type;
intf->dev.groups = usb_interface_groups;
intf->dev.dma_mask = dev->dev.dma_mask;
intf->dev.dma_pfn_offset = dev->dev.dma_pfn_offset;
INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
device_initialize(&intf->dev);
}
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
NULL, 0, USB_CTRL_SET_TIMEOUT);
if (!cp) {
usb_set_device_state(dev, USB_STATE_ADDRESS);
}
usb_set_device_state(dev, USB_STATE_CONFIGURED);
for (i = 0; i < nintf; ++i) {
struct usb_interface *intf = cp->interface[i];
ret = device_add(&intf->dev);
}
return 0;
}
我们直接看usb_set_configuration
函数. 从Spec 能够可以知道HUB有1个configuration, 至少1个interface.所以最后调到device_add()
中. 然后调到usb_device_match
中,然后调用is_usb_interface()
和usb_match_id()
, 而此时满足条件的驱动只有usb_probe_interface()
.
2.4 usb_probe_interface()函数
static int usb_probe_interface(struct device *dev)
{
//#define to_usb_driver(d) container_of(d, struct usb_driver, drvwrap.driver)
//想想这个地方,如果device是hub,为什么会得到hub_driver?
//首先在usb_register(&hub_driver)注册中,就会取得hub_driver相应的地址,
//然后用 hub_driver内部的drvwrap注册,
//然后hub intf 和 hub driver, 通过usb_match_id(),得到的是hub_driver
struct usb_driver *driver = to_usb_driver(dev->driver);
struct usb_interface *intf = to_usb_interface(dev);
struct usb_device *udev = interface_to_usbdev(intf);
const struct usb_device_id *id;
int error = -ENODEV;
int lpm_disable_error = -ENODEV;
/* Carry out a deferred switch to altsetting 0 */
if (intf->needs_altsetting0) {
error = usb_set_interface(udev, intf->altsetting[0].
desc.bInterfaceNumber, 0);
if (error < 0)
goto err;
intf->needs_altsetting0 = 0;
}
error = driver->probe(intf, id);
}
由于usb interface
是hub, 所以to_usb_driver()
, 就会取得hub_driver
, 然后driver->probe(...)
就会调用hub_probe()
来初始化hub.
USB驱动分析(一)总结:
- 初始化xHCI, 对其参数初始化,并且初始化Root Hub。
- 初始化Root Hub, 首先把Root Hub当作usb 设备,调用device驱动的wrapper函数
usb_probe_device()
, 然后调用其中generic_probe来初始化interface
,然后调用interface驱动的wrapper中函数usb_probe_interface()
,然后调用Root hub自己的驱动hub_probe()
。