usb-serial-2 usb主机控制器驱动

 linux2.6.35 mx535

usbserial modem老是disconnect,分析一下usb主控制器驱动原理及linux下主机对设备的枚举过程。

硬件接口

Chapter 77
Universal Serial Bus Controller (USB)
架构图如下,共计4个主机控制器,使用host 1





hi3518的架构更简单一些,

对比一下:
和mx535一样,hi3518控制器和收发器phy之间使用utmi。
并且root hub位于控制器内部。mx535架构图上没体现出来。


通用usb枚举过程


几个概念

传输transfer的分类:
1.控制传输:对设备进行控制,使用控制端点进行传输,主要用在usb枚举时
2.等时传输:
3.中断传输:鼠标键盘等hid设备均是
4.批量传输:u盘

事务transaction的分类:
1.in
2.out
3.setup

包packet的分类:
1.setup(令牌)
2.data(数据)
3.ack(握手)


几个概念的关系:
传输由若干个事务组成,事务由若干个包组成,包又域组成。

usb枚举过程:
1.获取设备描述符
2.复位
3.设置地址
4.再次获取设备描述符
5.获取配置描述符
6.获取接口,端点描述符
7.获取字符串描述符
8.选择设备配置

每个传输由主机发起,在usb枚举时的各个动作都是由传输完成,大部分是一个传输即可完成:
1.获取设备描述符----使用一个控制传输
2.复位----使用一个reset包
3.设置地址----使用一个控制传输
4.再次获取设备描述符----使用一个控制传输
5.获取配置描述符----使用n个控制传输
6.获取接口,端点描述符----使用一个控制传输
7.获取字符串描述符----使用n个控制传输
8.选择设备配置----使用一个控制传输
监视鼠标枚举:



关于端点:

端点的输入和输出都是以host而言的。 端点是成对出现的。
usb主机和usb设备如鼠标等都会有输入端点0和输出端点0,分别是芯片内部的若干字节的buffer,大于8bytes。
在枚举阶段,
usb设备将数据如设备描述符写入自身的输入端点0(对host而言输入),然后经过物理传输,host会在自身的输入端点收到数据。
usb设备读自身的输出端点0(对host而言的输出),将会读到host传来的命令信息比如获取设备描述符,host是通过将命令写入自身的输出端点0,然后经过物理传输,到达设备的输出端点0的。
比如d12芯片包括控制端点在内的3个端点,如下:

驱动实现

先看插上modem之后的打印信息:
root@freescale /$ hub 2-1.4:1.0: drivers/usb/core/hub.c,hub_events,3403, state 7 ports 7 chg 0000 evt 0010


drivers/usb/core/hub.c,hub_events,3447: ----------------------hub->descriptor->bNbrPorts=7,i=1


drivers/usb/core/hub.c,hub_events,3447: ----------------------hub->descriptor->bNbrPorts=7,i=2


drivers/usb/core/hub.c,hub_events,3447: ----------------------hub->descriptor->bNbrPorts=7,i=3


