您的位置:首页 > 其它

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

2017-04-20 18:03 405 查看
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;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