Usb(5)

pxa310 查看host目录下的Makefile

是要编译出一个名为”ohci_hcd”的模块

 

OHCI主控器进行编程要容易得多。控制器假设有一组端点(endpoint)可用,并知道帧中不同传输类型的调度优先级和排序。主控器使用的主要数据结构是端点描述符(ED),它上面连接着一个传输描述符(TD)的队列。 ED包含端点所允许的最大的包大小,控制器硬件完成包的分割。每次传输后都会更新指向数据缓冲区的指针,当起始和终止指针相等时,TD就退归到完成队列(done-queue)。四种类型的端点各有其自己的队列。控制和大块(bulk)端点分别在它们自己的队列排队。中断ED在树中排队,在树中的深度定义了它们运行的频度。

  帧列表 中断 同步(isochronous) 控制大块(bulk)

  主控器在每帧中运行的调度看起来如下。控制器首先运行非周期性控制和大块队列,最长可到HC驱动程序设置的一个时间限制。然后以帧编号低5位作为中断ED树上深度为0的那一层中的索引,运行那个帧编号的中断传输。在这个树的末尾,同步ED被连接,并随后被遍历。同步TD包含了传输应当运行其中的第一个帧的帧编号。所有周期性的传输运行过以后,控制和大块队列再次被遍历。中断服务例程会被周期性地调用,来处理完成的队列,为每个传输调用回调,并重新调度中断和同步端点。


  更详尽的描述请看 OHCI specification。服务层,即中间层,提供了以可控的方式对设备进行访问,并维护着由不同驱动程序和服务层所使用的资源。此层处理下面几方面:

设备配置信息

与设备进行通信的管道

探测和连接设备,以及从设备分离(detach)

 

ohci_hcd_mod_init

 

现在看一下HCDprobe 是如何发生的?

还是从源头说起吧

 

arch/arm/march-pxa/generic.c 中有如下代码

 

pxa_init 中注册了一系列的device

 

其中有这样一个device

 

static struct platform_device ohci_hcd_pxa_device = {

            .name = "pxa3xx-ohci",

            .id = -1,

            .dev                  = {

                        .platform_data  = &pxa_ohci_info,

                        .dma_mask = &ohci_hcd_pxa_dmamask,

                        .coherent_dma_mask = 0xffffffff,

            },

            .num_resources = ARRAY_SIZE(pxa3xx_ohci_resources),

            .resource      = pxa3xx_ohci_resources,

};

 

注意这个device的名字pxa3xx-ohci

以后还有一个同样名字的driver

 

platform_device  device的基础上封装了资源和ID

struct platform_device {

            const char         * name;

            u32                  id;

            struct device     dev;

            u32                  num_resources;

            struct resource  * resource;

};

 

看看这个HCD 拥有的资源

 

static struct resource pxa3xx_ohci_resources[] = {

            {

                        .start= 0x4C000000,

                        .end= 0x4C000fff,

                        .flags= IORESOURCE_MEM,

            }, {

                        .start= IRQ_USBH1,

                        .end= IRQ_USBH1,

                        .flags= IORESOURCE_IRQ,

            },

};

内存4K ,中断号 3

 

再来看一下driver 这一边

 

static struct platform_driver ohci_hcd_pxa3xx_driver = {

            .probe               = ohci_hcd_pxa3xx_drv_probe,

            .remove                        = ohci_hcd_pxa3xx_drv_remove,

            .shutdown        = usb_hcd_platform_shutdown,

#ifdef CONFIG_PM

            .suspend           = ohci_hcd_pxa3xx_drv_suspend,

            .resume                        = ohci_hcd_pxa3xx_drv_resume,

#endif

            .driver              = {

                        .name   = "pxa3xx-ohci",

            },

};

看看match 的时候 发生了什么事情?

static int ohci_hcd_pxa3xx_drv_probe(struct platform_device *pdev)

{

            int ret;

 

            pr_debug ("In ohci_hcd_pxa3xx_drv_probe");

 

            if (usb_disabled())

                        return -ENODEV;

 

            ret = usb_hcd_pxa3xx_probe(&ohci_pxa3xx_hc_driver, pdev);

            return ret;

}

 

usb_hcd_pxa3xx_probe

 

1 创建usb_hcd

2 hcd 中有

struct usb_bus                       self;                  /* hcd is-a bus */   

  这样一个结构体

  现在对这个usb_bus进行初始化

  usb_devmap 设置为0 ,这个结构体就是4int的数组

  其他的一些就不说了

  这样就完成了usb_bus 的初始化

  将内存资源给hcd

  Hcd 请求后,重新映射,这个就是映射过来的寄存器地址

哈哈!

 

设备的平台数据

 

struct pxaohci_platform_data {

            int (*init)(struct device *);

            void (*exit)(struct device *);

 

            int port_mode;

#define PMM_NPS_MODE           1

#define PMM_GLOBAL_MODE        2

#define PMM_PERPORT_MODE       3

 

            int power_budget;

};

启动hc

设置hc的内存管理模式

初始化ohci

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值