天天看點

驅動程式之_1_字元裝置_13_USB裝置_2_USB總線驅動_分析

驅動程式之_1_字元裝置_13_USB裝置_2_USB總線驅動_分析

USB主機控制器有三種規範

驅動程式之_1_字元裝置_13_USB裝置_2_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、發出指令,擷取裝置描述符

第一次接入裝置,提示

驅動程式之_1_字元裝置_13_USB裝置_2_USB總線驅動_分析

拔出時提示

驅動程式之_1_字元裝置_13_USB裝置_2_USB總線驅動_分析

第二次:

驅動程式之_1_字元裝置_13_USB裝置_2_USB總線驅動_分析

在核心的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

驅動程式之_1_字元裝置_13_USB裝置_2_USB總線驅動_分析