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

本文详细探讨了Linux系统中USB Hub的驱动实现,包括hub设备的注册、hub驱动的初始化,以及hub探测和配置的过程。文章指出hub实际上是一种特殊的USB设备,其驱动程序遵循USB驱动模板,并强调了hub电源管理和端口状态处理的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分类: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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值