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
...
@@ -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.
against the LSB, and can be replaced by using udev.
Who: Greg Kroah-Hartman <greg@kroah.com>
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 = {
...
@@ -65,7 +65,7 @@ static struct sysfs_ops driver_sysfs_ops = {
static
void
driver_release
(
struct
kobject
*
kobj
)
static
void
driver_release
(
struct
kobject
*
kobj
)
{
{
struct
device_driver
*
drv
=
to_driver
(
kobj
);
struct
device_driver
*
drv
=
to_driver
(
kobj
);
up
(
&
drv
->
unload_sem
);
complete
(
&
drv
->
unloaded
);
}
}
static
struct
kobj_type
ktype_driver
=
{
static
struct
kobj_type
ktype_driver
=
{
...
@@ -465,6 +465,7 @@ int bus_add_device(struct device * dev)
...
@@ -465,6 +465,7 @@ int bus_add_device(struct device * dev)
up_write
(
&
dev
->
bus
->
subsys
.
rwsem
);
up_write
(
&
dev
->
bus
->
subsys
.
rwsem
);
device_add_attrs
(
bus
,
dev
);
device_add_attrs
(
bus
,
dev
);
sysfs_create_link
(
&
bus
->
devices
.
kobj
,
&
dev
->
kobj
,
dev
->
bus_id
);
sysfs_create_link
(
&
bus
->
devices
.
kobj
,
&
dev
->
kobj
,
dev
->
bus_id
);
sysfs_create_link
(
&
dev
->
kobj
,
&
dev
->
bus
->
subsys
.
kset
.
kobj
,
"bus"
);
}
}
return
error
;
return
error
;
}
}
...
@@ -481,6 +482,7 @@ int bus_add_device(struct device * dev)
...
@@ -481,6 +482,7 @@ int bus_add_device(struct device * dev)
void
bus_remove_device
(
struct
device
*
dev
)
void
bus_remove_device
(
struct
device
*
dev
)
{
{
if
(
dev
->
bus
)
{
if
(
dev
->
bus
)
{
sysfs_remove_link
(
&
dev
->
kobj
,
"bus"
);
sysfs_remove_link
(
&
dev
->
bus
->
devices
.
kobj
,
dev
->
bus_id
);
sysfs_remove_link
(
&
dev
->
bus
->
devices
.
kobj
,
dev
->
bus_id
);
device_remove_attrs
(
dev
->
bus
,
dev
);
device_remove_attrs
(
dev
->
bus
,
dev
);
down_write
(
&
dev
->
bus
->
subsys
.
rwsem
);
down_write
(
&
dev
->
bus
->
subsys
.
rwsem
);
...
...
drivers/base/class.c
View file @
0a983298
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
#include "base.h"
#include "base.h"
#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
...
@@ -139,6 +140,7 @@ int class_register(struct class * cls)
...
@@ -139,6 +140,7 @@ int class_register(struct class * cls)
INIT_LIST_HEAD
(
&
cls
->
children
);
INIT_LIST_HEAD
(
&
cls
->
children
);
INIT_LIST_HEAD
(
&
cls
->
interfaces
);
INIT_LIST_HEAD
(
&
cls
->
interfaces
);
init_MUTEX
(
&
cls
->
sem
);
error
=
kobject_set_name
(
&
cls
->
subsys
.
kset
.
kobj
,
"%s"
,
cls
->
name
);
error
=
kobject_set_name
(
&
cls
->
subsys
.
kset
.
kobj
,
"%s"
,
cls
->
name
);
if
(
error
)
if
(
error
)
return
error
;
return
error
;
...
@@ -195,33 +197,6 @@ void class_device_remove_bin_file(struct class_device *class_dev,
...
@@ -195,33 +197,6 @@ void class_device_remove_bin_file(struct class_device *class_dev,
sysfs_remove_bin_file
(
&
class_dev
->
kobj
,
attr
);
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
static
ssize_t
class_device_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
class_device_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
)
char
*
buf
)
...
@@ -298,9 +273,9 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
...
@@ -298,9 +273,9 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
{
{
struct
class_device
*
class_dev
=
to_class_dev
(
kobj
);
struct
class_device
*
class_dev
=
to_class_dev
(
kobj
);
int
retval
=
0
;
int
i
=
0
;
int
i
=
0
;
int
length
=
0
;
int
length
=
0
;
int
retval
=
0
;
pr_debug
(
"%s - name = %s
\n
"
,
__FUNCTION__
,
class_dev
->
class_id
);
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,
...
@@ -313,26 +288,34 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
&
length
,
"PHYSDEVPATH=%s"
,
path
);
&
length
,
"PHYSDEVPATH=%s"
,
path
);
kfree
(
path
);
kfree
(
path
);
/* add bus name of physical device */
if
(
dev
->
bus
)
if
(
dev
->
bus
)
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVBUS=%s"
,
dev
->
bus
->
name
);
"PHYSDEVBUS=%s"
,
dev
->
bus
->
name
);
/* add driver name of physical device */
if
(
dev
->
driver
)
if
(
dev
->
driver
)
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVDRIVER=%s"
,
dev
->
driver
->
name
);
"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 */
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
envp
[
i
]
=
NULL
;
buffer
,
buffer_size
,
&
length
,
envp
=
&
envp
[
i
];
"MINOR=%u"
,
MINOR
(
class_dev
->
devt
));
num_envp
-=
i
;
buffer
=
&
buffer
[
length
];
buffer_size
-=
length
;
}
}
/* 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
)
{
if
(
class_dev
->
class
->
hotplug
)
{
/* have the bus specific function add its stuff */
/* have the bus specific function add its stuff */
retval
=
class_dev
->
class
->
hotplug
(
class_dev
,
envp
,
num_envp
,
retval
=
class_dev
->
class
->
hotplug
(
class_dev
,
envp
,
num_envp
,
...
@@ -388,6 +371,12 @@ static void class_device_remove_attrs(struct class_device * cd)
...
@@ -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
)
void
class_device_initialize
(
struct
class_device
*
class_dev
)
{
{
kobj_set_kset_s
(
class_dev
,
class_obj_subsys
);
kobj_set_kset_s
(
class_dev
,
class_obj_subsys
);
...
@@ -425,16 +414,21 @@ int class_device_add(struct class_device *class_dev)
...
@@ -425,16 +414,21 @@ int class_device_add(struct class_device *class_dev)
/* now take care of our own registration */
/* now take care of our own registration */
if
(
parent
)
{
if
(
parent
)
{
down
_write
(
&
parent
->
subsys
.
rw
sem
);
down
(
&
parent
->
sem
);
list_add_tail
(
&
class_dev
->
node
,
&
parent
->
children
);
list_add_tail
(
&
class_dev
->
node
,
&
parent
->
children
);
list_for_each_entry
(
class_intf
,
&
parent
->
interfaces
,
node
)
list_for_each_entry
(
class_intf
,
&
parent
->
interfaces
,
node
)
if
(
class_intf
->
add
)
if
(
class_intf
->
add
)
class_intf
->
add
(
class_dev
);
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_add_attrs
(
class_dev
);
class_device_dev_link
(
class_dev
);
if
(
class_dev
->
dev
)
class_device_driver_link
(
class_dev
);
sysfs_create_link
(
&
class_dev
->
kobj
,
&
class_dev
->
dev
->
kobj
,
"device"
);
register_done:
register_done:
if
(
error
&&
parent
)
if
(
error
&&
parent
)
...
@@ -455,16 +449,16 @@ void class_device_del(struct class_device *class_dev)
...
@@ -455,16 +449,16 @@ void class_device_del(struct class_device *class_dev)
struct
class_interface
*
class_intf
;
struct
class_interface
*
class_intf
;
if
(
parent
)
{
if
(
parent
)
{
down
_write
(
&
parent
->
subsys
.
rw
sem
);
down
(
&
parent
->
sem
);
list_del_init
(
&
class_dev
->
node
);
list_del_init
(
&
class_dev
->
node
);
list_for_each_entry
(
class_intf
,
&
parent
->
interfaces
,
node
)
list_for_each_entry
(
class_intf
,
&
parent
->
interfaces
,
node
)
if
(
class_intf
->
remove
)
if
(
class_intf
->
remove
)
class_intf
->
remove
(
class_dev
);
class_intf
->
remove
(
class_dev
);
up
_write
(
&
parent
->
subsys
.
rw
sem
);
up
(
&
parent
->
sem
);
}
}
class_device_dev_unlink
(
class_dev
);
if
(
class_dev
->
dev
)
class_device_driver_unlink
(
class_dev
);
sysfs_remove_link
(
&
class_dev
->
kobj
,
"device"
);
class_device_remove_attrs
(
class_dev
);
class_device_remove_attrs
(
class_dev
);
kobject_del
(
&
class_dev
->
kobj
);
kobject_del
(
&
class_dev
->
kobj
);
...
@@ -516,8 +510,8 @@ void class_device_put(struct class_device *class_dev)
...
@@ -516,8 +510,8 @@ void class_device_put(struct class_device *class_dev)
int
class_interface_register
(
struct
class_interface
*
class_intf
)
int
class_interface_register
(
struct
class_interface
*
class_intf
)
{
{
struct
class
*
parent
;
struct
class
*
parent
;
struct
class_device
*
class_dev
;
struct
class_device
*
class_dev
;
if
(
!
class_intf
||
!
class_intf
->
class
)
if
(
!
class_intf
||
!
class_intf
->
class
)
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -526,14 +520,13 @@ int class_interface_register(struct class_interface *class_intf)
...
@@ -526,14 +520,13 @@ int class_interface_register(struct class_interface *class_intf)
if
(
!
parent
)
if
(
!
parent
)
return
-
EINVAL
;
return
-
EINVAL
;
down
_write
(
&
parent
->
subsys
.
rw
sem
);
down
(
&
parent
->
sem
);
list_add_tail
(
&
class_intf
->
node
,
&
parent
->
interfaces
);
list_add_tail
(
&
class_intf
->
node
,
&
parent
->
interfaces
);
if
(
class_intf
->
add
)
{
if
(
class_intf
->
add
)
{
list_for_each_entry
(
class_dev
,
&
parent
->
children
,
node
)
list_for_each_entry
(
class_dev
,
&
parent
->
children
,
node
)
class_intf
->
add
(
class_dev
);
class_intf
->
add
(
class_dev
);
}
}
up
_write
(
&
parent
->
subsys
.
rw
sem
);
up
(
&
parent
->
sem
);
return
0
;
return
0
;
}
}
...
@@ -546,14 +539,13 @@ void class_interface_unregister(struct class_interface *class_intf)
...
@@ -546,14 +539,13 @@ void class_interface_unregister(struct class_interface *class_intf)
if
(
!
parent
)
if
(
!
parent
)
return
;
return
;
down
_write
(
&
parent
->
subsys
.
rw
sem
);
down
(
&
parent
->
sem
);
list_del_init
(
&
class_intf
->
node
);
list_del_init
(
&
class_intf
->
node
);
if
(
class_intf
->
remove
)
{
if
(
class_intf
->
remove
)
{
list_for_each_entry
(
class_dev
,
&
parent
->
children
,
node
)
list_for_each_entry
(
class_dev
,
&
parent
->
children
,
node
)
class_intf
->
remove
(
class_dev
);
class_intf
->
remove
(
class_dev
);
}
}
up
_write
(
&
parent
->
subsys
.
rw
sem
);
up
(
&
parent
->
sem
);
class_put
(
parent
);
class_put
(
parent
);
}
}
...
...
drivers/base/class_simple.c
View file @
0a983298
...
@@ -10,18 +10,15 @@
...
@@ -10,18 +10,15 @@
#include <linux/config.h>
#include <linux/config.h>
#include <linux/device.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/err.h>
#include <linux/err.h>
struct
class_simple
{
struct
class_simple
{
struct
class_device_attribute
attr
;
struct
class
class
;
struct
class
class
;
};
};
#define to_class_simple(d) container_of(d, struct class_simple, class)
#define to_class_simple(d) container_of(d, struct class_simple, class)
struct
simple_dev
{
struct
simple_dev
{
struct
list_head
node
;
struct
list_head
node
;
dev_t
dev
;
struct
class_device
class_dev
;
struct
class_device
class_dev
;
};
};
#define to_simple_dev(d) container_of(d, struct simple_dev, 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)
...
@@ -35,12 +32,6 @@ static void release_simple_dev(struct class_device *class_dev)
kfree
(
s_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
)
static
void
class_simple_release
(
struct
class
*
class
)
{
{
struct
class_simple
*
cs
=
to_class_simple
(
class
);
struct
class_simple
*
cs
=
to_class_simple
(
class
);
...
@@ -75,12 +66,6 @@ struct class_simple *class_simple_create(struct module *owner, char *name)
...
@@ -75,12 +66,6 @@ struct class_simple *class_simple_create(struct module *owner, char *name)
cs
->
class
.
class_release
=
class_simple_release
;
cs
->
class
.
class_release
=
class_simple_release
;
cs
->
class
.
release
=
release_simple_dev
;
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
);
retval
=
class_register
(
&
cs
->
class
);
if
(
retval
)
if
(
retval
)
goto
error
;
goto
error
;
...
@@ -143,7 +128,7 @@ struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev,
...
@@ -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
));
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
.
dev
=
device
;
s_dev
->
class_dev
.
class
=
&
cs
->
class
;
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,
...
@@ -154,8 +139,6 @@ struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev,
if
(
retval
)
if
(
retval
)
goto
error
;
goto
error
;
class_device_create_file
(
&
s_dev
->
class_dev
,
&
cs
->
attr
);
spin_lock
(
&
simple_dev_list_lock
);
spin_lock
(
&
simple_dev_list_lock
);
list_add
(
&
s_dev
->
node
,
&
simple_dev_list
);
list_add
(
&
s_dev
->
node
,
&
simple_dev_list
);
spin_unlock
(
&
simple_dev_list_lock
);
spin_unlock
(
&
simple_dev_list_lock
);
...
@@ -200,7 +183,7 @@ void class_simple_device_remove(dev_t dev)
...
@@ -200,7 +183,7 @@ void class_simple_device_remove(dev_t dev)
spin_lock
(
&
simple_dev_list_lock
);
spin_lock
(
&
simple_dev_list_lock
);
list_for_each_entry
(
s_dev
,
&
simple_dev_list
,
node
)
{
list_for_each_entry
(
s_dev
,
&
simple_dev_list
,
node
)
{
if
(
s_dev
->
dev
==
dev
)
{
if
(
s_dev
->
class_dev
.
devt
==
dev
)
{
found
=
1
;
found
=
1
;
break
;
break
;
}
}
...
...
drivers/base/driver.c
View file @
0a983298
...
@@ -79,14 +79,14 @@ void put_driver(struct device_driver * drv)
...
@@ -79,14 +79,14 @@ void put_driver(struct device_driver * drv)
* since most of the things we have to do deal with the bus
* since most of the things we have to do deal with the bus
* structures.
* structures.
*
*
* The one interesting aspect is that we
initialize @drv->unload_sem
* The one interesting aspect is that we
setup @drv->unloaded
*
to a locked state here. It will be unlocked when the driver
*
as a completion that gets complete when the driver reference
*
reference
count reaches 0.
* count reaches 0.
*/
*/
int
driver_register
(
struct
device_driver
*
drv
)
int
driver_register
(
struct
device_driver
*
drv
)
{
{
INIT_LIST_HEAD
(
&
drv
->
devices
);
INIT_LIST_HEAD
(
&
drv
->
devices
);
init_
MUTEX_LOCKED
(
&
drv
->
unload_sem
);
init_
completion
(
&
drv
->
unloaded
);
return
bus_add_driver
(
drv
);
return
bus_add_driver
(
drv
);
}
}
...
@@ -97,7 +97,7 @@ int driver_register(struct device_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.
* 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
* This will block until the driver refcount reaches 0, and it is
* released. Only modular drivers will call this function, and we
* released. Only modular drivers will call this function, and we
* have to guarantee that it won't complete, letting the driver
* have to guarantee that it won't complete, letting the driver
...
@@ -107,8 +107,7 @@ int driver_register(struct device_driver * drv)
...
@@ -107,8 +107,7 @@ int driver_register(struct device_driver * drv)
void
driver_unregister
(
struct
device_driver
*
drv
)
void
driver_unregister
(
struct
device_driver
*
drv
)
{
{
bus_remove_driver
(
drv
);
bus_remove_driver
(
drv
);
down
(
&
drv
->
unload_sem
);
wait_for_completion
(
&
drv
->
unloaded
);
up
(
&
drv
->
unload_sem
);
}
}
/**
/**
...
...
drivers/base/map.c
View file @
0a983298
...
@@ -25,7 +25,7 @@ struct kobj_map {
...
@@ -25,7 +25,7 @@ struct kobj_map {
int
(
*
lock
)(
dev_t
,
void
*
);
int
(
*
lock
)(
dev_t
,
void
*
);
void
*
data
;
void
*
data
;
}
*
probes
[
255
];
}
*
probes
[
255
];
struct
rw_
semaphore
*
sem
;
struct
semaphore
*
sem
;
};
};
int
kobj_map
(
struct
kobj_map
*
domain
,
dev_t
dev
,
unsigned
long
range
,
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,
...
@@ -53,7 +53,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
p
->
range
=
range
;
p
->
range
=
range
;
p
->
data
=
data
;
p
->
data
=
data
;
}
}
down
_write
(
domain
->
sem
);
down
(
domain
->
sem
);
for
(
i
=
0
,
p
-=
n
;
i
<
n
;
i
++
,
p
++
,
index
++
)
{
for
(
i
=
0
,
p
-=
n
;
i
<
n
;
i
++
,
p
++
,
index
++
)
{
struct
probe
**
s
=
&
domain
->
probes
[
index
%
255
];
struct
probe
**
s
=
&
domain
->
probes
[
index
%
255
];
while
(
*
s
&&
(
*
s
)
->
range
<
range
)
while
(
*
s
&&
(
*
s
)
->
range
<
range
)
...
@@ -61,7 +61,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
...
@@ -61,7 +61,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
p
->
next
=
*
s
;
p
->
next
=
*
s
;
*
s
=
p
;
*
s
=
p
;
}
}
up
_write
(
domain
->
sem
);
up
(
domain
->
sem
);
return
0
;
return
0
;
}
}
...
@@ -75,7 +75,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
...
@@ -75,7 +75,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
if
(
n
>
255
)
if
(
n
>
255
)
n
=
255
;
n
=
255
;
down
_write
(
domain
->
sem
);
down
(
domain
->
sem
);
for
(
i
=
0
;
i
<
n
;
i
++
,
index
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
,
index
++
)
{
struct
probe
**
s
;
struct
probe
**
s
;
for
(
s
=
&
domain
->
probes
[
index
%
255
];
*
s
;
s
=
&
(
*
s
)
->
next
)
{
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)
...
@@ -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
);
kfree
(
found
);
}
}
...
@@ -99,7 +99,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
...
@@ -99,7 +99,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
unsigned
long
best
=
~
0UL
;
unsigned
long
best
=
~
0UL
;
retry:
retry:
down
_read
(
domain
->
sem
);
down
(
domain
->
sem
);
for
(
p
=
domain
->
probes
[
MAJOR
(
dev
)
%
255
];
p
;
p
=
p
->
next
)
{
for
(
p
=
domain
->
probes
[
MAJOR
(
dev
)
%
255
];
p
;
p
=
p
->
next
)
{
struct
kobject
*
(
*
probe
)(
dev_t
,
int
*
,
void
*
);
struct
kobject
*
(
*
probe
)(
dev_t
,
int
*
,
void
*
);
struct
module
*
owner
;
struct
module
*
owner
;
...
@@ -120,7 +120,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
...
@@ -120,7 +120,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
module_put
(
owner
);
module_put
(
owner
);
continue
;
continue
;
}
}
up
_read
(
domain
->
sem
);
up
(
domain
->
sem
);
kobj
=
probe
(
dev
,
index
,
data
);
kobj
=
probe
(
dev
,
index
,
data
);
/* Currently ->owner protects _only_ ->probe() itself. */
/* Currently ->owner protects _only_ ->probe() itself. */
module_put
(
owner
);
module_put
(
owner
);
...
@@ -128,12 +128,11 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
...
@@ -128,12 +128,11 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
return
kobj
;
return
kobj
;
goto
retry
;
goto
retry
;
}
}
up
_read
(
domain
->
sem
);
up
(
domain
->
sem
);
return
NULL
;
return
NULL
;
}
}
struct
kobj_map
*
kobj_map_init
(
kobj_probe_t
*
base_probe
,
struct
kobj_map
*
kobj_map_init
(
kobj_probe_t
*
base_probe
,
struct
semaphore
*
sem
)
struct
subsystem
*
s
)
{
{
struct
kobj_map
*
p
=
kmalloc
(
sizeof
(
struct
kobj_map
),
GFP_KERNEL
);
struct
kobj_map
*
p
=
kmalloc
(
sizeof
(
struct
kobj_map
),
GFP_KERNEL
);
struct
probe
*
base
=
kmalloc
(
sizeof
(
struct
probe
),
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,
...
@@ -151,6 +150,6 @@ struct kobj_map *kobj_map_init(kobj_probe_t *base_probe,
base
->
get
=
base_probe
;
base
->
get
=
base_probe
;
for
(
i
=
0
;
i
<
255
;
i
++
)
for
(
i
=
0
;
i
<
255
;
i
++
)
p
->
probes
[
i
]
=
base
;
p
->
probes
[
i
]
=
base
;
p
->
sem
=
&
s
->
rw
sem
;
p
->
sem
=
sem
;
return
p
;
return
p
;
}
}
drivers/base/platform.c
View file @
0a983298
...
@@ -131,7 +131,7 @@ int platform_device_register(struct platform_device * pdev)
...
@@ -131,7 +131,7 @@ int platform_device_register(struct platform_device * pdev)
pdev
->
dev
.
bus
=
&
platform_bus_type
;
pdev
->
dev
.
bus
=
&
platform_bus_type
;
if
(
pdev
->
id
!=
-
1
)
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
else
strlcpy
(
pdev
->
dev
.
bus_id
,
pdev
->
name
,
BUS_ID_SIZE
);
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);
...
@@ -79,7 +79,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file);
/*
/*
* declare system_subsys
* declare system_subsys
*/
*/
decl_subsys
(
system
,
&
ktype_sysdev
,
NULL
);
static
decl_subsys
(
system
,
&
ktype_sysdev
,
NULL
);
int
sysdev_class_register
(
struct
sysdev_class
*
cls
)
int
sysdev_class_register
(
struct
sysdev_class
*
cls
)
{
{
...
@@ -102,7 +102,8 @@ EXPORT_SYMBOL_GPL(sysdev_class_register);
...
@@ -102,7 +102,8 @@ EXPORT_SYMBOL_GPL(sysdev_class_register);
EXPORT_SYMBOL_GPL
(
sysdev_class_unregister
);
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
* sysdev_driver_register - Register auxillary driver
...
@@ -112,14 +113,14 @@ static LIST_HEAD(global_drivers);
...
@@ -112,14 +113,14 @@ static LIST_HEAD(global_drivers);
* If @cls is valid, then @drv is inserted into @cls->drivers to be
* If @cls is valid, then @drv is inserted into @cls->drivers to be
* called on each operation on devices of that class. The refcount
* called on each operation on devices of that class. The refcount
* of @cls is incremented.
* 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.
* each device.
*/
*/
int
sysdev_driver_register
(
struct
sysdev_class
*
cls
,
int
sysdev_driver_register
(
struct
sysdev_class
*
cls
,
struct
sysdev_driver
*
drv
)
struct
sysdev_driver
*
drv
)
{
{
down
_write
(
&
system_subsys
.
rwsem
);
down
(
&
sysdev_drivers_lock
);
if
(
cls
&&
kset_get
(
&
cls
->
kset
))
{
if
(
cls
&&
kset_get
(
&
cls
->
kset
))
{
list_add_tail
(
&
drv
->
entry
,
&
cls
->
drivers
);
list_add_tail
(
&
drv
->
entry
,
&
cls
->
drivers
);
...
@@ -130,8 +131,8 @@ int sysdev_driver_register(struct sysdev_class * cls,
...
@@ -130,8 +131,8 @@ int sysdev_driver_register(struct sysdev_class * cls,
drv
->
add
(
dev
);
drv
->
add
(
dev
);
}
}
}
else
}
else
list_add_tail
(
&
drv
->
entry
,
&
global
_drivers
);
list_add_tail
(
&
drv
->
entry
,
&
sysdev
_drivers
);
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
return
0
;
return
0
;
}
}
...
@@ -144,7 +145,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
...
@@ -144,7 +145,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
void
sysdev_driver_unregister
(
struct
sysdev_class
*
cls
,
void
sysdev_driver_unregister
(
struct
sysdev_class
*
cls
,
struct
sysdev_driver
*
drv
)
struct
sysdev_driver
*
drv
)
{
{
down
_write
(
&
system_subsys
.
rwsem
);
down
(
&
sysdev_drivers_lock
);
list_del_init
(
&
drv
->
entry
);
list_del_init
(
&
drv
->
entry
);
if
(
cls
)
{
if
(
cls
)
{
if
(
drv
->
remove
)
{
if
(
drv
->
remove
)
{
...
@@ -154,7 +155,7 @@ void sysdev_driver_unregister(struct sysdev_class * cls,
...
@@ -154,7 +155,7 @@ void sysdev_driver_unregister(struct sysdev_class * cls,
}
}
kset_put
(
&
cls
->
kset
);
kset_put
(
&
cls
->
kset
);
}
}
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
}
}
EXPORT_SYMBOL_GPL
(
sysdev_driver_register
);
EXPORT_SYMBOL_GPL
(
sysdev_driver_register
);
...
@@ -193,13 +194,13 @@ int sysdev_register(struct sys_device * sysdev)
...
@@ -193,13 +194,13 @@ int sysdev_register(struct sys_device * sysdev)
if
(
!
error
)
{
if
(
!
error
)
{
struct
sysdev_driver
*
drv
;
struct
sysdev_driver
*
drv
;
down
_write
(
&
system_subsys
.
rwsem
);
down
(
&
sysdev_drivers_lock
);
/* Generic notification is implicit, because it's that
/* Generic notification is implicit, because it's that
* code that should have called us.
* code that should have called us.
*/
*/
/* Notify global drivers */
/* Notify global drivers */
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
add
)
if
(
drv
->
add
)
drv
->
add
(
sysdev
);
drv
->
add
(
sysdev
);
}
}
...
@@ -209,7 +210,7 @@ int sysdev_register(struct sys_device * sysdev)
...
@@ -209,7 +210,7 @@ int sysdev_register(struct sys_device * sysdev)
if
(
drv
->
add
)
if
(
drv
->
add
)
drv
->
add
(
sysdev
);
drv
->
add
(
sysdev
);
}
}
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
}
}
return
error
;
return
error
;
}
}
...
@@ -218,8 +219,8 @@ void sysdev_unregister(struct sys_device * sysdev)
...
@@ -218,8 +219,8 @@ void sysdev_unregister(struct sys_device * sysdev)
{
{
struct
sysdev_driver
*
drv
;
struct
sysdev_driver
*
drv
;
down
_write
(
&
system_subsys
.
rwsem
);
down
(
&
sysdev_drivers_lock
);
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
remove
)
if
(
drv
->
remove
)
drv
->
remove
(
sysdev
);
drv
->
remove
(
sysdev
);
}
}
...
@@ -228,7 +229,7 @@ void sysdev_unregister(struct sys_device * sysdev)
...
@@ -228,7 +229,7 @@ void sysdev_unregister(struct sys_device * sysdev)
if
(
drv
->
remove
)
if
(
drv
->
remove
)
drv
->
remove
(
sysdev
);
drv
->
remove
(
sysdev
);
}
}
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
kobject_unregister
(
&
sysdev
->
kobj
);
kobject_unregister
(
&
sysdev
->
kobj
);
}
}
...
@@ -255,7 +256,7 @@ void sysdev_shutdown(void)
...
@@ -255,7 +256,7 @@ void sysdev_shutdown(void)
pr_debug
(
"Shutting Down System Devices
\n
"
);
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
,
list_for_each_entry_reverse
(
cls
,
&
system_subsys
.
kset
.
list
,
kset
.
kobj
.
entry
)
{
kset
.
kobj
.
entry
)
{
struct
sys_device
*
sysdev
;
struct
sys_device
*
sysdev
;
...
@@ -268,7 +269,7 @@ void sysdev_shutdown(void)
...
@@ -268,7 +269,7 @@ void sysdev_shutdown(void)
pr_debug
(
" %s
\n
"
,
kobject_name
(
&
sysdev
->
kobj
));
pr_debug
(
" %s
\n
"
,
kobject_name
(
&
sysdev
->
kobj
));
/* Call global drivers first. */
/* Call global drivers first. */
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
shutdown
)
if
(
drv
->
shutdown
)
drv
->
shutdown
(
sysdev
);
drv
->
shutdown
(
sysdev
);
}
}
...
@@ -284,7 +285,7 @@ void sysdev_shutdown(void)
...
@@ -284,7 +285,7 @@ void sysdev_shutdown(void)
cls
->
shutdown
(
sysdev
);
cls
->
shutdown
(
sysdev
);
}
}
}
}
up
_write
(
&
system_subsys
.
rwsem
);
up
(
&
sysdev_drivers_lock
);
}
}
...
@@ -319,7 +320,7 @@ int sysdev_suspend(u32 state)
...
@@ -319,7 +320,7 @@ int sysdev_suspend(u32 state)
pr_debug
(
" %s
\n
"
,
kobject_name
(
&
sysdev
->
kobj
));
pr_debug
(
" %s
\n
"
,
kobject_name
(
&
sysdev
->
kobj
));
/* Call global drivers first. */
/* Call global drivers first. */
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
suspend
)
if
(
drv
->
suspend
)
drv
->
suspend
(
sysdev
,
state
);
drv
->
suspend
(
sysdev
,
state
);
}
}
...
@@ -375,7 +376,7 @@ int sysdev_resume(void)
...
@@ -375,7 +376,7 @@ int sysdev_resume(void)
}
}
/* Call global drivers. */
/* Call global drivers. */
list_for_each_entry
(
drv
,
&
global
_drivers
,
entry
)
{
list_for_each_entry
(
drv
,
&
sysdev
_drivers
,
entry
)
{
if
(
drv
->
resume
)
if
(
drv
->
resume
)
drv
->
resume
(
sysdev
);
drv
->
resume
(
sysdev
);
}
}
...
...
drivers/block/floppy.c
View file @
0a983298
...
@@ -4370,6 +4370,10 @@ int __init floppy_init(void)
...
@@ -4370,6 +4370,10 @@ int __init floppy_init(void)
goto
out_flush_work
;
goto
out_flush_work
;
}
}
err
=
platform_device_register
(
&
floppy_device
);
if
(
err
)
goto
out_flush_work
;
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
{
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
{
if
(
!
(
allowed_drive_mask
&
(
1
<<
drive
)))
if
(
!
(
allowed_drive_mask
&
(
1
<<
drive
)))
continue
;
continue
;
...
@@ -4379,23 +4383,12 @@ int __init floppy_init(void)
...
@@ -4379,23 +4383,12 @@ int __init floppy_init(void)
disks
[
drive
]
->
private_data
=
(
void
*
)(
long
)
drive
;
disks
[
drive
]
->
private_data
=
(
void
*
)(
long
)
drive
;
disks
[
drive
]
->
queue
=
floppy_queue
;
disks
[
drive
]
->
queue
=
floppy_queue
;
disks
[
drive
]
->
flags
|=
GENHD_FL_REMOVABLE
;
disks
[
drive
]
->
flags
|=
GENHD_FL_REMOVABLE
;
disks
[
drive
]
->
driverfs_dev
=
&
floppy_device
.
dev
;
add_disk
(
disks
[
drive
]);
add_disk
(
disks
[
drive
]);
}
}
err
=
platform_device_register
(
&
floppy_device
);
if
(
err
)
goto
out_del_disk
;
return
0
;
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:
out_flush_work:
flush_scheduled_work
();
flush_scheduled_work
();
if
(
usage_count
)
if
(
usage_count
)
...
@@ -4600,7 +4593,6 @@ void cleanup_module(void)
...
@@ -4600,7 +4593,6 @@ void cleanup_module(void)
int
drive
;
int
drive
;
init_completion
(
&
device_release
);
init_completion
(
&
device_release
);
platform_device_unregister
(
&
floppy_device
);
blk_unregister_region
(
MKDEV
(
FLOPPY_MAJOR
,
0
),
256
);
blk_unregister_region
(
MKDEV
(
FLOPPY_MAJOR
,
0
),
256
);
unregister_blkdev
(
FLOPPY_MAJOR
,
"fd"
);
unregister_blkdev
(
FLOPPY_MAJOR
,
"fd"
);
...
@@ -4614,6 +4606,7 @@ void cleanup_module(void)
...
@@ -4614,6 +4606,7 @@ void cleanup_module(void)
}
}
put_disk
(
disks
[
drive
]);
put_disk
(
disks
[
drive
]);
}
}
platform_device_unregister
(
&
floppy_device
);
devfs_remove
(
"floppy"
);
devfs_remove
(
"floppy"
);
del_timer_sync
(
&
fd_timeout
);
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)
...
@@ -302,7 +302,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
static
int
__init
genhd_device_init
(
void
)
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
();
blk_dev_init
();
subsystem_register
(
&
block_subsys
);
subsystem_register
(
&
block_subsys
);
return
0
;
return
0
;
...
@@ -430,43 +430,58 @@ static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
...
@@ -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
,
static
int
block_hotplug
(
struct
kset
*
kset
,
struct
kobject
*
kobj
,
char
**
envp
,
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
{
{
struct
device
*
dev
=
NULL
;
struct
kobj_type
*
ktype
=
get_ktype
(
kobj
);
struct
kobj_type
*
ktype
=
get_ktype
(
kobj
);
struct
device
*
physdev
;
struct
gendisk
*
disk
;
struct
hd_struct
*
part
;
int
length
=
0
;
int
length
=
0
;
int
i
=
0
;
int
i
=
0
;
/* get physical device backing disk or partition */
if
(
ktype
==
&
ktype_block
)
{
if
(
ktype
==
&
ktype_block
)
{
struct
gendisk
*
disk
=
container_of
(
kobj
,
struct
gendisk
,
kobj
);
disk
=
container_of
(
kobj
,
struct
gendisk
,
kobj
);
dev
=
disk
->
driverfs_dev
;
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"MINOR=%u"
,
disk
->
first_minor
);
}
else
if
(
ktype
==
&
ktype_part
)
{
}
else
if
(
ktype
==
&
ktype_part
)
{
struct
gendisk
*
disk
=
container_of
(
kobj
->
parent
,
struct
gendisk
,
kobj
);
disk
=
container_of
(
kobj
->
parent
,
struct
gendisk
,
kobj
);
dev
=
disk
->
driverfs_dev
;
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_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
/* add physical device, backing this device */
"MAJOR=%u"
,
disk
->
major
);
char
*
path
=
kobject_get_path
(
&
dev
->
kobj
,
GFP_KERNEL
);
/* 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
,
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVPATH=%s"
,
path
);
&
length
,
"PHYSDEVPATH=%s"
,
path
);
kfree
(
path
);
kfree
(
path
);
/* add bus name of physical device */
if
(
physdev
->
bus
)
if
(
dev
->
bus
)
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVBUS=%s"
,
dev
->
bus
->
name
);
"PHYSDEVBUS=%s"
,
physdev
->
bus
->
name
);
/* add driver name of physical device */
if
(
physdev
->
driver
)
if
(
dev
->
driver
)
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
add_hotplug_env_var
(
envp
,
num_envp
,
&
i
,
buffer
,
buffer_size
,
&
length
,
buffer
,
buffer_size
,
&
length
,
"PHYSDEVDRIVER=%s"
,
dev
->
driver
->
name
);
"PHYSDEVDRIVER=%s"
,
physdev
->
driver
->
name
);
envp
[
i
]
=
NULL
;
}
}
/* 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
;
return
0
;
}
}
...
...
drivers/i2c/i2c-dev.c
View file @
0a983298
...
@@ -108,13 +108,6 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
...
@@ -108,13 +108,6 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
spin_unlock
(
&
i2c_dev_array_lock
);
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
)
static
ssize_t
show_adapter_name
(
struct
class_device
*
class_dev
,
char
*
buf
)
{
{
struct
i2c_dev
*
i2c_dev
=
to_i2c_dev
(
class_dev
);
struct
i2c_dev
*
i2c_dev
=
to_i2c_dev
(
class_dev
);
...
@@ -451,11 +444,11 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
...
@@ -451,11 +444,11 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
else
else
i2c_dev
->
class_dev
.
dev
=
adap
->
dev
.
parent
;
i2c_dev
->
class_dev
.
dev
=
adap
->
dev
.
parent
;
i2c_dev
->
class_dev
.
class
=
&
i2c_dev_class
;
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
);
snprintf
(
i2c_dev
->
class_dev
.
class_id
,
BUS_ID_SIZE
,
"i2c-%d"
,
i2c_dev
->
minor
);
retval
=
class_device_register
(
&
i2c_dev
->
class_dev
);
retval
=
class_device_register
(
&
i2c_dev
->
class_dev
);
if
(
retval
)
if
(
retval
)
goto
error
;
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
);
class_device_create_file
(
&
i2c_dev
->
class_dev
,
&
class_device_attr_name
);
return
0
;
return
0
;
error:
error:
...
...
drivers/media/video/videodev.c
View file @
0a983298
...
@@ -46,15 +46,7 @@ static ssize_t show_name(struct class_device *cd, char *buf)
...
@@ -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
);
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
(
name
,
S_IRUGO
,
show_name
,
NULL
);
static
CLASS_DEVICE_ATTR
(
dev
,
S_IRUGO
,
show_dev
,
NULL
);
struct
video_device
*
video_device_alloc
(
void
)
struct
video_device
*
video_device_alloc
(
void
)
{
{
...
@@ -347,12 +339,11 @@ int video_register_device(struct video_device *vfd, int type, int nr)
...
@@ -347,12 +339,11 @@ int video_register_device(struct video_device *vfd, int type, int nr)
if
(
vfd
->
dev
)
if
(
vfd
->
dev
)
vfd
->
class_dev
.
dev
=
vfd
->
dev
;
vfd
->
class_dev
.
dev
=
vfd
->
dev
;
vfd
->
class_dev
.
class
=
&
video_class
;
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
);
strlcpy
(
vfd
->
class_dev
.
class_id
,
vfd
->
devfs_name
+
4
,
BUS_ID_SIZE
);
class_device_register
(
&
vfd
->
class_dev
);
class_device_register
(
&
vfd
->
class_dev
);
class_device_create_file
(
&
vfd
->
class_dev
,
class_device_create_file
(
&
vfd
->
class_dev
,
&
class_device_attr_name
);
&
class_device_attr_name
);
class_device_create_file
(
&
vfd
->
class_dev
,
&
class_device_attr_dev
);
#if 1
/* needed until all drivers are fixed */
#if 1
/* needed until all drivers are fixed */
if
(
!
vfd
->
release
)
if
(
!
vfd
->
release
)
...
...
drivers/usb/core/file.c
View file @
0a983298
...
@@ -66,16 +66,7 @@ static struct file_operations usb_fops = {
...
@@ -66,16 +66,7 @@ static struct file_operations usb_fops = {
.
open
=
usb_open
,
.
open
=
usb_open
,
};
};
static
void
release_usb_class_dev
(
struct
class_device
*
class_dev
)
static
struct
class_simple
*
usb_class
;
{
dbg
(
"%s - %s"
,
__FUNCTION__
,
class_dev
->
class_id
);
kfree
(
class_dev
);
}
static
struct
class
usb_class
=
{
.
name
=
"usb"
,
.
release
=
&
release_usb_class_dev
,
};
int
usb_major_init
(
void
)
int
usb_major_init
(
void
)
{
{
...
@@ -87,9 +78,9 @@ int usb_major_init(void)
...
@@ -87,9 +78,9 @@ int usb_major_init(void)
goto
out
;
goto
out
;
}
}
error
=
class_register
(
&
usb_class
);
usb_class
=
class_simple_create
(
THIS_MODULE
,
"usb"
);
if
(
error
)
{
if
(
IS_ERR
(
usb_class
)
)
{
err
(
"class_
register
failed for usb devices"
);
err
(
"class_
simple_create
failed for usb devices"
);
unregister_chrdev
(
USB_MAJOR
,
"usb"
);
unregister_chrdev
(
USB_MAJOR
,
"usb"
);
goto
out
;
goto
out
;
}
}
...
@@ -102,18 +93,11 @@ int usb_major_init(void)
...
@@ -102,18 +93,11 @@ int usb_major_init(void)
void
usb_major_cleanup
(
void
)
void
usb_major_cleanup
(
void
)
{
{
class_
unregister
(
&
usb_class
);
class_
simple_destroy
(
usb_class
);
devfs_remove
(
"usb"
);
devfs_remove
(
"usb"
);
unregister_chrdev
(
USB_MAJOR
,
"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
* usb_register_dev - register a USB device, and ask for a minor number
* @intf: pointer to the usb_interface that is being registered
* @intf: pointer to the usb_interface that is being registered
...
@@ -141,7 +125,6 @@ int usb_register_dev(struct usb_interface *intf,
...
@@ -141,7 +125,6 @@ int usb_register_dev(struct usb_interface *intf,
int
minor_base
=
class_driver
->
minor_base
;
int
minor_base
=
class_driver
->
minor_base
;
int
minor
=
0
;
int
minor
=
0
;
char
name
[
BUS_ID_SIZE
];
char
name
[
BUS_ID_SIZE
];
struct
class_device
*
class_dev
;
char
*
temp
;
char
*
temp
;
#ifdef CONFIG_USB_DYNAMIC_MINORS
#ifdef CONFIG_USB_DYNAMIC_MINORS
...
@@ -181,22 +164,18 @@ int usb_register_dev(struct usb_interface *intf,
...
@@ -181,22 +164,18 @@ int usb_register_dev(struct usb_interface *intf,
devfs_mk_cdev
(
MKDEV
(
USB_MAJOR
,
minor
),
class_driver
->
mode
,
name
);
devfs_mk_cdev
(
MKDEV
(
USB_MAJOR
,
minor
),
class_driver
->
mode
,
name
);
/* create a usb class device for this usb interface */
/* create a usb class device for this usb interface */
class_dev
=
kmalloc
(
sizeof
(
*
class_dev
),
GFP_KERNEL
);
temp
=
strrchr
(
name
,
'/'
);
if
(
class_dev
)
{
if
(
temp
&&
(
temp
[
1
]
!=
0x00
))
memset
(
class_dev
,
0x00
,
sizeof
(
struct
class_device
));
++
temp
;
class_dev
->
class
=
&
usb_class
;
else
class_dev
->
dev
=
&
intf
->
dev
;
temp
=
name
;
intf
->
class_dev
=
class_simple_device_add
(
usb_class
,
MKDEV
(
USB_MAJOR
,
minor
),
&
intf
->
dev
,
"%s"
,
temp
);
temp
=
strrchr
(
name
,
'/'
);
if
(
IS_ERR
(
intf
->
class_dev
))
{
if
(
temp
&&
(
temp
[
1
]
!=
0x00
))
spin_lock
(
&
minor_lock
);
++
temp
;
usb_minors
[
intf
->
minor
]
=
NULL
;
else
spin_unlock
(
&
minor_lock
);
temp
=
name
;
devfs_remove
(
name
);
snprintf
(
class_dev
->
class_id
,
BUS_ID_SIZE
,
"%s"
,
temp
);
retval
=
PTR_ERR
(
intf
->
class_dev
);
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
;
}
}
exit:
exit:
return
retval
;
return
retval
;
...
@@ -239,11 +218,8 @@ void usb_deregister_dev(struct usb_interface *intf,
...
@@ -239,11 +218,8 @@ void usb_deregister_dev(struct usb_interface *intf,
snprintf
(
name
,
BUS_ID_SIZE
,
class_driver
->
name
,
intf
->
minor
-
minor_base
);
snprintf
(
name
,
BUS_ID_SIZE
,
class_driver
->
name
,
intf
->
minor
-
minor_base
);
devfs_remove
(
name
);
devfs_remove
(
name
);
class_simple_device_remove
(
MKDEV
(
USB_MAJOR
,
intf
->
minor
));
if
(
intf
->
class_dev
)
{
intf
->
class_dev
=
NULL
;
class_device_unregister
(
intf
->
class_dev
);
intf
->
class_dev
=
NULL
;
}
intf
->
minor
=
-
1
;
intf
->
minor
=
-
1
;
}
}
EXPORT_SYMBOL
(
usb_deregister_dev
);
EXPORT_SYMBOL
(
usb_deregister_dev
);
...
...
fs/char_dev.c
View file @
0a983298
...
@@ -29,7 +29,7 @@ static struct kobj_map *cdev_map;
...
@@ -29,7 +29,7 @@ static struct kobj_map *cdev_map;
/* degrade to linked list for small systems */
/* degrade to linked list for small systems */
#define MAX_PROBE_HASH (CONFIG_BASE_SMALL ? 1 : 255)
#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
{
static
struct
char_device_struct
{
struct
char_device_struct
*
next
;
struct
char_device_struct
*
next
;
...
@@ -55,13 +55,13 @@ int get_chrdev_list(char *page)
...
@@ -55,13 +55,13 @@ int get_chrdev_list(char *page)
len
=
sprintf
(
page
,
"Character devices:
\n
"
);
len
=
sprintf
(
page
,
"Character devices:
\n
"
);
read_lock
(
&
chrdevs_lock
);
down
(
&
chrdevs_lock
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
chrdevs
)
;
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
chrdevs
)
;
i
++
)
{
for
(
cd
=
chrdevs
[
i
];
cd
;
cd
=
cd
->
next
)
for
(
cd
=
chrdevs
[
i
];
cd
;
cd
=
cd
->
next
)
len
+=
sprintf
(
page
+
len
,
"%3d %s
\n
"
,
len
+=
sprintf
(
page
+
len
,
"%3d %s
\n
"
,
cd
->
major
,
cd
->
name
);
cd
->
major
,
cd
->
name
);
}
}
read_unlock
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
return
len
;
return
len
;
}
}
...
@@ -91,7 +91,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
...
@@ -91,7 +91,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
memset
(
cd
,
0
,
sizeof
(
struct
char_device_struct
));
memset
(
cd
,
0
,
sizeof
(
struct
char_device_struct
));
write_lock_irq
(
&
chrdevs_lock
);
down
(
&
chrdevs_lock
);
/* temporary */
/* temporary */
if
(
major
==
0
)
{
if
(
major
==
0
)
{
...
@@ -126,10 +126,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
...
@@ -126,10 +126,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
}
}
cd
->
next
=
*
cp
;
cd
->
next
=
*
cp
;
*
cp
=
cd
;
*
cp
=
cd
;
write_unlock_irq
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
return
cd
;
return
cd
;
out:
out:
write_unlock_irq
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
kfree
(
cd
);
kfree
(
cd
);
return
ERR_PTR
(
ret
);
return
ERR_PTR
(
ret
);
}
}
...
@@ -140,7 +140,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
...
@@ -140,7 +140,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
struct
char_device_struct
*
cd
=
NULL
,
**
cp
;
struct
char_device_struct
*
cd
=
NULL
,
**
cp
;
int
i
=
major_to_index
(
major
);
int
i
=
major_to_index
(
major
);
write_lock_irq
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
for
(
cp
=
&
chrdevs
[
i
];
*
cp
;
cp
=
&
(
*
cp
)
->
next
)
for
(
cp
=
&
chrdevs
[
i
];
*
cp
;
cp
=
&
(
*
cp
)
->
next
)
if
((
*
cp
)
->
major
==
major
&&
if
((
*
cp
)
->
major
==
major
&&
(
*
cp
)
->
baseminor
==
baseminor
&&
(
*
cp
)
->
baseminor
==
baseminor
&&
...
@@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
...
@@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
cd
=
*
cp
;
cd
=
*
cp
;
*
cp
=
cd
->
next
;
*
cp
=
cd
->
next
;
}
}
write_unlock_irq
(
&
chrdevs_lock
);
up
(
&
chrdevs_lock
);
return
cd
;
return
cd
;
}
}
...
@@ -381,8 +381,6 @@ void cdev_del(struct cdev *p)
...
@@ -381,8 +381,6 @@ void cdev_del(struct cdev *p)
}
}
static
decl_subsys
(
cdev
,
NULL
,
NULL
);
static
void
cdev_default_release
(
struct
kobject
*
kobj
)
static
void
cdev_default_release
(
struct
kobject
*
kobj
)
{
{
struct
cdev
*
p
=
container_of
(
kobj
,
struct
cdev
,
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)
...
@@ -435,13 +433,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
void
__init
chrdev_init
(
void
)
void
__init
chrdev_init
(
void
)
{
{
/*
cdev_map
=
kobj_map_init
(
base_probe
,
&
chrdevs_lock
);
* 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
);
}
}
...
...
include/linux/device.h
View file @
0a983298
...
@@ -15,7 +15,6 @@
...
@@ -15,7 +15,6 @@
#include <linux/ioport.h>
#include <linux/ioport.h>
#include <linux/kobject.h>
#include <linux/kobject.h>
#include <linux/list.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/pm.h>
...
@@ -102,7 +101,7 @@ struct device_driver {
...
@@ -102,7 +101,7 @@ struct device_driver {
char
*
name
;
char
*
name
;
struct
bus_type
*
bus
;
struct
bus_type
*
bus
;
struct
semaphore
unload_sem
;
struct
completion
unloaded
;
struct
kobject
kobj
;
struct
kobject
kobj
;
struct
list_head
devices
;
struct
list_head
devices
;
...
@@ -148,6 +147,7 @@ struct class {
...
@@ -148,6 +147,7 @@ struct class {
struct
subsystem
subsys
;
struct
subsystem
subsys
;
struct
list_head
children
;
struct
list_head
children
;
struct
list_head
interfaces
;
struct
list_head
interfaces
;
struct
semaphore
sem
;
/* locks both the children and interfaces lists */
struct
class_attribute
*
class_attrs
;
struct
class_attribute
*
class_attrs
;
struct
class_device_attribute
*
class_dev_attrs
;
struct
class_device_attribute
*
class_dev_attrs
;
...
@@ -184,6 +184,7 @@ struct class_device {
...
@@ -184,6 +184,7 @@ struct class_device {
struct
kobject
kobj
;
struct
kobject
kobj
;
struct
class
*
class
;
/* required */
struct
class
*
class
;
/* required */
dev_t
devt
;
/* dev_t, creates the sysfs "dev" */
struct
device
*
dev
;
/* not necessary, but nice to have */
struct
device
*
dev
;
/* not necessary, but nice to have */
void
*
class_data
;
/* class-specific data */
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 *,
...
@@ -7,6 +7,6 @@ int kobj_map(struct kobj_map *, dev_t, unsigned long, struct module *,
kobj_probe_t
*
,
int
(
*
)(
dev_t
,
void
*
),
void
*
);
kobj_probe_t
*
,
int
(
*
)(
dev_t
,
void
*
),
void
*
);
void
kobj_unmap
(
struct
kobj_map
*
,
dev_t
,
unsigned
long
);
void
kobj_unmap
(
struct
kobj_map
*
,
dev_t
,
unsigned
long
);
struct
kobject
*
kobj_lookup
(
struct
kobj_map
*
,
dev_t
,
int
*
);
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
#endif
include/linux/kobject.h
View file @
0a983298
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/list.h>
#include <linux/sysfs.h>
#include <linux/sysfs.h>
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/rwsem.h>
#include <linux/kref.h>
#include <linux/kref.h>
#include <linux/kobject_uevent.h>
#include <linux/kobject_uevent.h>
...
@@ -102,6 +103,7 @@ struct kset {
...
@@ -102,6 +103,7 @@ struct kset {
struct
subsystem
*
subsys
;
struct
subsystem
*
subsys
;
struct
kobj_type
*
ktype
;
struct
kobj_type
*
ktype
;
struct
list_head
list
;
struct
list_head
list
;
spinlock_t
list_lock
;
struct
kobject
kobj
;
struct
kobject
kobj
;
struct
kset_hotplug_ops
*
hotplug_ops
;
struct
kset_hotplug_ops
*
hotplug_ops
;
};
};
...
...
include/linux/kref.h
View file @
0a983298
...
@@ -26,7 +26,7 @@ struct kref {
...
@@ -26,7 +26,7 @@ struct kref {
void
kref_init
(
struct
kref
*
kref
);
void
kref_init
(
struct
kref
*
kref
);
void
kref_get
(
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
/* __KERNEL__ */
#endif
/* _KREF_H_ */
#endif
/* _KREF_H_ */
lib/kobject.c
View file @
0a983298
...
@@ -140,9 +140,9 @@ void kobject_init(struct kobject * kobj)
...
@@ -140,9 +140,9 @@ void kobject_init(struct kobject * kobj)
static
void
unlink
(
struct
kobject
*
kobj
)
static
void
unlink
(
struct
kobject
*
kobj
)
{
{
if
(
kobj
->
kset
)
{
if
(
kobj
->
kset
)
{
down_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
spin_lock
(
&
kobj
->
kset
->
list_lock
);
list_del_init
(
&
kobj
->
entry
);
list_del_init
(
&
kobj
->
entry
);
up_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
spin_unlock
(
&
kobj
->
kset
->
list_lock
);
}
}
kobject_put
(
kobj
);
kobject_put
(
kobj
);
}
}
...
@@ -168,13 +168,13 @@ int kobject_add(struct kobject * kobj)
...
@@ -168,13 +168,13 @@ int kobject_add(struct kobject * kobj)
kobj
->
kset
?
kobj
->
kset
->
kobj
.
name
:
"<NULL>"
);
kobj
->
kset
?
kobj
->
kset
->
kobj
.
name
:
"<NULL>"
);
if
(
kobj
->
kset
)
{
if
(
kobj
->
kset
)
{
down_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
spin_lock
(
&
kobj
->
kset
->
list_lock
);
if
(
!
parent
)
if
(
!
parent
)
parent
=
kobject_get
(
&
kobj
->
kset
->
kobj
);
parent
=
kobject_get
(
&
kobj
->
kset
->
kobj
);
list_add_tail
(
&
kobj
->
entry
,
&
kobj
->
kset
->
list
);
list_add_tail
(
&
kobj
->
entry
,
&
kobj
->
kset
->
list
);
up_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
spin_unlock
(
&
kobj
->
kset
->
list_lock
);
}
}
kobj
->
parent
=
parent
;
kobj
->
parent
=
parent
;
...
@@ -380,6 +380,7 @@ void kset_init(struct kset * k)
...
@@ -380,6 +380,7 @@ void kset_init(struct kset * k)
{
{
kobject_init
(
&
k
->
kobj
);
kobject_init
(
&
k
->
kobj
);
INIT_LIST_HEAD
(
&
k
->
list
);
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)
...
@@ -444,7 +445,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name)
struct
list_head
*
entry
;
struct
list_head
*
entry
;
struct
kobject
*
ret
=
NULL
;
struct
kobject
*
ret
=
NULL
;
down_read
(
&
kset
->
subsys
->
rwsem
);
spin_lock
(
&
kset
->
list_lock
);
list_for_each
(
entry
,
&
kset
->
list
)
{
list_for_each
(
entry
,
&
kset
->
list
)
{
struct
kobject
*
k
=
to_kobj
(
entry
);
struct
kobject
*
k
=
to_kobj
(
entry
);
if
(
kobject_name
(
k
)
&&
!
strcmp
(
kobject_name
(
k
),
name
))
{
if
(
kobject_name
(
k
)
&&
!
strcmp
(
kobject_name
(
k
),
name
))
{
...
@@ -452,7 +453,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name)
...
@@ -452,7 +453,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name)
break
;
break
;
}
}
}
}
up_read
(
&
kset
->
subsys
->
rwsem
);
spin_unlock
(
&
kset
->
list_lock
);
return
ret
;
return
ret
;
}
}
...
@@ -524,7 +525,6 @@ void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
...
@@ -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_init
);
EXPORT_SYMBOL
(
kobject_register
);
EXPORT_SYMBOL
(
kobject_register
);
EXPORT_SYMBOL
(
kobject_unregister
);
EXPORT_SYMBOL
(
kobject_unregister
);
...
@@ -532,7 +532,6 @@ EXPORT_SYMBOL(kobject_get);
...
@@ -532,7 +532,6 @@ EXPORT_SYMBOL(kobject_get);
EXPORT_SYMBOL
(
kobject_put
);
EXPORT_SYMBOL
(
kobject_put
);
EXPORT_SYMBOL
(
kobject_add
);
EXPORT_SYMBOL
(
kobject_add
);
EXPORT_SYMBOL
(
kobject_del
);
EXPORT_SYMBOL
(
kobject_del
);
EXPORT_SYMBOL
(
kobject_rename
);
EXPORT_SYMBOL
(
kset_register
);
EXPORT_SYMBOL
(
kset_register
);
EXPORT_SYMBOL
(
kset_unregister
);
EXPORT_SYMBOL
(
kset_unregister
);
...
...
lib/kref.c
View file @
0a983298
...
@@ -42,14 +42,21 @@ void kref_get(struct kref *kref)
...
@@ -42,14 +42,21 @@ void kref_get(struct kref *kref)
* in as this function.
* in as this function.
*
*
* Decrement the refcount, and if 0, call release().
* 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
==
NULL
);
WARN_ON
(
release
==
(
void
(
*
)(
struct
kref
*
))
kfree
);
WARN_ON
(
release
==
(
void
(
*
)(
struct
kref
*
))
kfree
);
if
(
atomic_dec_and_test
(
&
kref
->
refcount
))
if
(
atomic_dec_and_test
(
&
kref
->
refcount
))
{
release
(
kref
);
release
(
kref
);
return
1
;
}
return
0
;
}
}
EXPORT_SYMBOL
(
kref_init
);
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