在ubuntu中接入罗技c920摄像头打印的信息如下:
在内核中,/driver/usb/core/driver.c 文件扮演了 USB 核心驱动程序管理的重要角色。该文件包含了 USB 核心驱动程序的实现,负责管理和调度 USB 设备的注册、匹配、连接和断开等操作。
具体而言,driver.c 文件的功能和作用包括:
USB 驱动程序的注册和注销:该文件实现了 usb_register_driver 和 usb_deregister_driver 函数,用于注册和注销 USB 驱动程序。
USB 设备的匹配和连接:通过实现 usb_match_id 函数和 usb_probe_interface 函数,该文件负责在 USB 子系统中进行设备的匹配和连接。当 USB 设备插入时,USB 核心会调用 usb_probe_interface 函数,以便驱动程序对设备进行初始化和配置。
USB 设备的断开和注销:通过实现 usb_disconnect 函数和 usb_remove_interface 函数,该文件负责在 USB 设备断开时执行相应的操作。当 USB 设备断开连接时,USB 核心会调用 usb_disconnect 函数,以便驱动程序对设备进行清理和注销。
驱动程序与 USB 接口的关联:通过实现 usb_register_interface 和 usb_deregister_interface 函数,该文件负责将驱动程序与 USB 接口进行关联。这样,在 USB 设备连接时,USB 核心可以根据驱动程序与接口的关联关系,选择正确的驱动程序来处理设备。
USB 驱动程序的挂起和恢复:通过实现 usb_suspend_interface 和 usb_resume_interface 函数,该文件处理 USB 设备的挂起和恢复操作。当 USB 设备进入挂起状态或从挂起状态恢复时,USB 核心会调用相应的函数通知驱动程序执行相应的操作。
总结起来,/driver/usb/core/driver.c 文件在内核中扮演了 USB 核心驱动程序管理的关键角色。它实现了 USB 驱动程序的注册、匹配、连接和断开等功能,负责与 USB 子系统协作,管理 USB 设备的初始化、配置和操作等操作。该文件的功能对于整个 USB 子系统的正常运行至关重要。
usb_bus_type
在/driver/usb/core/driver.c文件中,下面的内容定义了一个名为usb_bus_type的struct bus_type结构体,并对其成员进行了初始化。该结构体用于表示USB总线类型,并定义了与USB总线相关的操作。
具体来说,下面的内容的作用如下:
.name = “usb”:设置总线类型的名称为"usb",用于标识USB总线。
.match = usb_device_match:指定匹配函数为
usb_device_match。匹配函数用于在插入USB设备时判断该设备是否与该总线类型的驱动程序匹配。
.uevent = usb_uevent:指定uevent函数为
usb_uevent。uevent函数用于生成和发送与USB设备插入和拔出相关的uevent事件。
这些成员的初始化可以使USB核心了解USB总线类型,并在需要的时候调用相应的函数,从而实现与USB总线相关的操作和事件处理。
在实际使用中,USB总线类型结构体usb_bus_type会与具体的USB驱动程序进行关联,以便在USB设备插入和拔出时触发相应的操作。这样,当有新的USB设备插入时,USB核心会调用匹配函数进行驱动程序的匹配,并根据匹配结果调用相应的probe函数来初始化和配置驱动程序与设备的连接。同时,uevent函数可以生成和发送uevent事件,通知用户空间有关USB设备的信息变化。
/* USB总线类型结构体 */ struct bus_type usb_bus_type = { /* 名称 */ .name = "usb", /* 匹配函数 */ .match = usb_device_match, /* uevent函数 */ .uevent = usb_uevent, };
usb_device_match
static int usb_device_match(struct device *dev, struct device_driver *drv) { /* devices and interfaces are handled separately */ if (is_usb_device(dev)) { // 如果是 USB 设备 /* interface drivers never match devices */ if (!is_usb_device_driver(drv)) // 如果不是 USB 设备驱动 return 0; /* TODO: Add real matching code */ // TODO: 添加真正的匹配代码 return 1; } else if (is_usb_interface(dev)) { // 如果是 USB 接口 struct usb_interface *intf; struct usb_driver *usb_drv; const struct usb_device_id *id; /* device drivers never match interfaces */ if (is_usb_device_driver(drv)) // 如果是 USB 设备驱动 return 0; intf = to_usb_interface(dev); // 获取 USB 接口 usb_drv = to_usb_driver(drv); // 获取 USB 驱动 id = usb_match_id(intf, usb_drv->id_table); // 匹配 USB 设备 ID if (id) return 1; id = usb_match_dynamic_id(intf, usb_drv); // 匹配动态 USB 设备 ID if (id) return 1; } return 0; }
该函数的作用是判断USB设备和设备驱动是否匹配,用于设备与驱动之间的匹配过程。
函数的主要步骤如下:
首先判断设备类型,如果是USB设备,则执行设备匹配逻辑;如果是USB接口,则执行接口匹配逻辑。
如果是USB设备,首先判断驱动类型是否为USB设备驱动。如果是USB设备驱动,返回0,表示设备和驱动不匹配。如果不是USB设备驱动,执行后续的实际匹配代码(TODO:此处需要添加真正的匹配代码),并返回1表示设备和驱动匹配。
如果是USB接口,首先获取USB接口和USB驱动的相关信息。然后调用
usb_match_id函数,通过USB设备ID表来匹配USB设备ID。如果匹配成功,返回1表示设备和驱动匹配。如果未匹配成功,调用
usb_match_dynamic_id函数,通过动态USB设备ID匹配来匹配设备和驱动。如果匹配成功,返回1表示设备和驱动匹配。
如果以上都不匹配,则返回0表示设备和驱动不匹配。
该函数在USB核心中用于设备和驱动的匹配过程。当有USB设备或接口与设备驱动进行匹配时,USB核心会调用该函数来判断设备和驱动是否匹配,从而确定是否加载对应的驱动程序。
usb_uevent
static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; if (is_usb_device(dev)) { // 如果是 USB 设备 usb_dev = to_usb_device(dev); // 获取 USB 设备 } else if (is_usb_interface(dev)) { // 如果是 USB 接口 struct usb_interface *intf = to_usb_interface(dev); // 获取 USB 接口 usb_dev = interface_to_usbdev(intf); // 获取 USB 设备 } else { return 0; // 如果不是 USB 设备或 USB 接口,返回 0 } if (usb_dev->devnum < 0) { // 如果设备号小于 0 /* driver is often null here; dev_dbg() would oops */ pr_debug("usb %s: already deleted?\n", dev_name(dev)); // 打印调试信息 return -ENODEV; // 返回错误码 } if (!usb_dev->bus) { // 如果设备总线不存在 pr_debug("usb %s: bus removed?\n", dev_name(dev)); // 打印调试信息 return -ENODEV; // 返回错误码 } /* per-device configurations are common */ // 常见的每个设备的配置 if (add_uevent_var(env, "PRODUCT=%x/%x/%x", le16_to_cpu(usb_dev->descriptor.idVendor), le16_to_cpu(usb_dev->descriptor.idProduct), le16_to_cpu(usb_dev->descriptor.bcdDevice))) // 添加设备信息 return -ENOMEM; // 返回错误码 /* class-based driver binding models */ // 基于类的驱动程序绑定模型 if (add_uevent_var(env, "TYPE=%d/%d/%d", usb_dev->descriptor.bDeviceClass, usb_dev->descriptor.bDeviceSubClass, usb_dev->descriptor.bDeviceProtocol)) // 添加设备类型信息 return -ENOMEM; // 返回错误码 return 0; // 返回成功 }
该函数的作用是处理USB设备的uevent事件,即生成与USB设备插入和拔出相关的环境变量,并将其添加到uevent环境中。
函数的主要步骤如下:
判断设备类型,如果是USB设备,则获取USB设备;如果是USB接口,则获取对应的USB设备。
检查设备号和设备总线的有效性。如果设备号小于0或设备总线不存在,打印调试信息并返回错误码。
通过
add_uevent_var函数将设备的产品信息(vendor ID、product ID和device version)添加到uevent环境中。
通过
add_uevent_var函数将设备的类型信息(device class、device subclass和device protocol)添加到uevent环境中。
返回成功。
该函数在USB核心中起到了生成与USB设备插入和拔出相关的uevent事件的作用。当有USB设备插入或拔出时,USB核心会调用该函数来获取设备的相关信息,并生成相应的uevent事件,通知用户空间进行设备的动态管理和配置
usb_register_driver
/driver/usb/core/driver.c
函数 usb_register_driver 用于注册一个 USB 驱动程序,并将其与 USB 子系统进行关联。它的作用是告诉 USB 子系统,有一个新的驱动程序可用于管理特定类型的 USB 设备。
该函数的参数包括:
new_driver:指向 usb_driver 结构的指针,表示要注册的驱动程序。
owner:指向驱动程序所属内核模块的指针,通常是使用 THIS_MODULE 宏。
mod_name:表示驱动程序所属模块的名称,用于标识该驱动程序。
usb_register_driver 函数在驱动程序初始化阶段调用,通常在驱动程序的入口点函数中使用。当驱动程序调用 usb_register_driver 注册成功后,USB 子系统会将该驱动程序添加到其驱动程序列表中,并在有匹配的 USB 设备插入时调用该驱动程序的相应回调函数。
驱动程序注册后,USB 子系统会与该驱动程序进行协作,以匹配和管理符合驱动程序定义的设备。当插入符合驱动程序定义的 USB 设备时,USB 子系统会调用驱动程序中的回调函数来执行设备的初始化、配置、数据传输和管理等操作。
总结起来,usb_register_driver 函数的作用是将一个 USB 驱动程序注册到 USB 子系统中,以便USB子系统能够调用驱动程序的相应回调函数来管理特定类型的USB设备。通常在驱动程序初始化阶段调用该函数。
int usb_register_driver(struct usb_driver *new_driver, struct module *owner, const char *mod_name) { int retval = 0; if (usb_disabled()) return -ENODEV; // 设置驱动的相关信息 new_driver->drvwrap.for_devices = 0; // 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; // 探测函数 new_driver->drvwrap.driver.remove = usb_unbind_interface; // 卸载函数 new_driver->drvwrap.driver.owner = owner; // 模块所有者 new_driver->drvwrap.driver.mod_name = mod_name; // 模块名 spin_lock_init(&new_driver->dynids.lock); // 初始化动态ID锁 INIT_LIST_HEAD(&new_driver->dynids.list); // 初始化动态ID链表 // 注册驱动 retval = driver_register(&new_driver->drvwrap.driver); if (retval) goto out; // 创建新ID文件 retval = usb_create_newid_files(new_driver); if (retval) goto out_newid; pr_info("%s: registered new interface driver %s\n", usbcore_name, new_driver->name); out: return retval; out_newid: driver_unregister(&new_driver->drvwrap.driver); printk(KERN_ERR "%s: error %d registering interface " " driver %s\n", usbcore_name, retval, new_driver->name); goto out; } EXPORT_SYMBOL_GPL(usb_register_driver);
如果文章对您有帮助,点赞👍支持,感谢🤝