Linux USB驅(qū)動注冊方式
注冊接口
#define usb_register(driver) \
usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
const char *mod_name)注冊的結構體是struct usb_driver,主要填充name、probe、disconnect和id_table字段,其中name是驅(qū)動名稱,到時會在/sys/bus/usb/drivers顯示這個驅(qū)動名稱,probe和disconnect會在USB設備插入和拔出時調(diào)用,id_table就是匹配列表,可以通過VID、PID匹配,也可以通過USB設備類型匹配。
示例代碼
static int zslusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *usbdev;
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int i = 0;
usbdev = interface_to_usbdev(intf);
interface = intf->cur_altsetting;
printk(KERN_INFO "%s:num:%d \n",__func__,interface->desc.bNumEndpoints);
for (i = 0;i<interface->desc.bNumEndpoints;i++)
{
endpoint = &interface->endpoint[0].desc;
printk(KERN_INFO "%s: %x %x\n",__func__,endpoint->bEndpointAddress,endpoint->bmAttributes);
printk(KERN_INFO "%s: %x %x %x\n",__func__,interface->desc.bInterfaceClass,interface->desc.bInterfaceSubClass,interface->desc.bInterfaceProtocol);
}
return 0;
}
static void zslusb_disconnect(struct usb_interface *intf)
{
printk(KERN_INFO "%s: \n",__func__);
dump_stack();
}
static struct usb_device_id zslusb_id_table [] = {
{ USB_DEVICE(0x413D, 0x2113) },
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, USB_INTERFACE_PROTOCOL_KEYBOARD)},
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, zsl_usb_id_table);
static struct usb_driver zslusb_driver = {
.name = "zslusb",
.probe = zslusb_probe, /* usb設備插入時,id_table信息匹配成功則調(diào)用 */
.disconnect = zslusb_disconnect, /* usb設備拔出時調(diào)用 */
.id_table = zslusb_id_table, /* id_table,用于匹配設備描述符 */
};
void zslusb_init(void)
{
usb_register(&zslusb_driver); /* 注冊usb設備驅(qū)動,不申請設備號 */
}執(zhí)行后運行,USB設備插入和拔出就會調(diào)用zslusb_probe和zslusb_disconnect接口。
結果如下:
- 插入設備

- 拔掉設備

調(diào)用關系
設備注冊是調(diào)用usb_register接口注冊,本質(zhì)是usb_register_driver,在這個接口里主要是填充struct usb_driver結構體,把bus = &usb_bus_type,然后調(diào)用driver_register注冊驅(qū)動。
設備插入時如果主機控制器處于休眠狀態(tài),會先通過 hcd_resume_work 恢復供電,調(diào)用 rpm_resume 和 usb_runtime_resume 喚醒 Hub和恢復設備。隨后 Hub 檢測到端口變化,通過hub工作隊列 hub_wq 觸發(fā) hub_event,從而usb_new_device初始化新USB設備并device_add把USB設備注冊到內(nèi)核設備樹,觸發(fā)首次總線探測,bus_probe_device里遍歷所有驅(qū)動,對每個驅(qū)動執(zhí)行__device_attach_driver,通過match匹配到設備后調(diào)用通用USB驅(qū)動usb_generic_driver_probe,確保設備能被識別成基本USB設備,讀取設備描述符和分配資源。配置完成后,為每個接口注冊新設備(device_add),觸發(fā)二次總線探測,匹配后調(diào)用入口函數(shù)usb_probe_interface。
設備插入
├─ 休眠狀態(tài)? → hcd_resume_work → rpm_resume → usb_runtime_resume → hub_resume
└─ Hub檢測 → hub_wq → hub_event → usb_new_device → device_add
├─ 首次探測 → usb_generic_driver_probe(基礎初始化)
└─ 接口注冊 → device_add → usb_probe_interface(驅(qū)動加載)設備拔出是由硬件中斷觸發(fā)hub_irq,標記事件并觸發(fā)軟中斷tasklet_hi_action,下半部Tasklet調(diào)用 usb_giveback_urb_bh調(diào)度hub工作隊列 hub_wq觸發(fā)hub_event,調(diào)用usb_disconnect清理USB設備,禁用端點,device_del調(diào)用device_release_driver解綁驅(qū)動(釋放軟件資源),禁用設備(停用硬件端點),釋放設備內(nèi)存。
設備拔出 → hub_irq → tasklet_hi_action → usb_giveback_urb_bh → hub_wq → hub_event
├─ usb_disconnect → usb_disable_device(禁用端點+終止URB)
└─ device_del → device_release_driver → zslusb_disconnect(驅(qū)動清理) → usb_put_dev(內(nèi)存釋放)總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
PHP程序員玩轉(zhuǎn)Linux系列 Linux和Windows安裝nginx
這篇文章主要為大家詳細介紹了PHP程序員玩轉(zhuǎn)Linux系列文章,Linux和Windows安裝nginx教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
服務器安裝寶塔面板無法遠程連接數(shù)據(jù)庫的解決方法
這篇文章主要介紹了服務器安裝寶塔面板無法遠程連接數(shù)據(jù)庫的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-06
詳解Centos7.2安裝Nginx實現(xiàn)負載平衡
本篇文章主要介紹了詳解Centos7.2安裝Nginx實現(xiàn)負載平衡,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03
在Ubuntu 24.04(Noble)上配置阿里源的操作步驟
在使用 Ubuntu 系統(tǒng)時,選擇一個快速且穩(wěn)定的軟件源(Repository)對于系統(tǒng)更新和軟件安裝至關重要,阿里云提供的 Ubuntu 鏡像源在國內(nèi)用戶中非常受歡迎,本文將介紹如何在 Ubuntu 24.04 (Noble) 上配置阿里源,需要的朋友可以參考下2025-07-07
Linux中大內(nèi)存頁Oracle數(shù)據(jù)庫優(yōu)化的方法
這篇文章主要給大家介紹了關于Linux中大內(nèi)存頁Oracle數(shù)據(jù)庫優(yōu)化的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-11-11
linux查找大文件指定內(nèi)容的實現(xiàn)方法
今天小編就為大家分享一篇linux查找大文件指定內(nèi)容的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07

