我试图在Linux中学习设备驱动程序。我遇到了检测usb设备的代码。但它只检测那些在usb_device_id_pen_table[]
结构中有条目的设备。如何使这更通用,以便检测所有USB设备?
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/list.h>
static int pen_probe(struct usb_interface *interface, const struct
usb_device_id *id)
{
printk(KERN_INFO "MY Pen drive (%04X:%04X) plugged\n",id->idVendor, id->idProduct);
return 0;
}
static void pen_disconnect(struct usb_interface *interface)
{
printk(KERN_INFO "MY Pen drive removed\n");
}
static struct usb_device_id pen_table[] =
{
{ USB_DEVICE(0x03F0, 0xBF07) },
{ USB_DEVICE(0x0781, 0x5567) },
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, pen_table);
static struct usb_driver pen_driver =
{
.name = "pen_driver",
.id_table = pen_table,
.probe = pen_probe,
.disconnect = pen_disconnect,
};
static int __init pen_init(void)
{
return usb_register(&pen_driver);
}
static void __exit pen_exit(void)
{
usb_deregister(&pen_driver);
}
module_init(pen_init);
module_exit(pen_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("USB Pen Registration Driver");
答案 0 :(得分:2)
首先,您应该了解匹配的含义。当您插入新的USB设备时,内核从中获取信息(供应商ID,产品ID等)并尝试查找支持该设备的某些驱动程序(即指定相同供应商ID,产品ID等的驱动程序)。此过程调用匹配。
注意:通常匹配的设备(在您的驱动程序中),其vendorID / productID与您的设备不同,这是个坏主意。所以也许你真的不想这样做(实际上我不明白你为什么要这样做)。无论如何,答案如下。
USB设备匹配发生在usb_match_device()
功能(drivers/usb/core/driver.c)中。在那里,您可以看到.id_table
中的条目必须使用可用的匹配策略之一(请参阅下面的匹配标记)。
在usb_match_device()
函数中要注意的关键是,如果设备成功匹配(1
通常代表&#34;成功&#34;在内核中,它将返回0
。因此,此函数基本上逐个检查指定的所有匹配标志,并检查结构中的相应数据是否等于来自测试USB设备的数据。 .match_flags
中指定的所有匹配字段必须与您的设备相同,并且对于要检查的设备表条目,必须与usb_match_device()
函数返回成功结果相同。
您可以在include/linux/mod_devicetable.h中找到匹配的标记:
/* Some useful macros to use to create struct usb_device_id */
#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008
#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010
#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020
#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040
这些标记用于填充.match_flags
中的struct usb_device_id
字段。为方便起见,有些宏使用所选策略创建整个struct usb_device_id
(如您正在使用的USB_DEVICE()
宏)。这些宏在include/linux/usb.h:
USB_DEVICE - macro used to describe a specific usb device
USB_DEVICE_VER - describe a specific usb device with a version range
USB_DEVICE_INTERFACE_CLASS - describe a usb device with a specific interface class
USB_DEVICE_INTERFACE_PROTOCOL - describe a usb device with a specific interface protocol
USB_DEVICE_INTERFACE_NUMBER - describe a usb device with a specific interface number
USB_DEVICE_INFO - macro used to describe a class of usb devices
因此,您需要使用USB_DEVICE_INFO()
代替USB_DEVICE()
:
/**
* USB_DEVICE_INFO - macro used to describe a class of usb devices
* @cl: bDeviceClass value
* @sc: bDeviceSubClass value
* @pr: bDeviceProtocol value
*
* This macro is used to create a struct usb_device_id that matches a
* specific class of devices.
*/
#define USB_DEVICE_INFO(cl, sc, pr) \
.match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, \
.bDeviceClass = (cl), \
.bDeviceSubClass = (sc), \
.bDeviceProtocol = (pr)