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. [2018湖南省队集训] 6.28 T2 color

    毒瘤计数题2333,(小声)k其实可以出到1e9,不过这样求组合数的时候就要记1000种数的1~1000次下降幂(用到的组合数中第一维在1e9级别的只有1000种左右,第二维都是<=1000), ...

  2. [Codeforces-div.1 167B] Wizards and Huge Prize

    [Codeforces-div.1 167B] Wizards and Huge Prize 试题分析 注意到每个物品互相独立,互不干扰之后就非常好做了. 算出一个物品最后的价值期望,然后乘以K即可. ...

  3. 【动态规划】windy数

    BZOJ1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7893  Solved: 3559[Submit] ...

  4. 【manacher】HDU4513-吉哥系列故事——完美队形II

    [题目大意] 求最长回文队伍且队伍由中间向两边递减. [思路] 和字符串一样的做法,在递推的时候增加判断条件:a[i-p[i]]<=a[i-p[i]+2]. #include<iostre ...

  5. Bootstrap-table固定表头并解决表头与内容不对齐

    写在前面: 之前在做表格的时候,一直忽略了表格的height高度,导致表格的的表头不能固定,这个样子当表格数据过多的时候,导致无法分辨表头是什么,所以决定固定表头. 固定表头需要使用height这一属 ...

  6. Activity(活动)生命周期(1)--返回栈

    Android是使用任务(task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称为返回栈(Back stack).栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新的 ...

  7. sql 空值设置默认值

    ifnull(a.discountsign, ') AS "discountsign"

  8. System.Object 基类

    System.Object在.Net中是所有类型的基类,任何类型都直接或间接地继承自System.Object.没有指定基类的类型都默认继承于System.Object. 基类特性 正由于所有的类型都 ...

  9. VC知识库

    VC知识库http://www.vckbase.com/index.php/code

  10. XMPP 常见错误:<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>

    一般登陆/注册 出错,会在认证失败这里打印出error信息 - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLEleme ...