分析USB平台设备模型框架(1)

start_kernel
    	rest_init();
		kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
			do_basic_setup();
				driver_init();
					void __init driver_init(void)
						void __init driver_init(void)
						{
							/* These are the core pieces */
							devices_init();					 表示在/sys/devices /sys/dev  /sys/block /sys/char 目录
							buses_init();                                          /sys/bus
							classes_init();                                        /sys/class
							firmware_init();                                       /sys/firmware
							hypervisor_init(); 

							/* These are also core pieces, but must come after the
							 * core core pieces.
							 */
							platform_bus_init();
							system_bus_init();
							cpu_dev_init();
							memory_dev_init();
						}

平台总线设备驱动:
struct bus_type platform_bus_type = {
	.name		= "platform",
	.dev_attrs	= platform_dev_attrs,
	.match		= platform_match,
	.uevent		= platform_uevent,
	.pm		= PLATFORM_PM_OPS_PTR,
};
int __init platform_bus_init(void)
{
	int error;

	early_platform_cleanup();

	error = device_register(&platform_bus);
	if (error)
		return error;
	error =  bus_register(&platform_bus_type);      //平台总线注册
	if (error)
		device_unregister(&platform_bus);
	return error;
}

USB总线设备驱动:

USB总线匹配函数
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
	/* devices and interfaces are handled separately */
	if (is_usb_device(dev)) {

		/* interface drivers never match devices */
		if (!is_usb_device_driver(drv))
			return 0;

		/* TODO: Add real matching code */
		return 1;

	} else {
		struct usb_interface *intf;
		struct usb_driver *usb_drv;
		const struct usb_device_id *id;

		/* device drivers never match interfaces */
		if (is_usb_device_driver(drv))
			return 0;

		intf = to_usb_interface(dev);
		usb_drv = to_usb_driver(drv);

		id = usb_match_id(intf, usb_drv->id_table);
		if (id)
			return 1;

		id = usb_match_dynamic_id(intf, usb_drv);
		if (id)
			return 1;
	}

	return 0;
}

struct bus_type usb_bus_type = {
	.name =		"usb",
	.match =	usb_device_match,
	.uevent =	usb_uevent,
};

static const struct file_operations usb_fops = {
	.owner =	THIS_MODULE,
	.open =		usb_open,
};

USB HUB驱动,因此大多数情况下,可以直接使用USB HUB设备,系统已经完成device和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,
};

