summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJP Abgrall <jpa@google.com>2013-10-17 20:07:04 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2013-10-17 20:07:05 +0000
commitb387a7f2168a720fa486f31e8f3189114f69c0db (patch)
tree59fc38fe7e3f1c8560345da3e7bb902b4e357f6e
parentac568b8f783ee60a7a2cb0ab5b6db786bdb39b35 (diff)
parent157b00171a06f9ac2fd25ee3a86e801e896713d6 (diff)
downloadsystem_core-b387a7f2168a720fa486f31e8f3189114f69c0db.zip
system_core-b387a7f2168a720fa486f31e8f3189114f69c0db.tar.gz
system_core-b387a7f2168a720fa486f31e8f3189114f69c0db.tar.bz2
Merge "Wait for device to disappear after reboot-bootloader."
-rw-r--r--fastboot/Android.mk4
-rw-r--r--fastboot/engine.c31
-rw-r--r--fastboot/fastboot.c13
-rw-r--r--fastboot/fastboot.h3
-rw-r--r--fastboot/usb.h2
-rw-r--r--fastboot/usb_linux.c49
-rw-r--r--fastboot/usb_osx.c5
-rw-r--r--fastboot/usb_windows.c5
-rw-r--r--fastboot/util.c69
9 files changed, 122 insertions, 59 deletions
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 1189e1f..f339988 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -18,7 +18,7 @@ include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \
$(LOCAL_PATH)/../../extras/ext4_utils
-LOCAL_SRC_FILES := protocol.c engine.c bootimg.c fastboot.c
+LOCAL_SRC_FILES := protocol.c engine.c bootimg.c fastboot.c util.c
LOCAL_MODULE := fastboot
LOCAL_MODULE_TAGS := debug
@@ -69,7 +69,7 @@ $(call dist-for-goals,dist_files sdk,$(LOCAL_BUILT_MODULE))
ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := usbtest.c usb_linux.c
+LOCAL_SRC_FILES := usbtest.c usb_linux.c util.c
LOCAL_MODULE := usbtest
include $(BUILD_HOST_EXECUTABLE)
endif
diff --git a/fastboot/engine.c b/fastboot/engine.c
index 8d46991..84ea984 100644
--- a/fastboot/engine.c
+++ b/fastboot/engine.c
@@ -36,7 +36,6 @@
#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
@@ -48,34 +47,13 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-double now()
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
-}
-
-char *mkmsg(const char *fmt, ...)
-{
- char buf[256];
- char *s;
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
-
- s = strdup(buf);
- if (s == 0) die("out of memory");
- return s;
-}
-
#define OP_DOWNLOAD 1
#define OP_COMMAND 2
#define OP_QUERY 3
#define OP_NOTICE 4
#define OP_FORMAT 5
#define OP_DOWNLOAD_SPARSE 6
+#define OP_WAIT_FOR_DISCONNECT 7
typedef struct Action Action;
@@ -587,6 +565,11 @@ void fb_queue_notice(const char *notice)
a->data = (void*) notice;
}
+void fb_queue_wait_for_disconnect(void)
+{
+ queue_action(OP_WAIT_FOR_DISCONNECT, "");
+}
+
int fb_execute_queue(usb_handle *usb)
{
Action *a;
@@ -628,6 +611,8 @@ int fb_execute_queue(usb_handle *usb)
status = fb_download_data_sparse(usb, a->data);
status = a->func(a, status, status ? fb_get_error() : "");
if (status) break;
+ } else if (a->op == OP_WAIT_FOR_DISCONNECT) {
+ usb_wait_for_disconnect(usb);
} else {
die("bogus action");
}
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index 447b257..70b838f 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -30,7 +30,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
@@ -82,17 +81,6 @@ unsigned second_offset = 0x00f00000;
unsigned tags_offset = 0x00000100;
-void die(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr,"error: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr,"\n");
- va_end(ap);
- exit(1);
-}
-
void get_my_path(char *path);
char *find_item(const char *item, const char *product)
@@ -1031,6 +1019,7 @@ int main(int argc, char **argv)
fb_queue_reboot();
} else if (wants_reboot_bootloader) {
fb_queue_command("reboot-bootloader", "rebooting into bootloader");
+ fb_queue_wait_for_disconnect();
}
if (fb_queue_is_empty())
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index c1b2964..976c397 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -58,10 +58,13 @@ void fb_queue_reboot(void);
void fb_queue_command(const char *cmd, const char *msg);
void fb_queue_download(const char *name, void *data, unsigned size);
void fb_queue_notice(const char *notice);
+void fb_queue_wait_for_disconnect(void);
int fb_execute_queue(usb_handle *usb);
int fb_queue_is_empty(void);
/* util stuff */
+double now();
+char *mkmsg(const char *fmt, ...);
void die(const char *fmt, ...);
/* Current product */
diff --git a/fastboot/usb.h b/fastboot/usb.h
index d504ee2..17cf0a9 100644
--- a/fastboot/usb.h
+++ b/fastboot/usb.h
@@ -62,6 +62,6 @@ usb_handle *usb_open(ifc_match_func callback);
int usb_close(usb_handle *h);
int usb_read(usb_handle *h, void *_data, int len);
int usb_write(usb_handle *h, const void *_data, int len);
-
+int usb_wait_for_disconnect(usb_handle *h);
#endif
diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c
index 9153c8d..f2ce226 100644
--- a/fastboot/usb_linux.c
+++ b/fastboot/usb_linux.c
@@ -50,10 +50,17 @@
#endif
#include <asm/byteorder.h>
+#include "fastboot.h"
#include "usb.h"
#define MAX_RETRIES 5
+/* Timeout in seconds for usb_wait_for_disconnect.
+ * It doesn't usually take long for a device to disconnect (almost always
+ * under 2 seconds) but we'll time out after 3 seconds just in case.
+ */
+#define WAIT_FOR_DISCONNECT_TIMEOUT 3
+
#ifdef TRACE_USB
#define DBG1(x...) fprintf(stderr, x)
#define DBG(x...) fprintf(stderr, x)
@@ -103,7 +110,7 @@ static int check(void *_desc, int len, unsigned type, int size)
return 0;
}
-static int filter_usb_device(int fd, char* sysfs_name,
+static int filter_usb_device(char* sysfs_name,
char *ptr, int len, int writable,
ifc_match_func callback,
int *ept_in_id, int *ept_out_id, int *ifc_id)
@@ -308,7 +315,7 @@ static usb_handle *find_usb_device(const char *base, ifc_match_func callback)
n = read(fd, desc, sizeof(desc));
- if(filter_usb_device(fd, de->d_name, desc, n, writable, callback,
+ if(filter_usb_device(de->d_name, desc, n, writable, callback,
&in, &out, &ifc) == 0) {
usb = calloc(1, sizeof(usb_handle));
strcpy(usb->fname, devname);
@@ -340,26 +347,11 @@ int usb_write(usb_handle *h, const void *_data, int len)
struct usbdevfs_bulktransfer bulk;
int n;
- if(h->ep_out == 0) {
+ if(h->ep_out == 0 || h->desc == -1) {
return -1;
}
- if(len == 0) {
- bulk.ep = h->ep_out;
- bulk.len = 0;
- bulk.data = data;
- bulk.timeout = 0;
-
- n = ioctl(h->desc, USBDEVFS_BULK, &bulk);
- if(n != 0) {
- fprintf(stderr,"ERROR: n = %d, errno = %d (%s)\n",
- n, errno, strerror(errno));
- return -1;
- }
- return 0;
- }
-
- while(len > 0) {
+ do {
int xfer;
xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
@@ -378,7 +370,7 @@ int usb_write(usb_handle *h, const void *_data, int len)
count += xfer;
len -= xfer;
data += xfer;
- }
+ } while(len > 0);
return count;
}
@@ -390,7 +382,7 @@ int usb_read(usb_handle *h, void *_data, int len)
struct usbdevfs_bulktransfer bulk;
int n, retry;
- if(h->ep_in == 0) {
+ if(h->ep_in == 0 || h->desc == -1) {
return -1;
}
@@ -458,3 +450,18 @@ usb_handle *usb_open(ifc_match_func callback)
{
return find_usb_device("/sys/bus/usb/devices", callback);
}
+
+/* Wait for the system to notice the device is gone, so that a subsequent
+ * fastboot command won't try to access the device before it's rebooted.
+ * Returns 0 for success, -1 for timeout.
+ */
+int usb_wait_for_disconnect(usb_handle *usb)
+{
+ double deadline = now() + WAIT_FOR_DISCONNECT_TIMEOUT;
+ while (now() < deadline) {
+ if (access(usb->fname, F_OK))
+ return 0;
+ usleep(50000);
+ }
+ return -1;
+}
diff --git a/fastboot/usb_osx.c b/fastboot/usb_osx.c
index 1548ba8..0f55e0d 100644
--- a/fastboot/usb_osx.c
+++ b/fastboot/usb_osx.c
@@ -467,6 +467,11 @@ int usb_close(usb_handle *h) {
return 0;
}
+int usb_wait_for_disconnect(usb_handle *usb) {
+ /* TODO: Punt for now */
+ return 0;
+}
+
int usb_read(usb_handle *h, void *data, int len) {
IOReturn result;
UInt32 numBytes = len;
diff --git a/fastboot/usb_windows.c b/fastboot/usb_windows.c
index 7aa36b2..07f7be2 100644
--- a/fastboot/usb_windows.c
+++ b/fastboot/usb_windows.c
@@ -269,6 +269,11 @@ int usb_close(usb_handle* handle) {
return 0;
}
+int usb_wait_for_disconnect(usb_handle *usb) {
+ /* TODO: Punt for now */
+ return 0;
+}
+
int recognized_device(usb_handle* handle, ifc_match_func callback) {
struct usb_ifc_info info;
USB_DEVICE_DESCRIPTOR device_desc;
diff --git a/fastboot/util.c b/fastboot/util.c
new file mode 100644
index 0000000..f2bbd34
--- /dev/null
+++ b/fastboot/util.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/time.h>
+
+#include "fastboot.h"
+
+double now()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
+}
+
+char *mkmsg(const char *fmt, ...)
+{
+ char buf[256];
+ char *s;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ va_end(ap);
+
+ s = strdup(buf);
+ if (s == 0) die("out of memory");
+ return s;
+}
+
+void die(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr,"error: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr,"\n");
+ va_end(ap);
+ exit(1);
+}