Chinaunix首页 | 论坛 | 博客
  • 博客访问: 45474
  • 博文数量: 4
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 7
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-23 21:52
个人简介

专注Linux驱动开发、内核研究。

文章分类
文章存档

2015年(3)

2014年(1)

我的朋友

分类: 嵌入式

2015-11-02 16:37:29

分析的linux内核版本为3.10.73,USB设备为GL823 USB2.0 SD/MMC Card Reader Controller,为了使分析简单化,只取主干代码,次要的代码(如:sysfs相关代码,出错判断代码,异常处理逻辑代码,unlikely宏控制的代码)不展开分析。

阅读代码之前需要了解的一些概念:
1.USB Host Controller一般都有一个Root hub
2.USB初始化时会遍历挂接到USB总线上的设备
3.SCSI是通过channel、id、lun进行寻址的

流程图说明:
红色加粗:表示次要的代码
蓝色加粗:表示代码流程跳转
绿色加粗:表示还不太理解的代码;或不是三两句能道明的,需要后续开专题分析

色加粗:表示函数的简单说明

缩进:表示函数调用关系,没有缩进表示函数是同级的,即都由父函数调用

1.usb_init

usb_init

    usb_debugfs_init

    usb_devio_init

        register_chrdev_region

        cdev_init(usbdev_file_operations)

        cdev_add

        usb_register_notify(&usbdev_nb)->usbdev_notify

    usb_hub_init

        usb_register(&hub_driver)

            hub_probe

                hub_configure

                    get_hub_descriptor

                    INIT_WORK(hub_tt_work)

                    hub_hub_status

                    usb_alloc_urb

                    usb_fill_int_urb(hub_irq)

                    usb_hub_create_port_device

                    usb_hub_adjust_deviceremovable

                    hub_activate

                        kick_khubd
                            wake_up(&khubd_wait)
        kthread_run(hub_thread, NULL, "khubd")
            wait_event_freezable(khubd_wait)
                hub_events
                    hub_port_connect_change
                        usb_alloc_dev
                        hub_port_init
                        usb_new_device

                            usb_enumerate_device

                            device_add

                                generic_probe(第二次)

    usb_register_device_driver(&usb_generic_driver, THIS_MODULE)

        generic_probe

            usb_choose_configuration

            usb_set_configuration

                usb_hcd_alloc_bandwidth

                INIT_WORK(__usb_queue_reset_device)

                device_add

                    hub_probe(第一次调用generic_probe)

                    storage_probe(第二次调用generic_probe)

                create_intf_ep_devs

usb_debugfs_init:创建debug/usb/devices文件,这个文件包含了注册的usb设备。

usb_devio_init:注册/dev/usbdev*设备节点,用户态程序可以直接操作usb。 
usb_hub_init:完成hub的初始化工作,创建后台守护进程hub_thread。
hub_thread:当hub总线上的状态发生变化(例如usb设备插入),会唤醒该进程,并作出相应处理。
usb_register_device_driver(&usb_generic_driver, THIS_MODULE):发现usb device后会调用到,初始化usb device并注册usb interface。


2.ambarella_phy_module_init

ambarella_phy_module_init

    ambarella_phy_probe


ambarella_phy_module_init:平台相关代码,注册usb phy初始化函数,该函数在ehci_hcd_init流程中会调用到。

3.ehci_hcd_init

ehci_hcd_init

    ehci_ambarella_drv_probe

        ehci_init_driver

        usb_create_hcd

            usb_create_shared_hcd

                rh_timer_func

        usb_phy_init

        usb_add_hcd

            hcd_buffer_create

            usb_register_bus

            usb_alloc_dev

            usb_hcd_request_irqs

            ehci_run

            register_root_hub

                usb_get_device_descriptor

                usb_get_bos_descriptor

                usb_new_device

                    usb_enumerate_device

                    device_add

                        generic_probe(第一次)

                    usb_create_ep_devs

