当前位置:   article > 正文

Linux复位usb hub,linux usb hub初始化-steven

linux 重置usb hub

分类:LINUX

谨以此文纪念过往的岁月

一.前言

在上文中讲述了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 = &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(kref);--hub参数的初始化。

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

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

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

(leds, led_work);

INIT_DELAYED_WORK(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的实例后,就需要对hub的配置。你会发现这是一个巨大的函数,不要畏惧其的巨大,还是一如既往的去分析他吧!

static int hub_configure(struct usb_hub *hub,str

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/263497
推荐阅读
相关标签
  

闽ICP备14008679号