linux hub设备,linux usb hub初始化

初始化

谨以此文纪念过往的岁月

一.前言

在上文中讲述了usb子系统的初始化,在该文中来看usb hub的驱动。不过在这里需要说明一点,host controller和usb hub是不同的东西。hc是指usb的控制器,而hub是一种usb集线器,其本质还是一种usb设备,只不过这种usb设备有点特殊而已。一般的MCU都会自带一个usb hub,以s3c6410为例,其带有一个hub,该hub有两个下行口,就是俗话所说的两个usb接口。你可以在把两个usb设备插到该hub下,再多就不行了。而该hub就是传说中的root hub,以该root hub为例,如果在该hub下还挂载一个hub,那插入的hub不是root hub而是一个hub设备,对于linux而言其会为每一个hub创建一条总线,用于该hub下的设备与驱动绑定。对于一般系统而言,一般一个hc对应一个root hub。

二.hub设备

关于root hub的设备注册还记否,在上文OHCI中已经涉及到了,不过特意点明而已,就是在register_root_hub中。

三.hub驱动

usb hub其实也是一种usb设备,其驱动不脱离usb驱动的模板。在usb_init中会调用usb_hub_init函数来注册hub的驱动。usb_register(&hub_driver),注册一个hub驱动。

那下面来看该hub_driver的具体每一个函数。

static struct

usb_driver hub_driver = {

.name ="hub",

.probe =hub_probe,

.disconnect =hub_disconnect,

.suspend =hub_suspend,

.resume =hub_resume,

.reset_resume =hub_reset_resume,

.pre_reset =hub_pre_reset,

.post_reset =hub_post_reset,

.ioctl =hub_ioctl,

.id_table =hub_id_table,

.supports_autosuspend =1,

};

2.1 hub_probe

hub探测函数,在驱动注册或设备注册时会调用。

static int

hub_probe(struct usb_interface *intf, const struct usb_device_id *id)

{

struct usb_host_interface *desc;

struct usb_endpoint_descriptor

*endpoint;

struct usb_device *hdev;

struct usb_hub *hub;

desc = intf->cur_altsetting;

hdev = interface_to_usbdev(intf);

if (hdev->level == MAX_TOPO_LEVEL) { --只只支持六层嵌套,就是所谓的hub接hub,最多接六层。

return -E2BIG;

}

if ((desc->desc.bInterfaceSubClass

!= 0) && (desc->desc.bInterfaceSubClass != 1)) {--一些湖北的subclass

= 1。根据usb的spec这是不允许的不过这还是可以工作的的,这世界总有些特殊的嘛,即是在协议界。

descriptor_error:

return -EIO;

}

if (desc->desc.bNumEndpoints != 1)--记住hub的端点只能有一个!!

goto descriptor_error;

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

if (!usb_endpoint_is_int_in(endpoint))--而且这个端点还必须是中断in类型。

goto descriptor_error;

hub = kzalloc(sizeof(*hub),

GFP_KERNEL); --在上述情况都满足的情况下才能说有一个hub存在。

if (!hub) {

return -ENOMEM;

}

kref_init(&hub->kref);--hub参数的初始化。

INIT_LIST_HEAD(&hub->event_list);

--事件链表,每一次的插拔都会引起hub的中断。会将该链表添加到hub_event_list链表中,同时唤醒khubd_wait即hub守护程序。

hub->intfdev = &intf->dev;--接口设备

hub->hdev = hdev;--hub的实体。

(&hub->leds,

led_work);

INIT_DELAYED_WORK(&hub->init_work,

NULL);

usb_get_intf(intf);

usb_set_intfdata (intf, hub);

intf->needs_remote_wakeup = 1;

if (hdev->speed == USB_SPEED_HIGH)

highspeed_hubs++;

if ((hub,

endpoint) >= 0)

return 0;

hub_disconnect (intf);

return -ENODEV;

}

的实例后,就需要对hub的配置。你会发现这是一个巨大的函数,不要畏惧其的巨大,还是一如既往的去分析他吧!

static int hub_configure(struct

usb_hub *hub,struct usb_endpoint_descriptor *endpoint)

{

struct usb_device *hdev = hub->hdev;

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值