subsys_initcall(usb_init);
	retval = bus_register(&usb_bus_type);           //USB总线注册
				priv->devices_kset = kset_create_and_add("devices", NULL,&priv->subsys.kobj);  //在/sys/bus/usb下创建devices
				priv->drivers_kset = kset_create_and_add("drivers", NULL,&priv->subsys.kobj);  //在/sys/bus/usb下创建drivers
				klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);        初始化devices链表
				klist_init(&priv->klist_drivers, NULL, NULL);                                  初始化driver链表
	retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb);
	retval = usb_host_init();
	retval = usb_major_init();                    //注册字符设备
				error = register_chrdev(USB_MAJOR, "usb", &usb_fops);    //cat /proc/devices 下查看  180 usb,主设备号180
	retval = usb_register(&usbfs_driver);
	retval = usb_devio_init();
	retval = usbfs_init();
	retval = usb_hub_init();
		usb_register(&hub_driver)   ///将hub.c里面的hub_driver加入到usb总线下的驱动链表里
			new_driver->drvwrap.driver.bus = &usb_bus_type;    //指定增加的驱动的类型: &usb_bus_type;
			retval = driver_register(&new_driver->drvwrap.driver);
				ret = bus_add_driver(drv);
					 driver_find(drv->name, drv->bus);
					 ret = bus_add_driver(drv);
					 	error = driver_attach(drv);
					 		bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}								driver_match_device(drv, dev)   //调用总线上的match,检测驱动与设备是否匹配
								driver_probe_device(drv, dev);
									really_probe(dev, drv);
											if (dev->bus->probe) {
											ret = dev->bus->probe(dev);    //先使用总显得Probe
											if (ret)
												goto probe_failed;
											} else if (drv->probe) {
											ret = drv->probe(dev);         //再使用调用hub.c里面的驱动的probe函数
											if (ret)
												goto probe_failed;
											}

											static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
												hub_configure(hub, endpoint)
														pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress);
														maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe));
														hub->urb = usb_alloc_urb(0, GFP_KERNEL);
														usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,
															hub, endpoint->bInterval);
														hub->urb->transfer_dma = hub->buffer_dma;
														hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
														hub_activate(hub, HUB_INIT);
	static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);   //定义等待队列	

		khubd_task = kthread_run(hub_thread, NULL, "khubd");  //开启Hub_thread线程
			wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());	 //将当前进程加入到等待队列中,进程在这里停下来了,我们需要看看那里唤醒进程					        

        void usb_kick_khubd(struct usb_device *hdev)
                  static void kick_khubd(struct usb_hub *hub)
                  		wake_up(&khubd_wait);	//唤醒等待进程Hub_thread
                  			hub_events();
                  				hub_port_connect_change(hub, i,portstatus, portchange);
                  					udev = usb_alloc_dev(hdev, hdev->bus, port1);   //分配一个struct usb_device
                  						choose_address(udev);  //选择usb设备地址
                  						hub_port_init
							                  dev_info (&udev->dev,
									  "%s %s speed %sUSB device using %s and address %d\n",
									  (udev->config) ? "reset" : "new", speed, type,
									  udev->bus->controller->driver->name, devnum);

									  hub_set_address //将选择的地址告诉usb设备
									  retval = usb_get_device_descriptor(udev, 8); //获得设备描述符
									  retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);  ;//再次获得设备描述符

								status = usb_new_device(udev);
									announce_device(udev);
										show_string(udev, "Product", udev->product);
										show_string(udev, "Manufacturer", udev->manufacturer);
										show_string(udev, "SerialNumber", udev->serial);
									err = device_add(&udev->dev);
										error = bus_add_device(dev);;//将usb设备加入到usb总线旗下的设备列表里面
										bus_attach_device(dev);
											ret = device_attach(dev);
												ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);    //对所有的驱动,调用__device_attach判断设备与驱动是否匹配
													driver_match_device(drv, dev)
														return drv->bus->match ? drv->bus->match(dev, drv) : 1;
													 driver_probe_device(drv, dev);
													 	ret = really_probe(dev, drv);
															  drv->probe(dev);//一旦匹配的话就会调用驱动的probe函数

描述USB HUB 的结构体
struct usb_hub {
	struct device		*intfdev;	/* the "interface" device */
	struct usb_device	*hdev;
	struct kref		kref;
	struct urb		*urb;		/* for interrupt polling pipe */

	/* buffer for urb ... with extra space in case of babble */
	char			(*buffer)[8];
	dma_addr_t		buffer_dma;	/* DMA address for buffer */
	union {
		struct usb_hub_status	hub;
		struct usb_port_status	port;
	}			*status;	/* buffer for status reports */
	struct mutex		status_mutex;	/* for the status buffer */

	int			error;		/* last reported error */
	int			nerrors;	/* track consecutive errors */

	struct list_head	event_list;	/* hubs w/data or errs ready */
	unsigned long		event_bits[1];	/* status change bitmask */
	unsigned long		change_bits[1];	/* ports with logical connect
							status change */
	unsigned long		busy_bits[1];	/* ports being reset or
							resumed */
#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
#error event_bits[] is too short!
#endif

	struct usb_hub_descriptor *descriptor;	/* class descriptor */
	struct usb_tt		tt;		/* Transaction Translator */

	unsigned		mA_per_port;	/* current for each child */

	unsigned		limited_power:1;
	unsigned		quiescing:1;
	unsigned		disconnected:1;

	unsigned		has_indicators:1;
	u8			indicator[USB_MAXCHILDREN];
	struct delayed_work	leds;
	struct delayed_work	init_work;
};

分析USB平台设备模型框架(1),布布扣,bubuko.com

时间: 2024-10-19 14:14:52

分析USB平台设备模型框架(1)的相关文章

LCD驱动分析(一)字符设备驱动框架分析

LCD驱动也是字符设备驱动,也遵循字符设备驱动的流程: a. 分配主设备号 b. 构建file_operations结构体中的open,write,read...等函数 c. 调用register_chrdev()函数注册字符设备 d. 调用class_register()注册类 e. 调用device_create()创建设备,linux会在sysfs目录下自动创建字符设备. 以上的步骤同样适用于分析输入子系统,只不过上面的各个步骤可能分散在不同的文件与函数中完成. 1.linux/drive

Linux设备驱动框架设计

