Skip to content

Latest commit

 

History

History
255 lines (209 loc) · 7.07 KB

usb_moded-modules.c

File metadata and controls

255 lines (209 loc) · 7.07 KB
 
Mar 22, 2011
Mar 22, 2011
1
/**
Aug 24, 2018
Aug 24, 2018
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
* @file usb_moded-modules.c
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
* Copyright (C) 2012-2018 Jolla. All rights reserved.
*
* @author: Philippe De Swert <philippe.de-swert@nokia.com>
* @author: Philippe De Swert <phdeswer@lumi.maa>
* @author: Philippe De Swert <philippedeswert@gmail.com>
* @author: Philippe De Swert <philippe.deswert@jollamobile.com>
* @author: Thomas Perl <m@thp.io>
* @author: Slava Monich <slava.monich@jolla.com>
* @author: Simo Piiroinen <simo.piiroinen@jollamobile.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Lesser GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
Mar 22, 2011
Mar 22, 2011
29
Sep 5, 2018
Sep 5, 2018
30
31
32
33
#include "usb_moded-modules.h"
#include "usb_moded-log.h"
Mar 22, 2011
Mar 22, 2011
34
35
36
#include <stdlib.h>
#include <string.h>
Nov 13, 2012
Nov 13, 2012
37
38
#include <libkmod.h>
Sep 5, 2018
Sep 5, 2018
39
#include <glib.h>
Mar 22, 2011
Mar 22, 2011
40
Aug 24, 2018
Aug 24, 2018
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/* ========================================================================= *
* Prototypes
* ========================================================================= */
/* -- modules -- */
bool modules_init (void);
bool modules_in_use (void);
void modules_quit (void);
int modules_load_module (const char *module);
int modules_unload_module (const char *module);
/* ========================================================================= *
* Data
* ========================================================================= */
Aug 24, 2018
Aug 24, 2018
57
58
59
60
61
62
63
64
/** Availability of kernel module based gadget configuration functionality
*
* -1 = not checked yet
* 0 = not available
* 1 = chosen as means of gadget configuration for usb-moded
*/
static int modules_probed = -1;
Aug 24, 2018
Aug 24, 2018
65
66
/* kmod context - initialized at start in usbmoded_init by ctx_init()
* and cleaned up by ctx_cleanup() functions */
Aug 24, 2018
Aug 24, 2018
67
static struct kmod_ctx *modules_ctx = 0;
Nov 13, 2012
Nov 13, 2012
68
Aug 24, 2018
Aug 24, 2018
69
70
71
72
73
74
75
76
77
78
79
/* ========================================================================= *
* Functions
* ========================================================================= */
static bool modules_have_module(const char *module)
{
// TODO: not fully untested due to lack of suitable hw
bool ack = false;
struct kmod_list *list = 0;
Aug 24, 2018
Aug 24, 2018
80
if( kmod_module_new_from_lookup(modules_ctx, module, &list) < 0 )
Aug 24, 2018
Aug 24, 2018
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
goto EXIT;
if( list == 0 )
goto EXIT;
ack = true;
EXIT:
if( list )
kmod_module_unref_list(list);
log_debug("module %s does%s exist", module, ack ? "" : "not ");
return ack;
}
bool modules_in_use(void)
{
if( modules_probed < 0 )
log_debug("modules_in_use() called before modules_probe()");
return modules_probed > 0;
}
static bool modules_probe(void)
{
static const char * const lut[] = {
MODULE_MASS_STORAGE,
MODULE_FILE_STORAGE,
MODULE_DEVELOPER,
MODULE_MTP,
0
};
if( modules_probed == -1 ) {
modules_probed = false;
/* Check if we have at least one of the kernel modules we
* expect to use for something.
*/
for( size_t i = 0; lut[i] ; ++i ) {
if( modules_have_module(lut[i]) ) {
modules_probed = true;
break;
}
}
log_warning("MODULES %sdetected", modules_probed ? "" : "not ");
}
return modules_in_use();
}
Aug 5, 2014
Aug 5, 2014
132
/* kmod module init */
Aug 24, 2018
Aug 24, 2018
133
bool modules_init(void)
Aug 5, 2014
Aug 5, 2014
134
{
Aug 24, 2018
Aug 24, 2018
135
136
bool ack = false;
Aug 24, 2018
Aug 24, 2018
137
138
if( !modules_ctx ) {
if( !(modules_ctx = kmod_new(NULL, NULL)) )
Aug 24, 2018
Aug 24, 2018
139
140
141
goto EXIT;
}
Aug 24, 2018
Aug 24, 2018
142
if( kmod_load_resources(modules_ctx) < 0 )
Aug 24, 2018
Aug 24, 2018
143
144
145
146
147
148
149
150
goto EXIT;
if( !modules_probe() )
goto EXIT;
ack = true;
EXIT:
return ack;
Aug 5, 2014
Aug 5, 2014
151
152
153
}
/* kmod module cleanup */
Aug 24, 2018
Aug 24, 2018
154
void modules_quit(void)
Aug 5, 2014
Aug 5, 2014
155
{
Aug 24, 2018
Aug 24, 2018
156
157
if( modules_ctx )
kmod_unref(modules_ctx), modules_ctx = 0;
Aug 5, 2014
Aug 5, 2014
158
159
}
Aug 24, 2018
Aug 24, 2018
160
/** load module
Mar 22, 2011
Mar 22, 2011
161
162
163
164
165
*
* @param module Name of the module to load
* @return 0 on success, non-zero on failure
*
*/
Aug 24, 2018
Aug 24, 2018
166
int modules_load_module(const char *module)
Mar 22, 2011
Mar 22, 2011
167
{
Aug 24, 2018
Aug 24, 2018
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
int ret = 0;
const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST;
struct kmod_module *mod;
char *charging_args = NULL;
char *load = NULL;
if(!strcmp(module, MODULE_NONE))
return 0;
if( !modules_in_use() ) {
log_warning("load module %s - without module support", module);
return -1;
}
/* copy module to load as it might be modified if we're trying charging mode */
load = strdup(module);
if(!strcmp(module, MODULE_CHARGING) || !strcmp(module, MODULE_CHARGE_FALLBACK))
{
/* split the string in module name and argument, they are the same for MODULE_CHARGE_FALLBACK
Aug 24, 2018
Aug 24, 2018
188
* so no need to handle them separately */
Aug 24, 2018
Aug 24, 2018
189
190
191
gchar **strings;
/* since the mass_storage module is the newer one and we check against it to avoid
Aug 24, 2018
Aug 24, 2018
192
193
* loading failures we use it here, as we fall back to g_file_storage if g_mass_storage
* fails to load */
Aug 24, 2018
Aug 24, 2018
194
195
196
197
198
199
200
201
202
strings = g_strsplit(MODULE_CHARGE_FALLBACK, " ", 2);
//log_debug("module args = %s, module = %s\n", strings[1], strings[0]);
charging_args = strdup(strings[1]);
/* load was already assigned. Free it to re-assign */
free(load);
load = strdup(strings[0]);
g_strfreev(strings);
}
Aug 24, 2018
Aug 24, 2018
203
ret = kmod_module_new_from_name(modules_ctx, load, &mod);
Aug 24, 2018
Aug 24, 2018
204
/* since kmod_module_new_from_name does not check if the module
Aug 24, 2018
Aug 24, 2018
205
* exists we test it's path in case we deal with the mass-storage one */
Aug 24, 2018
Aug 24, 2018
206
207
208
209
if(!strcmp(module, MODULE_MASS_STORAGE) &&
(kmod_module_get_path(mod) == NULL))
{
log_debug("Fallback on older g_file_storage\n");
Aug 24, 2018
Aug 24, 2018
210
ret = kmod_module_new_from_name(modules_ctx, MODULE_FILE_STORAGE, &mod);
Aug 24, 2018
Aug 24, 2018
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
}
if(!charging_args)
ret = kmod_module_probe_insert_module(mod, probe_flags, NULL, NULL, NULL, NULL);
else
{
ret = kmod_module_probe_insert_module(mod, probe_flags, charging_args, NULL, NULL, NULL);
free(charging_args);
}
kmod_module_unref(mod);
free(load);
if( ret == 0)
log_info("Module %s loaded successfully\n", module);
else
log_info("Module %s failed to load\n", module);
return(ret);
Mar 22, 2011
Mar 22, 2011
228
229
230
}
/** unload module
Aug 24, 2018
Aug 24, 2018
231
*
Mar 22, 2011
Mar 22, 2011
232
233
234
235
* @param module Name of the module to unload
* @return 0 on success, non-zero on failure
*
*/
Aug 24, 2018
Aug 24, 2018
236
int modules_unload_module(const char *module)
Mar 22, 2011
Mar 22, 2011
237
{
Aug 24, 2018
Aug 24, 2018
238
int ret = 0;
Mar 22, 2011
Mar 22, 2011
239
Aug 24, 2018
Aug 24, 2018
240
struct kmod_module *mod;
Nov 13, 2012
Nov 13, 2012
241
Aug 24, 2018
Aug 24, 2018
242
243
if(!strcmp(module, MODULE_NONE))
return 0;
May 27, 2013
May 27, 2013
244
Aug 24, 2018
Aug 24, 2018
245
246
247
248
if( !modules_in_use() ) {
log_warning("unload module %s - without module support", module);
return -1;
}
Nov 13, 2012
Nov 13, 2012
249
Aug 24, 2018
Aug 24, 2018
250
kmod_module_new_from_name(modules_ctx, module, &mod);
Aug 24, 2018
Aug 24, 2018
251
252
253
254
ret = kmod_module_remove_module(mod, KMOD_REMOVE_NOWAIT);
kmod_module_unref(mod);
return(ret);
Mar 22, 2011
Mar 22, 2011
255
}