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
117e6adf
Commit
117e6adf
authored
Oct 30, 2002
by
Patrick Mochel
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://ldm@bkbits.net/linux-2.5-kobject
into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-kobject
parents
b1b782f7
8de57ed6
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
267 additions
and
281 deletions
+267
-281
drivers/base/bus.c
drivers/base/bus.c
+131
-3
drivers/base/core.c
drivers/base/core.c
+85
-1
drivers/base/driver.c
drivers/base/driver.c
+31
-1
drivers/base/fs/bus.c
drivers/base/fs/bus.c
+0
-78
drivers/base/fs/device.c
drivers/base/fs/device.c
+1
-104
drivers/base/fs/driver.c
drivers/base/fs/driver.c
+0
-78
drivers/base/interface.c
drivers/base/interface.c
+3
-3
include/linux/device.h
include/linux/device.h
+6
-0
include/linux/driverfs_fs.h
include/linux/driverfs_fs.h
+2
-5
include/linux/kobject.h
include/linux/kobject.h
+3
-1
include/linux/sysfs.h
include/linux/sysfs.h
+5
-7
No files found.
drivers/base/bus.c
View file @
117e6adf
...
...
@@ -12,6 +12,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/init.h>
#include "base.h"
static
LIST_HEAD
(
bus_driver_list
);
...
...
@@ -19,6 +20,109 @@ 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)
#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
#define to_bus(obj) container_of(obj,struct bus_type,subsys.kobj)
/*
* sysfs bindings for drivers
*/
#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
#define to_driver(obj) container_of(obj, struct device_driver, kobj)
static
ssize_t
drv_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
driver_attribute
*
drv_attr
=
to_drv_attr
(
attr
);
struct
device_driver
*
drv
=
to_driver
(
kobj
);
ssize_t
ret
=
0
;
if
(
drv_attr
->
show
)
ret
=
drv_attr
->
show
(
drv
,
buf
,
count
,
off
);
return
ret
;
}
static
ssize_t
drv_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
driver_attribute
*
drv_attr
=
to_drv_attr
(
attr
);
struct
device_driver
*
drv
=
to_driver
(
kobj
);
ssize_t
ret
=
0
;
if
(
drv_attr
->
store
)
ret
=
drv_attr
->
store
(
drv
,
buf
,
count
,
off
);
return
ret
;
}
static
struct
sysfs_ops
driver_sysfs_ops
=
{
.
show
=
drv_attr_show
,
.
store
=
drv_attr_store
,
};
/*
* sysfs bindings for drivers
*/
static
ssize_t
bus_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
bus_attribute
*
bus_attr
=
to_bus_attr
(
attr
);
struct
bus_type
*
bus
=
to_bus
(
kobj
);
ssize_t
ret
=
0
;
if
(
bus_attr
->
show
)
ret
=
bus_attr
->
show
(
bus
,
buf
,
count
,
off
);
return
ret
;
}
static
ssize_t
bus_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
bus_attribute
*
bus_attr
=
to_bus_attr
(
attr
);
struct
bus_type
*
bus
=
to_bus
(
kobj
);
ssize_t
ret
=
0
;
if
(
bus_attr
->
store
)
ret
=
bus_attr
->
store
(
bus
,
buf
,
count
,
off
);
return
ret
;
}
static
struct
sysfs_ops
bus_sysfs_ops
=
{
.
show
=
bus_attr_show
,
.
store
=
bus_attr_store
,
};
int
bus_create_file
(
struct
bus_type
*
bus
,
struct
bus_attribute
*
attr
)
{
int
error
;
if
(
get_bus
(
bus
))
{
error
=
sysfs_create_file
(
&
bus
->
subsys
.
kobj
,
&
attr
->
attr
);
put_bus
(
bus
);
}
else
error
=
-
EINVAL
;
return
error
;
}
void
bus_remove_file
(
struct
bus_type
*
bus
,
struct
bus_attribute
*
attr
)
{
if
(
get_bus
(
bus
))
{
sysfs_remove_file
(
&
bus
->
subsys
.
kobj
,
&
attr
->
attr
);
put_bus
(
bus
);
}
}
struct
subsystem
bus_subsys
=
{
.
kobj
=
{
.
name
=
"bus"
},
.
sysfs_ops
=
&
bus_sysfs_ops
,
};
/**
* bus_for_each_dev - walk list of devices and do something to each
* @bus: bus in question
...
...
@@ -92,6 +196,7 @@ static void attach(struct device * dev)
pr_debug
(
"bound device '%s' to driver '%s'
\n
"
,
dev
->
bus_id
,
dev
->
driver
->
name
);
list_add_tail
(
&
dev
->
driver_list
,
&
dev
->
driver
->
devices
);
sysfs_create_link
(
&
dev
->
driver
->
kobj
,
&
dev
->
kobj
,
dev
->
kobj
.
name
);
}
static
int
bus_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
...
...
@@ -162,6 +267,7 @@ static int driver_attach(struct device_driver * drv)
static
void
detach
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
if
(
drv
)
{
sysfs_remove_link
(
&
drv
->
kobj
,
dev
->
kobj
.
name
);
list_del_init
(
&
dev
->
driver_list
);
devclass_remove_device
(
dev
);
if
(
drv
->
remove
)
...
...
@@ -206,7 +312,7 @@ int bus_add_device(struct device * dev)
list_add_tail
(
&
dev
->
bus_list
,
&
dev
->
bus
->
devices
);
device_attach
(
dev
);
up_write
(
&
dev
->
bus
->
rwsem
);
device_bus_link
(
dev
);
sysfs_create_link
(
&
bus
->
devsubsys
.
kobj
,
&
dev
->
kobj
,
dev
->
bus_id
);
}
return
0
;
}
...
...
@@ -221,9 +327,9 @@ int bus_add_device(struct device * dev)
void
bus_remove_device
(
struct
device
*
dev
)
{
if
(
dev
->
bus
)
{
sysfs_remove_link
(
&
dev
->
bus
->
devsubsys
.
kobj
,
dev
->
bus_id
);
down_write
(
&
dev
->
bus
->
rwsem
);
pr_debug
(
"bus %s: remove device %s
\n
"
,
dev
->
bus
->
name
,
dev
->
bus_id
);
device_remove_symlink
(
&
dev
->
bus
->
device_dir
,
dev
->
bus_id
);
device_detach
(
dev
);
list_del_init
(
&
dev
->
bus_list
);
up_write
(
&
dev
->
bus
->
rwsem
);
...
...
@@ -240,7 +346,6 @@ int bus_add_driver(struct device_driver * drv)
list_add_tail
(
&
drv
->
bus_list
,
&
bus
->
drivers
);
driver_attach
(
drv
);
up_write
(
&
bus
->
rwsem
);
driver_make_dir
(
drv
);
}
return
0
;
}
...
...
@@ -286,6 +391,19 @@ int bus_register(struct bus_type * bus)
atomic_set
(
&
bus
->
refcount
,
2
);
bus
->
present
=
1
;
strncpy
(
bus
->
subsys
.
kobj
.
name
,
bus
->
name
,
KOBJ_NAME_LEN
);
bus
->
subsys
.
parent
=
&
bus_subsys
;
subsystem_register
(
&
bus
->
subsys
);
snprintf
(
bus
->
devsubsys
.
kobj
.
name
,
KOBJ_NAME_LEN
,
"devices"
);
bus
->
devsubsys
.
parent
=
&
bus
->
subsys
;
subsystem_register
(
&
bus
->
devsubsys
);
snprintf
(
bus
->
drvsubsys
.
kobj
.
name
,
KOBJ_NAME_LEN
,
"drivers"
);
bus
->
drvsubsys
.
parent
=
&
bus
->
subsys
;
bus
->
drvsubsys
.
sysfs_ops
=
&
driver_sysfs_ops
;
subsystem_register
(
&
bus
->
drvsubsys
);
spin_lock
(
&
device_lock
);
list_add_tail
(
&
bus
->
node
,
&
bus_driver_list
);
spin_unlock
(
&
device_lock
);
...
...
@@ -309,6 +427,13 @@ void bus_unregister(struct bus_type * bus)
put_bus
(
bus
);
}
static
int
__init
bus_subsys_init
(
void
)
{
return
subsystem_register
(
&
bus_subsys
);
}
core_initcall
(
bus_subsys_init
);
EXPORT_SYMBOL
(
bus_for_each_dev
);
EXPORT_SYMBOL
(
bus_for_each_drv
);
EXPORT_SYMBOL
(
bus_add_device
);
...
...
@@ -317,3 +442,6 @@ EXPORT_SYMBOL(bus_register);
EXPORT_SYMBOL
(
bus_unregister
);
EXPORT_SYMBOL
(
get_bus
);
EXPORT_SYMBOL
(
put_bus
);
EXPORT_SYMBOL
(
bus_create_file
);
EXPORT_SYMBOL
(
bus_remove_file
);
drivers/base/core.c
View file @
117e6adf
...
...
@@ -23,7 +23,76 @@ DECLARE_MUTEX(device_sem);
spinlock_t
device_lock
=
SPIN_LOCK_UNLOCKED
;
#define to_dev(node) container_of(node,struct device,driver_list)
struct
subsystem
device_subsys
;
#define to_dev(obj) container_of(obj,struct device,kobj)
/*
* sysfs bindings for devices.
*/
#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
extern
struct
attribute
*
dev_default_attrs
[];
static
ssize_t
dev_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
device_attribute
*
dev_attr
=
to_dev_attr
(
attr
);
struct
device
*
dev
=
to_dev
(
kobj
);
ssize_t
ret
=
0
;
if
(
dev_attr
->
show
)
ret
=
dev_attr
->
show
(
dev
,
buf
,
count
,
off
);
return
ret
;
}
static
ssize_t
dev_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
device_attribute
*
dev_attr
=
to_dev_attr
(
attr
);
struct
device
*
dev
=
to_dev
(
kobj
);
ssize_t
ret
=
0
;
if
(
dev_attr
->
store
)
ret
=
dev_attr
->
store
(
dev
,
buf
,
count
,
off
);
return
ret
;
}
static
struct
sysfs_ops
dev_sysfs_ops
=
{
.
show
=
dev_attr_show
,
.
store
=
dev_attr_store
,
};
struct
subsystem
device_subsys
=
{
.
kobj
=
{
.
name
=
"devices"
,
},
.
sysfs_ops
=
&
dev_sysfs_ops
,
.
default_attrs
=
dev_default_attrs
,
};
int
device_create_file
(
struct
device
*
dev
,
struct
device_attribute
*
attr
)
{
int
error
=
0
;
if
(
get_device
(
dev
))
{
error
=
sysfs_create_file
(
&
dev
->
kobj
,
&
attr
->
attr
);
put_device
(
dev
);
}
return
error
;
}
void
device_remove_file
(
struct
device
*
dev
,
struct
device_attribute
*
attr
)
{
if
(
get_device
(
dev
))
{
sysfs_remove_file
(
&
dev
->
kobj
,
&
attr
->
attr
);
put_device
(
dev
);
}
}
int
device_add
(
struct
device
*
dev
)
{
...
...
@@ -44,6 +113,12 @@ int device_add(struct device *dev)
pr_debug
(
"DEV: registering device: ID = '%s', name = %s
\n
"
,
dev
->
bus_id
,
dev
->
name
);
strncpy
(
dev
->
kobj
.
name
,
dev
->
bus_id
,
KOBJ_NAME_LEN
);
if
(
dev
->
parent
)
dev
->
kobj
.
parent
=
&
dev
->
parent
->
kobj
;
dev
->
kobj
.
subsys
=
&
device_subsys
;
kobject_register
(
&
dev
->
kobj
);
if
((
error
=
device_make_dir
(
dev
)))
goto
register_done
;
...
...
@@ -69,6 +144,7 @@ int device_add(struct device *dev)
void
device_initialize
(
struct
device
*
dev
)
{
kobject_init
(
&
dev
->
kobj
);
INIT_LIST_HEAD
(
&
dev
->
node
);
INIT_LIST_HEAD
(
&
dev
->
children
);
INIT_LIST_HEAD
(
&
dev
->
g_list
);
...
...
@@ -184,9 +260,17 @@ void device_unregister(struct device * dev)
pr_debug
(
"DEV: Unregistering device. ID = '%s', name = '%s'
\n
"
,
dev
->
bus_id
,
dev
->
name
);
kobject_unregister
(
&
dev
->
kobj
);
put_device
(
dev
);
}
static
int
__init
device_subsys_init
(
void
)
{
return
subsystem_register
(
&
device_subsys
);
}
core_initcall
(
device_subsys_init
);
EXPORT_SYMBOL
(
device_register
);
EXPORT_SYMBOL
(
device_unregister
);
EXPORT_SYMBOL
(
get_device
);
...
...
drivers/base/driver.c
View file @
117e6adf
...
...
@@ -12,6 +12,29 @@
#define to_dev(node) container_of(node,struct device,driver_list)
/*
* helpers for creating driver attributes in sysfs
*/
int
driver_create_file
(
struct
device_driver
*
drv
,
struct
driver_attribute
*
attr
)
{
int
error
;
if
(
get_driver
(
drv
))
{
error
=
sysfs_create_file
(
&
drv
->
kobj
,
&
attr
->
attr
);
put_driver
(
drv
);
}
else
error
=
-
EINVAL
;
return
error
;
}
void
driver_remove_file
(
struct
device_driver
*
drv
,
struct
driver_attribute
*
attr
)
{
if
(
get_driver
(
drv
))
{
sysfs_remove_file
(
&
drv
->
kobj
,
&
attr
->
attr
);
put_driver
(
drv
);
}
}
int
driver_for_each_dev
(
struct
device_driver
*
drv
,
void
*
data
,
int
(
*
callback
)(
struct
device
*
,
void
*
))
{
...
...
@@ -65,7 +88,6 @@ void put_driver(struct device_driver * drv)
return
;
spin_unlock
(
&
device_lock
);
BUG_ON
(
drv
->
present
);
bus_remove_driver
(
drv
);
if
(
drv
->
release
)
drv
->
release
(
drv
);
put_bus
(
bus
);
...
...
@@ -84,6 +106,11 @@ int driver_register(struct device_driver * drv)
pr_debug
(
"driver %s:%s: registering
\n
"
,
drv
->
bus
->
name
,
drv
->
name
);
kobject_init
(
&
drv
->
kobj
);
strncpy
(
drv
->
kobj
.
name
,
drv
->
name
,
KOBJ_NAME_LEN
);
drv
->
kobj
.
subsys
=
&
drv
->
bus
->
drvsubsys
;
kobject_register
(
&
drv
->
kobj
);
get_bus
(
drv
->
bus
);
atomic_set
(
&
drv
->
refcount
,
2
);
rwlock_init
(
&
drv
->
lock
);
...
...
@@ -108,3 +135,6 @@ EXPORT_SYMBOL(driver_register);
EXPORT_SYMBOL
(
driver_unregister
);
EXPORT_SYMBOL
(
get_driver
);
EXPORT_SYMBOL
(
put_driver
);
EXPORT_SYMBOL
(
driver_create_file
);
EXPORT_SYMBOL
(
driver_remove_file
);
drivers/base/fs/bus.c
View file @
117e6adf
...
...
@@ -6,86 +6,10 @@
static
struct
driver_dir_entry
bus_dir
;
#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
#define to_bus(dir) container_of(dir,struct bus_type,dir)
/* driverfs ops for device attribute files */
static
int
bus_attr_open
(
struct
driver_dir_entry
*
dir
)
{
struct
bus_type
*
bus
=
to_bus
(
dir
);
get_bus
(
bus
);
return
0
;
}
static
int
bus_attr_close
(
struct
driver_dir_entry
*
dir
)
{
struct
bus_type
*
bus
=
to_bus
(
dir
);
put_bus
(
bus
);
return
0
;
}
static
ssize_t
bus_attr_show
(
struct
driver_dir_entry
*
dir
,
struct
attribute
*
attr
,
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
bus_attribute
*
bus_attr
=
to_bus_attr
(
attr
);
struct
bus_type
*
bus
=
to_bus
(
dir
);
ssize_t
ret
=
0
;
if
(
bus_attr
->
show
)
ret
=
bus_attr
->
show
(
bus
,
buf
,
count
,
off
);
return
ret
;
}
static
ssize_t
bus_attr_store
(
struct
driver_dir_entry
*
dir
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
bus_attribute
*
bus_attr
=
to_bus_attr
(
attr
);
struct
bus_type
*
bus
=
to_bus
(
dir
);
ssize_t
ret
=
0
;
if
(
bus_attr
->
store
)
ret
=
bus_attr
->
store
(
bus
,
buf
,
count
,
off
);
return
ret
;
}
static
struct
driverfs_ops
bus_attr_ops
=
{
.
open
=
bus_attr_open
,
.
close
=
bus_attr_close
,
.
show
=
bus_attr_show
,
.
store
=
bus_attr_store
,
};
int
bus_create_file
(
struct
bus_type
*
bus
,
struct
bus_attribute
*
attr
)
{
int
error
;
if
(
get_bus
(
bus
))
{
error
=
driverfs_create_file
(
&
attr
->
attr
,
&
bus
->
dir
);
put_bus
(
bus
);
}
else
error
=
-
EINVAL
;
return
error
;
}
void
bus_remove_file
(
struct
bus_type
*
bus
,
struct
bus_attribute
*
attr
)
{
if
(
get_bus
(
bus
))
{
driverfs_remove_file
(
&
bus
->
dir
,
attr
->
attr
.
name
);
put_bus
(
bus
);
}
}
int
bus_make_dir
(
struct
bus_type
*
bus
)
{
int
error
;
bus
->
dir
.
name
=
bus
->
name
;
bus
->
dir
.
ops
=
&
bus_attr_ops
;
error
=
device_create_dir
(
&
bus
->
dir
,
&
bus_dir
);
if
(
!
error
)
{
...
...
@@ -119,5 +43,3 @@ static int __init bus_init(void)
core_initcall
(
bus_init
);
EXPORT_SYMBOL
(
bus_create_file
);
EXPORT_SYMBOL
(
bus_remove_file
);
drivers/base/fs/device.c
View file @
117e6adf
...
...
@@ -21,97 +21,6 @@ static struct driver_dir_entry device_root_dir = {
.
mode
=
(
S_IRWXU
|
S_IRUGO
|
S_IXUGO
),
};
extern
struct
device_attribute
*
device_default_files
[];
#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
#define to_device(d) container_of(d, struct device, dir)
/* driverfs ops for device attribute files */
static
int
dev_attr_open
(
struct
driver_dir_entry
*
dir
)
{
struct
device
*
dev
=
to_device
(
dir
);
get_device
(
dev
);
return
0
;
}
static
int
dev_attr_close
(
struct
driver_dir_entry
*
dir
)
{
struct
device
*
dev
=
to_device
(
dir
);
put_device
(
dev
);
return
0
;
}
static
ssize_t
dev_attr_show
(
struct
driver_dir_entry
*
dir
,
struct
attribute
*
attr
,
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
device_attribute
*
dev_attr
=
to_dev_attr
(
attr
);
struct
device
*
dev
=
to_device
(
dir
);
ssize_t
ret
=
0
;
if
(
dev_attr
->
show
)
ret
=
dev_attr
->
show
(
dev
,
buf
,
count
,
off
);
return
ret
;
}
static
ssize_t
dev_attr_store
(
struct
driver_dir_entry
*
dir
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
device_attribute
*
dev_attr
=
to_dev_attr
(
attr
);
struct
device
*
dev
=
to_device
(
dir
);
ssize_t
ret
=
0
;
if
(
dev_attr
->
store
)
ret
=
dev_attr
->
store
(
dev
,
buf
,
count
,
off
);
return
ret
;
}
static
struct
driverfs_ops
dev_attr_ops
=
{
.
open
=
dev_attr_open
,
.
close
=
dev_attr_close
,
.
show
=
dev_attr_show
,
.
store
=
dev_attr_store
,
};
/**
* device_create_file - create a driverfs file for a device
* @dev: device requesting file
* @entry: entry describing file
*
* Allocate space for file entry, copy descriptor, and create.
*/
int
device_create_file
(
struct
device
*
dev
,
struct
device_attribute
*
entry
)
{
int
error
=
-
EINVAL
;
if
(
get_device
(
dev
))
{
error
=
driverfs_create_file
(
&
entry
->
attr
,
&
dev
->
dir
);
put_device
(
dev
);
}
return
error
;
}
/**
* device_remove_file - remove a device's file by name
* @dev: device requesting removal
* @name: name of the file
*
*/
void
device_remove_file
(
struct
device
*
dev
,
struct
device_attribute
*
attr
)
{
if
(
dev
)
{
get_device
(
dev
);
driverfs_remove_file
(
&
dev
->
dir
,
attr
->
attr
.
name
);
put_device
(
dev
);
}
}
/**
* device_remove_dir - remove a device's directory
* @dev: device in question
...
...
@@ -213,24 +122,12 @@ int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * p
int
device_make_dir
(
struct
device
*
dev
)
{
struct
driver_dir_entry
*
parent
;
struct
device_attribute
*
entry
;
int
error
;
int
i
;
parent
=
dev
->
parent
?
&
dev
->
parent
->
dir
:
&
device_root_dir
;
dev
->
dir
.
name
=
dev
->
bus_id
;
dev
->
dir
.
ops
=
&
dev_attr_ops
;
if
((
error
=
device_create_dir
(
&
dev
->
dir
,
parent
)))
return
error
;
for
(
i
=
0
;
(
entry
=
*
(
device_default_files
+
i
));
i
++
)
{
if
((
error
=
device_create_file
(
dev
,
entry
)))
{
device_remove_dir
(
dev
);
break
;
}
}
return
error
;
return
device_create_dir
(
&
dev
->
dir
,
parent
);
}
static
int
device_driverfs_init
(
void
)
...
...
drivers/base/fs/driver.c
View file @
117e6adf
...
...
@@ -4,80 +4,6 @@
#include <linux/err.h>
#include "fs.h"
#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
#define to_drv(d) container_of(d, struct device_driver, dir)
/* driverfs ops for device attribute files */
static
int
drv_attr_open
(
struct
driver_dir_entry
*
dir
)
{
struct
device_driver
*
drv
=
to_drv
(
dir
);
get_driver
(
drv
);
return
0
;
}
static
int
drv_attr_close
(
struct
driver_dir_entry
*
dir
)
{
struct
device_driver
*
drv
=
to_drv
(
dir
);
put_driver
(
drv
);
return
0
;
}
static
ssize_t
drv_attr_show
(
struct
driver_dir_entry
*
dir
,
struct
attribute
*
attr
,
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
driver_attribute
*
drv_attr
=
to_drv_attr
(
attr
);
struct
device_driver
*
drv
=
to_drv
(
dir
);
ssize_t
ret
=
0
;
if
(
drv_attr
->
show
)
ret
=
drv_attr
->
show
(
drv
,
buf
,
count
,
off
);
return
ret
;
}
static
ssize_t
drv_attr_store
(
struct
driver_dir_entry
*
dir
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
driver_attribute
*
drv_attr
=
to_drv_attr
(
attr
);
struct
device_driver
*
drv
=
to_drv
(
dir
);
ssize_t
ret
=
0
;
if
(
drv_attr
->
store
)
ret
=
drv_attr
->
store
(
drv
,
buf
,
count
,
off
);
return
ret
;
}
static
struct
driverfs_ops
drv_attr_ops
=
{
.
open
=
drv_attr_open
,
.
close
=
drv_attr_close
,
.
show
=
drv_attr_show
,
.
store
=
drv_attr_store
,
};
int
driver_create_file
(
struct
device_driver
*
drv
,
struct
driver_attribute
*
attr
)
{
int
error
;
if
(
get_driver
(
drv
))
{
error
=
driverfs_create_file
(
&
attr
->
attr
,
&
drv
->
dir
);
put_driver
(
drv
);
}
else
error
=
-
EINVAL
;
return
error
;
}
void
driver_remove_file
(
struct
device_driver
*
drv
,
struct
driver_attribute
*
attr
)
{
if
(
get_driver
(
drv
))
{
driverfs_remove_file
(
&
drv
->
dir
,
attr
->
attr
.
name
);
put_driver
(
drv
);
}
}
/**
* driver_make_dir - create a driverfs directory for a driver
...
...
@@ -86,8 +12,6 @@ void driver_remove_file(struct device_driver * drv, struct driver_attribute * at
int
driver_make_dir
(
struct
device_driver
*
drv
)
{
drv
->
dir
.
name
=
drv
->
name
;
drv
->
dir
.
ops
=
&
drv_attr_ops
;
return
device_create_dir
(
&
drv
->
dir
,
&
drv
->
bus
->
driver_dir
);
}
...
...
@@ -96,5 +20,3 @@ void driver_remove_dir(struct device_driver * drv)
driverfs_remove_dir
(
&
drv
->
dir
);
}
EXPORT_SYMBOL
(
driver_create_file
);
EXPORT_SYMBOL
(
driver_remove_file
);
drivers/base/interface.c
View file @
117e6adf
...
...
@@ -88,8 +88,8 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o
static
DEVICE_ATTR
(
power
,
S_IWUSR
|
S_IRUGO
,
device_read_power
,
device_write_power
);
struct
device_attribute
*
device_default_file
s
[]
=
{
&
dev_attr_name
,
&
dev_attr_power
,
struct
attribute
*
dev_default_attr
s
[]
=
{
&
dev_attr_name
.
attr
,
&
dev_attr_power
.
attr
,
NULL
,
};
include/linux/device.h
View file @
117e6adf
...
...
@@ -29,6 +29,7 @@
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/driverfs_fs.h>
#include <linux/kobject.h>
#define DEVICE_NAME_SIZE 80
#define DEVICE_ID_SIZE 32
...
...
@@ -65,6 +66,9 @@ struct bus_type {
atomic_t
refcount
;
u32
present
;
struct
subsystem
subsys
;
struct
subsystem
drvsubsys
;
struct
subsystem
devsubsys
;
struct
list_head
node
;
struct
list_head
devices
;
struct
list_head
drivers
;
...
...
@@ -119,6 +123,7 @@ struct device_driver {
atomic_t
refcount
;
u32
present
;
struct
kobject
kobj
;
struct
list_head
bus_list
;
struct
list_head
class_list
;
struct
list_head
devices
;
...
...
@@ -275,6 +280,7 @@ struct device {
struct
list_head
intf_list
;
struct
device
*
parent
;
struct
kobject
kobj
;
char
name
[
DEVICE_NAME_SIZE
];
/* descriptive ascii string */
char
bus_id
[
BUS_ID_SIZE
];
/* position on parent bus */
...
...
include/linux/driverfs_fs.h
View file @
117e6adf
...
...
@@ -26,6 +26,8 @@
#ifndef _DRIVER_FS_H_
#define _DRIVER_FS_H_
#include <linux/sysfs.h>
struct
driver_dir_entry
;
struct
attribute
;
...
...
@@ -43,11 +45,6 @@ struct driver_dir_entry {
struct
driverfs_ops
*
ops
;
};
struct
attribute
{
char
*
name
;
mode_t
mode
;
};
extern
int
driverfs_create_dir
(
struct
driver_dir_entry
*
,
struct
driver_dir_entry
*
);
...
...
include/linux/kobject.h
View file @
117e6adf
...
...
@@ -12,8 +12,10 @@
#include <linux/rwsem.h>
#include <asm/atomic.h>
#define KOBJ_NAME_LEN 16
struct
kobject
{
char
name
[
16
];
char
name
[
KOBJ_NAME_LEN
];
atomic_t
refcount
;
struct
list_head
entry
;
struct
kobject
*
parent
;
...
...
include/linux/sysfs.h
View file @
117e6adf
...
...
@@ -9,20 +9,18 @@
#ifndef _SYSFS_H_
#define _SYSFS_H_
struct
driver_dir_entry
;
struct
attribute
;
struct
kobject
;
struct
sysfs_ops
{
ssize_t
(
*
show
)(
struct
kobject
*
,
struct
attribute
*
,
char
*
,
size_t
,
loff_t
);
ssize_t
(
*
store
)(
struct
kobject
*
,
struct
attribute
*
,
const
char
*
,
size_t
,
loff_t
);
};
struct
attribute
{
char
*
name
;
mode_t
mode
;
};
struct
sysfs_ops
{
ssize_t
(
*
show
)(
struct
kobject
*
,
struct
attribute
*
,
char
*
,
size_t
,
loff_t
);
ssize_t
(
*
store
)(
struct
kobject
*
,
struct
attribute
*
,
const
char
*
,
size_t
,
loff_t
);
};
extern
int
sysfs_create_dir
(
struct
kobject
*
);
...
...
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