bulkinterface驱动_USB驱动程序(较详细)三
(本部分的⼀些⽰例源码来⾃drivers/usb/usb-skeleton.c,它是Linux内核为我们提供的最基础的USB驱动程序,USB⾻架程序)
驱动程序把驱动对象注册到 USB ⼦系统中,之后使⽤供应商(idVendor)和设备(idProduct)标识来判断对应的硬件是否已经安装.
驱动的设备⽀持列表
struct usb_device_id 结构提供了这个驱动⽀持的不同类型 USB 设备的列表. USB 核⼼通过此列表⽤来决定设备对应的驱动,热插拔脚本也通过此列表来决定当特定设备被插⼊系统时,应该⾃动加载的驱动.
struct usb_device_id {
/* 确定设备信息去和结构体中哪⼏个字段匹配来判断驱动的适⽤性 */
__u16 match_flags;
/* Ud for product specific matches; range is inclusive */
__u16 idVendor;//USB设备的制造商ID,须向www.usb申请
__u16 idProduct;//USB设备的产品ID,有制造商⾃定
__u16 bcdDevice_lo; /* USB设备的产品版本号最低值*/
__u16 bcdDevice_hi; /* 和最⾼值,以BCD码来表⽰。*/
/* 分别定义设备的类,⼦类和协议,他们由 USB 论坛分配并定义在 USB 规范中. 这些值指定这个设备的⾏为, 包括设备上所有的接⼝ */
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
/* 分别定义单个接⼝的类,⼦类和协议,他们由 USB 论坛分配并定义在 USB 规范中 */
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
/* 这个值不⽤来匹配驱动的, 驱动⽤它来在 USB 驱动的探测回调函数中区分不同的设备 */
kernel_ulong_t driver_info;
};//以上结构体中__u16 match_flags;所使⽤的define://include/linux/mod_devicetable.h
/* Some uful macros to u 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_INT_SUBCLASS 0x0100
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200//include/linux/usb.h
#define USB_DEVICE_ID_MATCH_DEVICE \
(USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
#define USB_DEVICE_ID_MATCH_DEV_RANGE \
(USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION \
(USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
#define USB_DEVICE_ID_MATCH_DEV_INFO \
(USB_DEVICE_ID_MATCH_DEV_CLASS | \
USB_DEVICE_ID_MATCH_DEV_SUBCLASS | \
USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
#define USB_DEVICE_ID_MATCH_INT_INFO \
(USB_DEVICE_ID_MATCH_INT_CLASS | \
USB_DEVICE_ID_MATCH_INT_SUBCLASS | \
USB_DEVICE_ID_MATCH_INT_PROTOCOL)//这个结构体⼀般不⽤⼿动赋值,以下的宏可以实现赋值:/** * USB_DEVICE - macro ud to describe a specific usb device
* @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
*
* This macro is ud to create a struct usb_device_id that matches a
best wishes* specific device.
*///仅和指定的制造商和产品ID匹配,⽤于需要特定驱动的设备
#define USB_DEVICE(vend,prod) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
.idVendor = (vend), \
.idProduct = (prod)/**
* USB_DEVICE_VER - describe a specific usb device with a version range
* @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
* @lo: the bcdDevice_lo value
* @hi: the bcdDevice_hi value
奇迹 英语* specific device, with a version range.
*///仅和某版本范围内的指定的制造商和产品ID匹配
#define USB_DEVICE_VER(vend, prod, lo, hi) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \
countrymusic.idVendor = (vend), \
.idProduct = (prod), \
.bcdDevice_lo = (lo), \
.bcdDevice_hi = (hi)/**
* USB_DEVICE_INTERFACE_PROTOCOL - describe a usb device with a specific interface protocol * @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
* @pr: bInterfaceProtocol value
*
* This macro is ud to create a struct usb_device_id that matches a
* specific interface protocol of devices.
*///仅和指定的接⼝协议、制造商和产品ID匹配
#define USB_DEVICE_INTERFACE_PROTOCOL(vend, prod, pr) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
.idVendor = (vend), \
.idProduct = (prod), \
.bInterfaceProtocol = (pr)/**
* USB_DEVICE_INFO - macro ud to describe a class of usb devices
* @cl: bDeviceClass value
* @sc: bDeviceSubClass value
上海口译官网
* @pr: bDeviceProtocol value
*
* This macro is ud 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, \
* USB_INTERFACE_INFO - macro ud to describe a class of usb interfaces
* @cl: bInterfaceClass value
* @sc: bInterfaceSubClass value
* @pr: bInterfaceProtocol value
*
* This macro is ud to create a struct usb_device_id that matches a
* specific class of interfaces.
*///仅和指定的接⼝类型相匹配
#define USB_INTERFACE_INFO(cl, sc, pr) \
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \
.bInterfaceClass = (cl), \
.bInterfaceSubClass = (sc), \
.bInterfaceProtocol = (pr)/**
* USB_DEVICE_AND_INTERFACE_INFO - describe a specific usb device with a class of usb interfaces * @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
* @cl: bInterfaceClass value
* @sc: bInterfaceSubClass value
* @pr: bInterfaceProtocol value
*
* This macro is ud to create a struct usb_device_id that matches a
* specific device with a specific class of interfaces.
*
* This is especially uful when explicitly matching devices that have
* vendor specific bDeviceClass values, but standards-compliant interfaces.
*///仅和指定的制造商、产品ID和接⼝类型相匹配
#define USB_DEVICE_AND_INTERFACE_INFO(vend, prod, cl, sc, pr) \
.
match_flags = USB_DEVICE_ID_MATCH_INT_INFO \
| USB_DEVICE_ID_MATCH_DEVICE, \
.idVendor = (vend), \
.idProduct = (prod), \
/* ----------------------------------------------------------------------- */
对于⼀个只为⼀个供应商的⼀个 USB 设备的简单 USB 设备驱动, 其 struct usb_device_id 可定义如下:
/* Define the values to match your devices */宁波雅思培训保过班
#define USB_SKEL_VENDOR_ID 0xfff0
#define USB_SKEL_PRODUCT_ID 0xfff0
/* table of devices that work with this driver */
static struct usb_device_id skel_table [] = {jojoba
{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
{ } /* Terminating entry */
};
3q是什么意思MODULE_DEVICE_TABLE(usb, skel_table);
MODULE_DEVICE_TABLE 宏是必需的,它允许⽤户空间⼯具判断该驱动可控制什么设备. 对于 USB 驱动, 这个宏中的第⼀个值必须是usb .
如果你需要这个驱动被系统中每个 USB 设备调⽤, 创建仅需设置 driver_info 成员:
static struct usb_device_id usb_ids[] = {
{.driver_info = 42},
{}
};
注册USB驱动程序
所有 USB 驱动都必须创建的主要结构是 struct usb_driver. 这个结构必须被 USB 驱动程序⼿动填充并且包含多个回调函数和变量, 并向USB 核⼼描述 USB 驱动程序:
struct usb_driver {
const char *name;
2007年6月四级真题
/*指向驱动程序名字的指针. 它必须在内核所有的 USB 驱动中是唯⼀的(通常被设为和驱动模块名相同).当驱动在内核中运⾏时,会出现
在/sys/bus/usb/drivers⽬录中 */
int (*probe) (struct usb_interface *intf,
const struct usb_device_id *id);
/*
指向 USB 驱动中探测函数指针. 当USB 核⼼认为它有⼀个本驱动可处理的 struct usb_interface时此函数将被调⽤. USB
核⼼⽤来做判断的 struct usb_device_id 指针也被传递给此函数.如果这个 USB 驱动确认传递给它的 struct
考研报名照片要求usb_interface, 它应当正确地初始化设备并返回 0. 如果驱动没有确认这个设备或发⽣错误,则返回负错误值 */
void (*disconnect) (struct usb_interface *intf);