linux那些事之hub--初始

1、roothub通常被集成在了主控制器。

初始化driver/core/usb.c中

static int __init usb_init(void)
{
	。。。
	retval = usb_hub_init();
	if (retval)
		goto hub_init_failed;
        。。。
	return retval;
}
int usb_hub_init(void)
{
	if (usb_register(&hub_driver) < 0) { //先注册hub驱动</span></strong>
		printk(KERN_ERR "%s: can't register hub driver\n",
			usbcore_name);
		return -1;
	}

	khubd_task = kthread_run(hub_thread, NULL, "khubd");
	if (!IS_ERR(khubd_task)) //判断创建的进程是否正确</strong>
		return 0;

	/* Fall through if kernel_thread failed */
	usb_deregister(&hub_driver);
	printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);

	return -1;
}
判断空间开辟是否正确判断:通常将最后一页来存放错误号的,当返回的指针指向了最后页就代表错误。

#define MAX_ERRNO	4095

#ifndef __ASSEMBLY__

#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) //例如32bit 最高地址0xffffffff,最后页地址0xfffff000-0xffffffff

static inline void * __must_check ERR_PTR(long error)
{
	return (void *) error;
}

static inline long __must_check PTR_ERR(const void *ptr)
{
	return (long) ptr;
}

static inline long __must_check IS_ERR(const void *ptr)
{
	return IS_ERR_VALUE((unsigned long)ptr);
}
#define list_entry(ptr,type,member) \
             container_of(ptr,type,member) //ptr是type变量中的member成员的指针,通过该ptr得type指针。


static int hub_thread(void *__unused)
{
	set_freezable();
	do {
		hub_events();
		wait_event_freezable(khubd_wait,
				!list_empty(&hub_event_list) || //hub_event_list 为全局变量
				kthread_should_stop());
	} while (!kthread_should_stop() || !list_empty(&hub_event_list));

	pr_debug("%s: khubd exiting\n", usbcore_name);
	return 0;
}
wait_event_interruptible= sleep until a condition gets true,即条件为假则休眠


在hub中采用总分总分的结构来处理hub事件,如先

总:设置一个链表hub_event_list,设置一个总的函数hub_event()

分:每个hub都有个event_list,当有hub的event_list发生变化时,把该event_list插到hub_event_list中

总:再触发总hub_event()

分:hub_event又根据event_list确定是哪个struct usb_hub或者哪个hub有问题


接着看hub_event

static void hub_events(void)
{
	struct list_head *tmp;
	struct usb_device *hdev;
	struct usb_interface *intf;
	struct usb_hub *hub;
	struct device *hub_dev;
	u16 hubstatus;
	u16 hubchange;
	u16 portstatus;
	u16 portchange;
	int i, ret;
	int connect_change;

	while (1) {

		/* Grab the first entry at the beginning of the list */
		spin_lock_irq(&hub_event_lock);
		if (list_empty(&hub_event_list)) {
			spin_unlock_irq(&hub_event_lock);
			>break;
		}
.....

这里判断 hub_event_list为空,则直接退出该函数,线程hub_thread睡眠




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值