Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
bd53d127
L
linux
项目概览
xiphi1978
/
linux
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bd53d127
编写于
6月 30, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
上级
12829dcb
bf164c79
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
143 addition
and
21 deletion
+143
-21
drivers/base/base.h
drivers/base/base.h
+1
-0
drivers/base/bus.c
drivers/base/bus.c
+99
-18
drivers/base/core.c
drivers/base/core.c
+1
-1
drivers/base/dd.c
drivers/base/dd.c
+1
-1
drivers/base/driver.c
drivers/base/driver.c
+35
-0
include/linux/device.h
include/linux/device.h
+6
-1
未找到文件。
drivers/base/base.h
浏览文件 @
bd53d127
...
@@ -5,6 +5,7 @@ extern int bus_add_driver(struct device_driver *);
...
@@ -5,6 +5,7 @@ extern int bus_add_driver(struct device_driver *);
extern
void
bus_remove_driver
(
struct
device_driver
*
);
extern
void
bus_remove_driver
(
struct
device_driver
*
);
extern
void
driver_detach
(
struct
device_driver
*
drv
);
extern
void
driver_detach
(
struct
device_driver
*
drv
);
extern
int
driver_probe_device
(
struct
device_driver
*
,
struct
device
*
);
static
inline
struct
class_device
*
to_class_dev
(
struct
kobject
*
obj
)
static
inline
struct
class_device
*
to_class_dev
(
struct
kobject
*
obj
)
{
{
...
...
drivers/base/bus.c
浏览文件 @
bd53d127
...
@@ -133,6 +133,58 @@ static struct kobj_type ktype_bus = {
...
@@ -133,6 +133,58 @@ static struct kobj_type ktype_bus = {
decl_subsys
(
bus
,
&
ktype_bus
,
NULL
);
decl_subsys
(
bus
,
&
ktype_bus
,
NULL
);
/* Manually detach a device from it's associated driver. */
static
int
driver_helper
(
struct
device
*
dev
,
void
*
data
)
{
const
char
*
name
=
data
;
if
(
strcmp
(
name
,
dev
->
bus_id
)
==
0
)
return
1
;
return
0
;
}
static
ssize_t
driver_unbind
(
struct
device_driver
*
drv
,
const
char
*
buf
,
size_t
count
)
{
struct
bus_type
*
bus
=
get_bus
(
drv
->
bus
);
struct
device
*
dev
;
int
err
=
-
ENODEV
;
dev
=
bus_find_device
(
bus
,
NULL
,
(
void
*
)
buf
,
driver_helper
);
if
((
dev
)
&&
(
dev
->
driver
==
drv
))
{
device_release_driver
(
dev
);
err
=
count
;
}
return
err
;
}
static
DRIVER_ATTR
(
unbind
,
S_IWUSR
,
NULL
,
driver_unbind
);
/*
* Manually attach a device to a driver.
* Note: the driver must want to bind to the device,
* it is not possible to override the driver's id table.
*/
static
ssize_t
driver_bind
(
struct
device_driver
*
drv
,
const
char
*
buf
,
size_t
count
)
{
struct
bus_type
*
bus
=
get_bus
(
drv
->
bus
);
struct
device
*
dev
;
int
err
=
-
ENODEV
;
dev
=
bus_find_device
(
bus
,
NULL
,
(
void
*
)
buf
,
driver_helper
);
if
((
dev
)
&&
(
dev
->
driver
==
NULL
))
{
down
(
&
dev
->
sem
);
err
=
driver_probe_device
(
drv
,
dev
);
up
(
&
dev
->
sem
);
put_device
(
dev
);
}
return
err
;
}
static
DRIVER_ATTR
(
bind
,
S_IWUSR
,
NULL
,
driver_bind
);
static
struct
device
*
next_device
(
struct
klist_iter
*
i
)
static
struct
device
*
next_device
(
struct
klist_iter
*
i
)
{
{
struct
klist_node
*
n
=
klist_next
(
i
);
struct
klist_node
*
n
=
klist_next
(
i
);
...
@@ -177,6 +229,39 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
...
@@ -177,6 +229,39 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
return
error
;
return
error
;
}
}
/**
* bus_find_device - device iterator for locating a particular device.
* @bus: bus type
* @start: Device to begin with
* @data: Data to pass to match function
* @match: Callback function to check device
*
* This is similar to the bus_for_each_dev() function above, but it
* returns a reference to a device that is 'found' for later use, as
* determined by the @match callback.
*
* The callback should return 0 if the device doesn't match and non-zero
* if it does. If the callback returns non-zero, this function will
* return to the caller and not iterate over any more devices.
*/
struct
device
*
bus_find_device
(
struct
bus_type
*
bus
,
struct
device
*
start
,
void
*
data
,
int
(
*
match
)(
struct
device
*
,
void
*
))
{
struct
klist_iter
i
;
struct
device
*
dev
;
if
(
!
bus
)
return
NULL
;
klist_iter_init_node
(
&
bus
->
klist_devices
,
&
i
,
(
start
?
&
start
->
knode_bus
:
NULL
));
while
((
dev
=
next_device
(
&
i
)))
if
(
match
(
dev
,
data
)
&&
get_device
(
dev
))
break
;
klist_iter_exit
(
&
i
);
return
dev
;
}
static
struct
device_driver
*
next_driver
(
struct
klist_iter
*
i
)
static
struct
device_driver
*
next_driver
(
struct
klist_iter
*
i
)
...
@@ -363,6 +448,8 @@ int bus_add_driver(struct device_driver * drv)
...
@@ -363,6 +448,8 @@ int bus_add_driver(struct device_driver * drv)
module_add_driver
(
drv
->
owner
,
drv
);
module_add_driver
(
drv
->
owner
,
drv
);
driver_add_attrs
(
bus
,
drv
);
driver_add_attrs
(
bus
,
drv
);
driver_create_file
(
drv
,
&
driver_attr_unbind
);
driver_create_file
(
drv
,
&
driver_attr_bind
);
}
}
return
error
;
return
error
;
}
}
...
@@ -380,6 +467,8 @@ int bus_add_driver(struct device_driver * drv)
...
@@ -380,6 +467,8 @@ int bus_add_driver(struct device_driver * drv)
void
bus_remove_driver
(
struct
device_driver
*
drv
)
void
bus_remove_driver
(
struct
device_driver
*
drv
)
{
{
if
(
drv
->
bus
)
{
if
(
drv
->
bus
)
{
driver_remove_file
(
drv
,
&
driver_attr_bind
);
driver_remove_file
(
drv
,
&
driver_attr_unbind
);
driver_remove_attrs
(
drv
->
bus
,
drv
);
driver_remove_attrs
(
drv
->
bus
,
drv
);
klist_remove
(
&
drv
->
knode_bus
);
klist_remove
(
&
drv
->
knode_bus
);
pr_debug
(
"bus %s: remove driver %s
\n
"
,
drv
->
bus
->
name
,
drv
->
name
);
pr_debug
(
"bus %s: remove driver %s
\n
"
,
drv
->
bus
->
name
,
drv
->
name
);
...
@@ -394,31 +483,22 @@ void bus_remove_driver(struct device_driver * drv)
...
@@ -394,31 +483,22 @@ void bus_remove_driver(struct device_driver * drv)
/* Helper for bus_rescan_devices's iter */
/* Helper for bus_rescan_devices's iter */
static
int
bus_rescan_devices_helper
(
struct
device
*
dev
,
void
*
data
)
static
int
bus_rescan_devices_helper
(
struct
device
*
dev
,
void
*
data
)
{
{
int
*
count
=
data
;
if
(
!
dev
->
driver
)
device_attach
(
dev
);
if
(
!
dev
->
driver
&&
(
device_attach
(
dev
)
>
0
))
(
*
count
)
++
;
return
0
;
return
0
;
}
}
/**
/**
*
bus_rescan_devices - rescan devices on the bus for possible drivers
*
bus_rescan_devices - rescan devices on the bus for possible drivers
*
@bus:
the bus to scan.
*
@bus:
the bus to scan.
*
*
* This function will look for devices on the bus with no driver
* This function will look for devices on the bus with no driver
* attached and rescan it against existing drivers to see if it
* attached and rescan it against existing drivers to see if it matches
* matches any. Calls device_attach(). Returns the number of devices
* any by calling device_attach() for the unbound devices.
* that were sucessfully bound to a driver.
*/
*/
int
bus_rescan_devices
(
struct
bus_type
*
bus
)
void
bus_rescan_devices
(
struct
bus_type
*
bus
)
{
{
int
count
=
0
;
bus_for_each_dev
(
bus
,
NULL
,
NULL
,
bus_rescan_devices_helper
);
bus_for_each_dev
(
bus
,
NULL
,
&
count
,
bus_rescan_devices_helper
);
return
count
;
}
}
...
@@ -557,6 +637,7 @@ int __init buses_init(void)
...
@@ -557,6 +637,7 @@ int __init buses_init(void)
EXPORT_SYMBOL_GPL
(
bus_for_each_dev
);
EXPORT_SYMBOL_GPL
(
bus_for_each_dev
);
EXPORT_SYMBOL_GPL
(
bus_find_device
);
EXPORT_SYMBOL_GPL
(
bus_for_each_drv
);
EXPORT_SYMBOL_GPL
(
bus_for_each_drv
);
EXPORT_SYMBOL_GPL
(
bus_add_device
);
EXPORT_SYMBOL_GPL
(
bus_add_device
);
...
...
drivers/base/core.c
浏览文件 @
bd53d127
...
@@ -333,7 +333,7 @@ void device_del(struct device * dev)
...
@@ -333,7 +333,7 @@ void device_del(struct device * dev)
struct
device
*
parent
=
dev
->
parent
;
struct
device
*
parent
=
dev
->
parent
;
if
(
parent
)
if
(
parent
)
klist_
remove
(
&
dev
->
knode_parent
);
klist_
del
(
&
dev
->
knode_parent
);
/* Notify the platform of the removal, in case they
/* Notify the platform of the removal, in case they
* need to do anything...
* need to do anything...
...
...
drivers/base/dd.c
浏览文件 @
bd53d127
...
@@ -65,7 +65,7 @@ void device_bind_driver(struct device * dev)
...
@@ -65,7 +65,7 @@ void device_bind_driver(struct device * dev)
*
*
* This function must be called with @dev->sem held.
* This function must be called with @dev->sem held.
*/
*/
static
int
driver_probe_device
(
struct
device_driver
*
drv
,
struct
device
*
dev
)
int
driver_probe_device
(
struct
device_driver
*
drv
,
struct
device
*
dev
)
{
{
int
ret
=
0
;
int
ret
=
0
;
...
...
drivers/base/driver.c
浏览文件 @
bd53d127
...
@@ -55,6 +55,41 @@ int driver_for_each_device(struct device_driver * drv, struct device * start,
...
@@ -55,6 +55,41 @@ int driver_for_each_device(struct device_driver * drv, struct device * start,
EXPORT_SYMBOL_GPL
(
driver_for_each_device
);
EXPORT_SYMBOL_GPL
(
driver_for_each_device
);
/**
* driver_find_device - device iterator for locating a particular device.
* @driver: The device's driver
* @start: Device to begin with
* @data: Data to pass to match function
* @match: Callback function to check device
*
* This is similar to the driver_for_each_device() function above, but
* it returns a reference to a device that is 'found' for later use, as
* determined by the @match callback.
*
* The callback should return 0 if the device doesn't match and non-zero
* if it does. If the callback returns non-zero, this function will
* return to the caller and not iterate over any more devices.
*/
struct
device
*
driver_find_device
(
struct
device_driver
*
drv
,
struct
device
*
start
,
void
*
data
,
int
(
*
match
)(
struct
device
*
,
void
*
))
{
struct
klist_iter
i
;
struct
device
*
dev
;
if
(
!
drv
)
return
NULL
;
klist_iter_init_node
(
&
drv
->
klist_devices
,
&
i
,
(
start
?
&
start
->
knode_driver
:
NULL
));
while
((
dev
=
next_device
(
&
i
)))
if
(
match
(
dev
,
data
)
&&
get_device
(
dev
))
break
;
klist_iter_exit
(
&
i
);
return
dev
;
}
EXPORT_SYMBOL_GPL
(
driver_find_device
);
/**
/**
* driver_create_file - create sysfs file for driver.
* driver_create_file - create sysfs file for driver.
* @drv: driver.
* @drv: driver.
...
...
include/linux/device.h
浏览文件 @
bd53d127
...
@@ -69,7 +69,7 @@ struct bus_type {
...
@@ -69,7 +69,7 @@ struct bus_type {
extern
int
bus_register
(
struct
bus_type
*
bus
);
extern
int
bus_register
(
struct
bus_type
*
bus
);
extern
void
bus_unregister
(
struct
bus_type
*
bus
);
extern
void
bus_unregister
(
struct
bus_type
*
bus
);
extern
int
bus_rescan_devices
(
struct
bus_type
*
bus
);
extern
void
bus_rescan_devices
(
struct
bus_type
*
bus
);
extern
struct
bus_type
*
get_bus
(
struct
bus_type
*
bus
);
extern
struct
bus_type
*
get_bus
(
struct
bus_type
*
bus
);
extern
void
put_bus
(
struct
bus_type
*
bus
);
extern
void
put_bus
(
struct
bus_type
*
bus
);
...
@@ -80,6 +80,8 @@ extern struct bus_type * find_bus(char * name);
...
@@ -80,6 +80,8 @@ extern struct bus_type * find_bus(char * name);
int
bus_for_each_dev
(
struct
bus_type
*
bus
,
struct
device
*
start
,
void
*
data
,
int
bus_for_each_dev
(
struct
bus_type
*
bus
,
struct
device
*
start
,
void
*
data
,
int
(
*
fn
)(
struct
device
*
,
void
*
));
int
(
*
fn
)(
struct
device
*
,
void
*
));
struct
device
*
bus_find_device
(
struct
bus_type
*
bus
,
struct
device
*
start
,
void
*
data
,
int
(
*
match
)(
struct
device
*
,
void
*
));
int
bus_for_each_drv
(
struct
bus_type
*
bus
,
struct
device_driver
*
start
,
int
bus_for_each_drv
(
struct
bus_type
*
bus
,
struct
device_driver
*
start
,
void
*
data
,
int
(
*
fn
)(
struct
device_driver
*
,
void
*
));
void
*
data
,
int
(
*
fn
)(
struct
device_driver
*
,
void
*
));
...
@@ -142,6 +144,9 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute *
...
@@ -142,6 +144,9 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute *
extern
int
driver_for_each_device
(
struct
device_driver
*
drv
,
struct
device
*
start
,
extern
int
driver_for_each_device
(
struct
device_driver
*
drv
,
struct
device
*
start
,
void
*
data
,
int
(
*
fn
)(
struct
device
*
,
void
*
));
void
*
data
,
int
(
*
fn
)(
struct
device
*
,
void
*
));
struct
device
*
driver_find_device
(
struct
device_driver
*
drv
,
struct
device
*
start
,
void
*
data
,
int
(
*
match
)(
struct
device
*
,
void
*
));
/*
/*
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录