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
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
Hide 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
);
break
;
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
);
break
;
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
;
struct
device
*
prev
=
NULL
;
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
);
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
);
}
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:
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
);
if
(
error
&&
dev
->
parent
)
put_device
(
dev
->
parent
);
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
);
break
;
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
);
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
if
(
dev
->
driver
&&
dev
->
driver
->
suspend
)
error
=
dev
->
driver
->
suspend
(
dev
,
state
,
level
);
spin_lock
(
&
device_lock
);
prev
=
dev
;
dev
=
g_list_to_dev
(
prev
->
g_list
.
next
);
list_for_each
(
node
,
&
device_root
.
g_list
)
{
struct
device
*
dev
=
get_device_locked
(
dev
);
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
if
(
dev
->
driver
&&
dev
->
driver
->
suspend
)
error
=
dev
->
driver
->
suspend
(
dev
,
state
,
level
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
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
);
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
if
(
dev
->
driver
&&
dev
->
driver
->
resume
)
dev
->
driver
->
resume
(
dev
,
level
);
spin_lock
(
&
device_lock
);
prev
=
dev
;
dev
=
g_list_to_dev
(
prev
->
g_list
.
prev
);
list_for_each_prev
(
node
,
&
device_root
.
g_list
)
{
struct
device
*
dev
=
get_device_locked
(
to_dev
(
node
));
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
if
(
dev
->
driver
&&
dev
->
driver
->
resume
)
dev
->
driver
->
resume
(
dev
,
level
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
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
);
spin_unlock
(
&
device_lock
);
put_device
(
prev
);
if
(
dev
->
driver
&&
dev
->
driver
->
remove
)
dev
->
driver
->
remove
(
dev
);
spin_lock
(
&
device_lock
);
prev
=
dev
;
dev
=
g_list_to_dev
(
prev
->
g_list
.
next
);
list_for_each
(
node
,
&
device_root
.
g_list
)
{
struct
device
*
dev
=
get_device_locked
(
to_dev
(
node
));
if
(
dev
)
{
spin_unlock
(
&
device_lock
);
if
(
dev
->
driver
&&
dev
->
driver
->
remove
)
dev
->
driver
->
remove
(
dev
);
if
(
prev
)
put_device
(
prev
);
prev
=
dev
;
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