drivers/usb/core/hub.c,hub_events,3447: ----------------------hub->descriptor->bNbrPorts=7,i=4
drivers/usb/core/hub.c,hub_port_status,407: status=101,change=1
hub 2-1.4:1.0: drivers/usb/core/hub.c,hub_port_connect_change,3100, port 4, status 0101, change 0001, 12 Mb/s
drivers/usb/core/hub.c,hub_port_connect_change,3102: portstatus=101,portchange=1
drivers/usb/core/hub.c,hub_port_status,407: status=101,change=0
drivers/usb/core/hub.c,hub_port_status,407: status=101,change=0
drivers/usb/core/hub.c,hub_port_status,407: status=101,change=0
drivers/usb/core/hub.c,hub_port_status,407: status=101,change=0
drivers/usb/core/hub.c,hub_port_status,407: status=101,change=0
hub 2-1.4:1.0: debounce: port 4: total 100ms stable 100ms status 0x101
drivers/usb/core/hub.c,hub_port_status,407: status=103,change=10
usb 2-1.4.4: ------new full speed USB device using fsl-ehci and address 18
drivers/usb/core/hub.c,hub_port_status,407: status=111,change=0
hub 2-1.4:1.0: port 4 not reset yet, waiting 10ms
drivers/usb/core/hub.c,hub_port_status,407: status=103,change=10
usb 2-1.4.4: udev 18, busnum 2, minor = 145
usb 2-1.4.4: New USB device found, idVendor=1ab7, idProduct=5740
usb 2-1.4.4: New USB device strings: Mfr=0, Product=0, SerialNumber=0
option 2-1.4.4:1.0: GSM modem (1-port) converter detected
usb 2-1.4.4: GSM modem (1-port) converter now attached to ttyUSB5
option 2-1.4.4:1.1: GSM modem (1-port) converter detected
usb 2-1.4.4: GSM modem (1-port) converter now attached to ttyUSB6
option 2-1.4.4:1.2: GSM modem (1-port) converter detected
usb 2-1.4.4: GSM modem (1-port) converter now attached to ttyUSB7
option 2-1.4.4:1.3: GSM modem (1-port) converter detected
usb 2-1.4.4: GSM modem (1-port) converter now attached to ttyUSB8
option 2-1.4.4:1.4: GSM modem (1-port) converter detected
usb 2-1.4.4: GSM modem (1-port) converter now attached to ttyUSB9
option 2-1.4.4:1.5: GSM modem (1-port) converter detected
usb 2-1.4.4: GSM modem (1-port) converter now attached to ttyUSB10

line 15 hub 2-1.4:1.0: drivers/usb/core/hub.c,hub_port_connect_change,3100, port 4, status 0101, change 0001, 12 Mb/s
hub 2-1.4:1.0  其中
hub表示2-1.4是一个hub.
2表示2号总线或2号主机控制器或2号root hub。
1表示2号hub下的第一个口所接的东东(可以是hub或device)
4表示上面第一个口所接的东东(hub)的第4个口所接的东东表示2-1.4是一个hub.
即2号root hub下的第1个口接了一个hub,这个hub的第4个口也接的是个hub

line 28 usb 2-1.4.4: udev 18, busnum 2, minor = 145
usb 表示2-1.4.4是一个usb设备
合起来是2号root hub下的第1个口接了一个hub,这个hub下的第4个口接了一个接了一个hub,这hub下的第4个口接了一个usb device

line 31 option 2-1.4.4:1.0: GSM modem (1-port) converter detected
2-1.4.4:1.0表示最后一层hub的第4个口接了一个usb device,此device的配置1的接口0  (被转换成一个串口)

usb/serial/usbserial.c usb转串口驱动
usb/serial/bus.c

usb/host/ehci-hcd.c usb主机控制器驱动
usb/host/ehci-arc.c 

usb/host/ehci-hub.c 
usb/core/hub.c 负责usb设备的枚举

linux中使用usb_hcd描述usb主机控制器驱动,


在ehci-hcd.c进行平台设备ehci_fsl_driver的注册
#ifdef CONFIG_USB_EHCI_FSL
#include "ehci-fsl.c"
#define PLATFORM_DRIVERehci_fsl_driver
#endif
retval = platform_driver_register(&PLATFORM_DRIVER);

ehci_fsl_driver则是定义在ehci-arc.c的平台驱动:
static struct platform_driver ehci_fsl_driver = {
.probe = ehci_fsl_drv_probe,
.remove = ehci_fsl_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
#ifdef CONFIG_PM
.suspend = ehci_fsl_drv_suspend,
.resume = ehci_fsl_drv_resume,
#endif
.driver = {
  .name = "fsl-ehci",
},
};

平台驱动ehci_fsl_driver的probe函数中创建了usb_hcd, hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); 位于ehci-arc.c
usb_hcd的hc_driver  ehci_fsl_hc_driver很重要,实现usb很多操作的函数指针

