驅動程式之_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