最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux USB驅(qū)動(dòng)注冊(cè)方式

 更新時(shí)間:2025年07月22日 09:28:26   作者:大肥周  
USB驅(qū)動(dòng)通過(guò)structusb_driver注冊(cè),填充name、probe、disconnect和id_table字段,插入時(shí)觸發(fā)設(shè)備匹配與初始化,拔出時(shí)清理資源并解綁驅(qū)動(dòng),實(shí)現(xiàn)設(shè)備動(dòng)態(tài)管理

注冊(cè)接口

  #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)

注冊(cè)的結(jié)構(gòu)體是struct usb_driver,主要填充name、probe、disconnect和id_table字段,其中name是驅(qū)動(dòng)名稱,到時(shí)會(huì)在/sys/bus/usb/drivers顯示這個(gè)驅(qū)動(dòng)名稱,probe和disconnect會(huì)在USB設(shè)備插入和拔出時(shí)調(diào)用,id_table就是匹配列表,可以通過(guò)VID、PID匹配,也可以通過(guò)USB設(shè)備類型匹配。

示例代碼

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設(shè)備插入時(shí),id_table信息匹配成功則調(diào)用 */
       .disconnect    = zslusb_disconnect,  /* usb設(shè)備拔出時(shí)調(diào)用 */
       .id_table  = zslusb_id_table,    /* id_table,用于匹配設(shè)備描述符 */
};

void zslusb_init(void)
{     
       usb_register(&zslusb_driver);    /* 注冊(cè)u(píng)sb設(shè)備驅(qū)動(dòng),不申請(qǐng)?jiān)O(shè)備號(hào) */
}

執(zhí)行后運(yùn)行,USB設(shè)備插入和拔出就會(huì)調(diào)用zslusb_probe和zslusb_disconnect接口。

結(jié)果如下:

  • 插入設(shè)備

  • 拔掉設(shè)備

調(diào)用關(guān)系

設(shè)備注冊(cè)是調(diào)用usb_register接口注冊(cè),本質(zhì)是usb_register_driver,在這個(gè)接口里主要是填充struct usb_driver結(jié)構(gòu)體,把bus = &usb_bus_type,然后調(diào)用driver_register注冊(cè)驅(qū)動(dòng)。

設(shè)備插入時(shí)如果主機(jī)控制器處于休眠狀態(tài),會(huì)先通過(guò) hcd_resume_work 恢復(fù)供電,調(diào)用 rpm_resume 和 usb_runtime_resume 喚醒 Hub和恢復(fù)設(shè)備。隨后 Hub 檢測(cè)到端口變化,通過(guò)hub工作隊(duì)列 hub_wq 觸發(fā) hub_event,從而usb_new_device初始化新USB設(shè)備并device_add把USB設(shè)備注冊(cè)到內(nèi)核設(shè)備樹(shù),觸發(fā)首次總線探測(cè),bus_probe_device里遍歷所有驅(qū)動(dòng),對(duì)每個(gè)驅(qū)動(dòng)執(zhí)行__device_attach_driver,通過(guò)match匹配到設(shè)備后調(diào)用通用USB驅(qū)動(dòng)usb_generic_driver_probe,確保設(shè)備能被識(shí)別成基本USB設(shè)備,讀取設(shè)備描述符和分配資源。配置完成后,為每個(gè)接口注冊(cè)新設(shè)備(device_add),觸發(fā)二次總線探測(cè),匹配后調(diào)用入口函數(shù)usb_probe_interface。

設(shè)備插入
├─ 休眠狀態(tài)? → hcd_resume_work → rpm_resume → usb_runtime_resume → hub_resume
└─ Hub檢測(cè) → hub_wq → hub_event → usb_new_device → device_add
    ├─ 首次探測(cè) → usb_generic_driver_probe(基礎(chǔ)初始化)
    └─ 接口注冊(cè) → device_add → usb_probe_interface(驅(qū)動(dòng)加載)

設(shè)備拔出是由硬件中斷觸發(fā)hub_irq,標(biāo)記事件并觸發(fā)軟中斷tasklet_hi_action,下半部Tasklet調(diào)用 usb_giveback_urb_bh調(diào)度hub工作隊(duì)列 hub_wq觸發(fā)hub_event,調(diào)用usb_disconnect清理USB設(shè)備,禁用端點(diǎn),device_del調(diào)用device_release_driver解綁驅(qū)動(dòng)(釋放軟件資源),禁用設(shè)備(停用硬件端點(diǎn)),釋放設(shè)備內(nèi)存。

設(shè)備拔出 → hub_irq → tasklet_hi_action → usb_giveback_urb_bh → hub_wq → hub_event
    ├─ usb_disconnect → usb_disable_device(禁用端點(diǎn)+終止URB)
    └─ device_del → device_release_driver → zslusb_disconnect(驅(qū)動(dòng)清理) → usb_put_dev(內(nèi)存釋放)

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

临猗县| 永昌县| 大方县| 宜君县| 安西县| 南川市| 漳浦县| 财经| 永寿县| 武隆县| 邳州市| 井冈山市| 池州市| 治多县| 蕉岭县| 灵石县| 巫山县| 山阳县| 金山区| 江安县| 辽宁省| 漳浦县| 东阿县| 南乐县| 班戈县| 藁城市| 岳西县| 南丹县| 丁青县| 昌宁县| 礼泉县| 六盘水市| 唐海县| 白河县| 海丰县| 内乡县| 德阳市| 安多县| 大方县| 南召县| 普兰店市|