Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
76044a7f
Commit
76044a7f
authored
Aug 13, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://ldm.bkbits.net/linux-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
d001e08a
4446b906
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
199 additions
and
223 deletions
+199
-223
Documentation/filesystems/driverfs.txt
Documentation/filesystems/driverfs.txt
+4
-4
drivers/base/base.h
drivers/base/base.h
+2
-0
drivers/base/bus.c
drivers/base/bus.c
+46
-51
drivers/base/core.c
drivers/base/core.c
+56
-56
drivers/base/driver.c
drivers/base/driver.c
+23
-30
drivers/base/interface.c
drivers/base/interface.c
+2
-2
drivers/base/power.c
drivers/base/power.c
+41
-51
drivers/pci/proc.c
drivers/pci/proc.c
+2
-2
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_scan.c
+1
-1
drivers/scsi/sg.c
drivers/scsi/sg.c
+2
-2
drivers/scsi/sr.c
drivers/scsi/sr.c
+2
-2
drivers/scsi/st.c
drivers/scsi/st.c
+2
-2
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+6
-6
fs/partitions/check.c
fs/partitions/check.c
+2
-2
include/linux/device.h
include/linux/device.h
+8
-12
No files found.
Documentation/filesystems/driverfs.txt
View file @
76044a7f
...
...
@@ -165,9 +165,9 @@ Note that there is a struct attribute embedded in the structure. In
order to relieve pain in declaring attributes, the subsystem should
also define a macro, like:
#define DEVICE_ATTR(_name,_
str,_
mode,_show,_store) \
#define DEVICE_ATTR(_name,_mode,_show,_store) \
struct device_attribute dev_attr_##_name = { \
.attr = {.name = _
str
, .mode = _mode }, \
.attr = {.name = _
_stringify(_name)
, .mode = _mode }, \
.show = _show, \
.store = _store, \
};
...
...
@@ -252,7 +252,7 @@ struct bus_attribute {
Declaring:
BUS_ATTR(_name,_
str,_
mode,_show,_store)
BUS_ATTR(_name,_mode,_show,_store)
Creation/Removal:
...
...
@@ -273,7 +273,7 @@ struct driver_attribute {
Declaring:
DRIVER_ATTR(_name,_
str,_
mode,_show,_store)
DRIVER_ATTR(_name,_mode,_show,_store)
Creation/Removal:
...
...
drivers/base/base.h
View file @
76044a7f
...
...
@@ -9,6 +9,8 @@
extern
struct
device
device_root
;
extern
spinlock_t
device_lock
;
extern
struct
device
*
get_device_locked
(
struct
device
*
);
extern
int
bus_add_device
(
struct
device
*
dev
);
extern
void
bus_remove_device
(
struct
device
*
dev
);
...
...
drivers/base/bus.c
View file @
76044a7f
...
...
@@ -16,6 +16,9 @@
static
LIST_HEAD
(
bus_driver_list
);
#define to_dev(node) container_of(node,struct device,bus_list)
#define to_drv(node) container_of(node,struct device_driver,bus_list)
/**
* bus_for_each_dev - walk list of devices and do something to each
* @bus: bus in question
...
...
@@ -26,42 +29,41 @@ static LIST_HEAD(bus_driver_list);
* counting on devices as we touch each one.
*
* Algorithm:
* Take the bus lock and get the first node in the list. We increment
* the reference count and unlock the bus. If we have a device from a
* previous iteration, we decrement the reference count.
* After we call the callback, we get the next node in the list and loop.
* At the end, if @dev is not null, we still have it pinned, so we need
* to let it go.
* Take device_lock and get the first node in the list.
* Try and increment the reference count on it. If we can't, it's in the
* process of being removed, but that process hasn't acquired device_lock.
* It's still in the list, so we grab the next node and try that one.
* We drop the lock to call the callback.
* We can't decrement the reference count yet, because we need the next
* node in the list. So, we set @prev to point to the current device.
* On the next go-round, we decrement the reference count on @prev, so if
* it's being removed, it won't affect us.
*/
int
bus_for_each_dev
(
struct
bus_type
*
bus
,
void
*
data
,
int
(
*
callback
)(
struct
device
*
dev
,
void
*
data
))
{
struct
device
*
next
;
struct
device
*
dev
=
NULL
;
struct
list_head
*
node
;
struct
device
*
prev
=
NULL
;
int
error
=
0
;
get_bus
(
bus
);
read_lock
(
&
bus
->
lock
);
node
=
bus
->
devices
.
next
;
while
(
node
!=
&
bus
->
devices
)
{
next
=
list_entry
(
node
,
struct
device
,
bus_list
);
get_device
(
next
);
read_unlock
(
&
bus
->
lock
);
if
(
dev
)
put_device
(
dev
);
dev
=
next
;
if
((
error
=
callback
(
dev
,
data
)))
{
put_device
(
dev
);
spin_lock
(
&
device_lock
);
list_for_each
(
node
,
&
bus
->
devices
)
{
struct
device
*
dev
=
get_device_locked
(
to_dev
(
node
));
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
error
=
callback
(
dev
,
data
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
spin_lock
(
&
device_lock
);
if
(
error
)
break
;
}
read_lock
(
&
bus
->
lock
);
node
=
dev
->
bus_list
.
next
;
}
read_unlock
(
&
bus
->
lock
);
if
(
d
ev
)
put_device
(
d
ev
);
spin_unlock
(
&
device_
lock
);
if
(
pr
ev
)
put_device
(
pr
ev
);
put_bus
(
bus
);
return
error
;
}
...
...
@@ -69,34 +71,30 @@ int bus_for_each_dev(struct bus_type * bus, void * data,
int
bus_for_each_drv
(
struct
bus_type
*
bus
,
void
*
data
,
int
(
*
callback
)(
struct
device_driver
*
drv
,
void
*
data
))
{
struct
device_driver
*
next
;
struct
device_driver
*
drv
=
NULL
;
struct
list_head
*
node
;
struct
device_driver
*
prev
=
NULL
;
int
error
=
0
;
/* pin bus in memory */
get_bus
(
bus
);
read_lock
(
&
bus
->
lock
);
node
=
bus
->
drivers
.
next
;
while
(
node
!=
&
bus
->
drivers
)
{
next
=
list_entry
(
node
,
struct
device_driver
,
bus_list
);
get_driver
(
next
);
read_unlock
(
&
bus
->
lock
);
if
(
drv
)
put_driver
(
drv
);
drv
=
next
;
if
((
error
=
callback
(
drv
,
data
)))
{
put_driver
(
drv
);
spin_lock
(
&
device_lock
);
list_for_each
(
node
,
&
bus
->
drivers
)
{
struct
device_driver
*
drv
=
get_driver
(
to_drv
(
node
));
if
(
drv
)
{
spin_unlock
(
&
device_lock
);
error
=
callback
(
drv
,
data
);
if
(
prev
)
put_driver
(
prev
);
prev
=
drv
;
spin_lock
(
&
device_lock
);
if
(
error
)
break
;
}
read_lock
(
&
bus
->
lock
);
node
=
drv
->
bus_list
.
next
;
}
read_unlock
(
&
bus
->
lock
);
if
(
dr
v
)
put_driver
(
dr
v
);
spin_unlock
(
&
device_
lock
);
if
(
pre
v
)
put_driver
(
pre
v
);
put_bus
(
bus
);
return
error
;
}
...
...
@@ -115,9 +113,9 @@ int bus_add_device(struct device * dev)
if
(
dev
->
bus
)
{
pr_debug
(
"registering %s with bus '%s'
\n
"
,
dev
->
bus_id
,
dev
->
bus
->
name
);
get_bus
(
dev
->
bus
);
write_lock
(
&
dev
->
bus
->
lock
);
spin_lock
(
&
device_
lock
);
list_add_tail
(
&
dev
->
bus_list
,
&
dev
->
bus
->
devices
);
write_unlock
(
&
dev
->
bus
->
lock
);
spin_unlock
(
&
device_
lock
);
device_bus_link
(
dev
);
}
return
0
;
...
...
@@ -134,9 +132,6 @@ void bus_remove_device(struct device * dev)
{
if
(
dev
->
bus
)
{
device_remove_symlink
(
&
dev
->
bus
->
device_dir
,
dev
->
bus_id
);
write_lock
(
&
dev
->
bus
->
lock
);
list_del_init
(
&
dev
->
bus_list
);
write_unlock
(
&
dev
->
bus
->
lock
);
put_bus
(
dev
->
bus
);
}
}
...
...
drivers/base/core.c
View file @
76044a7f
...
...
@@ -25,6 +25,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
spinlock_t
device_lock
=
SPIN_LOCK_UNLOCKED
;
#define to_dev(node) container_of(node,struct device,driver_list)
/**
* found_match - do actual binding of device to driver
...
...
@@ -53,9 +55,9 @@ static int found_match(struct device * dev, struct device_driver * drv)
pr_debug
(
"bound device '%s' to driver '%s'
\n
"
,
dev
->
bus_id
,
drv
->
name
);
write_lock
(
&
drv
->
lock
);
spin_lock
(
&
device_
lock
);
list_add_tail
(
&
dev
->
driver_list
,
&
drv
->
devices
);
write_unlock
(
&
drv
->
lock
);
spin_unlock
(
&
device_
lock
);
goto
Done
;
...
...
@@ -101,19 +103,14 @@ static void device_detach(struct device * dev)
struct
device_driver
*
drv
;
if
(
dev
->
driver
)
{
lock_device
(
dev
);
spin_lock
(
&
device_lock
);
drv
=
dev
->
driver
;
dev
->
driver
=
NULL
;
unlock_device
(
dev
);
write_lock
(
&
drv
->
lock
);
list_del_init
(
&
dev
->
driver_list
);
write_unlock
(
&
drv
->
lock
);
spin_unlock
(
&
device_lock
);
/* detach from driver */
if
(
drv
->
remove
)
if
(
drv
&&
drv
->
remove
)
drv
->
remove
(
dev
);
put_driver
(
drv
);
}
}
...
...
@@ -134,47 +131,26 @@ int driver_attach(struct device_driver * drv)
return
bus_for_each_dev
(
drv
->
bus
,
drv
,
do_driver_attach
);
}
static
int
do_driver_detach
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
lock_device
(
dev
);
if
(
dev
->
driver
==
drv
)
{
dev
->
driver
=
NULL
;
unlock_device
(
dev
);
if
(
drv
->
remove
)
drv
->
remove
(
dev
);
}
else
unlock_device
(
dev
);
return
0
;
}
void
driver_detach
(
struct
device_driver
*
drv
)
{
struct
device
*
next
;
struct
device
*
dev
=
NULL
;
struct
list_head
*
node
;
int
error
=
0
;
write_lock
(
&
drv
->
lock
);
node
=
drv
->
devices
.
next
;
while
(
node
!=
&
drv
->
devices
)
{
next
=
list_entry
(
node
,
struct
device
,
driver_list
);
get_device
(
next
);
list_del_init
(
&
next
->
driver_list
);
write_unlock
(
&
drv
->
lock
);
struct
device
*
prev
=
NULL
;
if
(
dev
)
put_device
(
dev
);
dev
=
next
;
if
((
error
=
do_driver_detach
(
dev
,
drv
)))
{
put_device
(
dev
);
break
;
spin_lock
(
&
device_lock
);
list_for_each
(
node
,
&
drv
->
devices
)
{
struct
device
*
dev
=
get_device_locked
(
to_dev
(
node
));
if
(
dev
)
{
if
(
prev
)
list_del_init
(
&
prev
->
driver_list
);
spin_unlock
(
&
device_lock
);
device_detach
(
dev
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
spin_lock
(
&
device_lock
);
}
write_lock
(
&
drv
->
lock
);
node
=
drv
->
devices
.
next
;
}
write_unlock
(
&
drv
->
lock
);
if
(
dev
)
put_device
(
dev
);
spin_unlock
(
&
device_lock
);
}
/**
...
...
@@ -191,7 +167,6 @@ void driver_detach(struct device_driver * drv)
int
device_register
(
struct
device
*
dev
)
{
int
error
;
struct
device
*
prev_dev
;
if
(
!
dev
||
!
strlen
(
dev
->
bus_id
))
return
-
EINVAL
;
...
...
@@ -199,24 +174,21 @@ int device_register(struct device *dev)
INIT_LIST_HEAD
(
&
dev
->
node
);
INIT_LIST_HEAD
(
&
dev
->
children
);
INIT_LIST_HEAD
(
&
dev
->
g_list
);
INIT_LIST_HEAD
(
&
dev
->
driver_list
);
INIT_LIST_HEAD
(
&
dev
->
bus_list
);
spin_lock_init
(
&
dev
->
lock
);
atomic_set
(
&
dev
->
refcount
,
2
);
spin_lock
(
&
device_lock
);
if
(
dev
!=
&
device_root
)
{
if
(
!
dev
->
parent
)
dev
->
parent
=
&
device_root
;
get_device
(
dev
->
parent
);
if
(
list_empty
(
&
dev
->
parent
->
children
))
prev_dev
=
dev
->
parent
;
else
prev_dev
=
list_entry
(
dev
->
parent
->
children
.
prev
,
struct
device
,
node
);
list_add
(
&
dev
->
g_list
,
&
prev_dev
->
g_list
);
spin_lock
(
&
device_lock
);
list_add_tail
(
&
dev
->
g_list
,
&
dev
->
parent
->
g_list
);
list_add_tail
(
&
dev
->
node
,
&
dev
->
parent
->
children
);
}
spin_unlock
(
&
device_lock
);
}
pr_debug
(
"DEV: registering device: ID = '%s', name = %s
\n
"
,
dev
->
bus_id
,
dev
->
name
);
...
...
@@ -234,12 +206,37 @@ int device_register(struct device *dev)
platform_notify
(
dev
);
register_done:
put_device
(
dev
);
if
(
error
&&
dev
->
parent
)
if
(
error
)
{
spin_lock
(
&
device_lock
);
list_del_init
(
&
dev
->
g_list
);
list_del_init
(
&
dev
->
node
);
spin_unlock
(
&
device_lock
);
if
(
dev
->
parent
)
put_device
(
dev
->
parent
);
}
put_device
(
dev
);
return
error
;
}
struct
device
*
get_device_locked
(
struct
device
*
dev
)
{
struct
device
*
ret
=
dev
;
if
(
dev
&&
atomic_read
(
&
dev
->
refcount
)
>
0
)
atomic_inc
(
&
dev
->
refcount
);
else
ret
=
NULL
;
return
ret
;
}
struct
device
*
get_device
(
struct
device
*
dev
)
{
struct
device
*
ret
;
spin_lock
(
&
device_lock
);
ret
=
get_device_locked
(
dev
);
spin_unlock
(
&
device_lock
);
return
ret
;
}
/**
* put_device - decrement reference count, and clean up when it hits 0
* @dev: device in question
...
...
@@ -250,6 +247,8 @@ void put_device(struct device * dev)
return
;
list_del_init
(
&
dev
->
node
);
list_del_init
(
&
dev
->
g_list
);
list_del_init
(
&
dev
->
bus_list
);
list_del_init
(
&
dev
->
driver_list
);
spin_unlock
(
&
device_lock
);
pr_debug
(
"DEV: Unregistering device. ID = '%s', name = '%s'
\n
"
,
...
...
@@ -296,4 +295,5 @@ static int __init device_init(void)
core_initcall
(
device_init
);
EXPORT_SYMBOL
(
device_register
);
EXPORT_SYMBOL
(
get_device
);
EXPORT_SYMBOL
(
put_device
);
drivers/base/driver.c
View file @
76044a7f
...
...
@@ -10,35 +10,31 @@
#include <linux/errno.h>
#include "base.h"
#define to_dev(node) container_of(node,struct device,driver_list)
int
driver_for_each_dev
(
struct
device_driver
*
drv
,
void
*
data
,
int
(
*
callback
)(
struct
device
*
,
void
*
))
int
driver_for_each_dev
(
struct
device_driver
*
drv
,
void
*
data
,
int
(
*
callback
)(
struct
device
*
,
void
*
))
{
struct
device
*
next
;
struct
device
*
dev
=
NULL
;
struct
list_head
*
node
;
struct
device
*
prev
=
NULL
;
int
error
=
0
;
get_driver
(
drv
);
read_lock
(
&
drv
->
lock
);
node
=
drv
->
devices
.
next
;
while
(
node
!=
&
drv
->
devices
)
{
next
=
list_entry
(
node
,
struct
device
,
driver_list
);
get_device
(
next
);
read_unlock
(
&
drv
->
lock
);
if
(
dev
)
put_device
(
dev
);
dev
=
next
;
if
((
error
=
callback
(
dev
,
data
)))
{
put_device
(
dev
);
spin_lock
(
&
device_lock
);
list_for_each
(
node
,
&
drv
->
devices
)
{
struct
device
*
dev
=
get_device_locked
(
to_dev
(
node
));
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
error
=
callback
(
dev
,
data
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
spin_lock
(
&
device_lock
);
if
(
error
)
break
;
}
read_lock
(
&
drv
->
lock
);
node
=
dev
->
driver_list
.
next
;
}
read_unlock
(
&
drv
->
lock
);
if
(
dev
)
put_device
(
dev
);
spin_unlock
(
&
device_lock
);
put_driver
(
drv
);
return
error
;
}
...
...
@@ -60,9 +56,9 @@ int driver_register(struct device_driver * drv)
atomic_set
(
&
drv
->
refcount
,
2
);
rwlock_init
(
&
drv
->
lock
);
INIT_LIST_HEAD
(
&
drv
->
devices
);
write_lock
(
&
drv
->
bus
->
lock
);
spin_lock
(
&
device_
lock
);
list_add
(
&
drv
->
bus_list
,
&
drv
->
bus
->
drivers
);
write_unlock
(
&
drv
->
bus
->
lock
);
spin_unlock
(
&
device_
lock
);
driver_make_dir
(
drv
);
driver_attach
(
drv
);
put_driver
(
drv
);
...
...
@@ -81,10 +77,10 @@ static void __remove_driver(struct device_driver * drv)
void
remove_driver
(
struct
device_driver
*
drv
)
{
write_lock
(
&
drv
->
bus
->
lock
);
spin_lock
(
&
device_
lock
);
atomic_set
(
&
drv
->
refcount
,
0
);
list_del_init
(
&
drv
->
bus_list
);
write_unlock
(
&
drv
->
bus
->
lock
);
spin_unlock
(
&
device_
lock
);
__remove_driver
(
drv
);
}
...
...
@@ -94,13 +90,10 @@ void remove_driver(struct device_driver * drv)
*/
void
put_driver
(
struct
device_driver
*
drv
)
{
write_lock
(
&
drv
->
bus
->
lock
);
if
(
!
atomic_dec_and_test
(
&
drv
->
refcount
))
{
write_unlock
(
&
drv
->
bus
->
lock
);
if
(
!
atomic_dec_and_lock
(
&
drv
->
refcount
,
&
device_lock
))
return
;
}
list_del_init
(
&
drv
->
bus_list
);
write_unlock
(
&
drv
->
bus
->
lock
);
spin_unlock
(
&
device_
lock
);
__remove_driver
(
drv
);
}
...
...
drivers/base/interface.c
View file @
76044a7f
...
...
@@ -14,7 +14,7 @@ static ssize_t device_read_name(struct device * dev, char * buf, size_t count, l
return
off
?
0
:
sprintf
(
buf
,
"%s
\n
"
,
dev
->
name
);
}
static
DEVICE_ATTR
(
name
,
"name"
,
S_IRUGO
,
device_read_name
,
NULL
);
static
DEVICE_ATTR
(
name
,
S_IRUGO
,
device_read_name
,
NULL
);
static
ssize_t
device_read_power
(
struct
device
*
dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
...
...
@@ -85,7 +85,7 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o
return
error
<
0
?
error
:
count
;
}
static
DEVICE_ATTR
(
power
,
"power"
,
S_IWUSR
|
S_IRUGO
,
static
DEVICE_ATTR
(
power
,
S_IWUSR
|
S_IRUGO
,
device_read_power
,
device_write_power
);
struct
device_attribute
*
device_default_files
[]
=
{
...
...
drivers/base/power.c
View file @
76044a7f
...
...
@@ -14,6 +14,8 @@
#include <linux/module.h>
#include "base.h"
#define to_dev(node) container_of(node,struct device,g_list)
/**
* device_suspend - suspend all devices on the device tree
* @state: state we're entering
...
...
@@ -25,30 +27,26 @@
*/
int
device_suspend
(
u32
state
,
u32
level
)
{
struct
device
*
dev
;
struct
device
*
prev
=
&
device_root
;
struct
list_head
*
node
;
struct
device
*
prev
=
NULL
;
int
error
=
0
;
printk
(
KERN_EMERG
"Suspending Devices
\n
"
);
get_device
(
prev
);
spin_lock
(
&
device_lock
);
dev
=
g_list_to_dev
(
prev
->
g_list
.
next
);
while
(
dev
!=
&
device_root
&&
!
error
)
{
get_device
(
dev
);
list_for_each
(
node
,
&
device_root
.
g_list
)
{
struct
device
*
dev
=
get_device_locked
(
dev
);
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
if
(
dev
->
driver
&&
dev
->
driver
->
suspend
)
error
=
dev
->
driver
->
suspend
(
dev
,
state
,
level
);
spin_lock
(
&
device_lock
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
dev
=
g_list_to_dev
(
prev
->
g_list
.
next
);
spin_lock
(
&
device_lock
);
}
}
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
return
error
;
}
...
...
@@ -63,27 +61,23 @@ int device_suspend(u32 state, u32 level)
*/
void
device_resume
(
u32
level
)
{
struct
device
*
dev
;
struct
device
*
prev
=
&
device_root
;
get_device
(
prev
);
struct
list_head
*
node
;
struct
device
*
prev
=
NULL
;
spin_lock
(
&
device_lock
);
dev
=
g_list_to_dev
(
prev
->
g_list
.
prev
);
while
(
dev
!=
&
device_root
)
{
get_device
(
dev
);
list_for_each_prev
(
node
,
&
device_root
.
g_list
)
{
struct
device
*
dev
=
get_device_locked
(
to_dev
(
node
));
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
if
(
dev
->
driver
&&
dev
->
driver
->
resume
)
dev
->
driver
->
resume
(
dev
,
level
);
spin_lock
(
&
device_lock
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
dev
=
g_list_to_dev
(
prev
->
g_list
.
prev
);
spin_lock
(
&
device_lock
);
}
}
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
printk
(
KERN_EMERG
"Devices Resumed
\n
"
);
}
...
...
@@ -98,29 +92,25 @@ void device_resume(u32 level)
*/
void
device_shutdown
(
void
)
{
struct
device
*
dev
;
struct
device
*
prev
=
&
device_root
;
struct
list_head
*
node
;
struct
device
*
prev
=
NULL
;
printk
(
KERN_EMERG
"Shutting down devices
\n
"
);
get_device
(
prev
);
spin_lock
(
&
device_lock
);
dev
=
g_list_to_dev
(
prev
->
g_list
.
next
);
while
(
dev
!=
&
device_root
)
{
get_device
(
dev
);
list_for_each
(
node
,
&
device_root
.
g_list
)
{
struct
device
*
dev
=
get_device_locked
(
to_dev
(
node
));
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
if
(
dev
->
driver
&&
dev
->
driver
->
remove
)
dev
->
driver
->
remove
(
dev
);
spin_lock
(
&
device_lock
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
dev
=
g_list_to_dev
(
prev
->
g_list
.
next
);
spin_lock
(
&
device_lock
);
}
}
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
}
EXPORT_SYMBOL
(
device_suspend
);
...
...
drivers/pci/proc.c
View file @
76044a7f
...
...
@@ -378,7 +378,7 @@ static ssize_t pci_show_irq(struct device * dev, char * buf, size_t count, loff_
return
off
?
0
:
sprintf
(
buf
,
"%u
\n
"
,
pci_dev
->
irq
);
}
static
DEVICE_ATTR
(
irq
,
"irq"
,
S_IRUGO
,
pci_show_irq
,
NULL
);
static
DEVICE_ATTR
(
irq
,
S_IRUGO
,
pci_show_irq
,
NULL
);
static
ssize_t
pci_show_resources
(
struct
device
*
dev
,
char
*
buf
,
size_t
count
,
loff_t
off
)
{
...
...
@@ -402,7 +402,7 @@ static ssize_t pci_show_resources(struct device * dev, char * buf, size_t count,
return
(
str
-
buf
);
}
static
DEVICE_ATTR
(
resource
,
"resource"
,
S_IRUGO
,
pci_show_resources
,
NULL
);
static
DEVICE_ATTR
(
resource
,
S_IRUGO
,
pci_show_resources
,
NULL
);
int
pci_proc_attach_device
(
struct
pci_dev
*
dev
)
{
...
...
drivers/scsi/scsi_scan.c
View file @
76044a7f
...
...
@@ -305,7 +305,7 @@ static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page,
return
0
;
}
static
DEVICE_ATTR
(
type
,
"type"
,
S_IRUGO
,
scsi_device_type_read
,
NULL
);
static
DEVICE_ATTR
(
type
,
S_IRUGO
,
scsi_device_type_read
,
NULL
);
/* end content handlers */
...
...
drivers/scsi/sg.c
View file @
76044a7f
...
...
@@ -1401,14 +1401,14 @@ static ssize_t sg_device_kdev_read(struct device *driverfs_dev, char *page,
Sg_device
*
sdp
=
list_entry
(
driverfs_dev
,
Sg_device
,
sg_driverfs_dev
);
return
off
?
0
:
sprintf
(
page
,
"%x
\n
"
,
sdp
->
i_rdev
.
value
);
}
static
DEVICE_ATTR
(
kdev
,
"kdev"
,
S_IRUGO
,
sg_device_kdev_read
,
NULL
);
static
DEVICE_ATTR
(
kdev
,
S_IRUGO
,
sg_device_kdev_read
,
NULL
);
static
ssize_t
sg_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
return
off
?
0
:
sprintf
(
page
,
"CHR
\n
"
);
}
static
DEVICE_ATTR
(
type
,
"type"
,
S_IRUGO
,
sg_device_type_read
,
NULL
);
static
DEVICE_ATTR
(
type
,
S_IRUGO
,
sg_device_type_read
,
NULL
);
static
int
sg_attach
(
Scsi_Device
*
scsidp
)
{
...
...
drivers/scsi/sr.c
View file @
76044a7f
...
...
@@ -737,14 +737,14 @@ static ssize_t sr_device_kdev_read(struct device *driverfs_dev,
kdev
.
value
=
(
int
)(
long
)
driverfs_dev
->
driver_data
;
return
off
?
0
:
sprintf
(
page
,
"%x
\n
"
,
kdev
.
value
);
}
static
DEVICE_ATTR
(
kdev
,
"kdev"
,
S_IRUGO
,
sr_device_kdev_read
,
NULL
);
static
DEVICE_ATTR
(
kdev
,
S_IRUGO
,
sr_device_kdev_read
,
NULL
);
static
ssize_t
sr_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
return
off
?
0
:
sprintf
(
page
,
"CHR
\n
"
);
}
static
DEVICE_ATTR
(
type
,
"type"
,
S_IRUGO
,
sr_device_type_read
,
NULL
);
static
DEVICE_ATTR
(
type
,
S_IRUGO
,
sr_device_type_read
,
NULL
);
void
sr_finish
()
...
...
drivers/scsi/st.c
View file @
76044a7f
...
...
@@ -3533,14 +3533,14 @@ static ssize_t st_device_kdev_read(struct device *driverfs_dev,
kdev
.
value
=
(
int
)(
long
)
driverfs_dev
->
driver_data
;
return
off
?
0
:
sprintf
(
page
,
"%x
\n
"
,
kdev
.
value
);
}
static
DEVICE_ATTR
(
kdev
,
"kdev"
,
S_IRUGO
,
st_device_kdev_read
,
NULL
);
static
DEVICE_ATTR
(
kdev
,
S_IRUGO
,
st_device_kdev_read
,
NULL
);
static
ssize_t
st_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
return
off
?
0
:
sprintf
(
page
,
"CHR
\n
"
);
}
static
DEVICE_ATTR
(
type
,
"type"
,
S_IRUGO
,
st_device_type_read
,
NULL
);
static
DEVICE_ATTR
(
type
,
S_IRUGO
,
st_device_type_read
,
NULL
);
static
struct
file_operations
st_fops
=
...
...
drivers/usb/core/usb.c
View file @
76044a7f
...
...
@@ -836,7 +836,7 @@ show_config (struct device *dev, char *buf, size_t count, loff_t off)
return
sprintf
(
buf
,
"%u
\n
"
,
udev
->
actconfig
->
bConfigurationValue
);
}
static
DEVICE_ATTR
(
config
,
"configuration"
,
S_IRUGO
,
show_config
,
NULL
);
static
DEVICE_ATTR
(
config
uration
,
S_IRUGO
,
show_config
,
NULL
);
/* interfaces have one current setting; alternates
* can have different endpoints and class info.
...
...
@@ -851,7 +851,7 @@ show_altsetting (struct device *dev, char *buf, size_t count, loff_t off)
interface
=
to_usb_interface
(
dev
);
return
sprintf
(
buf
,
"%u
\n
"
,
interface
->
altsetting
->
bAlternateSetting
);
}
static
DEVICE_ATTR
(
altsetting
,
"altsetting"
,
S_IRUGO
,
show_altsetting
,
NULL
);
static
DEVICE_ATTR
(
altsetting
,
S_IRUGO
,
show_altsetting
,
NULL
);
/* product driverfs file */
static
ssize_t
show_product
(
struct
device
*
dev
,
char
*
buf
,
size_t
count
,
loff_t
off
)
...
...
@@ -870,7 +870,7 @@ static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t
buf
[
len
+
1
]
=
0
;
return
len
+
1
;
}
static
DEVICE_ATTR
(
product
,
"product"
,
S_IRUGO
,
show_product
,
NULL
);
static
DEVICE_ATTR
(
product
,
S_IRUGO
,
show_product
,
NULL
);
/* manufacturer driverfs file */
static
ssize_t
...
...
@@ -890,7 +890,7 @@ show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off)
buf
[
len
+
1
]
=
0
;
return
len
+
1
;
}
static
DEVICE_ATTR
(
manufacturer
,
"manufacturer"
,
S_IRUGO
,
show_manufacturer
,
NULL
);
static
DEVICE_ATTR
(
manufacturer
,
S_IRUGO
,
show_manufacturer
,
NULL
);
/* serial number driverfs file */
static
ssize_t
...
...
@@ -910,7 +910,7 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off)
buf
[
len
+
1
]
=
0
;
return
len
+
1
;
}
static
DEVICE_ATTR
(
serial
,
"serial"
,
S_IRUGO
,
show_serial
,
NULL
);
static
DEVICE_ATTR
(
serial
,
S_IRUGO
,
show_serial
,
NULL
);
/*
* This entrypoint gets called for each new device.
...
...
@@ -1440,7 +1440,7 @@ int usb_new_device(struct usb_device *dev)
err
=
device_register
(
&
dev
->
dev
);
if
(
err
)
return
err
;
device_create_file
(
&
dev
->
dev
,
&
dev_attr_config
);
device_create_file
(
&
dev
->
dev
,
&
dev_attr_config
uration
);
if
(
dev
->
descriptor
.
iManufacturer
)
device_create_file
(
&
dev
->
dev
,
&
dev_attr_manufacturer
);
if
(
dev
->
descriptor
.
iProduct
)
...
...
fs/partitions/check.c
View file @
76044a7f
...
...
@@ -164,14 +164,14 @@ static ssize_t partition_device_kdev_read(struct device *driverfs_dev,
kdev
.
value
=
(
int
)(
long
)
driverfs_dev
->
driver_data
;
return
off
?
0
:
sprintf
(
page
,
"%x
\n
"
,
kdev
.
value
);
}
static
DEVICE_ATTR
(
kdev
,
"kdev"
,
S_IRUGO
,
partition_device_kdev_read
,
NULL
);
static
DEVICE_ATTR
(
kdev
,
S_IRUGO
,
partition_device_kdev_read
,
NULL
);
static
ssize_t
partition_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
return
off
?
0
:
sprintf
(
page
,
"BLK
\n
"
);
}
static
DEVICE_ATTR
(
type
,
"type"
,
S_IRUGO
,
partition_device_type_read
,
NULL
);
static
DEVICE_ATTR
(
type
,
S_IRUGO
,
partition_device_type_read
,
NULL
);
void
driverfs_create_partitions
(
struct
gendisk
*
hd
,
int
minor
)
{
...
...
include/linux/device.h
View file @
76044a7f
...
...
@@ -93,9 +93,9 @@ struct bus_attribute {
ssize_t
(
*
store
)(
struct
bus_type
*
,
const
char
*
buf
,
size_t
count
,
loff_t
off
);
};
#define BUS_ATTR(_name,_
str,_
mode,_show,_store) \
#define BUS_ATTR(_name,_mode,_show,_store) \
struct bus_attribute bus_attr_##_name = { \
.attr = {.name
= _str, .mode
= _mode }, \
.attr = {.name
= __stringify(_name), .mode
= _mode }, \
.show = _show, \
.store = _store, \
};
...
...
@@ -150,9 +150,9 @@ struct driver_attribute {
ssize_t
(
*
store
)(
struct
device_driver
*
,
const
char
*
buf
,
size_t
count
,
loff_t
off
);
};
#define DRIVER_ATTR(_name,_
str,_
mode,_show,_store) \
#define DRIVER_ATTR(_name,_mode,_show,_store) \
struct driver_attribute driver_attr_##_name = { \
.attr = {.name
= _str, .mode
= _mode }, \
.attr = {.name
= __stringify(_name), .mode
= _mode }, \
.show = _show, \
.store = _store, \
};
...
...
@@ -222,13 +222,14 @@ struct device_attribute {
ssize_t
(
*
store
)(
struct
device
*
dev
,
const
char
*
buf
,
size_t
count
,
loff_t
off
);
};
#define DEVICE_ATTR(_name,_
str,_mode,_show,_store)
\
#define DEVICE_ATTR(_name,_
mode,_show,_store)
\
struct device_attribute dev_attr_##_name = { \
.attr = {.name
= _str, .mode
= _mode }, \
.attr = {.name
= __stringify(_name), .mode
= _mode }, \
.show = _show, \
.store = _store, \
};
extern
int
device_create_file
(
struct
device
*
device
,
struct
device_attribute
*
entry
);
extern
void
device_remove_file
(
struct
device
*
dev
,
struct
device_attribute
*
attr
);
...
...
@@ -260,12 +261,7 @@ static inline void unlock_device(struct device * dev)
* get_device - atomically increment the reference count for the device.
*
*/
static
inline
void
get_device
(
struct
device
*
dev
)
{
BUG_ON
(
!
atomic_read
(
&
dev
->
refcount
));
atomic_inc
(
&
dev
->
refcount
);
}
extern
struct
device
*
get_device
(
struct
device
*
dev
);
extern
void
put_device
(
struct
device
*
dev
);
/* drivers/base/sys.c */
...
...
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