在用户写入设备驱动程序中添加所有usb设备

时间:2015-04-07 19:03:47

标签: linux linux-device-driver 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");

1 个答案:

答案 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)