分析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)的更多相关文章
- LCD驱动分析(一)字符设备驱动框架分析
参考:S3C2440 LCD驱动(FrameBuffer)实例开发<一> S3C2440 LCD驱动(FrameBuffer)实例开发<二> LCD驱动也是字符设备驱动,也 ...
- Linux设备驱动框架设计
引子 Linux操作系统的一大优势就是支持数以万计的芯片设备,大大小小的芯片厂商工程师都在积极地向Linux kernel提交设备驱动代码.能让这个目标得以实现,这背后隐藏着一个看不见的技术优势:Li ...
- Linux Platform devices 平台设备驱动
设备总线驱动模型:http://blog.csdn.net/lizuobin2/article/details/51570196 本文主要参考:http://www.wowotech.net/devi ...
- Linux设备模型 学习总结
看LDD3中设备模型一章,觉得思维有些混乱.这里从整体的角度来理理思路.本文从四个方面来总结一些内容: 1.底层数据结构:kobject,kset.2.linux设备模型层次关系:bus_type,d ...
- Linux设备模型(总结)
转:http://www.360doc.com/content/11/1219/16/1299815_173418267.shtml 看了一段时间的驱动编程,从LDD3的hello wrod到后来的字 ...
- 【RT-Thread笔记】IO设备模型及GPIO设备
RTT内核对象--设备 RT-Thread有多种内核对象,其中设备device就是其中一种. 内核继承关系图如下: 设备继承关系图如下: device对象对应的结构体如下: 其中,设备类型type有如 ...
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
转载自:http://www.kancloud.cn/yueqian_scut/emlinux/106829 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sy ...
- [kernel]字符设备驱动、平台设备驱动、设备驱动模型、sysfs几者之间的比较和关联
转自:http://www.2cto.com/kf/201510/444943.html Linux驱动开发经验总结,绝对干货! 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动 ...
- 如何在Android平台上使用USB Audio设备
http://blog.csdn.net/kevinx_xu/article/details/12951131 需求:USB Headset插上去后,声音要从本地CODEC切换到USB Headset ...
随机推荐
- [BZOJ1860][ZJOI2006]Mahjong(DP)
1860: [Zjoi2006]Mahjong麻将 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 412 Solved: 248[Submit][Sta ...
- JZYZOJ1502 [haoi2008]下落的圆盘 计算几何 贪心
http://172.20.6.3/Problem_Show.asp?id=1502这种题用了快一天才写出来也是真的辣鸡.主要思路就是计算一下被挡住的弧度然后对弧度进行贪心.最开始比较困扰的是求弧度值 ...
- 【贪心】 Codeforces Round #419 (Div. 1) A. Karen and Game
容易发现,删除的顺序不影响答案. 所以可以随便删. 如果行数大于列数,就先删列:否则先删行. #include<cstdio> #include<algorithm> usin ...
- 【动态规划/二维背包问题】mr355-三角形牧场
应该也是USACO的题目?同样没有找到具体出处. [题目大意] 和所有人一样,奶牛喜欢变化.它们正在设想新造型牧场.奶牛建筑师Hei想建造围有漂亮白色栅栏的三角形牧场.她拥有N(3≤N≤40)块木板, ...
- django查询
阅读目录 大于.大于等于 小于.小于等于 在...范围内 模糊查询 是否为空 不等于/不包含于 大于.大于等于 1 2 3 4 5 __gt 大于 __gte 大于等于 User.objects. ...
- 找出最小元素的下标 Exercise07_10
import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:找出最小元素的下标 * */ public class Exercise0 ...
- Ui Automator Test Through Command
问题描述: 通过adb shell uiautomator runtest 命令,直接运行java测试例. 命令解析: adb shell uiautomator runtest <JARS&g ...
- node.js中express-session配置项详解
官方地址:https://www.npmjs.com/package/express-session 作用:用指定的参数创建一个session中间件,sesison数据不是保存在cookie中,仅仅s ...
- Unicode中的BOM
BOM简述 BOM是byte order mark的缩写,在UTF-16和UTF-32中需要使用BOM来区分字节的顺序,因为我们目前的CPU有两种系列,一种是大端模式,一种是小端模式(我们常用的电脑手 ...
- Newtonsoft.Json.4.5.11使用方法总结---反序列化json字符串
写在开头: 最近项目需求,需要在C#中处理json字符串,毫不犹豫的下载了Newtonsoft.Json 4.5.11(2012.12.17)http://json.codeplex.com/,然后百 ...