基于S3C2440平台的linux2.6.22内核版本的USB驱动框架分析

发布时间:2014-07-18 16:47:31来源:红联作者:linux08071151

driver/usb/host/ohci-s3c2410.c

static struct platform_driver ohci_hcd_s3c2410_driver

注册usb_device_driver

static int __init usb_init(void)

usb_register_device_driver(&usb_generic_driver, THIS_MODULE)/*注册usb_device_driver 到内核中*/

当找到usb总线上有匹配的usb_device就会调用generic_probe

generic_probe

usb_set_configuration

ret = device_add (&intf->dev);/*将每个USB接口注册到内核*/

struct usb_device_driver usb_generic_driver

driver/usb/host/ohci-hcd.c

注册USB平台驱动

ohci_hcd_mod_init

#define PLATFORM_DRIVER ohci_hcd_s3c2410_driver

platform_driver_register(&PLATFORM_DRIVER);

usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev)

hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx")

usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED)

hcd_buffer_create(hcd)

usb_register_bus(&hcd->self)

usb_alloc_dev(NULL, &hcd->self, 0)

register_root_hub(hcd)

usb_new_device (usb_dev)

device_add(&udev->dev)/*将usb_device添加到usb总线的klist_devices链表上,以便于usb_register_device_driver注册usb_device_driver的时候匹配该设备*/

S3C2410 HUB初始化

usb_hub_init

usb_register(&hub_driver)/*该过程匹配USB总线上的USB HUB接口设备,通过usb_probe_interface进行匹配,若匹配则调用hub_probe*/

hub_probe

hub_configure

usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, hub, endpoint->bInterval);/*填充urb->complete = hub_irq*/

hub_activate(hub);

usb_submit_urb

khubd_task = kthread_run(hub_thread, NULL, "khubd");/*建立内核线程*/

list_empty(&hub_event_list)/*若hub_event_list链表为空,则该线程休眠,知道urb_irq检测到hub接口状态发生变化,将该事件添加到hub_event_list链表,然后唤醒该线程*/

创建HCD

usb_create_hcd

init_timer(&hcd->rh_timer);

hcd->rh_timer.function = rh_timer_func;

hcd->rh_timer.data = (unsigned long) hcd;

static void rh_timer_func (unsigned long _hcd)

usb_hcd_poll_rh_status

mod_timer (&hcd->rh_timer, jiffies + msecs_to_jiffies(250));

usb_submit_urb(struct urb *urb, gfp_t mem_flags)

status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);

finish_urb (struct ohci_hcd *ohci, struct urb *urb)

usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb);

urb->complete (urb);/*调用注册的HUB_IRQ*/

1.中断类型的端口用于监控 root hub上是否有设备插入,root hub通过两种方式来监控是否有设备插入:

1.一种是通过中断方式,使能相应中断,当状态发生变化时产生中断,然后运行中断服务程序获取取状态寄存器信息;

2.一种是定时轮询方式,当定时时间到了运行定时器程时指定的定时器rh_timer的function函数rh_timer_func。

问:为什么要两种方式?

答:个人认为如果只使用中断方式的话,当插入USB的设备的时候,只会发生一次中断,若此次的中断丢失的话那么系统永远无法感知有USB设备的接入,但是定时器的可以定时的轮训该USB设备接入状态,可以避免这种情况的发生

一、中断方式:

usb_hcd_s3c2410_probe

usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);

request_irq(irqnum, &usb_hcd_irq, irqflags,hcd->irq_descr, hcd))/*usb_hcd_irq会调用hcd->driver->irq (hcd) = ohci_irq*/

ohci_irq

usb_hcd_poll_rh_status(hcd);

二、定时器方式:

usb_hcd_s3c2410_probe

usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED)

hcd->driver->start(hcd)/*调用ohci_s3c2410_hc_driver中的ohci_s3c2410_start,该函数*/

ohci_s3c2410_start (struct usb_hcd *hcd)

ohci_run (ohci)

hcd->poll_rh = 1;

hcd->uses_new_polling = 1;

if (hcd->uses_new_polling && hcd->poll_rh)

usb_hcd_poll_rh_status(hcd);/*进行一次USB HUB接口状态的检查,该函数中启动定时器链表rh_timer,当定时器超时的时候,调用超时函数rh_timer_func*/

