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
nexedi
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