引子 Linux操作系统的一大优势就是支持数以万计的芯片设备,大大小小的芯片厂商工程师都在积极地向Linux kernel提交设备驱动代码.能让这个目标得以实现,这背后隐藏着一个看不见的技术优势:Linux内核提供了一套易于扩展和维护的设备驱动框架.Linux内核本身提供一套设备驱动模型,此模型提供了Linux内核对设备的一般性抽象描述,包括设备的电源管理.对象生命周期管理.用户空间呈现等等.在设备模型的帮助下,设备驱动开发工程师从设备的一般性抽象中解脱出来.但是每个设备的具体功能实现还需要大量

mtk设备模型之LCM

1.Linux设备模型 站在BSP的角度来看,整个系统可以由三部分组成:设备.总线.驱动. Linux kernel有一些总线,比如USB.I2C等.对于每一个总线都会有一些设备和驱动挂在上面.驱动服务于匹配的设备,使Linux正确的操作硬件设备.当一个设备或者驱动注册到特定的总线上的时候就会触发总线匹配函数,比如一个设备注册到了总线,所有的该总线的驱动都会被枚举,判断是不是可以服务于新添加的设备(一般通过name来匹配),反之亦然. 如果总线匹配成功,就会调用驱动的probe函数,检查指定的硬

Linux Platform devices 平台设备驱动

设备总线驱动模型:http://blog.csdn.net/lizuobin2/article/details/51570196 本文主要参考:http://www.wowotech.net/device_model/platform_device.html platform平台设备驱动是基于设备总线驱动模型的,它只不过是将 device 进一步封装成为 platform_device,将 device_driver 进一步封装成为 platform_device_driver,前面已经分析过设

字符设备驱动、平台设备驱动、设备驱动模型、sysfs的关系

Linux驱动开发的童鞋们来膜拜吧:-)  学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sysfs等相关概念和技术.对于初学者来说会非常困惑,甚至对Linux有一定基础的工程师而言,能够较好理解这些相关技术也相对不错了.要深刻理解其中的原理需要非常熟悉设备驱动相关的框架和模型代码.网络上有关这些技术的文章不少,但多是对其中的某一点进行阐述,很难找到对这些技术进行比较和关联的分析.对于开发者而言,能够熟悉某一点并分享出来已很难得,但对于专注传授技术和经验给

[kernel]字符设备驱动、平台设备驱动、设备驱动模型、sysfs几者之间的比较和关联

转自:http://www.2cto.com/kf/201510/444943.html Linux驱动开发经验总结,绝对干货! 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sysfs等相关概念和技术.对于初学者来说会非常困惑,甚至对Linux有一定基础的工程师而言,能够较好理解这些相关技术也相对不错了.要深刻理解其中的原理需要非常熟悉设备驱动相关的框架和模型代码.网络上有关这些技术的文章不少,但多是对其中的某一点进行阐述,很难找到对这些技术进行比较和关

Linux平台总线驱动设备模型

platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为platform_device. 总线将设备和驱动绑定,在系统每注册一个设备的时候,会寻找与之匹配的驱动:相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成. Linux2.6系统中定义了一个bus_type的实例platform_bus_type [cpp] view plai

Linux驱动之平台设备驱动模型简析(驱动分离分层概念的建立)

Linux设备模型的目的:为内核建立一个统一的设备模型,从而有一个对系统结构的一般性抽象描述.换句话说,Linux设备模型提取了设备操作的共同属性,进行抽象,并将这部分共同的属性在内核中实现,而为需要新添加设备或驱动提供一般性的统一接口,这使得驱动程序的开发变得更简单了,而程序员只需要去学习接口就行了. 对于整个设备总线驱动模型的样子,如下图.简单来说,bus 负责维护注册进来的devcie 与 driver,每注册进来一个device 或者 driver 都会调用 Bus->match 函数

设备模型(device-model)之平台总线(bus),驱动(driver),设备(device)

关于关于驱动设备模型相关概念请参考<Linux Device Drivers>等相关书籍,和内核源码目录...\Documentation\driver-model 简单来说总线(bus),驱动(driver),设备(device)这三者之间的关系就是:驱动开发者可以通过总线(bus)来将驱动(driver)和设备(device)进行隔离,这样的好处就是开发者可以将相对稳定不变的驱动(driver)独立起来,可以通过总线(bus)来桥接与之匹配的设备(device).设备(device)只需要