static void rh_timer_func (unsigned long _hcd)

{

usb_hcd_poll_rh_status((struct usb_hcd *) _hcd);

} /*usb_hcd_poll_rh_status函数中会再次修改rh_timer,添加到内核定时器链表,定时器的周期为250ms*/

不管是通过中断方式还是通过定时轮询方式 ,最终都是通过调用usb_hcd_poll_rh_status来实现的root hub状态查

接下来分析usb_hcd_poll_rh_status函数

usb_hcd_poll_rh_status

length = hcd->driver->hub_status_data(hcd, buffer)

if (length > 0)

usb_hcd_giveback_urb (hcd, urb)

urb->complete (urb)/*该函数即为usb_fill_int_urb填充的hub_irq*/

kick_khubd(hub);/*当urb->status=0是说明urb传输完成,此时需要唤醒内核线程hub_thread*/

list_add_tail(&hub->event_list, &hub_event_list)

wake_up(&khubd_wait)

接着分析线程hub_thread

for (i = 1; i <= hub->descriptor->bNbrPorts; i++)

hub_port_status/*获取HUB接口状态*/

connect_change = 1/*当接口状态发生改变时,connect_change设为1*/

if(connect_change)

hub_port_connect_change(hub, i, portstatus, portchange)

udev = usb_alloc_dev(hdev, hdev->bus, port1)

dev->dev.bus = &usb_bus_type;

dev->dev.type = &usb_device_type;

struct usb_device *udev/*创建一个usb_device设备*/

choose_address(udev)/*给USB分配地址,最大为127*/

hub_port_init(hub, udev, port1, i)

hub_set_address

retval = usb_get_device_descriptor(udev, 8)/*因为不确定USB设备的能够支持的最大传输大小,先读取8字节,第8个字节为bMaxPacketSize0*/

i = udev->descriptor.bMaxPacketSize0 == 0xff?512 : udev->descriptor.bMaxPacketSize0;

udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);/*设置UDEV的描述符wMaxPacketSize = bMaxPacketSize0*/

retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE)/*将USB设备中的设备描述、配置描述符、接口描述符、端点描述符一次性全部读出来进行分析*/

usb_new_device(udev)

device_add(&udev->dev)/*将该设备添加到usb_bus_type类型的总线上,匹配成功的话,将调用需要我们写的usb_driver->probe*/

举例usb_driver:

驱动编写者需要添加自己usb_driver,如usbmouse_as_key.c

static struct usb_driver usbmouse_as_key_driver

usb_register(&usbmouse_as_key_driver)/*若匹配的过程是设备接口,则调用usbmouse_as_key_driver的probe函数*/

usbmouse_as_key_probe

input_register_device(uk_dev);

usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usbmouse_as_key_irq, NULL, endpoint->bInterval)

usb_submit_urb

