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
media
v4l2-core
v4l2-int-device.c
Go to the documentation of this file.
1
/*
2
* drivers/media/video/v4l2-int-device.c
3
*
4
* V4L2 internal ioctl interface.
5
*
6
* Copyright (C) 2007 Nokia Corporation.
7
*
8
* Contact: Sakari Ailus <
[email protected]
>
9
*
10
* This program is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU General Public License
12
* version 2 as published by the Free Software Foundation.
13
*
14
* This program is distributed in the hope that it will be useful, but
15
* WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22
* 02110-1301 USA
23
*/
24
25
#include <linux/kernel.h>
26
#include <linux/list.h>
27
#include <
linux/sort.h
>
28
#include <linux/string.h>
29
#include <linux/module.h>
30
31
#include <
media/v4l2-int-device.h
>
32
33
static
DEFINE_MUTEX
(
mutex
);
34
static
LIST_HEAD
(int_list);
35
36
void
v4l2_int_device_try_attach_all
(
void
)
37
{
38
struct
v4l2_int_device
*
m
, *
s
;
39
40
list_for_each_entry
(m, &int_list,
head
) {
41
if
(m->
type
!=
v4l2_int_type_master
)
42
continue
;
43
44
list_for_each_entry
(s, &int_list,
head
) {
45
if
(s->
type
!=
v4l2_int_type_slave
)
46
continue
;
47
48
/* Slave is connected? */
49
if
(s->
u
.
slave
->master)
50
continue
;
51
52
/* Slave wants to attach to master? */
53
if
(s->
u
.
slave
->attach_to[0] != 0
54
&&
strncmp
(m->
name
, s->
u
.
slave
->attach_to,
55
V4L2NAMESIZE
))
56
continue
;
57
58
if
(!try_module_get(m->
module
))
59
continue
;
60
61
s->
u
.
slave
->master =
m
;
62
if
(m->
u
.
master
->attach(s)) {
63
s->
u
.
slave
->master =
NULL
;
64
module_put(m->
module
);
65
continue
;
66
}
67
}
68
}
69
}
70
EXPORT_SYMBOL_GPL
(
v4l2_int_device_try_attach_all
);
71
72
static
int
ioctl_sort_cmp(
const
void
*
a
,
const
void
*
b
)
73
{
74
const
struct
v4l2_int_ioctl_desc
*
d1
=
a
, *
d2
=
b
;
75
76
if
(d1->
num
> d2->num)
77
return
1;
78
79
if
(d1->
num
< d2->num)
80
return
-1;
81
82
return
0;
83
}
84
85
int
v4l2_int_device_register
(
struct
v4l2_int_device
*
d
)
86
{
87
if
(d->
type
==
v4l2_int_type_slave
)
88
sort
(d->
u
.
slave
->ioctls, d->
u
.
slave
->num_ioctls,
89
sizeof
(
struct
v4l2_int_ioctl_desc
),
90
&ioctl_sort_cmp,
NULL
);
91
mutex_lock
(&
mutex
);
92
list_add(&d->
head
, &int_list);
93
v4l2_int_device_try_attach_all
();
94
mutex_unlock
(&
mutex
);
95
96
return
0;
97
}
98
EXPORT_SYMBOL_GPL
(
v4l2_int_device_register
);
99
100
void
v4l2_int_device_unregister
(
struct
v4l2_int_device
*
d
)
101
{
102
mutex_lock
(&
mutex
);
103
list_del
(&d->
head
);
104
if
(d->
type
==
v4l2_int_type_slave
105
&& d->
u
.
slave
->master !=
NULL
) {
106
d->
u
.
slave
->master->u.master->detach(d);
107
module_put(d->
u
.
slave
->master->module);
108
d->
u
.
slave
->master =
NULL
;
109
}
110
mutex_unlock
(&
mutex
);
111
}
112
EXPORT_SYMBOL_GPL
(
v4l2_int_device_unregister
);
113
114
/* Adapted from search_extable in extable.c. */
115
static
v4l2_int_ioctl_func
*find_ioctl(
struct
v4l2_int_slave
*
slave
,
int
cmd
,
116
v4l2_int_ioctl_func
*no_such_ioctl)
117
{
118
const
struct
v4l2_int_ioctl_desc
*
first
= slave->
ioctls
;
119
const
struct
v4l2_int_ioctl_desc
*
last
=
120
first + slave->
num_ioctls
- 1;
121
122
while
(first <= last) {
123
const
struct
v4l2_int_ioctl_desc
*
mid
;
124
125
mid = (last -
first
) / 2 + first;
126
127
if
(mid->
num
< cmd)
128
first = mid + 1;
129
else
if
(mid->
num
> cmd)
130
last = mid - 1;
131
else
132
return
mid->
func
;
133
}
134
135
return
no_such_ioctl;
136
}
137
138
static
int
no_such_ioctl_0(
struct
v4l2_int_device
*
d
)
139
{
140
return
-
ENOIOCTLCMD
;
141
}
142
143
int
v4l2_int_ioctl_0
(
struct
v4l2_int_device
*
d
,
int
cmd)
144
{
145
return
((
v4l2_int_ioctl_func_0
*)
146
find_ioctl(d->
u
.
slave
, cmd,
147
(
v4l2_int_ioctl_func
*)no_such_ioctl_0))(
d
);
148
}
149
EXPORT_SYMBOL_GPL
(
v4l2_int_ioctl_0
);
150
151
static
int
no_such_ioctl_1(
struct
v4l2_int_device
*
d
,
void
*
arg
)
152
{
153
return
-
ENOIOCTLCMD
;
154
}
155
156
int
v4l2_int_ioctl_1
(
struct
v4l2_int_device
*
d
,
int
cmd,
void
*
arg
)
157
{
158
return
((
v4l2_int_ioctl_func_1
*)
159
find_ioctl(d->
u
.
slave
, cmd,
160
(
v4l2_int_ioctl_func
*)no_such_ioctl_1))(
d
,
arg
);
161
}
162
EXPORT_SYMBOL_GPL
(
v4l2_int_ioctl_1
);
163
164
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 13:52:55 for Linux Kernel by
1.8.2