简单的USB内核模块

4

我正在尝试熟悉Linux内核模块。因此,我编写了这个最简单的模块,它运行在USB上。但我不确定是否遗漏了什么。模块已经被加载。同时在dmesg中,我可以看到以下信息:

   [27245.911387] usbcore: registered new interface driver testusb
   [27245.911392] testusb: driver registered successfully

但是当我插入USB时,我的testusb_probe函数没有被调用。有没有想法我哪里出错了。 以下是模块的代码:

   #include <linux/kernel.h>
   #include <linux/module.h>
   #include <linux/usb.h>


   static int testusb_probe(struct usb_interface *interface, const struct usb_device_id *id)
   {
    printk("testusb: probe module\n");
    return 0;
   }


   static void testusb_disconnect(struct usb_interface *interface)
   {
    printk("testusb: disconnect module\n");
   }


   static struct usb_driver testusb_driver = {
           name: "testusb",
        probe: testusb_probe,
           disconnect: testusb_disconnect,
   };

   static int __init testusb_init(void)
   {
           int result;

           result = usb_register(&testusb_driver);
           if (result) {
                   printk("testusb: registering driver failed");
           } else {
                   printk("testusb: driver registered successfully");
           }

           return result;
   }


   static void __exit testusb_exit(void)
   {
           usb_deregister(&testusb_driver);
           printk("testusb: module deregistered");
   }

   module_init(testusb_init);
   module_exit(testusb_exit);

   MODULE_AUTHOR("Dal Chand");
   MODULE_LICENSE("GPL");

1
很可能内核正在寻找另一个模块(也加载在RAM中)来处理该设备。卸载所有其他模块,只留下你自己的模块。 - karlphillip
尝试插入一种Linux没有驱动程序的USB设备。 - Turbo J
3个回答

2
您的测试驱动程序未启用USB热插拔功能。 http://www.linuxjournal.com/node/4786/print
/* Define these values to match your devices */
#define USB_VENDOR_ID      0xfff0
#define USB_PRODUCT_ID     0xfff0

/* table of devices that work with this driver */
static struct usb_device_id test_table [] = {
        { USB_DEVICE(USB_VENDOR_ID, USB_PRODUCT_ID) },
        { }                                     /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, test_table);

USB_VENDOR_ID和USB_PRODUCT_ID是您的USB存储设备的ID。 如果您不知道这些ID,请在插入设备时检查dmesg消息。

2
根据位于linux/usb.hstruct usb_driver上方的内核源代码注释:
USB interface drivers must provide a name, probe() and disconnect()
methods, and an id_table.  Other driver fields are optional.

The id_table is used in hotplugging.  It holds a set of descriptors,
and specialized data may be associated with each entry.  That table
is used by both user and kernel mode hotplugging support.

你的testusb_driver结构体是不正确的。你需要设置id_table字段。

这需要创建一个struct usb_device_id的数组,这个数组将被USB子系统用来匹配设备。这个数组需要使用MODULE_DEVICE_TABLE(usb, ...)导出。Wataru给出的答案是一个很好的例子。


0

你需要为来自usbcore的通知注册驱动程序。以下代码应该可以工作:

static int usb_notify(struct notifier_block *self, unsigned long action, void *dev) { 
    printk(KERN_INFOUSB device added \n”); 
    switch (action) { 
    case USB_DEVICE_ADD: 
        printk(KERN_INFOUSB device added \n”);
        break;
    case USB_DEVICE_REMOVE: 
        printk(KERN_INFOUSB device removed \n”); 
        break; 
    case USB_BUS_ADD: 
        printk(KERN_INFOUSB Bus added \n”); 
        break; 
    case USB_BUS_REMOVE: 
        printk(KERN_INFOUSB Bus removed \n”); 
    } 
    return NOTIFY_OK; 
} 

static struct notifier_block usb_nb = { 
    .notifier_call = usb_notify, 
}; 

int init_module(void) { 
    printk(KERN_INFOInit USB hook.\n”); 
    /* 
    * Hook to the USB core to get notification on any addition or removal of USB devices */ 
    usb_register_notify(&usb_nb); 
    return 0; 
}

void cleanup_module(void) { 
    /* 
    * Remove the hook */ 
    usb_unregister_notify(&usb_nb); 
    printk(KERN_INFORemove USB hook\n”);
} 

<gregkh> betterrolf: that stack overflow response is horrid, don't trust it at all. <gregkh> betterrolf: ok, but no driver should use usb notification, it's just in the kernel for a few exceptions. - sarnold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接