在用户编写的设备驱动中添加所有usb设备

Add all the usb devices in the user writen device driver

我试图在 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");

首先你应该明白匹配是什么意思。当您插入新的 USB 设备时,内核会从中获取信息(供应商 ID、产品 ID 等)并尝试找到支持此设备的某些驱动程序(即指定相同供应商 ID、产品 ID 等的驱动程序)。此过程调用匹配.

注意:通常匹配设备(在您的驱动程序中)vendorID/productID 不同于您的 设备是个坏主意。所以也许你真的不想这样做(实际上我不明白你为什么要这样做)。不管怎样,答案在下面。

USB 设备匹配发生在 usb_match_device() 函数中(在 drivers/usb/core/driver.c 中)。从那里您可以看到您在 .id_table 中的条目必须使用一种可用的匹配策略(请参阅下面的 匹配标志 )。

usb_match_device()函数中需要注意的关键是如果设备成功匹配它returns 1(而不是通常代表[=57=的0 ] 在内核中)。所以这个函数基本上是检查all个指定的匹配标志,一个一个地检查你的结构中相应的数据是否等于来自被测USB设备的数据。 所有 匹配字段,在 .match_flags 中指定,对于您的设备和正在检查的设备 table 条目必须相同,以 usb_match_device() 函数 return 成功结果。

您可以在 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

这些标志用于填充 struct usb_device_id 中的 .match_flags 字段。为了您的方便,有一些宏可以使用所选策略创建整个 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)