I am trying to get familiar with Linux Kernel Module. So I have written this simplest module which works on usb. I am not sure what I am missing. The module is being loaded. Also on dmesg I can see this :
[27245.911387] usbcore: registered new interface driver testusb
[27245.911392] testusb: driver registered successfully
but when I insert a usb stick my testusb_probe function is not getting called. Any idea where I am going wrong. here is the code of the module:
#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");
Your test driver is not enabled the USB hotplug.
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 and USB_PRODUCT_ID is your usb stick's IDs. If you don't know IDs, check dmesg message when you insert the stick.
According to a comment in the kernel source code above struct usb_driver
in linux/usb.h
:
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.
Your testusb_driver
struct is incorrect. You need to set the id_table
field.
This requires creating an array of struct usb_device_id
which will be used by the USB subsystem to match the device. This array needs to be exported with MODULE_DEVICE_TABLE(usb, ...)
. The answer given by Wataru is an excellent example.
You have to register driver for notifications from usbcore. Following code should work:
static int usb_notify(struct notifier_block *self, unsigned long action, void *dev) {
printk(KERN_INFO “USB device added \n”);
switch (action) {
case USB_DEVICE_ADD:
printk(KERN_INFO “USB device added \n”);
break;
case USB_DEVICE_REMOVE:
printk(KERN_INFO “USB device removed \n”);
break;
case USB_BUS_ADD:
printk(KERN_INFO “USB Bus added \n”);
break;
case USB_BUS_REMOVE:
printk(KERN_INFO “USB Bus removed \n”);
}
return NOTIFY_OK;
}
static struct notifier_block usb_nb = {
.notifier_call = usb_notify,
};
int init_module(void) {
printk(KERN_INFO “Init 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_INFO “Remove USB hook\n”);
}
精彩评论