Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
base
driver.c
Go to the documentation of this file.
1
/*
2
* driver.c - centralized device driver management
3
*
4
* Copyright (c) 2002-3 Patrick Mochel
5
* Copyright (c) 2002-3 Open Source Development Labs
6
* Copyright (c) 2007 Greg Kroah-Hartman <
[email protected]
>
7
* Copyright (c) 2007 Novell Inc.
8
*
9
* This file is released under the GPLv2
10
*
11
*/
12
13
#include <linux/device.h>
14
#include <linux/module.h>
15
#include <linux/errno.h>
16
#include <linux/slab.h>
17
#include <linux/string.h>
18
#include "
base.h
"
19
20
static
struct
device
*next_device(
struct
klist_iter
*
i
)
21
{
22
struct
klist_node
*
n
=
klist_next
(i);
23
struct
device
*
dev
=
NULL
;
24
struct
device_private
*dev_prv;
25
26
if
(n) {
27
dev_prv =
to_device_private_driver
(n);
28
dev = dev_prv->
device
;
29
}
30
return
dev
;
31
}
32
42
int
driver_for_each_device
(
struct
device_driver
*drv,
struct
device
*
start
,
43
void
*
data
,
int
(*
fn
)(
struct
device
*,
void
*))
44
{
45
struct
klist_iter
i;
46
struct
device
*
dev
;
47
int
error
= 0;
48
49
if
(!drv)
50
return
-
EINVAL
;
51
52
klist_iter_init_node
(&drv->
p
->klist_devices, &i,
53
start ? &start->
p
->knode_driver :
NULL
);
54
while
((dev = next_device(&i)) && !error)
55
error =
fn
(dev, data);
56
klist_iter_exit
(&i);
57
return
error
;
58
}
59
EXPORT_SYMBOL_GPL
(
driver_for_each_device
);
60
76
struct
device
*
driver_find_device
(
struct
device_driver
*drv,
77
struct
device
*start,
void
*data,
78
int
(*
match
)(
struct
device
*dev,
void
*data))
79
{
80
struct
klist_iter
i;
81
struct
device
*
dev
;
82
83
if
(!drv || !drv->
p
)
84
return
NULL
;
85
86
klist_iter_init_node
(&drv->
p
->klist_devices, &i,
87
(start ? &start->
p
->knode_driver :
NULL
));
88
while
((dev = next_device(&i)))
89
if
(
match
(dev, data) &&
get_device
(dev))
90
break
;
91
klist_iter_exit
(&i);
92
return
dev
;
93
}
94
EXPORT_SYMBOL_GPL
(
driver_find_device
);
95
101
int
driver_create_file
(
struct
device_driver
*drv,
102
const
struct
driver_attribute
*
attr
)
103
{
104
int
error
;
105
if
(drv)
106
error =
sysfs_create_file
(&drv->
p
->kobj, &attr->
attr
);
107
else
108
error = -
EINVAL
;
109
return
error
;
110
}
111
EXPORT_SYMBOL_GPL
(
driver_create_file
);
112
118
void
driver_remove_file
(
struct
device_driver
*drv,
119
const
struct
driver_attribute
*
attr
)
120
{
121
if
(drv)
122
sysfs_remove_file
(&drv->
p
->kobj, &attr->
attr
);
123
}
124
EXPORT_SYMBOL_GPL
(
driver_remove_file
);
125
126
static
int
driver_add_groups(
struct
device_driver
*drv,
127
const
struct
attribute_group
**
groups
)
128
{
129
int
error
= 0;
130
int
i
;
131
132
if
(groups) {
133
for
(i = 0; groups[
i
]; i++) {
134
error =
sysfs_create_group
(&drv->
p
->kobj, groups[i]);
135
if
(error) {
136
while
(--i >= 0)
137
sysfs_remove_group
(&drv->
p
->kobj,
138
groups[i]);
139
break
;
140
}
141
}
142
}
143
return
error
;
144
}
145
146
static
void
driver_remove_groups(
struct
device_driver
*drv,
147
const
struct
attribute_group
**groups)
148
{
149
int
i
;
150
151
if
(groups)
152
for
(i = 0; groups[
i
]; i++)
153
sysfs_remove_group
(&drv->
p
->kobj, groups[i]);
154
}
155
164
int
driver_register
(
struct
device_driver
*drv)
165
{
166
int
ret
;
167
struct
device_driver
*
other
;
168
169
BUG_ON
(!drv->
bus
->p);
170
171
if
((drv->
bus
->probe && drv->
probe
) ||
172
(drv->
bus
->remove && drv->
remove
) ||
173
(drv->
bus
->shutdown && drv->
shutdown
))
174
printk
(
KERN_WARNING
"Driver '%s' needs updating - please use "
175
"bus_type methods\n"
, drv->
name
);
176
177
other =
driver_find
(drv->
name
, drv->
bus
);
178
if
(other) {
179
printk
(
KERN_ERR
"Error: Driver '%s' is already registered, "
180
"aborting...\n"
, drv->
name
);
181
return
-
EBUSY
;
182
}
183
184
ret =
bus_add_driver
(drv);
185
if
(ret)
186
return
ret
;
187
ret = driver_add_groups(drv, drv->
groups
);
188
if
(ret) {
189
bus_remove_driver
(drv);
190
return
ret
;
191
}
192
kobject_uevent
(&drv->
p
->kobj,
KOBJ_ADD
);
193
194
return
ret
;
195
}
196
EXPORT_SYMBOL_GPL
(
driver_register
);
197
204
void
driver_unregister
(
struct
device_driver
*drv)
205
{
206
if
(!drv || !drv->
p
) {
207
WARN
(1,
"Unexpected driver unregister!\n"
);
208
return
;
209
}
210
driver_remove_groups(drv, drv->
groups
);
211
bus_remove_driver
(drv);
212
}
213
EXPORT_SYMBOL_GPL
(
driver_unregister
);
214
227
struct
device_driver
*
driver_find
(
const
char
*
name
,
struct
bus_type
*
bus
)
228
{
229
struct
kobject
*
k
=
kset_find_obj
(bus->
p
->drivers_kset, name);
230
struct
driver_private
*
priv
;
231
232
if
(k) {
233
/* Drop reference added by kset_find_obj() */
234
kobject_put
(k);
235
priv =
to_driver
(k);
236
return
priv->
driver
;
237
}
238
return
NULL
;
239
}
240
EXPORT_SYMBOL_GPL
(
driver_find
);
Generated on Thu Jan 10 2013 13:12:59 for Linux Kernel by
1.8.2