Skip to content

Commit

Permalink
[android] Optionally force an USB function on bootup. JB#41747
Browse files Browse the repository at this point in the history
On some devices enumeration fails on the 1st connect after bootup unless
android usb has already been set up for some function at least once.

Add --android-bootup-function option that can be used on such devices
to force usb-moded to program some function and then clear the function
list when usb-moded is executed during device bootup.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Jun 5, 2018
1 parent c30c835 commit 6b38de2
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
25 changes: 23 additions & 2 deletions src/usb_moded-android.c
Expand Up @@ -23,6 +23,7 @@
#include <stdio.h>
#include <glib.h>

#include "usb_moded.h"
#include "usb_moded-android.h"
#include "usb_moded-log.h"
#include "usb_moded-modesetting.h"
Expand Down Expand Up @@ -84,11 +85,17 @@ void android_init_values(void)
{
gchar *text;

/* If the directory is not there, no point emitting warnings
* about every file that is not going to be there either. */
if( access("/sys/class/android_usb/android0", F_OK) != 0 )
{
goto EXIT;
}

/* Disable */
write_to_file("/sys/class/android_usb/android0/enable", "0");

/* Configure */
if( (text = get_android_serial()) )
{
write_to_file("/sys/class/android_usb/android0/iSerial", text);
Expand Down Expand Up @@ -128,8 +135,22 @@ void android_init_values(void)
/* For rndis to be discovered correctly in M$ Windows (vista and later) */
write_to_file("/sys/class/android_usb/f_rndis/wceis", "1");

/* Make sure android_usb does not stay disabled in case usb moded
* has crashed / been killed in inconvenient time. */

/* Some devices can have enumeration issues due to incomplete
* configuration on the 1st connect after bootup. Briefly setting
* up for example mass_storage function can be utilized as a
* workaround in such cases. */
if(!init_done_p()) {
const char *function = get_android_bootup_function();
if(function) {
write_to_file("/sys/class/android_usb/android0/functions", function);
write_to_file("/sys/class/android_usb/android0/enable", "1");
write_to_file("/sys/class/android_usb/android0/enable", "0");
}
}

/* Clear functions and enable */
write_to_file("/sys/class/android_usb/android0/functions", "none");
write_to_file("/sys/class/android_usb/android0/enable", "1");

EXIT:
Expand Down
37 changes: 36 additions & 1 deletion src/usb_moded.c
Expand Up @@ -92,6 +92,30 @@ static gboolean android_ignore_next_udev_disconnect_event = FALSE;
static gboolean systemd_notify = FALSE;
#endif

/** Optional android usb function to setup during bootup */
static gchar *android_bootup_function = 0;


/** Get android usb function to setup during bootup
*
* @returns function name, or NULL if no function was requested
*/
const char *get_android_bootup_function(void)
{
return android_bootup_function;
}

/** Set android usb function to setup during bootup
*
* @param function usb function name, or NULL
*/
void set_android_bootup_function(const char *function)
{
char *value = function ? g_strdup(function) : 0;
g_free(android_bootup_function);
android_bootup_function = value;
}

/** Default allowed cable detection delay
*
* To comply with USB standards, the delay should be
Expand Down Expand Up @@ -879,6 +903,10 @@ static void usage(void)
" output version information and exit\n"
" -m, --max-cable-delay=<ms>\n"
" maximum delay before accepting cable connection\n"
" -b, --android-bootup-function=<function>\n"
" Setup given function during bootup. Might be required\n"
" on some devices to make enumeration work on the 1st\n"
" cable connect.\n"
"\n");
}

Expand Down Expand Up @@ -1332,6 +1360,7 @@ int main(int argc, char* argv[])
{ "systemd", no_argument, 0, 'n' },
{ "version", no_argument, 0, 'v' },
{ "max-cable-delay", required_argument, 0, 'm' },
{ "android-bootup-function", required_argument, 0, 'b' },
{ 0, 0, 0, 0 }
};

Expand All @@ -1343,7 +1372,7 @@ int main(int argc, char* argv[])
* - - - - - - - - - - - - - - - - - - - */

/* Parse the command-line options */
while ((opt = getopt_long(argc, argv, "aifsTlDdhrnvm:", options, &opt_idx)) != -1)
while ((opt = getopt_long(argc, argv, "aifsTlDdhrnvm:b:", options, &opt_idx)) != -1)
{
switch (opt)
{
Expand Down Expand Up @@ -1397,6 +1426,10 @@ int main(int argc, char* argv[])
set_cable_connection_delay(strtol(optarg, 0, 0));
break;

case 'b':
set_android_bootup_function(optarg);
break;

default:
usage();
exit(0);
Expand Down Expand Up @@ -1602,6 +1635,8 @@ int main(int argc, char* argv[])
# endif
#endif

set_android_bootup_function(0);

/* Must be done just before exit to make sure no more wakelocks
* are taken and left behind on exit path */
allow_suspend();
Expand Down
3 changes: 3 additions & 0 deletions src/usb_moded.h
Expand Up @@ -108,4 +108,7 @@ bool init_done_p(void);
void set_init_done(bool reached);
void probe_init_done(void);

const char *get_android_bootup_function(void);
void set_android_bootup_function(const char *function);

#endif /* USB_MODED_H */

0 comments on commit 6b38de2

Please sign in to comment.