ehci主机控制器用ehci_hcd结构体描述,和usb_hcd结构体使用私有数据指针联系。
ehci_hcd结构体的初始化位于ehci-hcd.c的ehci_init()
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
ehci->need_io_watchdog = 1;
init_timer(&ehci->watchdog);
ehci->watchdog.function = ehci_watchdog;
ehci->watchdog.data = (unsigned long) ehci;


init_timer(&ehci->iaa_watchdog);
ehci->iaa_watchdog.function = ehci_iaa_watchdog;
ehci->iaa_watchdog.data = (unsigned long) ehci;




hub_port_connect_change函数中所调用的函数中,有两个函数很重要
分别是hub_port_init和usb_new_device,如下
hub_events()------->hub_port_connect_change()------->hub_port_init()------->hub_port_reset------->hub_port_wait_reset------->hub_port_status获取此口所接设备的速度
hub_events()------->hub_port_connect_change()------->usb_new_device()------->usb_enumerate_device()------->usb_get_configuration()获取设备描述符



usb driver中的提交函数usb_submit_urb()最终是通过usb core机制调用了主机控制器的urb_enqueue(),将数据通过phy发出
usb_submit_urb()------->usb_hcd_submit_urb()(位于usb/core/hcd.c)-------> hcd->driver->urb_enqueue()(位于usb/host/ehci-arc.c)-------> ehci_urb_enqueue()(位于usb/host/ehci-hcd.c)




windows下监视usb

在任务管理器中可以观察到usb host ctrl和root hub






使用 usb bound更清楚,并可以监视usb数据传输。
从下图一目了然,每个控制器下挂的hub,每个hub下挂的设备:
一般笔记本上引出的usb口,都是位于不同的hub下的.


在device页选中要监视的设备,在capture点击run即可监视。

linux下监视usb
lsusb -v
1、在win98、winme、win2000,windows XP系统中: 先双击driver里hidcominst程序,它没有任何显示。然后再插上USB线, 根据系统提示及可正确安装。 安装完成之后,进入设备管理器,在“端口”一栏中可以看到虚拟的串口设备 SemiTech USB-HID->COM device (COM X ) ,表示设备已经正确安装完成, 可以正常使用。 2、在WinXP系统中:有些可能失败安装HIDCOM driver 。双击driver里HidcomInst程序,就可以在设备管理器的"端口"一栏中可以看到虚拟的串口设备。semiTech.USB-HID->COM device (COM X ),表示设备已经正确安装完成,可以正常使用. 或者先插上USB线,进入设备管理器,在“人体学输入设备”一栏中可以看到 “HID-compliant Device”和“USB人体学输入设备” (在此之前请确认已经移去所有其他“USB人体学输入设备”), 在“HID-compliant Device”上点击鼠标右键: 选择:更新驱动程序 选择:从列表或指定位置安装,单击下一步, 选择:不要搜索,我要自己选择要安装的驱动程序.单击下一步, 选择:从磁盘安装,打开浏览,从驱动盘中找到hidcom.INF文件,打开,单击确定, 选择下一步,此时系统会提示微软的数字签证,选择仍然继续,单击完成。 在“USB人体学输入设备”上点击鼠标右键: 选择:更新驱动程序 选择:从列表或指定位置安装,单击下一步, 选择:不要搜索,我要自己选择要安装的驱动程序.单击下一步, 选择:从磁盘安装,打开浏览,从驱动盘中找到hidcom.INF文件,打开,单击确定, 选择下一步,此时系统会提示微软的数字签证,选择仍然继续,单击完成。 完成以上两项更新之后,在设备管理器的“端口”一栏中可以看到虚拟的串口设备 SemiTech USB-HID->COM device (COM X ) ,表示设备已经正确安装完成,可以正常使用。 3、如果在win98、winme、win2000系统安装过程中出现设备不能正常使用,请参看WinXP的 安装方法进行程序升级。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值