驱动程序之_1_字符设备_13_USB设备_2_USB总线驱动_分析
USB主机控制器有三种规范
其中
USB1.1支持低速(1.5Mbps)
USB2.0支持全速/高速(12Mbps/480Mbps)
目测最新的USB3.0最高传输速度是USB2.0的10倍(4.8Gbps),并且更节能
S3C2410的USB规范使用的是OHCI
USB总线驱动的作用:
1、识别USB设备
2、查找、安装USB设备驱动
3、提供USB设备的读写接口
在识别USB设备过程中:
1、分配地址,告诉USB设备
2、发出命令,获取设备描述符
第一次接入设备,提示
拔出时提示
第二次:
在内核的drivers目录下搜索"USB device using"
grep "USB device using" * -nR
找到总线驱动程序所在文件drivers/usb/core/hub.c(hub是USB主机自带的一个USB设备)
设备检测信息在hub_port_init函数中被打印
hub_port_init由hub_port_connect_change调用
hub_port_connect_change由hub_events调用
hub_events由hub_thread调用
hub_thread中进程进入休眠,在kick_khubd唤醒
kick_khubd由usb_kick_khubd调用
usb_kick_khubd由hub_irq调用
在hub_port_connect_change
1、choose_address,为设备分配地址,地址最大分配到127(1~127)
2、hub_port_init,设置端口地址,读取、解析描述符(先读取前8字节,得到最大包大小)
3、usb_new_device,将设备添加到总线链表,从总线driver链表中取出成员与之比较,若匹配,则建立联系
static void hub_port_connect_change(struct usb_hub *hub, int port1, u16 portstatus, u16 portchange)
{
/*********************************/
choose_address(udev);
/*********************************/
status = hub_port_init(hub, udev, port1, i);
/*********************************/
status = usb_new_device(udev);
/*********************************/
}
static void choose_address(struct usb_device *udev)
{
int devnum;
struct usb_bus *bus = udev->bus;
/* If khubd ever becomes multithreaded, this will need a lock */
/* Try to allocate the next devnum beginning at bus->devnum_next. */
devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
bus->devnum_next);
if (devnum >= 128)
devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1);
bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
if (devnum < 128) {
set_bit(devnum, bus->devmap.devicemap);
udev->devnum = devnum;
}
}
static int hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, int retry_counter)
{
/*********************************/
for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
retval = hub_set_address(udev);
if (retval >= 0)
break;
msleep(200);
}
/*********************************/
retval = usb_get_device_descriptor(udev, 8);
/*********************************/
}
struct usb_device_descriptor {
/**************前8字节*******************/
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
/**************前8字节*******************/
__le16 idVendor;
__le16 idProduct;
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__ ((packed));
int usb_new_device(struct usb_device *udev)
{
/*********************************/
err = device_add(&udev->dev);
/*********************************/
}
int device_add(struct device *dev)
{
/*********************************/
/* tie the class to the device */
list_add_tail(&dev->node, &dev->class->devices);
/* notify any interfaces that the device is here */
list_for_each_entry(class_intf, &dev->class->interfaces, node)
if (class_intf->add_dev)
class_intf->add_dev(dev, class_intf);
/*********************************/
}
一个设备具有一个设备描述符,设备描述符下面有接口描述符,接口描述符又有端点描述符
描述符规范位于include/linux/usb/Ch9.h