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
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
Show 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