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
27d2d64c
Commit
27d2d64c
authored
Mar 03, 2003
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
5d8a45ef
2e646ed0
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
104 additions
and
171 deletions
+104
-171
drivers/base/base.h
drivers/base/base.h
+1
-0
drivers/base/class.c
drivers/base/class.c
+47
-33
drivers/base/core.c
drivers/base/core.c
+0
-1
drivers/base/intf.c
drivers/base/intf.c
+34
-85
fs/sysfs/inode.c
fs/sysfs/inode.c
+19
-25
include/linux/device.h
include/linux/device.h
+2
-26
include/linux/kobject.h
include/linux/kobject.h
+1
-1
No files found.
drivers/base/base.h
View file @
27d2d64c
#undef DEBUG
extern
struct
semaphore
device_sem
;
extern
struct
semaphore
devclass_sem
;
extern
int
bus_add_device
(
struct
device
*
dev
);
extern
void
bus_remove_device
(
struct
device
*
dev
);
...
...
drivers/base/class.c
View file @
27d2d64c
...
...
@@ -13,6 +13,8 @@
#define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr)
#define to_class(obj) container_of(obj,struct device_class,subsys.kset.kobj)
DECLARE_MUTEX
(
devclass_sem
);
static
ssize_t
devclass_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
)
{
...
...
@@ -163,29 +165,34 @@ int devclass_add_device(struct device * dev)
struct
device_class
*
cls
;
int
error
=
0
;
down
(
&
devclass_sem
);
if
(
dev
->
driver
)
{
cls
=
get_devclass
(
dev
->
driver
->
devclass
);
if
(
cls
)
{
down_write
(
&
cls
->
subsys
.
rwsem
);
if
(
!
cls
)
goto
Done
;
pr_debug
(
"device class %s: adding device %s
\n
"
,
cls
->
name
,
dev
->
name
);
if
(
cls
->
add_device
)
error
=
cls
->
add_device
(
dev
);
if
(
!
error
)
{
enum_device
(
cls
,
dev
);
interface_add_dev
(
dev
)
;
if
(
error
)
{
put_devclass
(
cls
);
goto
Done
;
}
down_write
(
&
cls
->
subsys
.
rwsem
);
enum_device
(
cls
,
dev
);
list_add_tail
(
&
dev
->
class_list
,
&
cls
->
devices
.
list
);
/* notify userspace (call /sbin/hotplug) */
class_hotplug
(
dev
,
"add"
);
up_write
(
&
cls
->
subsys
.
rwsem
);
if
(
error
)
put_devclass
(
cls
);
}
interface_add_dev
(
dev
);
}
Done:
up
(
&
devclass_sem
);
return
error
;
}
...
...
@@ -193,13 +200,18 @@ void devclass_remove_device(struct device * dev)
{
struct
device_class
*
cls
;
down
(
&
devclass_sem
);
if
(
dev
->
driver
)
{
cls
=
dev
->
driver
->
devclass
;
if
(
cls
)
{
if
(
!
cls
)
goto
Done
;
interface_remove_dev
(
dev
);
down_write
(
&
cls
->
subsys
.
rwsem
);
pr_debug
(
"device class %s: removing device %s
\n
"
,
cls
->
name
,
dev
->
name
);
interface_remove_dev
(
dev
);
unenum_device
(
cls
,
dev
);
list_del
(
&
dev
->
class_list
);
...
...
@@ -207,12 +219,14 @@ void devclass_remove_device(struct device * dev)
/* notify userspace (call /sbin/hotplug) */
class_hotplug
(
dev
,
"remove"
);
up_write
(
&
cls
->
subsys
.
rwsem
);
if
(
cls
->
remove_device
)
cls
->
remove_device
(
dev
);
up_write
(
&
cls
->
subsys
.
rwsem
);
put_devclass
(
cls
);
}
}
Done:
up
(
&
devclass_sem
);
}
struct
device_class
*
get_devclass
(
struct
device_class
*
cls
)
...
...
drivers/base/core.c
View file @
27d2d64c
...
...
@@ -143,7 +143,6 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD
(
&
dev
->
driver_list
);
INIT_LIST_HEAD
(
&
dev
->
bus_list
);
INIT_LIST_HEAD
(
&
dev
->
class_list
);
INIT_LIST_HEAD
(
&
dev
->
intf_list
);
}
/**
...
...
drivers/base/intf.c
View file @
27d2d64c
...
...
@@ -12,80 +12,31 @@
#define to_intf(node) container_of(node,struct device_interface,kset.kobj.entry)
#define to_d
ata(e) container_of(e,struct intf_data,kobj.entry
)
#define to_d
ev(d) container_of(d,struct device,class_list
)
/**
* intf_dev_link - create sysfs symlink for interface.
* @data: interface data descriptor.
* @intf: interface.
* @dev: device.
*
* Create a symlink 'phys' in the interface's directory to
*/
static
int
intf_dev_link
(
struct
intf_data
*
data
)
static
int
intf_dev_link
(
struct
device_interface
*
intf
,
struct
device
*
dev
)
{
char
name
[
16
];
snprintf
(
name
,
16
,
"%d"
,
data
->
intf_num
);
return
sysfs_create_link
(
&
data
->
intf
->
kset
.
kobj
,
&
data
->
dev
->
kobj
,
name
);
return
sysfs_create_link
(
&
intf
->
kset
.
kobj
,
&
dev
->
kobj
,
dev
->
bus_id
);
}
/**
* intf_dev_unlink - remove symlink for interface.
* @intf: interface data descriptor.
*
*/
static
void
intf_dev_unlink
(
struct
intf_data
*
data
)
{
char
name
[
16
];
snprintf
(
name
,
16
,
"%d"
,
data
->
intf_num
);
sysfs_remove_link
(
&
data
->
intf
->
kset
.
kobj
,
name
);
}
/**
* interface_add_data - attach data descriptor
* @data: interface data descriptor.
*
* This attaches the per-instance interface object to the
* interface (by registering its kobject) and the device
* itself (by inserting it into the device's list).
*
* Note that there is no explicit protection done in this
* function. This should be called from the interface's
* add_device() method, which is called under the protection
* of the class's rwsem.
*/
int
interface_add_data
(
struct
intf_data
*
data
)
{
struct
device_interface
*
intf
=
data
->
intf
;
if
(
intf
)
{
data
->
intf_num
=
intf
->
devnum
++
;
data
->
kobj
.
kset
=
&
intf
->
kset
;
kobject_register
(
&
data
->
kobj
);
list_add_tail
(
&
data
->
dev_entry
,
&
data
->
dev
->
intf_list
);
return
intf_dev_link
(
data
);
}
return
-
EINVAL
;
}
/**
* interface_remove_data - detach data descriptor.
* @data: interface data descriptor.
* @intf: interface.
* @dev: device.
*
* This detaches the per-instance data descriptor by removing
* it from the device's list and unregistering the kobject from
* the subsystem.
*/
void
interface_remove_data
(
struct
intf_data
*
data
)
static
void
intf_dev_unlink
(
struct
device_interface
*
intf
,
struct
device
*
dev
)
{
intf_dev_unlink
(
data
);
list_del_init
(
&
data
->
dev_entry
);
kobject_unregister
(
&
data
->
kobj
);
sysfs_remove_link
(
&
intf
->
kset
.
kobj
,
dev
->
bus_id
);
}
...
...
@@ -103,33 +54,28 @@ static int add(struct device_interface * intf, struct device * dev)
{
int
error
=
0
;
if
(
intf
->
add_device
)
error
=
intf
->
add_device
(
dev
);
if
(
intf
->
add_device
)
{
if
(
!
(
error
=
intf
->
add_device
(
dev
)))
intf_dev_link
(
intf
,
dev
);
}
pr_debug
(
" -> %s (%d)
\n
"
,
dev
->
bus_id
,
error
);
return
error
;
}
/**
* del - detach device from interface.
* @data: interface data descriptor.
*
* Another simple helper. Remove the data descriptor from
* the device and the interface, then call the interface's
* remove_device() method.
* @intf: interface.
* @dev: device.
*/
static
void
del
(
struct
intf_data
*
data
)
static
void
del
(
struct
device_interface
*
intf
,
struct
device
*
dev
)
{
struct
device_interface
*
intf
=
data
->
intf
;
pr_debug
(
" -> %s "
,
intf
->
name
);
interface_remove_data
(
data
);
if
(
intf
->
remove_device
)
intf
->
remove_device
(
data
);
intf
->
remove_device
(
dev
);
intf_dev_unlink
(
intf
,
dev
);
}
#define to_dev(entry) container_of(entry,struct device,class_list)
/**
* add_intf - add class's devices to interface.
...
...
@@ -145,10 +91,8 @@ static void add_intf(struct device_interface * intf)
struct
device_class
*
cls
=
intf
->
devclass
;
struct
list_head
*
entry
;
down_write
(
&
cls
->
subsys
.
rwsem
);
list_for_each
(
entry
,
&
cls
->
devices
.
list
)
add
(
intf
,
to_dev
(
entry
));
up_write
(
&
cls
->
subsys
.
rwsem
);
}
/**
...
...
@@ -164,6 +108,7 @@ int interface_register(struct device_interface * intf)
{
struct
device_class
*
cls
=
get_devclass
(
intf
->
devclass
);
down
(
&
devclass_sem
);
if
(
cls
)
{
pr_debug
(
"register interface '%s' with class '%s'
\n
"
,
intf
->
name
,
cls
->
name
);
...
...
@@ -173,6 +118,7 @@ int interface_register(struct device_interface * intf)
kset_register
(
&
intf
->
kset
);
add_intf
(
intf
);
}
up
(
&
devclass_sem
);
return
0
;
}
...
...
@@ -188,14 +134,13 @@ int interface_register(struct device_interface * intf)
static
void
del_intf
(
struct
device_interface
*
intf
)
{
struct
device_class
*
cls
=
intf
->
devclass
;
struct
list_head
*
entry
;
down_write
(
&
intf
->
devclass
->
subsys
.
rwsem
);
list_for_each
(
entry
,
&
intf
->
kset
.
list
)
{
struct
intf_data
*
data
=
to_data
(
entry
);
del
(
data
);
list_for_each
(
entry
,
&
cls
->
devices
.
list
)
{
struct
device
*
dev
=
to_dev
(
entry
);
del
(
intf
,
dev
);
}
up_write
(
&
intf
->
devclass
->
subsys
.
rwsem
);
}
/**
...
...
@@ -210,6 +155,8 @@ static void del_intf(struct device_interface * intf)
void
interface_unregister
(
struct
device_interface
*
intf
)
{
struct
device_class
*
cls
=
intf
->
devclass
;
down
(
&
devclass_sem
);
if
(
cls
)
{
pr_debug
(
"unregistering interface '%s' from class '%s'
\n
"
,
intf
->
name
,
cls
->
name
);
...
...
@@ -217,6 +164,7 @@ void interface_unregister(struct device_interface * intf)
kset_unregister
(
&
intf
->
kset
);
put_devclass
(
cls
);
}
up
(
&
devclass_sem
);
}
...
...
@@ -255,20 +203,21 @@ int interface_add_dev(struct device * dev)
* This is another helper for the class driver core, and called
* when the device is being removed from the class.
*
* We iterate over the list of
interface data descriptors attached
*
to the device, and call del() [above] for each. Again, the
*
class's rwsem is assumed to be held during this
.
* We iterate over the list of
the class's devices and call del()
*
[above] for each. Again, the class's rwsem is _not_ held, but
*
the devclass_sem is (see class.c)
.
*/
void
interface_remove_dev
(
struct
device
*
dev
)
{
struct
list_head
*
entry
,
*
next
;
struct
device_class
*
cls
=
dev
->
driver
->
devclass
;
pr_debug
(
"interfaces: removing device %s
\n
"
,
dev
->
name
);
list_for_each_safe
(
entry
,
next
,
&
dev
->
intf_
list
)
{
struct
intf_data
*
intf_data
=
to_data
(
entry
);
del
(
intf
_data
);
list_for_each_safe
(
entry
,
next
,
&
cls
->
subsys
.
kset
.
list
)
{
struct
device_interface
*
intf
=
to_intf
(
entry
);
del
(
intf
,
dev
);
}
}
...
...
fs/sysfs/inode.c
View file @
27d2d64c
...
...
@@ -98,10 +98,9 @@ static int sysfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
if
(
!
dentry
->
d_inode
)
{
inode
=
sysfs_get_inode
(
dir
->
i_sb
,
mode
,
dev
);
if
(
inode
)
{
if
(
inode
)
d_instantiate
(
dentry
,
inode
);
dget
(
dentry
);
}
else
else
error
=
-
ENOSPC
;
}
else
error
=
-
EEXIST
;
...
...
@@ -703,10 +702,6 @@ static void hash_and_remove(struct dentry * dir, const char * name)
pr_debug
(
"sysfs: Removing %s (%d)
\n
"
,
victim
->
d_name
.
name
,
atomic_read
(
&
victim
->
d_count
));
/**
* Drop reference from initial get_dentry().
*/
dput
(
victim
);
}
/**
...
...
@@ -795,7 +790,7 @@ void sysfs_remove_link(struct kobject * kobj, char * name)
void
sysfs_remove_dir
(
struct
kobject
*
kobj
)
{
struct
list_head
*
node
,
*
next
;
struct
list_head
*
node
;
struct
dentry
*
dentry
=
dget
(
kobj
->
dentry
);
struct
dentry
*
parent
;
...
...
@@ -807,32 +802,31 @@ void sysfs_remove_dir(struct kobject * kobj)
down
(
&
parent
->
d_inode
->
i_sem
);
down
(
&
dentry
->
d_inode
->
i_sem
);
list_for_each_safe
(
node
,
next
,
&
dentry
->
d_subdirs
)
{
struct
dentry
*
d
=
dget
(
list_entry
(
node
,
struct
dentry
,
d_child
));
/**
* Make sure dentry is still there
*/
pr_debug
(
" o %s: "
,
d
->
d_name
.
name
);
if
(
d
->
d_inode
)
{
spin_lock
(
&
dcache_lock
);
node
=
dentry
->
d_subdirs
.
next
;
while
(
node
!=
&
dentry
->
d_subdirs
)
{
struct
dentry
*
d
=
list_entry
(
node
,
struct
dentry
,
d_child
);
list_del_init
(
node
);
pr_debug
(
" o %s (%d): "
,
d
->
d_name
.
name
,
atomic_read
(
&
d
->
d_count
));
if
(
d
->
d_inode
)
{
d
=
dget_locked
(
d
);
pr_debug
(
"removing"
);
/**
* Unlink and unhash.
*/
s
imple_unlink
(
dentry
->
d_inode
,
d
);
s
pin_unlock
(
&
dcache_lock
);
d_delete
(
d
);
/**
* Drop reference from initial get_dentry().
*/
simple_unlink
(
dentry
->
d_inode
,
d
);
dput
(
d
);
spin_lock
(
&
dcache_lock
);
}
pr_debug
(
" done (%d)
\n
"
,
atomic_read
(
&
d
->
d_count
));
/**
* drop reference from dget() above.
*/
dput
(
d
);
pr_debug
(
" done
\n
"
);
node
=
dentry
->
d_subdirs
.
next
;
}
spin_unlock
(
&
dcache_lock
);
up
(
&
dentry
->
d_inode
->
i_sem
);
d_invalidate
(
dentry
);
...
...
include/linux/device.h
View file @
27d2d64c
...
...
@@ -27,9 +27,9 @@
#include <linux/ioport.h>
#include <linux/kobject.h>
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <asm/semaphore.h>
#include <asm/atomic.h>
#define DEVICE_NAME_SIZE 50
...
...
@@ -207,8 +207,6 @@ extern void devclass_remove_file(struct device_class *, struct devclass_attribut
* it supports the device.
*/
struct
intf_data
;
struct
device_interface
{
char
*
name
;
struct
device_class
*
devclass
;
...
...
@@ -217,41 +215,19 @@ struct device_interface {
u32
devnum
;
int
(
*
add_device
)
(
struct
device
*
);
int
(
*
remove_device
)
(
struct
intf_data
*
);
int
(
*
remove_device
)
(
struct
device
*
);
};
extern
int
interface_register
(
struct
device_interface
*
);
extern
void
interface_unregister
(
struct
device_interface
*
);
/*
* intf_data - per-device data for an interface
* Each interface typically has a per-device data structure
* that it allocates. It should embed one of these structures
* in that structure and call interface_add_data() to add it
* to the device's list.
* That will also enumerate the device within the interface
* and create a driverfs symlink for it.
*/
struct
intf_data
{
struct
device_interface
*
intf
;
struct
device
*
dev
;
u32
intf_num
;
struct
list_head
dev_entry
;
struct
kobject
kobj
;
};
extern
int
interface_add_data
(
struct
intf_data
*
);
struct
device
{
struct
list_head
node
;
/* node in sibling list */
struct
list_head
bus_list
;
/* node in bus's list */
struct
list_head
class_list
;
struct
list_head
driver_list
;
struct
list_head
children
;
struct
list_head
intf_list
;
struct
device
*
parent
;
struct
kobject
kobj
;
...
...
include/linux/kobject.h
View file @
27d2d64c
...
...
@@ -73,7 +73,7 @@ extern void kset_unregister(struct kset * k);
static
inline
struct
kset
*
to_kset
(
struct
kobject
*
kobj
)
{
return
container_of
(
kobj
,
struct
kset
,
kobj
)
;
return
kobj
?
container_of
(
kobj
,
struct
kset
,
kobj
)
:
NULL
;
}
static
inline
struct
kset
*
kset_get
(
struct
kset
*
k
)
...
...
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