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)的更多相关文章

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

    参考:S3C2440 LCD驱动(FrameBuffer)实例开发<一>   S3C2440 LCD驱动(FrameBuffer)实例开发<二> LCD驱动也是字符设备驱动,也 ...

  2. Linux设备驱动框架设计

    引子 Linux操作系统的一大优势就是支持数以万计的芯片设备,大大小小的芯片厂商工程师都在积极地向Linux kernel提交设备驱动代码.能让这个目标得以实现,这背后隐藏着一个看不见的技术优势:Li ...

  3. Linux Platform devices 平台设备驱动

    设备总线驱动模型:http://blog.csdn.net/lizuobin2/article/details/51570196 本文主要参考:http://www.wowotech.net/devi ...

  4. Linux设备模型 学习总结

    看LDD3中设备模型一章,觉得思维有些混乱.这里从整体的角度来理理思路.本文从四个方面来总结一些内容: 1.底层数据结构:kobject,kset.2.linux设备模型层次关系:bus_type,d ...

  5. Linux设备模型(总结)

    转:http://www.360doc.com/content/11/1219/16/1299815_173418267.shtml 看了一段时间的驱动编程,从LDD3的hello wrod到后来的字 ...

  6. 【RT-Thread笔记】IO设备模型及GPIO设备

    RTT内核对象--设备 RT-Thread有多种内核对象,其中设备device就是其中一种. 内核继承关系图如下: 设备继承关系图如下: device对象对应的结构体如下: 其中,设备类型type有如 ...

  7. 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联

    转载自:http://www.kancloud.cn/yueqian_scut/emlinux/106829 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sy ...

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

    转自:http://www.2cto.com/kf/201510/444943.html Linux驱动开发经验总结,绝对干货! 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动 ...

  9. 如何在Android平台上使用USB Audio设备

    http://blog.csdn.net/kevinx_xu/article/details/12951131 需求:USB Headset插上去后,声音要从本地CODEC切换到USB Headset ...

随机推荐

  1. WebService的网络协议

    SOAP协议.XML-RPC以及Hessian 是WebService的主要传输(编码)协议 SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XM ...

  2. 【POJ 2186】Popular Cows

    http://poj.org/problem?id=2186 tarjan求强连通分量. 因为SD省选用WinXP+Cena评测而且不开栈,所以dfs只好写手动栈了. 写手动栈时思路清晰一点应该是不会 ...

  3. 【线段树】Mayor's posters

    [poj2528]Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 66154   Accept ...

  4. HDU 2255 奔小康赚大钱(KM算法)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=2255 [题目大意] 求最大匹配 [题解] KM模板 [代码] #include <cstdi ...

  5. 【推导】【凸包】MIPT-2016 Pre-Finals Workshop, Taiwan NTU Contest, Sunday, March 27, 2016 Problem D. Drawing Hell

    平面上n个点,两个人交替决策,用线段连接两个点,但不能跨越其他点或者已经存在的线段.不能做的人算输,问你谁赢. 实际上,跟两个人的决策无关,n个点将平面三角剖分,只需要算出有几条边即可. 凸包上如果有 ...

  6. Team Queue(POJ 2259)

    题意:有若干个团体,每个团体有若干个元素,他们按次序来排队,如果队列中已经有同一团体的元素在,则可以插队到它后面,模拟这个过程 思路:用map存下元素与团体的关系,并开2个队列,一个存整体队伍的排列( ...

  7. 抽象类(abstract class)和接口(interface)的异同

    抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用.一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类. 接口比抽象类更加抽象,因 ...

  8. 简单实现ToolStripMenuItem(菜单栏)的单选效果

    来源:http://www.97world.com/archives/2194 这几天在写又拍云的客户端,老实说确实学到了不少东西!接下来的几天我会把一些技巧或者原来没有接触过的一些东西发上来,算是复 ...

  9. response letter模板

    Dear Dr. or Prof. XXXX (family name of the Editor or Editor-in-Chief who issued the decision letter) ...

  10. Flask参数解析、请求钩子

    转载请注明出处 https://www.cnblogs.com/chenxianpao/p/9949279.html  参数解析 Flask的参数解析主要用Request完成(from flask i ...