Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
0447d4d5
Commit
0447d4d5
authored
Oct 16, 2002
by
Patrick Mochel
Browse files
Options
Browse Files
Download
Plain Diff
Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin
into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core
parents
9af95a10
ba809e8a
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
151 additions
and
102 deletions
+151
-102
drivers/base/bus.c
drivers/base/bus.c
+42
-18
drivers/base/class.c
drivers/base/class.c
+31
-5
drivers/base/core.c
drivers/base/core.c
+17
-31
drivers/base/driver.c
drivers/base/driver.c
+45
-29
fs/driverfs/inode.c
fs/driverfs/inode.c
+3
-1
include/linux/device.h
include/linux/device.h
+13
-16
include/linux/driverfs_fs.h
include/linux/driverfs_fs.h
+0
-2
No files found.
drivers/base/bus.c
View file @
0447d4d5
...
...
@@ -47,23 +47,21 @@ int bus_for_each_dev(struct bus_type * bus, void * data,
int
error
=
0
;
get_bus
(
bus
);
spin_lock
(
&
device_lock
);
down_write
(
&
bus
->
rwsem
);
list_for_each
(
node
,
&
bus
->
devices
)
{
struct
device
*
dev
=
get_device
_locked
(
to_dev
(
node
));
struct
device
*
dev
=
get_device
(
to_dev
(
node
));
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
error
=
callback
(
dev
,
data
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
spin_lock
(
&
device_lock
);
if
(
error
)
break
;
}
}
spin_unlock
(
&
device_lock
);
if
(
prev
)
put_device
(
prev
);
up_write
(
&
bus
->
rwsem
);
put_bus
(
bus
);
return
error
;
}
...
...
@@ -77,24 +75,21 @@ int bus_for_each_drv(struct bus_type * bus, void * data,
/* pin bus in memory */
get_bus
(
bus
);
spin_lock
(
&
device_lock
);
down_write
(
&
bus
->
rwsem
);
list_for_each
(
node
,
&
bus
->
drivers
)
{
struct
device_driver
*
drv
=
get_driver
(
to_drv
(
node
));
if
(
drv
)
{
spin_unlock
(
&
device_lock
);
error
=
callback
(
drv
,
data
);
if
(
prev
)
put_driver
(
prev
);
prev
=
drv
;
spin_lock
(
&
device_lock
);
if
(
error
)
break
;
}
}
spin_unlock
(
&
device_lock
);
if
(
prev
)
put_driver
(
prev
);
up_write
(
&
bus
->
rwsem
);
put_bus
(
bus
);
return
error
;
}
...
...
@@ -111,11 +106,11 @@ int bus_for_each_drv(struct bus_type * bus, void * data,
int
bus_add_device
(
struct
device
*
dev
)
{
if
(
dev
->
bus
)
{
down_write
(
&
dev
->
bus
->
rwsem
);
pr_debug
(
"registering %s with bus '%s'
\n
"
,
dev
->
bus_id
,
dev
->
bus
->
name
);
get_bus
(
dev
->
bus
);
spin_lock
(
&
device_lock
);
list_add_tail
(
&
dev
->
bus_list
,
&
dev
->
bus
->
devices
);
spin_unlock
(
&
device_lock
);
up_write
(
&
dev
->
bus
->
rwsem
);
device_bus_link
(
dev
);
}
return
0
;
...
...
@@ -131,17 +126,43 @@ int bus_add_device(struct device * dev)
void
bus_remove_device
(
struct
device
*
dev
)
{
if
(
dev
->
bus
)
{
down_write
(
&
dev
->
bus
->
rwsem
);
list_del_init
(
&
dev
->
bus_list
);
device_remove_symlink
(
&
dev
->
bus
->
device_dir
,
dev
->
bus_id
);
up_write
(
&
dev
->
bus
->
rwsem
);
put_bus
(
dev
->
bus
);
}
}
struct
bus_type
*
get_bus
(
struct
bus_type
*
bus
)
{
struct
bus_type
*
ret
=
bus
;
spin_lock
(
&
device_lock
);
if
(
bus
&&
bus
->
present
&&
atomic_read
(
&
bus
->
refcount
))
atomic_inc
(
&
bus
->
refcount
);
else
ret
=
NULL
;
spin_unlock
(
&
device_lock
);
return
ret
;
}
void
put_bus
(
struct
bus_type
*
bus
)
{
if
(
!
atomic_dec_and_lock
(
&
bus
->
refcount
,
&
device_lock
))
return
;
list_del_init
(
&
bus
->
node
);
spin_unlock
(
&
device_lock
);
BUG_ON
(
bus
->
present
);
bus_remove_dir
(
bus
);
}
int
bus_register
(
struct
bus_type
*
bus
)
{
rwlock_init
(
&
bus
->
lock
);
init_rwsem
(
&
bus
->
rwsem
);
INIT_LIST_HEAD
(
&
bus
->
devices
);
INIT_LIST_HEAD
(
&
bus
->
drivers
);
atomic_set
(
&
bus
->
refcount
,
2
);
bus
->
present
=
1
;
spin_lock
(
&
device_lock
);
list_add_tail
(
&
bus
->
node
,
&
bus_driver_list
);
...
...
@@ -156,13 +177,14 @@ int bus_register(struct bus_type * bus)
return
0
;
}
void
put_bus
(
struct
bus_type
*
bus
)
void
bus_unregister
(
struct
bus_type
*
bus
)
{
if
(
!
atomic_dec_and_lock
(
&
bus
->
refcount
,
&
device_lock
))
return
;
list_del_init
(
&
bus
->
node
);
spin_lock
(
&
device_lock
);
bus
->
present
=
0
;
spin_unlock
(
&
device_lock
);
bus_remove_dir
(
bus
);
pr_debug
(
"bus %s: unregistering
\n
"
,
bus
->
name
);
put_bus
(
bus
);
}
EXPORT_SYMBOL
(
bus_for_each_dev
);
...
...
@@ -170,4 +192,6 @@ EXPORT_SYMBOL(bus_for_each_drv);
EXPORT_SYMBOL
(
bus_add_device
);
EXPORT_SYMBOL
(
bus_remove_device
);
EXPORT_SYMBOL
(
bus_register
);
EXPORT_SYMBOL
(
bus_unregister
);
EXPORT_SYMBOL
(
get_bus
);
EXPORT_SYMBOL
(
put_bus
);
drivers/base/class.c
View file @
0447d4d5
...
...
@@ -81,29 +81,55 @@ void devclass_remove_device(struct device * dev)
}
}
struct
device_class
*
get_devclass
(
struct
device_class
*
cls
)
{
struct
device_class
*
ret
=
cls
;
spin_lock
(
&
device_lock
);
if
(
cls
&&
cls
->
present
&&
atomic_read
(
&
cls
->
refcount
)
>
0
)
atomic_inc
(
&
cls
->
refcount
);
else
ret
=
NULL
;
spin_unlock
(
&
device_lock
);
return
ret
;
}
void
put_devclass
(
struct
device_class
*
cls
)
{
if
(
atomic_dec_and_lock
(
&
cls
->
refcount
,
&
device_lock
))
{
list_del_init
(
&
cls
->
node
);
spin_unlock
(
&
device_lock
);
devclass_remove_dir
(
cls
);
}
}
int
devclass_register
(
struct
device_class
*
cls
)
{
INIT_LIST_HEAD
(
&
cls
->
drivers
);
INIT_LIST_HEAD
(
&
cls
->
intf_list
);
pr_debug
(
"registering device class '%s'
\n
"
,
cls
->
name
);
atomic_set
(
&
cls
->
refcount
,
2
);
cls
->
present
=
1
;
pr_debug
(
"device class '%s': registering
\n
"
,
cls
->
name
);
spin_lock
(
&
device_lock
);
list_add_tail
(
&
cls
->
node
,
&
class_list
);
spin_unlock
(
&
device_lock
);
devclass_make_dir
(
cls
);
put_devclass
(
cls
);
return
0
;
}
void
devclass_unregister
(
struct
device_class
*
cls
)
{
pr_debug
(
"unregistering device class '%s'
\n
"
,
cls
->
name
);
devclass_remove_dir
(
cls
);
spin_lock
(
&
device_lock
);
list_del_init
(
&
class_list
)
;
cls
->
present
=
0
;
spin_unlock
(
&
device_lock
);
pr_debug
(
"device class '%s': unregistering
\n
"
,
cls
->
name
);
put_devclass
(
cls
);
}
EXPORT_SYMBOL
(
devclass_register
);
EXPORT_SYMBOL
(
devclass_unregister
);
EXPORT_SYMBOL
(
get_devclass
);
EXPORT_SYMBOL
(
put_devclass
);
drivers/base/core.c
View file @
0447d4d5
...
...
@@ -259,34 +259,21 @@ struct device * get_device(struct device * dev)
*/
void
put_device
(
struct
device
*
dev
)
{
struct
device
*
parent
;
if
(
!
atomic_dec_and_lock
(
&
dev
->
refcount
,
&
device_lock
))
return
;
parent
=
dev
->
parent
;
dev
->
parent
=
NULL
;
list_del_init
(
&
dev
->
node
);
list_del_init
(
&
dev
->
g_list
);
list_del_init
(
&
dev
->
driver_list
);
spin_unlock
(
&
device_lock
);
BUG_ON
(
dev
->
present
);
if
(
dev
->
release
)
dev
->
release
(
dev
);
if
(
parent
)
put_device
(
parent
);
device_del
(
dev
);
}
void
device_del
(
struct
device
*
dev
)
{
spin_lock
(
&
device_lock
);
dev
->
present
=
0
;
list_del_init
(
&
dev
->
node
);
list_del_init
(
&
dev
->
g_list
);
list_del_init
(
&
dev
->
bus_list
);
list_del_init
(
&
dev
->
driver_list
);
spin_unlock
(
&
device_lock
);
pr_debug
(
"DEV: Unregistering device. ID = '%s', name = '%s'
\n
"
,
dev
->
bus_id
,
dev
->
name
);
struct
device
*
parent
=
dev
->
parent
;
/* Notify the platform of the removal, in case they
* need to do anything...
...
...
@@ -302,6 +289,12 @@ void device_del(struct device * dev)
/* remove the driverfs directory */
device_remove_dir
(
dev
);
if
(
dev
->
release
)
dev
->
release
(
dev
);
if
(
parent
)
put_device
(
parent
);
}
/**
...
...
@@ -315,22 +308,15 @@ void device_del(struct device * dev)
*/
void
device_unregister
(
struct
device
*
dev
)
{
device_del
(
dev
);
put_device
(
dev
);
}
static
int
__init
device_init
(
void
)
{
int
error
;
spin_lock
(
&
device_lock
);
dev
->
present
=
0
;
spin_unlock
(
&
device_lock
);
error
=
init_driverfs_fs
();
if
(
error
)
panic
(
"DEV: could not initialize driverfs"
);
return
0
;
pr_debug
(
"DEV: Unregistering device. ID = '%s', name = '%s'
\n
"
,
dev
->
bus_id
,
dev
->
name
);
put_device
(
dev
);
}
core_initcall
(
device_init
);
EXPORT_SYMBOL
(
device_register
);
EXPORT_SYMBOL
(
device_unregister
);
EXPORT_SYMBOL
(
get_device
);
...
...
drivers/base/driver.c
View file @
0447d4d5
...
...
@@ -39,6 +39,43 @@ int driver_for_each_dev(struct device_driver * drv, void * data,
return
error
;
}
struct
device_driver
*
get_driver
(
struct
device_driver
*
drv
)
{
struct
device_driver
*
ret
=
drv
;
spin_lock
(
&
device_lock
);
if
(
drv
&&
drv
->
present
&&
atomic_read
(
&
drv
->
refcount
)
>
0
)
atomic_inc
(
&
drv
->
refcount
);
else
ret
=
NULL
;
spin_unlock
(
&
device_lock
);
return
ret
;
}
void
remove_driver
(
struct
device_driver
*
drv
)
{
BUG
();
}
/**
* put_driver - decrement driver's refcount and clean up if necessary
* @drv: driver in question
*/
void
put_driver
(
struct
device_driver
*
drv
)
{
struct
bus_type
*
bus
=
drv
->
bus
;
if
(
!
atomic_dec_and_lock
(
&
drv
->
refcount
,
&
device_lock
))
return
;
list_del_init
(
&
drv
->
bus_list
);
spin_unlock
(
&
device_lock
);
BUG_ON
(
drv
->
present
);
driver_detach
(
drv
);
driver_remove_dir
(
drv
);
if
(
drv
->
release
)
drv
->
release
(
drv
);
put_bus
(
bus
);
}
/**
* driver_register - register driver with bus
* @drv: driver to register
...
...
@@ -50,12 +87,13 @@ int driver_register(struct device_driver * drv)
if
(
!
drv
->
bus
)
return
-
EINVAL
;
pr_debug
(
"
Registering driver '%s' with bus '%s'
\n
"
,
drv
->
name
,
drv
->
bus
->
name
);
pr_debug
(
"
driver %s:%s: registering
\n
"
,
drv
->
bus
->
name
,
drv
->
name
);
get_bus
(
drv
->
bus
);
atomic_set
(
&
drv
->
refcount
,
2
);
rwlock_init
(
&
drv
->
lock
);
INIT_LIST_HEAD
(
&
drv
->
devices
);
drv
->
present
=
1
;
spin_lock
(
&
device_lock
);
list_add
(
&
drv
->
bus_list
,
&
drv
->
bus
->
drivers
);
spin_unlock
(
&
device_lock
);
...
...
@@ -65,39 +103,17 @@ int driver_register(struct device_driver * drv)
return
0
;
}
static
void
__remove_driver
(
struct
device_driver
*
drv
)
{
pr_debug
(
"Unregistering driver '%s' from bus '%s'
\n
"
,
drv
->
name
,
drv
->
bus
->
name
);
driver_detach
(
drv
);
driver_remove_dir
(
drv
);
if
(
drv
->
release
)
drv
->
release
(
drv
);
put_bus
(
drv
->
bus
);
}
void
remove_driver
(
struct
device_driver
*
drv
)
void
driver_unregister
(
struct
device_driver
*
drv
)
{
spin_lock
(
&
device_lock
);
atomic_set
(
&
drv
->
refcount
,
0
);
list_del_init
(
&
drv
->
bus_list
);
spin_unlock
(
&
device_lock
);
__remove_driver
(
drv
);
}
/**
* put_driver - decrement driver's refcount and clean up if necessary
* @drv: driver in question
*/
void
put_driver
(
struct
device_driver
*
drv
)
{
if
(
!
atomic_dec_and_lock
(
&
drv
->
refcount
,
&
device_lock
))
return
;
list_del_init
(
&
drv
->
bus_list
);
drv
->
present
=
0
;
spin_unlock
(
&
device_lock
);
__remove_driver
(
drv
);
pr_debug
(
"driver %s:%s: unregistering
\n
"
,
drv
->
bus
->
name
,
drv
->
name
);
put_driver
(
drv
);
}
EXPORT_SYMBOL
(
driver_for_each_dev
);
EXPORT_SYMBOL
(
driver_register
);
EXPORT_SYMBOL
(
driver_unregister
);
EXPORT_SYMBOL
(
get_driver
);
EXPORT_SYMBOL
(
put_driver
);
EXPORT_SYMBOL
(
remove_driver
);
fs/driverfs/inode.c
View file @
0447d4d5
...
...
@@ -509,11 +509,13 @@ static void put_mount(void)
DBG
(
"driverfs: mount_count = %d
\n
"
,
mount_count
);
}
int
__init
init_driverfs_fs
(
void
)
static
int
__init
driverfs_init
(
void
)
{
return
register_filesystem
(
&
driverfs_fs_type
);
}
core_initcall
(
driverfs_init
);
static
struct
dentry
*
get_dentry
(
struct
dentry
*
parent
,
const
char
*
name
)
{
struct
qstr
qstr
;
...
...
include/linux/device.h
View file @
0447d4d5
...
...
@@ -54,8 +54,9 @@ struct device_class;
struct
bus_type
{
char
*
name
;
rwlock_t
lock
;
struct
rw_semaphore
rwsem
;
atomic_t
refcount
;
u32
present
;
struct
list_head
node
;
struct
list_head
devices
;
...
...
@@ -73,14 +74,9 @@ struct bus_type {
extern
int
bus_register
(
struct
bus_type
*
bus
);
extern
void
bus_unregister
(
struct
bus_type
*
bus
);
static
inline
struct
bus_type
*
get_bus
(
struct
bus_type
*
bus
)
{
BUG_ON
(
!
atomic_read
(
&
bus
->
refcount
));
atomic_inc
(
&
bus
->
refcount
);
return
bus
;
}
extern
struct
bus_type
*
get_bus
(
struct
bus_type
*
bus
);
extern
void
put_bus
(
struct
bus_type
*
bus
);
extern
int
bus_for_each_dev
(
struct
bus_type
*
bus
,
void
*
data
,
...
...
@@ -114,6 +110,7 @@ struct device_driver {
rwlock_t
lock
;
atomic_t
refcount
;
u32
present
;
struct
list_head
bus_list
;
struct
list_head
class_list
;
...
...
@@ -131,16 +128,10 @@ struct device_driver {
};
extern
int
driver_register
(
struct
device_driver
*
drv
);
extern
void
driver_unregister
(
struct
device_driver
*
drv
);
static
inline
struct
device_driver
*
get_driver
(
struct
device_driver
*
drv
)
{
BUG_ON
(
!
atomic_read
(
&
drv
->
refcount
));
atomic_inc
(
&
drv
->
refcount
);
return
drv
;
}
extern
struct
device_driver
*
get_driver
(
struct
device_driver
*
drv
);
extern
void
put_driver
(
struct
device_driver
*
drv
);
extern
void
remove_driver
(
struct
device_driver
*
drv
);
...
...
@@ -172,6 +163,9 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute *
*/
struct
device_class
{
char
*
name
;
atomic_t
refcount
;
u32
present
;
u32
devnum
;
struct
list_head
node
;
...
...
@@ -189,6 +183,9 @@ struct device_class {
extern
int
devclass_register
(
struct
device_class
*
);
extern
void
devclass_unregister
(
struct
device_class
*
);
extern
struct
device_class
*
get_devclass
(
struct
device_class
*
);
extern
void
put_devclass
(
struct
device_class
*
);
struct
devclass_attribute
{
struct
attribute
attr
;
...
...
include/linux/driverfs_fs.h
View file @
0447d4d5
...
...
@@ -65,6 +65,4 @@ driverfs_create_symlink(struct driver_dir_entry * parent,
extern
void
driverfs_remove_file
(
struct
driver_dir_entry
*
,
const
char
*
name
);
extern
int
init_driverfs_fs
(
void
);
#endif
/* _DDFS_H_ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment