`
dato0123
  • 浏览: 939979 次
文章分类
社区版块
存档分类
最新评论

Linux那些事儿之我是Hub(6)probe,又见probe!

 
阅读更多

话说因为hub驱动无所事事,所以hub_thread()进入了睡眠,直到某一天,hub_probe被调用.所以我们来看hub_probe().这个函数来自drivers/usb/hub.c,其作用就如同当初我们在usb-storage中的那个storage_probe()一样.

887 static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)

888 {

889 struct usb_host_interface *desc;

890 struct usb_endpoint_descriptor *endpoint;

891 struct usb_device *hdev;

892 struct usb_hub *hub;

893

894 desc = intf->cur_altsetting;

895 hdev = interface_to_usbdev(intf);

896

897 #ifdef CONFIG_USB_OTG_BLACKLIST_HUB

898 if (hdev->parent) {

899 dev_warn(&intf->dev, "ignoring external hub/n");

900 return -ENODEV;

901 }

902 #endif

903

904 /* Some hubs have a subclass of 1, which AFAICT according to the */

905 /* specs is not defined, but it works */

906 if ((desc->desc.bInterfaceSubClass != 0) &&

907 (desc->desc.bInterfaceSubClass != 1)) {

908 descriptor_error:

909 dev_err (&intf->dev, "bad descriptor, ignoring hub/n");

910 return -EIO;

911 }

912

913 /* Multiple endpoints? What kind of mutant ninja-hub is this? */

914 if (desc->desc.bNumEndpoints != 1)

915 goto descriptor_error;

916

917 endpoint = &desc->endpoint[0].desc;

918

919 /* If it's not an interrupt in endpoint, we'd better punt! */

920 if (!usb_endpoint_is_int_in(endpoint))

921 goto descriptor_error;

922

923 /* We found a hub */

924 dev_info (&intf->dev, "USB hub found/n");

925

926 hub = kzalloc(sizeof(*hub), GFP_KERNEL);

927 if (!hub) {

928 dev_dbg (&intf->dev, "couldn't kmalloc hub struct/n");

929 return -ENOMEM;

930 }

931

932 INIT_LIST_HEAD(&hub->event_list);

933 hub->intfdev = &intf->dev;

934 hub->hdev = hdev;

935 INIT_DELAYED_WORK(&hub->leds, led_work);

936

937 usb_set_intfdata (intf, hub);

938 intf->needs_remote_wakeup = 1;

939

940 if (hdev->speed == USB_SPEED_HIGH)

941 highspeed_hubs++;

942

943 if (hub_configure(hub, endpoint) >= 0)

944 return 0;

945

946 hub_disconnect (intf);

947 return -ENODEV;

948 }

幸运的是这个函数还不是很长.看过usb-storage的兄弟姐妹们应该不难看懂这个函数.尤其是894,895这几行经典的赋值.尽管当年我们看的usb-storage2.6.10的内核,而斗转星移,如今我们看的是2.6.22.1的内核,但是江山会变,四季会变,有些经典并不会改变.894,desc,是这个函数里定义的一个struct usb_host_interface结构体指针,其实这就相当于当年的那个altsetting,只是换了个名字,别以为披上马夹咱就不认识它了.struct usb_host_interface结构体的定义依然还是当初那样,鉴于子曾经曰过温故而知新,我们这里再贴一次这个结构体吧,来自include/linux/usb.h:

69 /* host-side wrapper for one interface setting's parsed descriptors */

70 struct usb_host_interface {

71 struct usb_interface_descriptor desc;

72

73 /* array of desc.bNumEndpoint endpoints associated with this

74 * interface setting. these will be in no particular order.

75 */

76 struct usb_host_endpoint *endpoint;

77

78 char *string; /* iInterface string, if present */

79 unsigned char *extra; /* Extra descriptors */

80 int extralen;

81 };

需要注意的是,71,这里有一个成员,对应接口描述符的结构体,struct usb_interface_descriptor desc,刚才我们的那个指针也叫做desc,所以一会我们就会看到,desc->desc这样的用法.

同样895行这个赋值我们也是很眼熟, interface_to_usbdev()这个宏就是为了从一个struct usb_interface的结构体指针得到那个与它相关的struct usb_device结构体指针.这里等号右边的intf自不必说,而左边的hdev正是我们这里为了hub而定义的一个struct usb_device结构体指针.

897902,这是为OTG而准备的,为了简化问题,在这里我做一个伟大的假设,即假设我们不支持OTG.在内核编译选项中有一个叫做CONFIG_USB_OTG的选项,OTG就是On The Go的意思,正在进行中的意思,随着USB传输协议的诞生以及它的迅速走红,人们不再满足于以前那种一个设备要么就是主设备,要么就是从设备的现状,也就是说要么是Host,或者叫主设备,要么是外设,也叫Slave,或者叫从设备.那个年代里,只有当一台Host与一台Slave连接时才能实现数据的传输,而后来善良的开发者们又公布了USB OTG规范,于是出现了OTG设备,即既可以充当Host,亦能充当Slave的设备.就是说你有一个数码相机,你有一台打印机,它们各有一个USB接口,把这两个口连接起来,然后就可以把你的美女照片打印出来了.不过我们为了省事,还是别玩这种高科技了吧,省点时间玩几盘CS不是挺好么?所以我只能假设我们不打开支持OTG的编译开关,而这里我们看到的CONFIG_USB_OTG_BLACKLIST_HUB,其实就是一CONFIG_OTG下面的子选项,不选后者根本就见不到前者,因此咱们也不用看.

904911,这我真是无话可说了,每一个USB设备它属于哪个类,以及哪个子类,这都是上天注定的,自打盘古开天地那会儿就已经确定下来了,比如hub的子类就是0,desc->desc这个interface描述符里边的bInterfaceSubClass就该是0.所以这里本是判断如果bInterfaceSubClass不为0那就出错了,那就甭往下走了,返回吧,返回值是-EIO.就像一个人如果连自己是哪一类物种都能弄错,那还活个什么劲呢?不过我真正来气的是偏偏有些没事找抽型的企业愣是把自己家生产的hub里边的描述符中的bInterfaceSubClass这一位弄成了1,完了实践证明该hub也还能工作,别的方面都还正常,你说你要是调试设备驱动程序老是碰上这样的设备是不是非得急死你?

914,915,其实干的事情是差不多的,针对接口描述符再做一次判断,这次是判断这个hub有几个端点,或者说Endpoint.spec规定了hub就是一个endpoint,中断endpoint,因为hub的传输是中断传输.当然还有控制传输,但是因为控制传输是每一个设备都必须支持的,即每一个usb设备都会有一个控制端点,所以在desc->desc.bNumEndpoints中是不包含那个大家都有的控制端点的.因此如果这个值不为1,那么就说明又出错了,仍然只能是返回.

917,就是得到这个唯一的端点所对应的端点描述符,920921行就是判断这个端点是不是中断端点,如果不是那还是一样,返回报错吧.

如果以上几种常见的错误都没有出现,那这时候我们才开始正式的去做一些事情,让我们继续,向前进,向前进,战士的责任重,妇女的冤仇深.

924,打印调试信息.

926,申请hub的数据结构struct usb_hub.早些时候我们已经贴出来这个结构体的定义了,不记得的回去看看.不过926行有一个很新潮的函数,kzalloc().其实这个函数就是原来的两个函数的整合,即原来我们每次申请内存的时候都会这么做,先是用kmalloc()申请空间,然后用memset()来初始化,而现在省事了,一步到位,直接调用kzalloc(),效果等同于原来那两个函数,所有申请的元素都被初始化为0.其实对写驱动的来说,知道现在应该用kzalloc()代替原来的kmalloc()memset()就可以了,这是内核中内存管理部分做出的改变,确切的说是改进,负责内存管理那部分的兄弟们的目标无非就是让内核跑起来更快一些,而从kmalloc/memsetkzalloc的改变确实也是为了实现这方面的优化.所以自从2005年底内核中引入kzalloc之后,忽如一夜春风来,整个内核代码的许多模块里面都先后把原来的kmalloc/memset统统换成了kzalloc().咱们这里就是其中一处.927930行不用说了,如果没申请成功那就挂了,返回ENOMEM.

932,还记得咱们之前说了什么吗,总分的想法,一个总的事件队列,hub_event_list,然后各个hub都有一个分的事件队列,就是这里的hub->event_list,前面咱们初始化了全局的那个hub_event_list,而这里咱们针对单个hub就得为其初始化一个event_list.

933行和934,struct usb_hub中的两个成员,struct device *intfdev, struct usb_device *hdev,干嘛用的想必不用多说了吧,第一个,甭管你是usb设备也好,pci设备也好,scsi设备也好,Linux内核中都为你准备一个struct device结构体来描述,所以intfdev就是和咱们这usb hub相关联的struct device指针,第二个,甭管你是hub也好,u盘也好,移动硬盘也好,usb鼠标也好,usb core都为你准备一个struct usb_device来描述,所以hdev就将是与咱们这个hub相对应的struct usb_device指针.而这些,在我们调用hub_probe之前就已经建立好了,都在那个参数struct usb_interface *intf,具体怎么得到的,对于root hub来说,这涉及到host controller的驱动程序,咱们先不去理睬.但对于一个普通的外接的hub,那咱们一会儿会看到如何得到它的struct usb_interface,因为建立并初始化一个usb设备的struct usb_interface正是hub驱动里做的事情.其实也就是我们对hub驱动最好奇的地方.因为找到了这个问题的答案,我们就知道了对于一个usb设备驱动,probe指针是在什么情况下被调用的,比如咱们这里的hub_probe对于普通hub来说是谁调用的?比如咱们之前那个usb-storage中最有意思的函数storage_probe()究竟是谁调用的?这正是我们想知道的.

分享到:
评论

相关推荐

    Linux那些事儿之我是Hub

    ### Linux那些事儿之我是Hub —— 深入解析Linux下的USB Hub驱动 #### 引言 《Linux那些事儿之我是Hub》这篇文章以其独特的视角,深入浅出地讲解了Linux系统下USB Hub的工作原理及其与操作系统之间的交互机制。...

    Linux那些事儿之我是SCSI硬盘.pdf

    《Linux那些事儿之我是SCSI硬盘》一书深入剖析了SCSI硬盘在Linux系统中的运作机制,特别是针对SCSI子系统及其驱动程序的分析。SCSI(Small Computer System Interface)是一种用于连接计算机与多种硬件设备(如硬盘...

    Linux那些事儿之我是EHCI主机控制器.pdf

    ### Linux那些事儿之我是EHCI主机控制器 #### 引言 在深入了解EHCI(Enhanced Host Controller Interface,增强型主机控制器接口)之前,让我们先简要回顾一下EHCI的背景及其在Linux系统中的作用。EHCI是USB 2.0...

    Linux那些事儿之我是Block层

    ### Linux Block 层详解 #### 一、Block 层简介 在 Linux 内核发展过程中,Block 层作为存储子系统的重要组成部分,在处理磁盘读写请求方面扮演着至关重要的角色。从内核版本 2.6.15 开始,内核源代码的顶级目录下...

    Linux那些事之我是USB

    在IT领域,Linux操作系统以其开源、稳定和高度可定制性而受到广大用户的喜爱。而Linux下的USB(Universal Serial Bus)技术则是连接外部设备的重要接口,它使得设备的安装和使用变得简单而直观。本篇文章将深入探讨...

    Linux那些事儿之我是USB Core(v1.0)

    《Linux那些事儿之我是USB Core》是一篇深入剖析Linux内核2.6.22版本中USB核心(USB Core)源码的文章。文章采用轻松幽默的语言风格,将复杂的USB核心工作原理和技术细节娓娓道来,不仅适合有一定Linux内核开发基础...

    GENEX+Probe使用指导书.doc

    GENEX+Probe 使用指导书 GENEX+Probe 使用指导书是一个详细的指导手册,旨在帮助用户正确地使用 GENEX+Probe 软件进行测试。该手册从安装 Probe 软件开始,指导用户如何安装 Hisi UE Agent 和 FileZilla 软件,...

    Linux I2C总线分析(主要是probe的方式)

    "Linux I2C总线分析(主要是probe的方式)" Linux I2C总线分析是指Linux操作系统中I2C总线的工作机制和结构。I2C总线是串行总线,它可以实现多个设备之间的数据交换。Linux I2C总线分析可以分为三个组成部分:I2C...

    ucProbe.zip

    6. **跨平台**:ucProbe支持Windows、Linux和Mac OS操作系统,满足不同开发环境的需求。 7. **源码级调试**:通过集成的GDB调试服务器,ucProbe能实现源码级别的调试,这对于理解代码执行流程和查找错误至关重要。 ...

    Tomcat监控工具Probe,支持tomcat6-7-8-9.zip

    6.probe使用介绍 Applecations:tomcat上面正在跑的应用,可以看到每个应用的状态、请求数、session数等,点进去可以查看详细信息 Data Sources:tomcat的数据源,我这里没有配置数据源 Deployment:代码部署...

    Micrium-uC-Probe

    uC/Probe4.8.0.0免费版本,安装即可使用。uC/Probe是micrium公司推出的嵌入式系统调试工具。

    UCOSIII使用中的任务监控uC/Probe的目标代码

    6. **故障诊断**:当系统出现异常时,uC/Probe的监控信息可以帮助开发者快速定位问题所在,例如检查是否有任务陷入无限循环或资源竞争。 总的来说,使用uC/Probe监控UCOSIII的任务,不仅可以提升开发效率,还可以在...

    probe.rar,解压后即为probe.war 3.2.0版本

    《探究probe.war 3.2.0版本的深度解析》 probe.war是一个Web应用程序的归档文件,它是基于Java技术栈构建的。在Java世界中,WAR(Web ARchive)文件格式用于打包和部署Web应用。probe.war 3.2.0版本是我们今天要...

    最新Probe2.3.3中文版本

    标题 "最新Probe2.3.3中文版本" 暗示了这是一个针对Probe软件的更新,特别是其2.3.3版本,并且该版本已经本地化为中文,适合中文用户使用。Probe通常是一款用于系统监控和性能分析的工具,特别在Java应用服务器,如...

    uC/Probe 调试工具

    6. **日志记录与回放**:uC/Probe 具有日志记录功能,可以捕获系统的运行轨迹,便于后期分析。更有甚者,它支持日志回放,允许开发者重演历史事件,以研究问题发生的原因。 7. **兼容性与集成**:uC/Probe 能与多种...

    你了解Embeded linux中的probe.docx

    在嵌入式Linux系统中,`probe`是一个关键机制,用于连接硬件设备(device)与驱动程序(device_driver)。在Linux内核加载过程中,probe机制允许内核发现并初始化硬件设备,确保驱动程序能正确地识别和管理这些设备...

    USB-HUB驱动分析 .docx

    当USB设备连接至USB接口时,需要通过`hub_probe`函数对USB Hub进行配置。在此过程中,会调用`hub_configure`函数来分配并初始化URB(USB Request Block),这是USB通信的基本单位。 ```c void hub_configure(struct...

    probe 1.7b含汉化文件

    "Probe 1.7b 含汉化文件"是一个针对Probe软件的中文本地化版本,主要目的是为了方便中文用户理解和操作。 Probe是一款广泛使用的网络诊断和监控工具,它能够帮助IT专业人员深入分析网络性能,识别潜在的问题,并提供...

    psi-probe最新版

    6. **自定义告警**:用户可以根据需求设置告警规则,当服务器状态达到预设阈值时,psi-probe会自动发送告警通知,及时处理潜在问题。 7. **可视化界面**:psi-probe提供了直观的Web界面,使监控数据一目了然,便于...

    Allegro172版本DFM规则之DFT Probe

    Allegro172 版本 DFM 规则之 DFT Probe Allegro172 版本 DFM 规则之 DFT Probe 是一个基于 Allegro 设计和分析平台的设计规则设置,用于确保Printed Circuit Board(PCB)的设计质量和效率。DFM 规则是一组规则和...

Global site tag (gtag.js) - Google Analytics