ehci_hcd_init:host controller 的初始化(ehci符合usb 2.0规范、ohci符合usb 1.1规范),初始化struct usb_hcd并add到usb子系统中。
usb_create_hcd、usb_add_hcd:初始化hcd并加入系统中,其中会分配root hub usb device并注册。
usb_phy_init:平台相关代码,初始化USB PHY


4.init_scsi

init_scsi

    scsi_init_procfs

    scsi_init_devinfo

    scsi_init_sysctl

init_scsi:
scsi_init_procfs:创建/proc/scsi/scsi文件,显示attached到scsi总线上的target。

scsi_init_devinfo:创建/proc/scsi/device_info文件,scsi驱动支持的设备列表,以vendor:model格式显示,该文件可写echo "vendor:model:flag" > /proc/scsi/device_info。

scsi_init_sysctl:创建/proc/sys/dev/scsi/logging_level文件,通过它可以设置LOG打印等级,需要使能CONFIG_SCSI_LOGGING。


5.init_sd

init_sd

    register_blkdev

    scsi_register_driver

        sd_probe

            alloc_disk

            async_schedule_domain

                sd_probe_async

                    sd_revalidate_disk

                    blk_queue_prep_rq(sdp->request_queue, sd_prep_fn)

                    blk_queue_unprep_rq(sdp->request_queue, sd_unprep_fn)

                    add_disk 
                        register_disk
                            device_add
                    sd_revalidate_disk

init_sd:注册/dev/sda*设备节点,
blk_queue_prep_rq(sdp->request_queue, sd_prep_fn):注册request_queue的prep_fn
blk_queue_unprep_rq(sdp->request_queue, sd_unprep_fn):注册request_queue的unprep_fn
sd_revalidate_disk:第一次调用sd_revalidate_disk是为了flush request_queue中的request,因为马上要改变prep_fn了,第二次是为了检测是否存在sd卡


6.module_usb_driver(usb_storage_driver)

storage_probe

    usb_stor_probe1

        scsi_host_alloc

            kthread_run(scsi_error_handler)

        INIT_DELAYED_WORK(usb_stor_scan_dwork)

                            scsi_scan_host

                                do_scsi_scan_host

                                    scsi_scan_host_selected

                                        scsi_scan_channel

                                            __scsi_scan_target

                                                scsi_alloc_target

                                                scsi_probe_and_add_lun

                                                    scsi_alloc_sdev

                                                        INIT_WORK(scsi_evt_thread)

                                                        INIT_WORK(scsi_requeue_run_queue)

                                                        scsi_alloc_queue

                                                            __scsi_alloc_queue(scsi_request_fn)

                                                                blk_init_queue

                                                            blk_queue_prep_rq(scsi_prep_fn)

                                                            blk_queue_softirq_done(scsi_softirq_done)

                                                            blk_queue_rq_timed_out(scsi_times_out)

                                                            blk_queue_lld_busy(scsi_lld_busy)

                                                        scsi_adjust_queue_depth

                                                        scsi_sysfs_device_initialize

                                                    scsi_probe_lun

                                                    scsi_add_lun

                                                        scsi_sysfs_add_sdev

                                                            scsi_target_add

                                                            device_add

                                                                sd_probe

        associate_dev

        get_device_info

        get_transport

        get_protocol

    usb_stor_probe2

        get_pipes

        usb_stor_acquire_resources

            usb_alloc_urb

            kthread_run(usb_stor_control_thread, us, "usb-storage")

        scsi_add_host

            scsi_add_host_with_dma

                scsi_setup_command_freelist

                    scsi_get_host_cmd_pool

                    scsi_host_alloc_command

        queue_delayed_work

            usb_stor_scan_dwork
storage_probe:注册scsi host,初始化blk相关的钩子函数,扫描scsi总线,添加scsi target 

附件:
usb_storage.rar

阅读(4212) | 评论(0) | 转发(0) |
0

上一篇:cygwin下arm交叉编译环境搭建

下一篇:没有了

给主人留下些什么吧!~~