linux内核usb驱动框架,基于S3C2440平台的linux2.6.22内核版本的USB驱动框架分析相关推荐

  1. Intel平台计算机升级到22.60.0.6蓝牙驱动导致蓝牙不稳定,请卸载!

    由于蓝牙驱动更新导致华为蓝牙鼠标链接不稳定.这里设置驱动不自动更新.Intel平台计算机升级到22.60.0.6蓝牙驱动导致蓝牙不稳定,请卸载!

  2. s3c2440a如何保证嵌入式linux对于虚拟内存的支持?,基于S3C2440的嵌入式LINUX操作系统内核研究【资料学习】.doc...

    学校代码: 11059 学 号:0805070285 Hefei University 毕业论文(设计) BACHELOR DISSERTATION 论文题目: 基于S3C2440的嵌入式 LINUX ...

  3. 基于u盘的linux桌面系统3 -基于windows平台的系统介绍

    基于U盘的移动操作系统,不仅有linux下开源的,也有基于windows平台的.使用起来也非常方便. 我自己试用过的有Prayaya V3,关于它的介绍可以到其官网查看.官方网址:http://www ...

  4. Linux四大安全实验二-基于实验楼平台的学习

    ShellShock攻击实验 前言 何为ShellShock 搭建环境 bash自定义函数 进行复现 深究源码 总结 前言 要理解这个实验可能需要一些set-uid程序的基础,详见我的上一篇博客 何为 ...

  5. Go微服务框架及基础平台选择

    Go微服务框架及基础平台选择 1 考虑因素 2 现有Go微服务框架 2.1 istio 2.1.1 Istio 特点 2.2 Go-kit 2.2.1 暂未找到 2.3 Kratos(奎托斯) 2.3 ...

  6. linux达芬奇安装教程,在Linux系统中能安装和运行达芬奇DaVinci Resolve 17版本

    如果你想在Linux系统中安装达芬奇DaVinci Resolve 17版本和运行它,请按以下说明操作,以下以Deepin 20.2为例,也适用在Ubuntu 20.04.UOS.Debian发行版中 ...

  7. linux移植wifi板载驱,基于arm\Linux平台USB无线网卡的wifi驱动移植

    arm平台是三星2440,Linux内核是2.6.24,威盛VNT6656的USB无线网卡:开发平台是Fedora10,内核是2.6.27.遭遇的问题主要有如下几个: 一.驱动程序的版本不对 开始在网 ...

  8. linux mic阵列通道丢数据,基于XMOS平台的USB麦克风阵列多声道采集装置

    技术领域 本实用新型涉及麦克风阵列多声道声音采集领域,尤其涉及基于XMOS平台的USB麦克风阵列多声道采集装置. 背景技术 麦克风阵列(Array Microphone),是由2个以上数量的声学数字或 ...

  9. 移植根文件系统到linux内核 s3c2440,u-boot-2011.06在基于s3c2440开发板的移植之引导内核与加载根文件系统...

    三.根文件系统的制作 我们利用busybox来制作根文件系统 1.在下列网站下载busybox-1.15.0.tar.bz2 在当前目录下解压busybox tar -jxvf busybox-1.1 ...

最新文章

  1. 阿里云高级总监谈超大规模超高性能分布式快存储系统
  2. JMS(Java消息服务)入门教程
  3. 最近面试一些厂的面经整理(阿里,腾讯,字节等)
  4. Node.JS 学习路线图
  5. C语言数组、字符与字符串笔记
  6. LeetCode 963. 最小面积矩形 II
  7. Linux采用服务器网址,Linux实现https方式访问站点
  8. H3C telnet 配置
  9. php动态生成页面结构,PHP 动态生成静态HTML页面示例代码
  10. javascript中的cookie
  11. STC8G七彩数字时钟、GPIO设置、DS1302使用、热敏电阻测温、SM5166P和MBI5024控制数码管显示
  12. TF-IDF算法原理和公式
  13. 微信小程序通过公众号(服务号)推送通知或提醒步骤及代码(一,获取推送前所需信息)
  14. c语言程序转换成单片机语言,STC12C2052AD单片机AD转换C语言程序(成功)
  15. python开源报表工具_12个最好的开源报表工具
  16. 国外十大在线支付服务网站
  17. mysql三表联合查询(员工表,部门表,工资表)
  18. 苹果怎么登录服务器未响应,王者荣耀登陆游戏服务器未响应该怎么解决 王者荣耀无法登陆解决办法...
  19. 大厂技术实现 | 爱奇艺文娱知识图谱的构建与应用实践 @自然语言处理系列
  20. [VOT10](2022CVPR)TCTrack: Temporal Contexts for Aerial Tracking

热门文章

  1. 计算机毕业设计JavaWEB儿童运动馆业务信息系统(源码+系统+mysql数据库+lw文档)
  2. 情人节礼物:抖音表白程序Python版 之无法拒绝的爱附完整源代码
  3. 软件测试————测试级别
  4. c++string 加引号_一文带你了解Java字符串处理(String,StringBuffer,StringBuild)
  5. WEB开发零基础到入门之HTML+CSS(学习记录)
  6. 安装、文件-Windows 8 完美越狱教程 -by小雨
  7. Matlab的输入输出函数,input()fprintf()disp()语法介绍,fprintf()disp()的区别
  8. YolactEdge: Real-time Instance Segmentation on the Edge (Jetson AGX Xavier: 30 FPS, RTX 2080 Ti: 170
  9. 微信小程序の再体验 - - 常用组件
  10. HTTP Status 400 - Required String parameter '/q' is not present