浅析usb设备描述符读取usb_control_msg
hub_thread
==>hub_events
==*>hub_port_connect_change
==**>usb_new_device(udev); // 向/sys/bus/usb总线添加hub检测到的设备
usb_device_match将该udev和usb_generic_driver关联上,之后执行generic_probe函数,进一步
与使用usb_register注册的interface接口函数们,进行一一匹配,尝试获得驱动刚刚插入的usb设备[luther.gliethttp].
usb_generic_driver
==>generic_probe
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
.suspend = usb_suspend,
.resume = usb_resume,
};
hub_thread
==>hub_events
==*>hub_port_connect_change
// hdev = hub->hdev即hdev对应hub,为该预申请的插入的usb设备udev的parent
// usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
udev = usb_alloc_dev(hdev, hdev->bus, port1); // 为插入的usb设备建立sys路径名,都是些内存操作
udev->speed = USB_SPEED_UNKNOWN; // 设置speed为USB_SPEED_UNKNOWN,在后面的hub_port_reset中填入插入的usb设备具体值
choose_address(udev); // 从udev->bus上面获取一个usb设备地址,开始使用0地址和插入的usb设备通信,之后将使用
// 这里申请到的address与该usb设备通信.
hub_port_init(hub, udev, port1, i); // 获取描述符
==**>hub_port_init
hub_port_reset(hub, port1, udev, delay);==>set_port_feature
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
__u8 requesttype, __u16 value, __u16 index, void *data,
__u16 size, int timeout)
// 发送usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),USB_REQ_SET_FEATURE, USB_RT_PORT
// 读取usb设备的speed类型信息,最后设置下面4种中的某一个具体值
// udev->speed = USB_SPEED_VARIABLE; 对应的udev->ep0.desc.wMaxPacketSize = 512字节
// udev->speed = USB_SPEED_HIGH; 对应的udev->ep0.desc.wMaxPacketSize = 64字节
// udev->speed = USB_SPEED_FULL; 对应的udev->ep0.desc.wMaxPacketSize = 64字节
// udev->speed = USB_SPEED_LOW; 对应的udev->ep0.desc.wMaxPacketSize = 8字节
usb_control_msg(udev, usb_rcvaddr0pipe(), // 使用0地址第1次获取设备描述符
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
USB_DT_DEVICE << 8, 0,
buf, 64,
USB_CTRL_GET_TIMEOUT);
hub_set_address(udev, devnum); // 发送addr地址给usb设备,之后hub将使用该地址与usb设备通信
usb_get_device_descriptor(udev, 8); // 使用addr地址第2次获取设备描述符
==> usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(USB_DT_DEVICE << 8) + index, 0, buf, size,
USB_CTRL_GET_TIMEOUT);
status = usb_new_device(udev);
==>device_add(&udev->dev); // 将udev添加到usb-bus总线上,因为这个dev为
因为上面udev = usb_alloc_dev(hdev, hdev->bus, port1);时
==>dev->dev.bus = &usb_bus_type;设置dev为usb总线上的设备
==>dev->dev.type = &usb_device_type;设置该dev为usb设备而非接口
设置了类型为usb_device_type,
所以
device_add==>bus_attach_device(dev);为设备绑定驱动时,就会使用
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
.suspend = usb_suspend,
.resume = usb_resume,
};
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
/* devices and interfaces are handled separately */
if (is_usb_device(dev)) {
// 会发现他是一个device而直接返回1
// dev为设备,
/* interface drivers never match devices */
if (!is_usb_device_driver(drv))
return 0; // driver为interface的话就返回0
/* TODO: Add real matching code */
return 1; // ok, driver也是device驱动
} else {
struct usb_interface *intf;
struct usb_driver *usb_drv;
const struct usb_device_id *id;
/* device drivers never match interfaces */
if (is_usb_device_driver(drv))
return 0; // dev为interface设备,所以需要interface驱动
intf = to_usb_interface(dev);
usb_drv = to_usb_driver(drv);
id = usb_match_id(intf, usb_drv->id_table);
if (id)
return 1;
id = usb_match_dynamic_id(intf, usb_drv);
if (id)
return 1;
}
return 0;
}
subsys_initcall(usb_init);
==>usb_init
==>usb_register_device_driver(&usb_generic_driver, THIS_MODULE);
struct usb_device_driver usb_generic_driver = {
.name = "usb",
.probe = generic_probe,
.disconnect = generic_disconnect,
#ifdef CONFIG_PM
.suspend = generic_suspend,
.resume = generic_resume,
#endif
.supports_autosuspend = 1,
};
==>generic_probe // 为设备的probe函数
==>usb_set_configuration // 生成该设置配置描述下的所有接口描述符所描述的接口dev对象
==>ret = device_add(&intf->dev);
/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__le16 idVendor;
__le16 idProduct;
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__ ((packed));
#define USB_DT_DEVICE_SIZE 18
/*
* Descriptor types ... USB 2.0 spec table 9.5
*/
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
#define USB_DT_STRING 0x03
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
#define USB_DT_DEVICE_QUALIFIER 0x06
#define USB_DT_OTHER_SPEED_CONFIG 0x07
#define USB_DT_INTERFACE_POWER 0x08
/* these are from a minor usb 2.0 revision (ECN) */
#define USB_DT_OTG 0x09
#define USB_DT_DEBUG 0x0a
#define USB_DT_INTERFACE_ASSOCIATION 0x0b
/* these are from the Wireless USB spec */
#define USB_DT_SECURITY 0x0c
#define USB_DT_KEY 0x0d
#define USB_DT_ENCRYPTION_TYPE 0x0e
#define USB_DT_BOS 0x0f
#define USB_DT_DEVICE_CAPABILITY 0x10
#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
#define USB_DT_WIRE_ADAPTER 0x21
#define USB_DT_RPIPE 0x22
阅读(7783) | 评论(0) | 转发(0) |