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
0a983298
Commit
0a983298
authored
Mar 09, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/gregkh/linux/2.6.11/driver
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
aa61674d
0c156ba8
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
196 additions
and
234 deletions
+196
-234
Documentation/feature-removal-schedule.txt
Documentation/feature-removal-schedule.txt
+17
-0
drivers/base/bus.c
drivers/base/bus.c
+3
-1
drivers/base/class.c
drivers/base/class.c
+44
-52
drivers/base/class_simple.c
drivers/base/class_simple.c
+2
-19
drivers/base/driver.c
drivers/base/driver.c
+6
-7
drivers/base/map.c
drivers/base/map.c
+10
-11
drivers/base/platform.c
drivers/base/platform.c
+1
-1
drivers/base/sys.c
drivers/base/sys.c
+20
-19
drivers/block/floppy.c
drivers/block/floppy.c
+6
-13
drivers/block/genhd.c
drivers/block/genhd.c
+34
-19
drivers/i2c/i2c-dev.c
drivers/i2c/i2c-dev.c
+1
-8
drivers/media/video/videodev.c
drivers/media/video/videodev.c
+1
-10
drivers/usb/core/file.c
drivers/usb/core/file.c
+19
-43
fs/char_dev.c
fs/char_dev.c
+9
-17
include/linux/device.h
include/linux/device.h
+3
-2
include/linux/kobj_map.h
include/linux/kobj_map.h
+1
-1
include/linux/kobject.h
include/linux/kobject.h
+2
-0
include/linux/kref.h
include/linux/kref.h
+1
-1
lib/kobject.c
lib/kobject.c
+7
-8
lib/kref.c
lib/kref.c
+9
-2
No files found.
Documentation/feature-removal-schedule.txt
View file @
0a983298
...
...
@@ -15,3 +15,20 @@ Why: It has been unmaintained for a number of years, has unfixable
against the LSB, and can be replaced by using udev.
Who: Greg Kroah-Hartman <greg@kroah.com>
---------------------------
What: /proc/sys/cpu/*, sysctl and /proc/cpufreq interfaces to cpufreq (2.4.x interfaces)
When: January 2005
Files: drivers/cpufreq/: cpufreq_userspace.c, proc_intf.c
Why: /proc/sys/cpu/* has been deprecated since inclusion of cpufreq into
the main kernel tree. It bloats /proc/ unnecessarily and doesn't work
well with the "governor"-based design of cpufreq.
/proc/cpufreq/* has also been deprecated for a long time and was only
meant for usage during 2.5. until the new sysfs-based interface became
ready. It has an inconsistent interface which doesn't work well with
userspace setting the frequency. The output from /proc/cpufreq/* can
be emulated using "cpufreq-info --proc" (cpufrequtils).
Both interfaces are superseded by the cpufreq interface in
/sys/devices/system/cpu/cpu%n/cpufreq/.
Who: Dominik Brodowski <linux@brodo.de>
drivers/base/bus.c
View file @
0a983298
...
...
@@ -65,7 +65,7 @@ static struct sysfs_ops driver_sysfs_ops = {
static
void
driver_release
(
struct
kobject
*
kobj
)
{
struct
device_driver
*
drv
=
to_driver
(
kobj
);
up
(
&
drv
->
unload_sem
);
complete
(
&
drv
->
unloaded
);
}
static
struct
kobj_type
ktype_driver
=
{
...
...
@@ -465,6 +465,7 @@ int bus_add_device(struct device * dev)
up_write
(
&
dev
->
bus
->
subsys
.
rwsem
);
device_add_attrs
(
bus
,
dev
);
sysfs_create_link
(
&
bus
->
devices
.
kobj
,
&
dev
->
kobj
,
dev
->
bus_id
);
sysfs_create_link
(
&
dev
->
kobj
,
&
dev
->
bus
->
subsys
.
kset
.
kobj
,
"bus"
);
}
return
error
;
}
...
...
@@ -481,6 +482,7 @@ int bus_add_device(struct device * dev)
void
bus_remove_device
(
struct
device
*
dev
)
{
if
(
dev
->
bus
)
{
sysfs_remove_link
(
&
dev
->
kobj
,
"bus"
);
sysfs_remove_link
(
&
dev
->
bus
->
devices
.
kobj
,
dev
->
bus_id
);
device_remove_attrs
(
dev
->
bus
,
dev
);
down_write
(
&
dev
->
bus
->
subsys
.
rwsem
);
...
...
drivers/base/class.c
View file @
0a983298
...
...
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
#include "base.h"
#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
...
...
@@ -139,6 +140,7 @@ int class_register(struct class * cls)
INIT_LIST_HEAD
(
&
cls
->
children
);
INIT_LIST_HEAD
(
&
cls
->
interfaces
);
init_MUTEX
(
&
cls
->
sem
);
error
=
kobject_set_name
(
&
cls
->
subsys
.
kset
.
kobj
,
"%s"
,
cls
->
name
);
if
(
error
)
return
error
;
...
...
@@ -195,33 +197,6 @@ void class_device_remove_bin_file(struct class_device *class_dev,
sysfs_remove_bin_file
(
&
class_dev
->
kobj
,
attr
);
}
static
int
class_device_dev_link
(
struct
class_device
*
class_dev
)
{
if
(
class_dev
->
dev
)
return
sysfs_create_link
(
&
class_dev
->
kobj
,
&
class_dev
->
dev
->
kobj
,
"device"
);
return
0
;
}
static
void
class_device_dev_unlink
(
struct
class_device
*
class_dev
)
{
sysfs_remove_link
(
&
class_dev
->
kobj
,
"device"
);
}
static
int
class_device_driver_link
(
struct
class_device
*
class_dev
)
{
if
((
class_dev
->
dev
)
&&
(
class_dev
->
dev
->
driver
))
return
sysfs_create_link
(
&
class_dev
->
kobj
,
&
class_dev
->
dev
->
driver
->
kobj
,
"driver"
);
return
0
;
}
static
void
class_device_driver_unlink
(
struct
class_device
*
class_dev
)
{
sysfs_remove_link
(
&
class_dev
->
kobj
,
"driver"
);
}
static
ssize_t
class_device_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
)
...
...
@@ -298,9 +273,9 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
{
struct
class_device
*
class_dev
=
to_class_dev
(
kobj
);
int
retval
=
0
;
int
i
=
0
;
int
length
=
0
;
int
retval
=
0
;
pr_debug
(
"%s - name = %s
\n
"
,
__FUNCTION__
,
class_dev
->
class_id
);
...
...
@@ -313,26 +288,34 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
&
length
,
"PHYSDEVPATH=%s"
,
path
);
kfree
(
path
);
/* add bus name of physical device */
if
(
dev
->
bus
)
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVBUS=%s"
,
dev
->
bus
->
name
);
/* add driver name of physical device */
if
(
dev
->
driver
)
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVDRIVER=%s"
,
dev
->
driver
->
name
);
}
if
(
MAJOR
(
class_dev
->
devt
))
{
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"MAJOR=%u"
,
MAJOR
(
class_dev
->
devt
));
/* terminate, set to next free slot, shrink available space */
envp
[
i
]
=
NULL
;
envp
=
&
envp
[
i
];
num_envp
-=
i
;
buffer
=
&
buffer
[
length
];
buffer_size
-=
length
;
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"MINOR=%u"
,
MINOR
(
class_dev
->
devt
));
}
/* terminate, set to next free slot, shrink available space */
envp
[
i
]
=
NULL
;
envp
=
&
envp
[
i
];
num_envp
-=
i
;
buffer
=
&
buffer
[
length
];
buffer_size
-=
length
;
if
(
class_dev
->
class
->
hotplug
)
{
/* have the bus specific function add its stuff */
retval
=
class_dev
->
class
->
hotplug
(
class_dev
,
envp
,
num_envp
,
...
...
@@ -388,6 +371,12 @@ static void class_device_remove_attrs(struct class_device * cd)
}
}
static
ssize_t
show_dev
(
struct
class_device
*
class_dev
,
char
*
buf
)
{
return
print_dev_t
(
buf
,
class_dev
->
devt
);
}
static
CLASS_DEVICE_ATTR
(
dev
,
S_IRUGO
,
show_dev
,
NULL
);
void
class_device_initialize
(
struct
class_device
*
class_dev
)
{
kobj_set_kset_s
(
class_dev
,
class_obj_subsys
);
...
...
@@ -425,16 +414,21 @@ int class_device_add(struct class_device *class_dev)
/* now take care of our own registration */
if
(
parent
)
{
down
_write
(
&
parent
->
subsys
.
rw
sem
);
down
(
&
parent
->
sem
);
list_add_tail
(
&
class_dev
->
node
,
&
parent
->
children
);
list_for_each_entry
(
class_intf
,
&
parent
->
interfaces
,
node
)
if
(
class_intf
->
add
)
class_intf
->
add
(
class_dev
);
up
_write
(
&
parent
->
subsys
.
rw
sem
);
up
(
&
parent
->
sem
);
}
if
(
MAJOR
(
class_dev
->
devt
))
class_device_create_file
(
class_dev
,
&
class_device_attr_dev
);
class_device_add_attrs
(
class_dev
);
class_device_dev_link
(
class_dev
);
class_device_driver_link
(
class_dev
);
if
(
class_dev
->
dev
)
sysfs_create_link
(
&
class_dev
->
kobj
,
&
class_dev
->
dev
->
kobj
,
"device"
);
register_done:
if
(
error
&&
parent
)
...
...
@@ -455,16 +449,16 @@ void class_device_del(struct class_device *class_dev)
struct
class_interface
*
class_intf
;
if
(
parent
)
{
down
_write
(
&
parent
->
subsys
.
rw
sem
);
down
(
&
parent
->
sem
);
list_del_init
(
&
class_dev
->
node
);
list_for_each_entry
(
class_intf
,
&
parent
->
interfaces
,
node
)
if
(
class_intf
->
remove
)
class_intf
->
remove
(
class_dev
);
up
_write
(
&
parent
->
subsys
.
rw
sem
);
up
(
&
parent
->
sem
);
}
class_device_dev_unlink
(
class_dev
);
class_device_driver_unlink
(
class_dev
);
if
(
class_dev
->
dev
)
sysfs_remove_link
(
&
class_dev
->
kobj
,
"device"
);
class_device_remove_attrs
(
class_dev
);
kobject_del
(
&
class_dev
->
kobj
);
...
...
@@ -516,8 +510,8 @@ void class_device_put(struct class_device *class_dev)
int
class_interface_register
(
struct
class_interface
*
class_intf
)
{
struct
class
*
parent
;
struct
class_device
*
class_dev
;
struct
class
*
parent
;
struct
class_device
*
class_dev
;
if
(
!
class_intf
||
!
class_intf
->
class
)
return
-
ENODEV
;
...
...
@@ -526,14 +520,13 @@ int class_interface_register(struct class_interface *class_intf)
if
(
!
parent
)
return
-
EINVAL
;
down
_write
(
&
parent
->
subsys
.
rw
sem
);
down
(
&
parent
->
sem
);
list_add_tail
(
&
class_intf
->
node
,
&
parent
->
interfaces
);
if
(
class_intf
->
add
)
{
list_for_each_entry
(
class_dev
,
&
parent
->
children
,
node
)
class_intf
->
add
(
class_dev
);
}
up
_write
(
&
parent
->
subsys
.
rw
sem
);
up
(
&
parent
->
sem
);
return
0
;
}
...
...
@@ -546,14 +539,13 @@ void class_interface_unregister(struct class_interface *class_intf)
if
(
!
parent
)
return
;
down
_write
(
&
parent
->
subsys
.
rw
sem
);
down
(
&
parent
->
sem
);
list_del_init
(
&
class_intf
->
node
);
if
(
class_intf
->
remove
)
{
list_for_each_entry
(
class_dev
,
&
parent
->
children
,
node
)
class_intf
->
remove
(
class_dev
);
}
up
_write
(
&
parent
->
subsys
.
rw
sem
);
up
(
&
parent
->
sem
);
class_put
(
parent
);
}
...
...
drivers/base/class_simple.c
View file @
0a983298
...
...
@@ -10,18 +10,15 @@
#include <linux/config.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/err.h>
struct
class_simple
{
struct
class_device_attribute
attr
;
struct
class
class
;
};
#define to_class_simple(d) container_of(d, struct class_simple, class)
struct
simple_dev
{
struct
list_head
node
;
dev_t
dev
;
struct
class_device
class_dev
;
};
#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
...
...
@@ -35,12 +32,6 @@ static void release_simple_dev(struct class_device *class_dev)
kfree
(
s_dev
);
}
static
ssize_t
show_dev
(
struct
class_device
*
class_dev
,
char
*
buf
)
{
struct
simple_dev
*
s_dev
=
to_simple_dev
(
class_dev
);
return
print_dev_t
(
buf
,
s_dev
->
dev
);
}
static
void
class_simple_release
(
struct
class
*
class
)
{
struct
class_simple
*
cs
=
to_class_simple
(
class
);
...
...
@@ -75,12 +66,6 @@ struct class_simple *class_simple_create(struct module *owner, char *name)
cs
->
class
.
class_release
=
class_simple_release
;
cs
->
class
.
release
=
release_simple_dev
;
cs
->
attr
.
attr
.
name
=
"dev"
;
cs
->
attr
.
attr
.
mode
=
S_IRUGO
;
cs
->
attr
.
attr
.
owner
=
owner
;
cs
->
attr
.
show
=
show_dev
;
cs
->
attr
.
store
=
NULL
;
retval
=
class_register
(
&
cs
->
class
);
if
(
retval
)
goto
error
;
...
...
@@ -143,7 +128,7 @@ struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev,
}
memset
(
s_dev
,
0x00
,
sizeof
(
*
s_dev
));
s_dev
->
dev
=
dev
;
s_dev
->
class_dev
.
devt
=
dev
;
s_dev
->
class_dev
.
dev
=
device
;
s_dev
->
class_dev
.
class
=
&
cs
->
class
;
...
...
@@ -154,8 +139,6 @@ struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev,
if
(
retval
)
goto
error
;
class_device_create_file
(
&
s_dev
->
class_dev
,
&
cs
->
attr
);
spin_lock
(
&
simple_dev_list_lock
);
list_add
(
&
s_dev
->
node
,
&
simple_dev_list
);
spin_unlock
(
&
simple_dev_list_lock
);
...
...
@@ -200,7 +183,7 @@ void class_simple_device_remove(dev_t dev)
spin_lock
(
&
simple_dev_list_lock
);
list_for_each_entry
(
s_dev
,
&
simple_dev_list
,
node
)
{
if
(
s_dev
->
dev
==
dev
)
{
if
(
s_dev
->
class_dev
.
devt
==
dev
)
{
found
=
1
;
break
;
}
...
...
drivers/base/driver.c
View file @
0a983298
...
...
@@ -79,14 +79,14 @@ void put_driver(struct device_driver * drv)
* since most of the things we have to do deal with the bus
* structures.
*
* The one interesting aspect is that we
initialize @drv->unload_sem
*
to a locked state here. It will be unlocked when the driver
*
reference
count reaches 0.
* The one interesting aspect is that we
setup @drv->unloaded
*
as a completion that gets complete when the driver reference
* count reaches 0.
*/
int
driver_register
(
struct
device_driver
*
drv
)
{
INIT_LIST_HEAD
(
&
drv
->
devices
);
init_
MUTEX_LOCKED
(
&
drv
->
unload_sem
);
init_
completion
(
&
drv
->
unloaded
);
return
bus_add_driver
(
drv
);
}
...
...
@@ -97,7 +97,7 @@ int driver_register(struct device_driver * drv)
*
* Again, we pass off most of the work to the bus-level call.
*
* Though, once that is done, we
attempt to take @drv->unload_sem
.
* Though, once that is done, we
wait until @drv->unloaded is completed
.
* This will block until the driver refcount reaches 0, and it is
* released. Only modular drivers will call this function, and we
* have to guarantee that it won't complete, letting the driver
...
...
@@ -107,8 +107,7 @@ int driver_register(struct device_driver * drv)
void
driver_unregister
(
struct
device_driver
*
drv
)
{
bus_remove_driver
(
drv
);
down
(
&
drv
->
unload_sem
);
up
(
&
drv
->
unload_sem
);
wait_for_completion
(
&
drv
->
unloaded
);
}
/**
...
...
drivers/base/map.c
View file @
0a983298
...
...
@@ -25,7 +25,7 @@ struct kobj_map {
int
(
*
lock
)(
dev_t
,
void
*
);
void
*
data
;
}
*
probes
[
255
];
struct
rw_
semaphore
*
sem
;
struct
semaphore
*
sem
;
};
int
kobj_map
(
struct
kobj_map
*
domain
,
dev_t
dev
,
unsigned
long
range
,
...
...
@@ -53,7 +53,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
p
->
range
=
range
;
p
->
data
=
data
;
}
down
_write
(
domain
->
sem
);
down
(
domain
->
sem
);
for
(
i
=
0
,
p
-=
n
;
i
<
n
;
i
++
,
p
++
,
index
++
)
{
struct
probe
**
s
=
&
domain
->
probes
[
index
%
255
];
while
(
*
s
&&
(
*
s
)
->
range
<
range
)
...
...
@@ -61,7 +61,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
p
->
next
=
*
s
;
*
s
=
p
;
}
up
_write
(
domain
->
sem
);
up
(
domain
->
sem
);
return
0
;
}
...
...
@@ -75,7 +75,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
if
(
n
>
255
)
n
=
255
;
down
_write
(
domain
->
sem
);
down
(
domain
->
sem
);
for
(
i
=
0
;
i
<
n
;
i
++
,
index
++
)
{
struct
probe
**
s
;
for
(
s
=
&
domain
->
probes
[
index
%
255
];
*
s
;
s
=
&
(
*
s
)
->
next
)
{
...
...
@@ -88,7 +88,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
}
}
}
up
_write
(
domain
->
sem
);
up
(
domain
->
sem
);
kfree
(
found
);
}
...
...
@@ -99,7 +99,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
unsigned
long
best
=
~
0UL
;
retry:
down
_read
(
domain
->
sem
);
down
(
domain
->
sem
);
for
(
p
=
domain
->
probes
[
MAJOR
(
dev
)
%
255
];
p
;
p
=
p
->
next
)
{
struct
kobject
*
(
*
probe
)(
dev_t
,
int
*
,
void
*
);
struct
module
*
owner
;
...
...
@@ -120,7 +120,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
module_put
(
owner
);
continue
;
}
up
_read
(
domain
->
sem
);
up
(
domain
->
sem
);
kobj
=
probe
(
dev
,
index
,
data
);
/* Currently ->owner protects _only_ ->probe() itself. */
module_put
(
owner
);
...
...
@@ -128,12 +128,11 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
return
kobj
;
goto
retry
;
}
up
_read
(
domain
->
sem
);
up
(
domain
->
sem
);
return
NULL
;
}
struct
kobj_map
*
kobj_map_init
(
kobj_probe_t
*
base_probe
,
struct
subsystem
*
s
)
struct
kobj_map
*
kobj_map_init
(
kobj_probe_t
*
base_probe
,
struct
semaphore
*
sem
)
{
struct
kobj_map
*
p
=
kmalloc
(
sizeof
(
struct
kobj_map
),
GFP_KERNEL
);
struct
probe
*
base
=
kmalloc
(
sizeof
(
struct
probe
),
GFP_KERNEL
);
...
...
@@ -151,6 +150,6 @@ struct kobj_map *kobj_map_init(kobj_probe_t *base_probe,
base
->
get
=
base_probe
;
for
(
i
=
0
;
i
<
255
;
i
++
)
p
->
probes
[
i
]
=
base
;
p
->
sem
=
&
s
->
rw
sem
;
p
->
sem
=
sem
;
return
p
;
}
drivers/base/platform.c
View file @
0a983298
...
...
@@ -131,7 +131,7 @@ int platform_device_register(struct platform_device * pdev)
pdev
->
dev
.
bus
=
&
platform_bus_type
;
if
(
pdev
->
id
!=
-
1
)
snprintf
(
pdev
->
dev
.
bus_id
,
BUS_ID_SIZE
,
"%s%u"
,
pdev
->
name
,
pdev
->
id
);
snprintf
(
pdev
->
dev
.
bus_id
,
BUS_ID_SIZE
,
"%s
.
%u"
,
pdev
->
name
,
pdev
->
id
);
else
strlcpy
(
pdev
->
dev
.
bus_id
,
pdev
->
name
,
BUS_ID_SIZE
);
...
...
drivers/base/sys.c
View file @
0a983298
...
...
@@ -79,7 +79,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file);
/*
* declare system_subsys
*/
decl_subsys
(
system
,
&
ktype_sysdev
,
NULL
);
static
decl_subsys
(
system
,
&
ktype_sysdev
,
NULL
);
int
sysdev_class_register
(
struct
sysdev_class
*
cls
)
{
...
...
@@ -102,7 +102,8 @@ EXPORT_SYMBOL_GPL(sysdev_class_register);
EXPORT_SYMBOL_GPL
(
sysdev_class_unregister
);
static
LIST_HEAD
(
global_drivers
);
static
LIST_HEAD
(
sysdev_drivers
);
static
DECLARE_MUTEX
(
sysdev_drivers_lock
);
/**
* sysdev_driver_register - Register auxillary driver
...
...
@@ -112,14 +113,14 @@ static LIST_HEAD(global_drivers);
* If @cls is valid, then @drv is inserted into @cls->drivers to be
* called on each operation on devices of that class. The refcount
* of @cls is incremented.
* Otherwise, @drv is inserted into
global
_drivers, and called for
* Otherwise, @drv is inserted into
sysdev
_drivers, and called for
* each device.
*/
int
sysdev_driver_register
(
struct
sysdev_class
*
cls
,
struct
sysdev_driver
*
drv
)
{
down
_write
(
&
system_subsys
.
rwsem
);
down
(
&
sysdev_drivers_lock
);
if
(
cls
&&
kset_get
(
&
cls
->
kset
))
{
list_add_tail
(
&
drv
->
entry
,
&
cls
->
drivers
);
...
...
@@ -130,8 +131,8 @@ int sysdev_driver_register(struct sysdev_class * cls,
drv
->
add
(
dev
);
}
}
else
list_add_tail
(
&
drv
->
entry
,
&
global
_drivers
);
up
_write
(
&
system_subsys
.
rwsem
);
list_add_tail
(
&
drv
->
entry
,
&
sysdev
_drivers
);
up
(
&
sysdev_drivers_lock
);
return
0
;
}
...
...
@@ -144,7 +145,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
void
sysdev_driver_unregister
(
struct
sysdev_class
*
cls
,
struct
sysdev_driver
*
drv
)
{
down
_write
(
&
system_subsys
.
rwsem
);
down
(
&
sysdev_drivers_lock
);
list_del_init
(
&
drv
->
entry
);
if
(
cls
)
{
if
(
drv
->
remove
)
{
...
...
@@ -154,7 +155,7 @@ void sysdev_driver_unregister(struct sysdev_class * cls,
}
kset_put
(
&
cls
->
kset
);
}
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
}
EXPORT_SYMBOL_GPL
(
sysdev_driver_register
);
...
...
@@ -193,13 +194,13 @@ int sysdev_register(struct sys_device * sysdev)
if
(
!
error
)
{
struct
sysdev_driver
*
drv
;
down
_write
(
&
system_subsys
.
rwsem
);
down
(
&
sysdev_drivers_lock
);
/* Generic notification is implicit, because it's that
* code that should have called us.
*/
/* Notify global drivers */
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
add
)
drv
->
add
(
sysdev
);
}
...
...
@@ -209,7 +210,7 @@ int sysdev_register(struct sys_device * sysdev)
if
(
drv
->
add
)
drv
->
add
(
sysdev
);
}
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
}
return
error
;
}
...
...
@@ -218,8 +219,8 @@ void sysdev_unregister(struct sys_device * sysdev)
{
struct
sysdev_driver
*
drv
;
down
_write
(
&
system_subsys
.
rwsem
);
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
down
(
&
sysdev_drivers_lock
);
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
remove
)
drv
->
remove
(
sysdev
);
}
...
...
@@ -228,7 +229,7 @@ void sysdev_unregister(struct sys_device * sysdev)
if
(
drv
->
remove
)
drv
->
remove
(
sysdev
);
}
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
kobject_unregister
(
&
sysdev
->
kobj
);
}
...
...
@@ -255,7 +256,7 @@ void sysdev_shutdown(void)
pr_debug
(
"Shutting Down System Devices
\n
"
);
down
_write
(
&
system_subsys
.
rwsem
);
down
(
&
sysdev_drivers_lock
);
list_for_each_entry_reverse
(
cls
,
&
system_subsys
.
kset
.
list
,
kset
.
kobj
.
entry
)
{
struct
sys_device
*
sysdev
;
...
...
@@ -268,7 +269,7 @@ void sysdev_shutdown(void)
pr_debug
(
" %s
\n
"
,
kobject_name
(
&
sysdev
->
kobj
));
/* Call global drivers first. */
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
shutdown
)
drv
->
shutdown
(
sysdev
);
}
...
...
@@ -284,7 +285,7 @@ void sysdev_shutdown(void)
cls
->
shutdown
(
sysdev
);
}
}
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
}
...
...
@@ -319,7 +320,7 @@ int sysdev_suspend(u32 state)
pr_debug
(
" %s
\n
"
,
kobject_name
(
&
sysdev
->
kobj
));
/* Call global drivers first. */
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
suspend
)
drv
->
suspend
(
sysdev
,
state
);
}
...
...
@@ -375,7 +376,7 @@ int sysdev_resume(void)
}
/* Call global drivers. */
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
resume
)
drv
->
resume
(
sysdev
);
}
...
...
drivers/block/floppy.c
View file @
0a983298
...
...
@@ -4370,6 +4370,10 @@ int __init floppy_init(void)
goto
out_flush_work
;
}
err
=
platform_device_register
(
&
floppy_device
);
if
(
err
)
goto
out_flush_work
;
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
{
if
(
!
(
allowed_drive_mask
&
(
1
<<
drive
)))
continue
;
...
...
@@ -4379,23 +4383,12 @@ int __init floppy_init(void)
disks
[
drive
]
->
private_data
=
(
void
*
)(
long
)
drive
;
disks
[
drive
]
->
queue
=
floppy_queue
;
disks
[
drive
]
->
flags
|=
GENHD_FL_REMOVABLE
;
disks
[
drive
]
->
driverfs_dev
=
&
floppy_device
.
dev
;
add_disk
(
disks
[
drive
]);
}
err
=
platform_device_register
(
&
floppy_device
);
if
(
err
)
goto
out_del_disk
;
return
0
;
out_del_disk:
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
{
if
(
!
(
allowed_drive_mask
&
(
1
<<
drive
)))
continue
;
if
(
fdc_state
[
FDC
(
drive
)].
version
==
FDC_NONE
)
continue
;
del_gendisk
(
disks
[
drive
]);
}
out_flush_work:
flush_scheduled_work
();
if
(
usage_count
)
...
...
@@ -4600,7 +4593,6 @@ void cleanup_module(void)
int
drive
;
init_completion
(
&
device_release
);
platform_device_unregister
(
&
floppy_device
);
blk_unregister_region
(
MKDEV
(
FLOPPY_MAJOR
,
0
),
256
);
unregister_blkdev
(
FLOPPY_MAJOR
,
"fd"
);
...
...
@@ -4614,6 +4606,7 @@ void cleanup_module(void)
}
put_disk
(
disks
[
drive
]);
}
platform_device_unregister
(
&
floppy_device
);
devfs_remove
(
"floppy"
);
del_timer_sync
(
&
fd_timeout
);
...
...
drivers/block/genhd.c
View file @
0a983298
...
...
@@ -302,7 +302,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
static
int
__init
genhd_device_init
(
void
)
{
bdev_map
=
kobj_map_init
(
base_probe
,
&
block_subsys
);
bdev_map
=
kobj_map_init
(
base_probe
,
&
block_subsys
_sem
);
blk_dev_init
();
subsystem_register
(
&
block_subsys
);
return
0
;
...
...
@@ -430,43 +430,58 @@ static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
static
int
block_hotplug
(
struct
kset
*
kset
,
struct
kobject
*
kobj
,
char
**
envp
,
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
{
struct
device
*
dev
=
NULL
;
struct
kobj_type
*
ktype
=
get_ktype
(
kobj
);
struct
device
*
physdev
;
struct
gendisk
*
disk
;
struct
hd_struct
*
part
;
int
length
=
0
;
int
i
=
0
;
/* get physical device backing disk or partition */
if
(
ktype
==
&
ktype_block
)
{
struct
gendisk
*
disk
=
container_of
(
kobj
,
struct
gendisk
,
kobj
);
dev
=
disk
->
driverfs_dev
;
disk
=
container_of
(
kobj
,
struct
gendisk
,
kobj
);
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"MINOR=%u"
,
disk
->
first_minor
);
}
else
if
(
ktype
==
&
ktype_part
)
{
struct
gendisk
*
disk
=
container_of
(
kobj
->
parent
,
struct
gendisk
,
kobj
);
dev
=
disk
->
driverfs_dev
;
}
disk
=
container_of
(
kobj
->
parent
,
struct
gendisk
,
kobj
);
part
=
container_of
(
kobj
,
struct
hd_struct
,
kobj
);
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"MINOR=%u"
,
disk
->
first_minor
+
part
->
partno
);
}
else
return
0
;
if
(
dev
)
{
/* add physical device, backing this device */
char
*
path
=
kobject_get_path
(
&
dev
->
kobj
,
GFP_KERNEL
);
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"MAJOR=%u"
,
disk
->
major
);
/* add physical device, backing this device */
physdev
=
disk
->
driverfs_dev
;
if
(
physdev
)
{
char
*
path
=
kobject_get_path
(
&
physdev
->
kobj
,
GFP_KERNEL
);
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVPATH=%s"
,
path
);
kfree
(
path
);
/* add bus name of physical device */
if
(
dev
->
bus
)
if
(
physdev
->
bus
)
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVBUS=%s"
,
dev
->
bus
->
name
);
"PHYSDEVBUS=%s"
,
physdev
->
bus
->
name
);
/* add driver name of physical device */
if
(
dev
->
driver
)
if
(
physdev
->
driver
)
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVDRIVER=%s"
,
dev
->
driver
->
name
);
envp
[
i
]
=
NULL
;
"PHYSDEVDRIVER=%s"
,
physdev
->
driver
->
name
);
}
/* terminate, set to next free slot, shrink available space */
envp
[
i
]
=
NULL
;
envp
=
&
envp
[
i
];
num_envp
-=
i
;
buffer
=
&
buffer
[
length
];
buffer_size
-=
length
;
return
0
;
}
...
...
drivers/i2c/i2c-dev.c
View file @
0a983298
...
...
@@ -108,13 +108,6 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
spin_unlock
(
&
i2c_dev_array_lock
);
}
static
ssize_t
show_dev
(
struct
class_device
*
class_dev
,
char
*
buf
)
{
struct
i2c_dev
*
i2c_dev
=
to_i2c_dev
(
class_dev
);
return
print_dev_t
(
buf
,
MKDEV
(
I2C_MAJOR
,
i2c_dev
->
minor
));
}
static
CLASS_DEVICE_ATTR
(
dev
,
S_IRUGO
,
show_dev
,
NULL
);
static
ssize_t
show_adapter_name
(
struct
class_device
*
class_dev
,
char
*
buf
)
{
struct
i2c_dev
*
i2c_dev
=
to_i2c_dev
(
class_dev
);
...
...
@@ -451,11 +444,11 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
else
i2c_dev
->
class_dev
.
dev
=
adap
->
dev
.
parent
;
i2c_dev
->
class_dev
.
class
=
&
i2c_dev_class
;
i2c_dev
->
class_dev
.
devt
=
MKDEV
(
I2C_MAJOR
,
i2c_dev
->
minor
);
snprintf
(
i2c_dev
->
class_dev
.
class_id
,
BUS_ID_SIZE
,
"i2c-%d"
,
i2c_dev
->
minor
);
retval
=
class_device_register
(
&
i2c_dev
->
class_dev
);
if
(
retval
)
goto
error
;
class_device_create_file
(
&
i2c_dev
->
class_dev
,
&
class_device_attr_dev
);
class_device_create_file
(
&
i2c_dev
->
class_dev
,
&
class_device_attr_name
);
return
0
;
error:
...
...
drivers/media/video/videodev.c
View file @
0a983298
...
...
@@ -46,15 +46,7 @@ static ssize_t show_name(struct class_device *cd, char *buf)
return
sprintf
(
buf
,
"%.*s
\n
"
,(
int
)
sizeof
(
vfd
->
name
),
vfd
->
name
);
}
static
ssize_t
show_dev
(
struct
class_device
*
cd
,
char
*
buf
)
{
struct
video_device
*
vfd
=
container_of
(
cd
,
struct
video_device
,
class_dev
);
dev_t
dev
=
MKDEV
(
VIDEO_MAJOR
,
vfd
->
minor
);
return
print_dev_t
(
buf
,
dev
);
}
static
CLASS_DEVICE_ATTR
(
name
,
S_IRUGO
,
show_name
,
NULL
);
static
CLASS_DEVICE_ATTR
(
dev
,
S_IRUGO
,
show_dev
,
NULL
);
struct
video_device
*
video_device_alloc
(
void
)
{
...
...
@@ -347,12 +339,11 @@ int video_register_device(struct video_device *vfd, int type, int nr)
if
(
vfd
->
dev
)
vfd
->
class_dev
.
dev
=
vfd
->
dev
;
vfd
->
class_dev
.
class
=
&
video_class
;
vfd
->
class_dev
.
devt
=
MKDEV
(
VIDEO_MAJOR
,
vfd
->
minor
);
strlcpy
(
vfd
->
class_dev
.
class_id
,
vfd
->
devfs_name
+
4
,
BUS_ID_SIZE
);
class_device_register
(
&
vfd
->
class_dev
);
class_device_create_file
(
&
vfd
->
class_dev
,
&
class_device_attr_name
);
class_device_create_file
(
&
vfd
->
class_dev
,
&
class_device_attr_dev
);
#if 1
/* needed until all drivers are fixed */
if
(
!
vfd
->
release
)
...
...
drivers/usb/core/file.c
View file @
0a983298
...
...
@@ -66,16 +66,7 @@ static struct file_operations usb_fops = {
.
open
=
usb_open
,
};
static
void
release_usb_class_dev
(
struct
class_device
*
class_dev
)
{
dbg
(
"%s - %s"
,
__FUNCTION__
,
class_dev
->
class_id
);
kfree
(
class_dev
);
}
static
struct
class
usb_class
=
{
.
name
=
"usb"
,
.
release
=
&
release_usb_class_dev
,
};
static
struct
class_simple
*
usb_class
;
int
usb_major_init
(
void
)
{
...
...
@@ -87,9 +78,9 @@ int usb_major_init(void)
goto
out
;
}
error
=
class_register
(
&
usb_class
);
if
(
error
)
{
err
(
"class_
register
failed for usb devices"
);
usb_class
=
class_simple_create
(
THIS_MODULE
,
"usb"
);
if
(
IS_ERR
(
usb_class
)
)
{
err
(
"class_
simple_create
failed for usb devices"
);
unregister_chrdev
(
USB_MAJOR
,
"usb"
);
goto
out
;
}
...
...
@@ -102,18 +93,11 @@ int usb_major_init(void)
void
usb_major_cleanup
(
void
)
{
class_
unregister
(
&
usb_class
);
class_
simple_destroy
(
usb_class
);
devfs_remove
(
"usb"
);
unregister_chrdev
(
USB_MAJOR
,
"usb"
);
}
static
ssize_t
show_dev
(
struct
class_device
*
class_dev
,
char
*
buf
)
{
int
minor
=
(
int
)(
long
)
class_get_devdata
(
class_dev
);
return
print_dev_t
(
buf
,
MKDEV
(
USB_MAJOR
,
minor
));
}
static
CLASS_DEVICE_ATTR
(
dev
,
S_IRUGO
,
show_dev
,
NULL
);
/**
* usb_register_dev - register a USB device, and ask for a minor number
* @intf: pointer to the usb_interface that is being registered
...
...
@@ -141,7 +125,6 @@ int usb_register_dev(struct usb_interface *intf,
int
minor_base
=
class_driver
->
minor_base
;
int
minor
=
0
;
char
name
[
BUS_ID_SIZE
];
struct
class_device
*
class_dev
;
char
*
temp
;
#ifdef CONFIG_USB_DYNAMIC_MINORS
...
...
@@ -181,22 +164,18 @@ int usb_register_dev(struct usb_interface *intf,
devfs_mk_cdev
(
MKDEV
(
USB_MAJOR
,
minor
),
class_driver
->
mode
,
name
);
/* create a usb class device for this usb interface */
class_dev
=
kmalloc
(
sizeof
(
*
class_dev
),
GFP_KERNEL
);
if
(
class_dev
)
{
memset
(
class_dev
,
0x00
,
sizeof
(
struct
class_device
));
class_dev
->
class
=
&
usb_class
;
class_dev
->
dev
=
&
intf
->
dev
;
temp
=
strrchr
(
name
,
'/'
);
if
(
temp
&&
(
temp
[
1
]
!=
0x00
))
++
temp
;
else
temp
=
name
;
snprintf
(
class_dev
->
class_id
,
BUS_ID_SIZE
,
"%s"
,
temp
);
class_set_devdata
(
class_dev
,
(
void
*
)(
long
)
intf
->
minor
);
class_device_register
(
class_dev
);
class_device_create_file
(
class_dev
,
&
class_device_attr_dev
);
intf
->
class_dev
=
class_dev
;
temp
=
strrchr
(
name
,
'/'
);
if
(
temp
&&
(
temp
[
1
]
!=
0x00
))
++
temp
;
else
temp
=
name
;
intf
->
class_dev
=
class_simple_device_add
(
usb_class
,
MKDEV
(
USB_MAJOR
,
minor
),
&
intf
->
dev
,
"%s"
,
temp
);
if
(
IS_ERR
(
intf
->
class_dev
))
{
spin_lock
(
&
minor_lock
);
usb_minors
[
intf
->
minor
]
=
NULL
;
spin_unlock
(
&
minor_lock
);
devfs_remove
(
name
);
retval
=
PTR_ERR
(
intf
->
class_dev
);
}
exit:
return
retval
;
...
...
@@ -239,11 +218,8 @@ void usb_deregister_dev(struct usb_interface *intf,
snprintf
(
name
,
BUS_ID_SIZE
,
class_driver
->
name
,
intf
->
minor
-
minor_base
);
devfs_remove
(
name
);
if
(
intf
->
class_dev
)
{
class_device_unregister
(
intf
->
class_dev
);
intf
->
class_dev
=
NULL
;
}
class_simple_device_remove
(
MKDEV
(
USB_MAJOR
,
intf
->
minor
));
intf
->
class_dev
=
NULL
;
intf
->
minor
=
-
1
;
}
EXPORT_SYMBOL
(
usb_deregister_dev
);
...
...
fs/char_dev.c
View file @
0a983298
...
...
@@ -29,7 +29,7 @@ static struct kobj_map *cdev_map;
/* degrade to linked list for small systems */
#define MAX_PROBE_HASH (CONFIG_BASE_SMALL ? 1 : 255)
static
DE
FINE_RWLOCK
(
chrdevs_lock
);
static
DE
CLARE_MUTEX
(
chrdevs_lock
);
static
struct
char_device_struct
{
struct
char_device_struct
*
next
;
...
...
@@ -55,13 +55,13 @@ int get_chrdev_list(char *page)
len
=
sprintf
(
page
,
"Character devices:
\n
"
);
read_lock
(
&
chrdevs_lock
);
down
(
&
chrdevs_lock
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
chrdevs
)
;
i
++
)
{
for
(
cd
=
chrdevs
[
i
];
cd
;
cd
=
cd
->
next
)
len
+=
sprintf
(
page
+
len
,
"%3d %s
\n
"
,
cd
->
major
,
cd
->
name
);
}
read_unlock
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
return
len
;
}
...
...
@@ -91,7 +91,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
memset
(
cd
,
0
,
sizeof
(
struct
char_device_struct
));
write_lock_irq
(
&
chrdevs_lock
);
down
(
&
chrdevs_lock
);
/* temporary */
if
(
major
==
0
)
{
...
...
@@ -126,10 +126,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
}
cd
->
next
=
*
cp
;
*
cp
=
cd
;
write_unlock_irq
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
return
cd
;
out:
write_unlock_irq
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
kfree
(
cd
);
return
ERR_PTR
(
ret
);
}
...
...
@@ -140,7 +140,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
struct
char_device_struct
*
cd
=
NULL
,
**
cp
;
int
i
=
major_to_index
(
major
);
write_lock_irq
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
for
(
cp
=
&
chrdevs
[
i
];
*
cp
;
cp
=
&
(
*
cp
)
->
next
)
if
((
*
cp
)
->
major
==
major
&&
(
*
cp
)
->
baseminor
==
baseminor
&&
...
...
@@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
cd
=
*
cp
;
*
cp
=
cd
->
next
;
}
write_unlock_irq
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
return
cd
;
}
...
...
@@ -381,8 +381,6 @@ void cdev_del(struct cdev *p)
}
static
decl_subsys
(
cdev
,
NULL
,
NULL
);
static
void
cdev_default_release
(
struct
kobject
*
kobj
)
{
struct
cdev
*
p
=
container_of
(
kobj
,
struct
cdev
,
kobj
);
...
...
@@ -435,13 +433,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
void
__init
chrdev_init
(
void
)
{
/*
* Keep cdev_subsys around because (and only because) the kobj_map code
* depends on the rwsem it contains. We don't make it public in sysfs,
* however.
*/
subsystem_init
(
&
cdev_subsys
);
cdev_map
=
kobj_map_init
(
base_probe
,
&
cdev_subsys
);
cdev_map
=
kobj_map_init
(
base_probe
,
&
chrdevs_lock
);
}
...
...
include/linux/device.h
View file @
0a983298
...
...
@@ -15,7 +15,6 @@
#include <linux/ioport.h>
#include <linux/kobject.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pm.h>
...
...
@@ -102,7 +101,7 @@ struct device_driver {
char
*
name
;
struct
bus_type
*
bus
;
struct
semaphore
unload_sem
;
struct
completion
unloaded
;
struct
kobject
kobj
;
struct
list_head
devices
;
...
...
@@ -148,6 +147,7 @@ struct class {
struct
subsystem
subsys
;
struct
list_head
children
;
struct
list_head
interfaces
;
struct
semaphore
sem
;
/* locks both the children and interfaces lists */
struct
class_attribute
*
class_attrs
;
struct
class_device_attribute
*
class_dev_attrs
;
...
...
@@ -184,6 +184,7 @@ struct class_device {
struct
kobject
kobj
;
struct
class
*
class
;
/* required */
dev_t
devt
;
/* dev_t, creates the sysfs "dev" */
struct
device
*
dev
;
/* not necessary, but nice to have */
void
*
class_data
;
/* class-specific data */
...
...
include/linux/kobj_map.h
View file @
0a983298
...
...
@@ -7,6 +7,6 @@ int kobj_map(struct kobj_map *, dev_t, unsigned long, struct module *,
kobj_probe_t
*
,
int
(
*
)(
dev_t
,
void
*
),
void
*
);
void
kobj_unmap
(
struct
kobj_map
*
,
dev_t
,
unsigned
long
);
struct
kobject
*
kobj_lookup
(
struct
kobj_map
*
,
dev_t
,
int
*
);
struct
kobj_map
*
kobj_map_init
(
kobj_probe_t
*
,
struct
s
ubsystem
*
);
struct
kobj_map
*
kobj_map_init
(
kobj_probe_t
*
,
struct
s
emaphore
*
);
#endif
include/linux/kobject.h
View file @
0a983298
...
...
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/sysfs.h>
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/kref.h>
#include <linux/kobject_uevent.h>
...
...
@@ -102,6 +103,7 @@ struct kset {
struct
subsystem
*
subsys
;
struct
kobj_type
*
ktype
;
struct
list_head
list
;
spinlock_t
list_lock
;
struct
kobject
kobj
;
struct
kset_hotplug_ops
*
hotplug_ops
;
};
...
...
include/linux/kref.h
View file @
0a983298
...
...
@@ -26,7 +26,7 @@ struct kref {
void
kref_init
(
struct
kref
*
kref
);
void
kref_get
(
struct
kref
*
kref
);
void
kref_put
(
struct
kref
*
kref
,
void
(
*
release
)
(
struct
kref
*
kref
));
int
kref_put
(
struct
kref
*
kref
,
void
(
*
release
)
(
struct
kref
*
kref
));
#endif
/* __KERNEL__ */
#endif
/* _KREF_H_ */
lib/kobject.c
View file @
0a983298
...
...
@@ -140,9 +140,9 @@ void kobject_init(struct kobject * kobj)
static
void
unlink
(
struct
kobject
*
kobj
)
{
if
(
kobj
->
kset
)
{
down_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
spin_lock
(
&
kobj
->
kset
->
list_lock
);
list_del_init
(
&
kobj
->
entry
);
up_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
spin_unlock
(
&
kobj
->
kset
->
list_lock
);
}
kobject_put
(
kobj
);
}
...
...
@@ -168,13 +168,13 @@ int kobject_add(struct kobject * kobj)
kobj
->
kset
?
kobj
->
kset
->
kobj
.
name
:
"<NULL>"
);
if
(
kobj
->
kset
)
{
down_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
spin_lock
(
&
kobj
->
kset
->
list_lock
);
if
(
!
parent
)
parent
=
kobject_get
(
&
kobj
->
kset
->
kobj
);
list_add_tail
(
&
kobj
->
entry
,
&
kobj
->
kset
->
list
);
up_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
spin_unlock
(
&
kobj
->
kset
->
list_lock
);
}
kobj
->
parent
=
parent
;
...
...
@@ -380,6 +380,7 @@ void kset_init(struct kset * k)
{
kobject_init
(
&
k
->
kobj
);
INIT_LIST_HEAD
(
&
k
->
list
);
spin_lock_init
(
&
k
->
list_lock
);
}
...
...
@@ -444,7 +445,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name)
struct
list_head
*
entry
;
struct
kobject
*
ret
=
NULL
;
down_read
(
&
kset
->
subsys
->
rwsem
);
spin_lock
(
&
kset
->
list_lock
);
list_for_each
(
entry
,
&
kset
->
list
)
{
struct
kobject
*
k
=
to_kobj
(
entry
);
if
(
kobject_name
(
k
)
&&
!
strcmp
(
kobject_name
(
k
),
name
))
{
...
...
@@ -452,7 +453,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name)
break
;
}
}
up_read
(
&
kset
->
subsys
->
rwsem
);
spin_unlock
(
&
kset
->
list_lock
);
return
ret
;
}
...
...
@@ -524,7 +525,6 @@ void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
}
}
EXPORT_SYMBOL
(
kobject_get_path
);
EXPORT_SYMBOL
(
kobject_init
);
EXPORT_SYMBOL
(
kobject_register
);
EXPORT_SYMBOL
(
kobject_unregister
);
...
...
@@ -532,7 +532,6 @@ EXPORT_SYMBOL(kobject_get);
EXPORT_SYMBOL
(
kobject_put
);
EXPORT_SYMBOL
(
kobject_add
);
EXPORT_SYMBOL
(
kobject_del
);
EXPORT_SYMBOL
(
kobject_rename
);
EXPORT_SYMBOL
(
kset_register
);
EXPORT_SYMBOL
(
kset_unregister
);
...
...
lib/kref.c
View file @
0a983298
...
...
@@ -42,14 +42,21 @@ void kref_get(struct kref *kref)
* in as this function.
*
* Decrement the refcount, and if 0, call release().
* Return 1 if the object was removed, otherwise return 0. Beware, if this
* function returns 0, you still can not count on the kref from remaining in
* memory. Only use the return value if you want to see if the kref is now
* gone, not present.
*/
void
kref_put
(
struct
kref
*
kref
,
void
(
*
release
)
(
struct
kref
*
kref
))
int
kref_put
(
struct
kref
*
kref
,
void
(
*
release
)
(
struct
kref
*
kref
))
{
WARN_ON
(
release
==
NULL
);
WARN_ON
(
release
==
(
void
(
*
)(
struct
kref
*
))
kfree
);
if
(
atomic_dec_and_test
(
&
kref
->
refcount
))
if
(
atomic_dec_and_test
(
&
kref
->
refcount
))
{
release
(
kref
);
return
1
;
}
return
0
;
}
EXPORT_SYMBOL
(
kref_init
);
...
...
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