首页 > 代码库 > 分析USB平台设备模型框架(1)

分析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;
};