Usb(6)

本文详细解析了PXA3xx平台USB驱动的初始化过程,包括ohci_hcd_pxa3xx_drv_probe函数的具体实现,usb_hcd_pxa3xx_probe中的资源检查、USB HDC创建及内存映射等关键步骤。同时介绍了类设备注册流程及root_hub的创建过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

驱动pxa3xx-ohci 提供了设备的探测方法

 

ohci_hcd_pxa3xx_drv_probe

 

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;

}

 

 

其中static const struct hc_driver ohci_pxa3xx_hc_driver

主要提供了一些方法

接下来

usb_hcd_pxa3xx_probe

1 判断平台设备的第二个资源是不是irq资源

2 创建了一个usb_hdc,注意self->controller 指向的是device

3 内存资源给了hdc,并进行了重新隐射

4 usb_add_hcd 完成hcd的初始化和注册

  hcd分配dma Buffe

  系统中最多允许有64usb bus,用一个int 数组来做为bus的位图

  数组的元素个数为2

   在位图中找到第一个为0bit,找出下表作为bus num

  创建一个类设备

 

  先看一下class的定义

struct class {

            const char                     * name;

            struct module               * owner;

 

            struct subsystem           subsys;

            struct list_head children;

            struct list_head devices;

            struct list_head interfaces;

            struct semaphore          sem;     /* locks both the children and interfaces lists */

 

            struct kobject                *virtual_dir;

 

            struct class_attribute                 * class_attrs;

            struct class_device_attribute      * class_dev_attrs;

            struct device_attribute              * dev_attrs;

 

            int        (*uevent)(struct class_device *dev, char **envp,

                                       int num_envp, char *buffer, int buffer_size);

            int        (*dev_uevent)(struct device *dev, char **envp, int num_envp,

                                                char *buffer, int buffer_size);

 

            void      (*release)(struct class_device *dev);

            void      (*class_release)(struct class *class);

            void      (*dev_release)(struct device *dev);

 

            int        (*suspend)(struct device *, pm_message_t state);

            int        (*resume)(struct device *);

};

封装了一个子系统

 

再来看一个类是如何注册的

 

int class_register(struct class * cls)

{

            int error;

 

            pr_debug("device class '%s': registering/n", cls->name);

 

            INIT_LIST_HEAD(&cls->children);

            INIT_LIST_HEAD(&cls->devices);

            INIT_LIST_HEAD(&cls->interfaces);

            init_MUTEX(&cls->sem);

            error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name);

            if (error)

                        return error;

 

  类注册的核心就是子系统注册

            subsys_set_kset(cls, class_subsys);

 

看看

#define subsys_set_kset(obj,_subsys) /

            (obj)->subsys.kset.kobj.kset = &(_subsys).kset

需要弄明的是class 也是一个子系统

也就是所谓的ksetkset,呵呵

 

            error = subsystem_register(&cls->subsys);

            if (!error) {

                        error = add_class_attrs(class_get(cls));

                        class_put(cls);

            }

            return error;

}

 

再来看一下子系统的定义

 

struct subsystem {

            struct kset                    kset;

            struct rw_semaphore     rwsem;

};

 

就是带有信号的kset

 

所以子系统的初始化也比较简单,只要初始化kset 和信号就OK

 

struct kset {

            struct subsystem           * subsys;

            struct kobj_type            * ktype;

            struct list_head list;

            spinlock_t                     list_lock;

            struct kobject                kobj;

            struct kset_uevent_ops  * uevent_ops;

};

 

子系统的注册实际上就是把kset 加到对应的kobject 体系结构中去

 

Usb bus的注册本质上就是注册了一个类设备

 

接下来看看如何来添加一个USB 设备

 

Hcd 的第一个usb 设备就是root_hub 

struct usb_device *

usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)

 

第一个参数如果为NULL 表示创建的这个设备就是 root_hub

 

将分配的root_hub 分配成能够唤醒且应该唤醒

 

如果hcd driver reset 方法就reset 一下

 

接下来request_irq

Start

register_root_hub 注册root_hub

他的父亲很显然就是controller

这个设备最终被加到设备树中去了

 

Root_hub 的产生就是这个流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值