驱动程序之_1_字符设备_13_USB设备_2_USB总线驱动_分析

驱动程序之_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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值