Merge "Adds UXTB16 support to Pixelflinger"
diff --git a/adb/OVERVIEW.TXT b/adb/OVERVIEW.TXT
index 6a5191a..c40695a 100644
--- a/adb/OVERVIEW.TXT
+++ b/adb/OVERVIEW.TXT
@@ -35,7 +35,7 @@
     (through USB for devices, through TCP for emulators) and provide a
     few services for clients that run on the host.
 
-    The ADB server considers that a device is ONLINE when it has succesfully
+    The ADB server considers that a device is ONLINE when it has successfully
     connected to the adbd program within it. Otherwise, the device is OFFLINE,
     meaning that the ADB server detected a new device/emulator, but could not
     connect to the adbd daemon.
diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT
index b0124a4..be4d50b 100644
--- a/adb/SERVICES.TXT
+++ b/adb/SERVICES.TXT
@@ -74,7 +74,7 @@
 
 host-local:<request>
     A variant of host-serial used to target the single emulator instance
-    running on the host. This will fail if therre is none or more than one.
+    running on the host. This will fail if there is none or more than one.
 
 host:<request>
     When asking for information related to a device, 'host:' can also be
@@ -146,7 +146,7 @@
 dev:<path>
     Opens a device file and connects the client directly to it for
     read/write purposes. Useful for debugging, but may require special
-    priviledges and thus may not run on all devices. <path> is a full
+    privileges and thus may not run on all devices. <path> is a full
     path from the root of the filesystem.
 
 tcp:<port>
@@ -173,7 +173,7 @@
 
 framebuffer:
     This service is used to send snapshots of the framebuffer to a client.
-    It requires sufficient priviledges but works as follow:
+    It requires sufficient privileges but works as follow:
 
       After the OKAY, the service sends 16-byte binary structure
       containing the following fields (little-endian format):
@@ -190,14 +190,14 @@
       one byte through the channel, which will trigger the service
       to send it 'size' bytes of framebuffer data.
 
-      If the adbd daemon doesn't have sufficient priviledges to open
+      If the adbd daemon doesn't have sufficient privileges to open
       the framebuffer device, the connection is simply closed immediately.
 
 dns:<server-name>
     This service is an exception because it only runs within the ADB server.
     It is used to implement USB networking, i.e. to provide a network connection
     to the device through the host machine (note: this is the exact opposite of
-    network thetering).
+    network tethering).
 
     It is used to perform a gethostbyname(<address>) on the host and return
     the corresponding IP address as a 4-byte string.
@@ -209,7 +209,7 @@
 
        - creating a file named /tmp/update
        - reading 'size' bytes from the client and writing them to /tmp/update
-       - when everything is read succesfully, create a file named /tmp/update.start
+       - when everything is read successfully, create a file named /tmp/update.start
 
     This service can only work when the device is in recovery mode. Otherwise,
     the /tmp directory doesn't exist and the connection will be closed immediately.
diff --git a/adb/adb.c b/adb/adb.c
index 7df3f7b..4655d7c 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -144,9 +144,6 @@
 void handle_online(void)
 {
     D("adb: online\n");
-#if !ADB_HOST
-    property_set("adb.connected","1");
-#endif
 }
 
 void handle_offline(atransport *t)
@@ -154,9 +151,6 @@
     D("adb: offline\n");
     //Close the associated usb
     run_transport_disconnects(t);
-#if !ADB_HOST
-    property_set("adb.connected","");
-#endif
 }
 
 #if TRACE_PACKETS
@@ -693,7 +687,7 @@
 #endif
 
 #if ADB_HOST
-int launch_server()
+int launch_server(int server_port)
 {
 #ifdef HAVE_WIN32_PROC
     /* we need to start the server in the background                    */
@@ -828,7 +822,17 @@
 }
 #endif
 
-int adb_main(int is_daemon)
+/* Constructs a local name of form tcp:port.
+ * target_str points to the target string, it's content will be overwritten.
+ * target_size is the capacity of the target string.
+ * server_port is the port number to use for the local name.
+ */
+void build_local_name(char* target_str, size_t target_size, int server_port)
+{
+  snprintf(target_str, target_size, "tcp:%d", server_port);
+}
+
+int adb_main(int is_daemon, int server_port)
 {
 #if !ADB_HOST
     int secure = 0;
@@ -851,9 +855,11 @@
     HOST = 1;
     usb_vendors_init();
     usb_init();
-    local_init(ADB_LOCAL_TRANSPORT_PORT);
+    local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
 
-    if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
+    char local_name[30];
+    build_local_name(local_name, sizeof(local_name), server_port);
+    if(install_listener(local_name, "*smartsocket*", NULL)) {
         exit(1);
     }
 #else
@@ -879,7 +885,7 @@
         }
     }
 
-    /* don't listen on port 5037 if we are running in secure mode */
+    /* don't listen on a port (default 5037) if running in secure mode */
     /* don't run as root if we are running in secure mode */
     if (secure) {
         struct __user_cap_header_struct header;
@@ -911,18 +917,23 @@
         cap.inheritable = 0;
         capset(&header, &cap);
 
-        D("Local port 5037 disabled\n");
+        D("Local port disabled\n");
     } else {
-        if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
+        char local_name[30];
+        build_local_name(local_name, sizeof(local_name), server_port);
+        if(install_listener(local_name, "*smartsocket*", NULL)) {
             exit(1);
         }
     }
 
         /* for the device, start the usb transport if the
-        ** android usb device exists and "service.adb.tcp"
-        ** is not set, otherwise start the network transport.
+        ** android usb device exists and the "service.adb.tcp.port" and
+        ** "persist.adb.tcp.port" properties are not set.
+        ** Otherwise start the network transport.
         */
-    property_get("service.adb.tcp.port", value, "0");
+    property_get("service.adb.tcp.port", value, "");
+    if (!value[0])
+        property_get("persist.adb.tcp.port", value, "");
     if (sscanf(value, "%d", &port) == 1 && port > 0) {
         // listen on TCP port specified by service.adb.tcp.port property
         local_init(port);
@@ -931,7 +942,7 @@
         usb_init();
     } else {
         // listen on default port
-        local_init(ADB_LOCAL_TRANSPORT_PORT);
+        local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
     }
     init_jdwp();
 #endif
@@ -1172,6 +1183,6 @@
     }
 
     start_device_log();
-    return adb_main(0);
+    return adb_main(0, DEFAULT_ADB_PORT);
 #endif
 }
diff --git a/adb/adb.h b/adb/adb.h
index a148019..a2b611e 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -33,7 +33,7 @@
 #define ADB_VERSION_MAJOR 1         // Used for help/version information
 #define ADB_VERSION_MINOR 0         // Used for help/version information
 
-#define ADB_SERVER_VERSION    25    // Increment this when we want to force users to start a new adb server
+#define ADB_SERVER_VERSION    26    // Increment this when we want to force users to start a new adb server
 
 typedef struct amessage amessage;
 typedef struct apacket apacket;
@@ -237,8 +237,8 @@
 void send_packet(apacket *p, atransport *t);
 
 void get_my_path(char *s, size_t maxLen);
-int launch_server();
-int adb_main(int is_daemon);
+int launch_server(int server_port);
+int adb_main(int is_daemon, int server_port);
 
 
 /* transports are ref-counted
@@ -358,8 +358,8 @@
 #define print_packet(tag,p) do {} while (0)
 #endif
 
-#define ADB_PORT 5037
-#define ADB_LOCAL_TRANSPORT_PORT 5555
+#define DEFAULT_ADB_PORT 5037
+#define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555
 
 #define ADB_CLASS              0xff
 #define ADB_SUBCLASS           0x42
diff --git a/adb/adb_client.c b/adb/adb_client.c
index 243f0fa..882810a 100644
--- a/adb/adb_client.c
+++ b/adb/adb_client.c
@@ -16,12 +16,19 @@
 static transport_type __adb_transport = kTransportAny;
 static const char* __adb_serial = NULL;
 
+static int __adb_server_port = DEFAULT_ADB_PORT;
+
 void adb_set_transport(transport_type type, const char* serial)
 {
     __adb_transport = type;
     __adb_serial = serial;
 }
 
+void adb_set_tcp_specifics(int server_port)
+{
+    __adb_server_port = server_port;
+}
+
 int  adb_get_emulator_console_port(void)
 {
     const char*   serial = __adb_serial;
@@ -174,7 +181,7 @@
     }
     snprintf(tmp, sizeof tmp, "%04x", len);
 
-    fd = socket_loopback_client(ADB_PORT, SOCK_STREAM);
+    fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
     if(fd < 0) {
         strcpy(__adb_error, "cannot connect to daemon");
         return -2;
@@ -204,9 +211,10 @@
     int fd = _adb_connect("host:version");
 
     if(fd == -2) {
-        fprintf(stdout,"* daemon not running. starting it now *\n");
+        fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
+                __adb_server_port);
     start_server:
-        if(launch_server(0)) {
+        if(launch_server(__adb_server_port)) {
             fprintf(stderr,"* failed to start daemon *\n");
             return -1;
         } else {
@@ -314,5 +322,3 @@
     adb_close(fd);
     return 0;
 }
-
-
diff --git a/adb/adb_client.h b/adb/adb_client.h
index 8061579..40ab189 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -25,6 +25,10 @@
 */
 void adb_set_transport(transport_type type, const char* serial);
 
+/* Set TCP specifics of the transport to use
+*/
+void adb_set_tcp_specifics(int server_port);
+
 /* Return the console port of the currently connected emulator (if any)
  * of -1 if there is no emulator, and -2 if there is more than one.
  * assumes adb_set_transport() was alled previously...
diff --git a/adb/commandline.c b/adb/commandline.c
index 52bcedc..8003a64 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -105,13 +105,14 @@
         "                                 environment variable is used, which must\n"
         "                                 be an absolute path.\n"
         " devices                       - list all connected devices\n"
-        " connect <host>:<port>         - connect to a device via TCP/IP"
-        " disconnect <host>:<port>      - disconnect from a TCP/IP device"
+        " connect <host>:<port>         - connect to a device via TCP/IP\n"
+        " disconnect <host>:<port>      - disconnect from a TCP/IP device\n"
         "\n"
         "device commands:\n"
         "  adb push <local> <remote>    - copy file/dir to device\n"
-        "  adb pull <remote> <local>    - copy file/dir from device\n"
+        "  adb pull <remote> [<local>]  - copy file/dir from device\n"
         "  adb sync [ <directory> ]     - copy host->device only if changed\n"
+        "                                 (-l means list but don't copy)\n"
         "                                 (see 'adb help all')\n"
         "  adb shell                    - run remote shell interactively\n"
         "  adb shell <command>          - run remote shell command\n"
@@ -151,8 +152,9 @@
         "  adb status-window            - continuously print device status for a specified device\n"
         "  adb remount                  - remounts the /system partition on the device read-write\n"
         "  adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
+        "  adb reboot-bootloader        - reboots the device into the bootloader\n"
         "  adb root                     - restarts the adbd daemon with root permissions\n"
-        "  adb usb                      - restarts the adbd daemon listening on USB"
+        "  adb usb                      - restarts the adbd daemon listening on USB\n"
         "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port"
         "\n"
         "networking:\n"
@@ -168,6 +170,12 @@
         "\n"
         "  - If it is \"system\" or \"data\", only the corresponding partition\n"
         "    is updated.\n"
+        "\n"
+        "environmental variables:\n"
+        "  ADB_TRACE                    - Print debug information. A comma separated list of the following values\n"
+        "                                 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
+        "  ANDROID_SERIAL               - The serial number to connect to. -s takes priority over this if given.\n"
+        "  ANDROID_LOG_TAGS             - When used with the logcat option, only these debug tags are printed.\n"
         );
 }
 
@@ -219,8 +227,8 @@
             if(errno == EINTR) continue;
             break;
         }
-        /* we want to output to stdout, so no adb_write here !! */
-        unix_write(1, buf, len);
+        fwrite(buf, 1, len, stdout);
+        fflush(stdout);
     }
 }
 
@@ -759,6 +767,7 @@
     int quote;
     transport_type ttype = kTransportAny;
     char* serial = NULL;
+    char* server_port_str = NULL;
 
         /* If defined, this should be an absolute path to
          * the directory containing all of the various system images
@@ -774,7 +783,20 @@
 
     serial = getenv("ANDROID_SERIAL");
 
-        /* modifiers and flags */
+    /* Validate and assign the server port */
+    server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
+    int server_port = DEFAULT_ADB_PORT;
+    if (server_port_str && strlen(server_port_str) > 0) {
+        server_port = (int) strtol(server_port_str, NULL, 0);
+        if (server_port <= 0) {
+            fprintf(stderr,
+                    "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number. Got \"%s\"\n",
+                    server_port_str);
+            return usage();
+        }
+    }
+
+    /* modifiers and flags */
     while(argc > 0) {
         if(!strcmp(argv[0],"nodaemon")) {
             no_daemon = 1;
@@ -803,7 +825,7 @@
             if (isdigit(argv[0][2])) {
                 serial = argv[0] + 2;
             } else {
-                if(argc < 2) return usage();
+                if(argc < 2 || argv[0][2] != '\0') return usage();
                 serial = argv[1];
                 argc--;
                 argv++;
@@ -821,12 +843,13 @@
     }
 
     adb_set_transport(ttype, serial);
+    adb_set_tcp_specifics(server_port);
 
     if ((argc > 0) && (!strcmp(argv[0],"server"))) {
         if (no_daemon || is_daemon) {
-            r = adb_main(is_daemon);
+            r = adb_main(is_daemon, server_port);
         } else {
-            r = launch_server();
+            r = launch_server(server_port);
         }
         if(r) {
             fprintf(stderr,"* could not start server *\n");
@@ -891,10 +914,10 @@
             /* quote empty strings and strings with spaces */
             quote = (**argv == 0 || strchr(*argv, ' '));
             if (quote)
-            	strcat(buf, "\"");
+                strcat(buf, "\"");
             strcat(buf, *argv++);
             if (quote)
-            	strcat(buf, "\"");
+                strcat(buf, "\"");
         }
 
         for(;;) {
@@ -929,10 +952,13 @@
     }
 
     if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
+            || !strcmp(argv[0], "reboot-bootloader")
             || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
             || !strcmp(argv[0], "root")) {
         char command[100];
-        if (argc > 1)
+        if (!strcmp(argv[0], "reboot-bootloader"))
+            snprintf(command, sizeof(command), "reboot:bootloader");
+        else if (argc > 1)
             snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
         else
             snprintf(command, sizeof(command), "%s:", argv[0]);
@@ -947,10 +973,8 @@
     }
 
     if(!strcmp(argv[0], "bugreport")) {
-        if (argc != 1) {
-            return 1;
-        }
-        do_cmd(ttype, serial, "shell", "dumpstate", "-", 0);
+        if (argc != 1) return usage();
+        do_cmd(ttype, serial, "shell", "bugreport", 0);
         return 0;
     }
 
@@ -990,9 +1014,13 @@
     if(!strcmp(argv[0], "forward")) {
         if(argc != 3) return usage();
         if (serial) {
-            snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial,argv[1],argv[2]);
+            snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial, argv[1], argv[2]);
+        } else if (ttype == kTransportUsb) {
+            snprintf(buf, sizeof buf, "host-usb:forward:%s;%s", argv[1], argv[2]);
+        } else if (ttype == kTransportLocal) {
+            snprintf(buf, sizeof buf, "host-local:forward:%s;%s", argv[1], argv[2]);
         } else {
-            snprintf(buf, sizeof buf, "host:forward:%s;%s",argv[1],argv[2]);
+            snprintf(buf, sizeof buf, "host:forward:%s;%s", argv[1], argv[2]);
         }
         if(adb_command(buf)) {
             fprintf(stderr,"error: %s\n", adb_error());
@@ -1014,8 +1042,13 @@
     }
 
     if(!strcmp(argv[0], "pull")) {
-        if(argc != 3) return usage();
-        return do_sync_pull(argv[1], argv[2]);
+        if (argc == 2) {
+            return do_sync_pull(argv[1], ".");
+        } else if (argc == 3) {
+            return do_sync_pull(argv[1], argv[2]);
+        } else {
+            return usage();
+        }
     }
 
     if(!strcmp(argv[0], "install")) {
@@ -1030,10 +1063,19 @@
 
     if(!strcmp(argv[0], "sync")) {
         char *srcarg, *android_srcpath, *data_srcpath;
+        int listonly = 0;
+
         int ret;
         if(argc < 2) {
             /* No local path was specified. */
             srcarg = NULL;
+        } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
+            listonly = 1;
+            if (argc == 3) {
+                srcarg = argv[2];
+            } else {
+                srcarg = NULL;
+            }
         } else if(argc == 2) {
             /* A local path or "android"/"data" arg was specified. */
             srcarg = argv[1];
@@ -1044,9 +1086,9 @@
         if(ret != 0) return usage();
 
         if(android_srcpath != NULL)
-            ret = do_sync_sync(android_srcpath, "/system");
+            ret = do_sync_sync(android_srcpath, "/system", listonly);
         if(ret == 0 && data_srcpath != NULL)
-            ret = do_sync_sync(data_srcpath, "/data");
+            ret = do_sync_sync(data_srcpath, "/data", listonly);
 
         free(android_srcpath);
         free(data_srcpath);
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index 0ebfe73..da25ae8 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -670,7 +670,7 @@
 }
 
 
-static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, int checktimestamps)
+static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, int checktimestamps, int listonly)
 {
     copyinfo *filelist = 0;
     copyinfo *ci, *next;
@@ -718,8 +718,9 @@
     for(ci = filelist; ci != 0; ci = next) {
         next = ci->next;
         if(ci->flag == 0) {
-            fprintf(stderr,"push: %s -> %s\n", ci->src, ci->dst);
-            if(sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */)){
+            fprintf(stderr,"%spush: %s -> %s\n", listonly ? "would " : "", ci->src, ci->dst);
+            if(!listonly &&
+               sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */)){
                 return 1;
             }
             pushed++;
@@ -757,7 +758,7 @@
 
     if(S_ISDIR(st.st_mode)) {
         BEGIN();
-        if(copy_local_dir_remote(fd, lpath, rpath, 0)) {
+        if(copy_local_dir_remote(fd, lpath, rpath, 0, 0)) {
             return 1;
         } else {
             END();
@@ -959,7 +960,7 @@
         return 1;
     }
 
-    if(S_ISREG(mode) || S_ISCHR(mode) || S_ISBLK(mode)) {
+    if(S_ISREG(mode) || S_ISLNK(mode) || S_ISCHR(mode) || S_ISBLK(mode)) {
         if(stat(lpath, &st) == 0) {
             if(S_ISDIR(st.st_mode)) {
                     /* if we're copying a remote file to a local directory,
@@ -1001,7 +1002,7 @@
     }
 }
 
-int do_sync_sync(const char *lpath, const char *rpath)
+int do_sync_sync(const char *lpath, const char *rpath, int listonly)
 {
     fprintf(stderr,"syncing %s...\n",rpath);
 
@@ -1012,7 +1013,7 @@
     }
 
     BEGIN();
-    if(copy_local_dir_remote(fd, lpath, rpath, 1)){
+    if(copy_local_dir_remote(fd, lpath, rpath, 1, listonly)){
         return 1;
     } else {
         END();
diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h
index 4ee40ba..11ea06b 100644
--- a/adb/file_sync_service.h
+++ b/adb/file_sync_service.h
@@ -79,7 +79,7 @@
 void file_sync_service(int fd, void *cookie);
 int do_sync_ls(const char *path);
 int do_sync_push(const char *lpath, const char *rpath, int verifyApk);
-int do_sync_sync(const char *lpath, const char *rpath);
+int do_sync_sync(const char *lpath, const char *rpath, int listonly);
 int do_sync_pull(const char *rpath, const char *lpath);
 
 #define SYNC_DATA_MAX (64*1024)
diff --git a/adb/transport_local.c b/adb/transport_local.c
index 81d120e..cfd3b4b 100644
--- a/adb/transport_local.c
+++ b/adb/transport_local.c
@@ -132,7 +132,7 @@
 static void *client_socket_thread(void *x)
 {
 #if ADB_HOST
-    int  port  = ADB_LOCAL_TRANSPORT_PORT;
+    int  port  = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
     int  count = ADB_LOCAL_TRANSPORT_MAX;
 
     D("transport: client_socket_thread() starting\n");
@@ -244,7 +244,7 @@
     if (HOST && local) {
         adb_mutex_lock( &local_transports_lock );
         {
-            int  index = (port - ADB_LOCAL_TRANSPORT_PORT)/2;
+            int  index = (port - DEFAULT_ADB_LOCAL_TRANSPORT_PORT)/2;
 
             if (!(port & 1) || index < 0 || index >= ADB_LOCAL_TRANSPORT_MAX) {
                 D("bad local transport port number: %d\n", port);
diff --git a/adb/usb_linux.c b/adb/usb_linux.c
index 863af1d..bb86813 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.c
@@ -21,6 +21,7 @@
 
 #include <sys/ioctl.h>
 #include <sys/types.h>
+#include <sys/time.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -150,13 +151,13 @@
         while((de = readdir(devdir))) {
             unsigned char devdesc[256];
             unsigned char* bufptr = devdesc;
+            unsigned char* bufend;
             struct usb_device_descriptor* device;
             struct usb_config_descriptor* config;
             struct usb_interface_descriptor* interface;
             struct usb_endpoint_descriptor *ep1, *ep2;
             unsigned zero_mask = 0;
             unsigned vid, pid;
-            int i, interfaces;
             size_t desclength;
 
             if(badname(de->d_name)) continue;
@@ -173,6 +174,7 @@
             }
 
             desclength = adb_read(fd, devdesc, sizeof(devdesc));
+            bufend = bufptr + desclength;
 
                 // should have device and configuration descriptors, and atleast two endpoints
             if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) {
@@ -203,75 +205,73 @@
                 continue;
             }
 
-                // loop through all the interfaces and look for the ADB interface
-            interfaces = config->bNumInterfaces;
-            for (i = 0; i < interfaces; i++) {
-                if (bufptr + USB_DT_ENDPOINT_SIZE > devdesc + desclength)
-                    break;
+                // loop through all the descriptors and look for the ADB interface
+            while (bufptr < bufend) {
+                unsigned char length = bufptr[0];
+                unsigned char type = bufptr[1];
 
-                interface = (struct usb_interface_descriptor *)bufptr;
-                bufptr += USB_DT_INTERFACE_SIZE;
-                if (interface->bLength != USB_DT_INTERFACE_SIZE ||
-                    interface->bDescriptorType != USB_DT_INTERFACE) {
-                    D("usb_interface_descriptor not found\n");
-                    break;
-                }
+                if (type == USB_DT_INTERFACE) {
+                    interface = (struct usb_interface_descriptor *)bufptr;
+                    bufptr += length;
 
-                DBGX("bInterfaceClass: %d,  bInterfaceSubClass: %d,"
-                     "bInterfaceProtocol: %d, bNumEndpoints: %d\n",
-                     interface->bInterfaceClass, interface->bInterfaceSubClass,
-                     interface->bInterfaceProtocol, interface->bNumEndpoints);
-
-                if (interface->bNumEndpoints == 2 &&
-                        is_adb_interface(vid, pid, interface->bInterfaceClass,
-                        interface->bInterfaceSubClass, interface->bInterfaceProtocol))  {
-
-                    DBGX("looking for bulk endpoints\n");
-                        // looks like ADB...
-                    ep1 = (struct usb_endpoint_descriptor *)bufptr;
-                    bufptr += USB_DT_ENDPOINT_SIZE;
-                    ep2 = (struct usb_endpoint_descriptor *)bufptr;
-                    bufptr += USB_DT_ENDPOINT_SIZE;
-
-                    if (bufptr > devdesc + desclength ||
-                        ep1->bLength != USB_DT_ENDPOINT_SIZE ||
-                        ep1->bDescriptorType != USB_DT_ENDPOINT ||
-                        ep2->bLength != USB_DT_ENDPOINT_SIZE ||
-                        ep2->bDescriptorType != USB_DT_ENDPOINT) {
-                        D("endpoints not found\n");
+                    if (length != USB_DT_INTERFACE_SIZE) {
+                        D("interface descriptor has wrong size\n");
                         break;
                     }
 
-                        // both endpoints should be bulk
-                    if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK ||
-                        ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) {
-                        D("bulk endpoints not found\n");
-                        continue;
+                    DBGX("bInterfaceClass: %d,  bInterfaceSubClass: %d,"
+                         "bInterfaceProtocol: %d, bNumEndpoints: %d\n",
+                         interface->bInterfaceClass, interface->bInterfaceSubClass,
+                         interface->bInterfaceProtocol, interface->bNumEndpoints);
+
+                    if (interface->bNumEndpoints == 2 &&
+                            is_adb_interface(vid, pid, interface->bInterfaceClass,
+                            interface->bInterfaceSubClass, interface->bInterfaceProtocol))  {
+
+                        DBGX("looking for bulk endpoints\n");
+                            // looks like ADB...
+                        ep1 = (struct usb_endpoint_descriptor *)bufptr;
+                        bufptr += USB_DT_ENDPOINT_SIZE;
+                        ep2 = (struct usb_endpoint_descriptor *)bufptr;
+                        bufptr += USB_DT_ENDPOINT_SIZE;
+
+                        if (bufptr > devdesc + desclength ||
+                            ep1->bLength != USB_DT_ENDPOINT_SIZE ||
+                            ep1->bDescriptorType != USB_DT_ENDPOINT ||
+                            ep2->bLength != USB_DT_ENDPOINT_SIZE ||
+                            ep2->bDescriptorType != USB_DT_ENDPOINT) {
+                            D("endpoints not found\n");
+                            break;
+                        }
+
+                            // both endpoints should be bulk
+                        if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK ||
+                            ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) {
+                            D("bulk endpoints not found\n");
+                            continue;
+                        }
+                            /* aproto 01 needs 0 termination */
+                        if(interface->bInterfaceProtocol == 0x01) {
+                            zero_mask = ep1->wMaxPacketSize - 1;
+                        }
+
+                            // we have a match.  now we just need to figure out which is in and which is out.
+                        if (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+                            local_ep_in = ep1->bEndpointAddress;
+                            local_ep_out = ep2->bEndpointAddress;
+                        } else {
+                            local_ep_in = ep2->bEndpointAddress;
+                            local_ep_out = ep1->bEndpointAddress;
+                        }
+
+                        register_device_callback(devname, local_ep_in, local_ep_out,
+                                interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
+                        break;
                     }
-
-                        /* aproto 01 needs 0 termination */
-                    if(interface->bInterfaceProtocol == 0x01) {
-                        zero_mask = ep1->wMaxPacketSize - 1;
-                    }
-
-                        // we have a match.  now we just need to figure out which is in and which is out.
-                    if (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
-                        local_ep_in = ep1->bEndpointAddress;
-                        local_ep_out = ep2->bEndpointAddress;
-                    } else {
-                        local_ep_in = ep2->bEndpointAddress;
-                        local_ep_out = ep1->bEndpointAddress;
-                    }
-
-                    register_device_callback(devname, local_ep_in, local_ep_out,
-                            interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
-
-                    break;
                 } else {
-                    // seek next interface descriptor
-                    bufptr += (USB_DT_ENDPOINT_SIZE * interface->bNumEndpoints);
-                 }
-            } // end of for
+                    bufptr += length;
+                }
+            } // end of while
 
             adb_close(fd);
         } // end of devdir while
@@ -288,6 +288,8 @@
 {
     struct usbdevfs_urb *urb = &h->urb_out;
     int res;
+    struct timeval tv;
+    struct timespec ts;
 
     memset(urb, 0, sizeof(*urb));
     urb->type = USBDEVFS_URB_TYPE_BULK;
@@ -314,8 +316,12 @@
     res = -1;
     h->urb_out_busy = 1;
     for(;;) {
-        adb_cond_wait(&h->notify, &h->lock);
-        if(h->dead) {
+        /* time out after five seconds */
+        gettimeofday(&tv, NULL);
+        ts.tv_sec = tv.tv_sec + 5;
+        ts.tv_nsec = tv.tv_usec * 1000L;
+        res = pthread_cond_timedwait(&h->notify, &h->lock, &ts);
+        if(res < 0 || h->dead) {
             break;
         }
         if(h->urb_out_busy == 0) {
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 064abc0..7f3cb54 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -51,6 +51,23 @@
 #define VENDOR_ID_ACER          0x0502
 // Sony Ericsson's USB Vendor ID
 #define VENDOR_ID_SONY_ERICSSON 0x0FCE
+// Foxconn's USB Vendor ID
+#define VENDOR_ID_FOXCONN       0x0489
+// Dell's USB Vendor ID
+#define VENDOR_ID_DELL          0x413c
+// Nvidia's USB Vendor ID
+#define VENDOR_ID_NVIDIA        0x0955
+// Garmin-Asus's USB Vendor ID
+#define VENDOR_ID_GARMIN_ASUS   0x091E
+// Sharp's USB Vendor ID
+#define VENDOR_ID_SHARP         0x04dd
+// ZTE's USB Vendor ID
+#define VENDOR_ID_ZTE           0x19D2
+// Kyocera's USB Vendor ID
+#define VENDOR_ID_KYOCERA       0x0482
+// Pantech's USB Vendor ID
+#define VENDOR_ID_PANTECH       0x10A9
+
 
 /** built-in vendor list */
 int builtInVendorIds[] = {
@@ -62,6 +79,14 @@
     VENDOR_ID_HUAWEI,
     VENDOR_ID_ACER,
     VENDOR_ID_SONY_ERICSSON,
+    VENDOR_ID_FOXCONN,
+    VENDOR_ID_DELL,
+    VENDOR_ID_NVIDIA,
+    VENDOR_ID_GARMIN_ASUS,
+    VENDOR_ID_SHARP,
+    VENDOR_ID_ZTE,
+    VENDOR_ID_KYOCERA,
+    VENDOR_ID_PANTECH,
 };
 
 #define BUILT_IN_VENDOR_COUNT    (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index 1a0183f..1308f26 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -151,6 +151,7 @@
        (info->dev_vendor != 0x0451) &&
        (info->dev_vendor != 0x22b8) &&  // Motorola
        (info->dev_vendor != 0x0502) &&
+       (info->dev_vendor != 0x413c) &&  // DELL
        (info->dev_vendor != 0x0bb4))    // HTC
             return -1;
     if(info->ifc_class != 0xff) return -1;
diff --git a/include/arch/darwin-x86/AndroidConfig.h b/include/arch/darwin-x86/AndroidConfig.h
index 20e0000..363a8f7 100644
--- a/include/arch/darwin-x86/AndroidConfig.h
+++ b/include/arch/darwin-x86/AndroidConfig.h
@@ -146,7 +146,7 @@
  */
 #if (defined(__ppc__) || defined(__ppc64__))
 #   define HAVE_BIG_ENDIAN
-#elif defined(__i386__)
+#elif (defined(__i386__) || defined(__x86_64__))
 #   define HAVE_LITTLE_ENDIAN
 #endif
 
@@ -219,7 +219,7 @@
  */
 #if (defined(__ppc__) || defined(__ppc64__))
 #   define ARCH_PPC
-#elif defined(__i386__)
+#elif (defined(__i386__) || defined(__x86_64__))
 #   define ARCH_X86
 #endif
 
diff --git a/init/devices.c b/init/devices.c
index 55c5ee4..1dffcd4 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -138,6 +138,7 @@
     { "/dev/msm_snd",       0660,   AID_SYSTEM,     AID_AUDIO,      1 },
     { "/dev/msm_mp3",       0660,   AID_SYSTEM,     AID_AUDIO,      1 },
     { "/dev/audience_a1026", 0660,   AID_SYSTEM,     AID_AUDIO,      1 },
+    { "/dev/tpa2018d1",     0660,   AID_SYSTEM,     AID_AUDIO,      1 },
     { "/dev/msm_audpre",    0660,   AID_SYSTEM,     AID_AUDIO,      0 },
     { "/dev/msm_audio_ctl", 0660,   AID_SYSTEM,     AID_AUDIO,      0 },
     { "/dev/htc-acoustic",  0660,   AID_SYSTEM,     AID_AUDIO,      0 },
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index 64d9bb7..8134aa1 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -53,13 +53,22 @@
     sprintf(path, "/dev/cpuctl/%s/tasks", grp_name);
 
     if ((fd = open(path, O_WRONLY)) < 0) {
-        LOGE("add_tid_to_cgroup failed to open '%s' (%s)\n", path, strerror(errno));
+        LOGE("add_tid_to_cgroup failed to open '%s' (%s)\n", path,
+             strerror(errno));
         return -1;
     }
 
     sprintf(text, "%d", tid);
     if (write(fd, text, strlen(text)) < 0) {
         close(fd);
+	/*
+	 * If the thread is in the process of exiting,
+	 * don't flag an error
+	 */
+	if (errno == ESRCH)
+		return 0;
+        LOGW("add_tid_to_cgroup failed to write '%s' (%s)\n", path,
+             strerror(errno));
         return -1;
     }
 
diff --git a/liblog/logprint.c b/liblog/logprint.c
index 080f9e3..acfa9f4 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -753,6 +753,16 @@
             suffixLen = 1;
             break;
     }
+    /* snprintf has a weird return value.   It returns what would have been
+     * written given a large enough buffer.  In the case that the prefix is
+     * longer then our buffer(128), it messes up the calculations below
+     * possibly causing heap corruption.  To avoid this we double check and
+     * set the length at the maximum (size minus null byte)
+     */
+    if(prefixLen >= sizeof(prefixBuf))
+        prefixLen = sizeof(prefixBuf) - 1;
+    if(suffixLen >= sizeof(suffixBuf))
+        suffixLen = sizeof(suffixBuf) - 1;
 
     /* the following code is tragically unreadable */
 
diff --git a/libpixelflinger/Android.mk b/libpixelflinger/Android.mk
index 0cc85d9..6491d24 100644
--- a/libpixelflinger/Android.mk
+++ b/libpixelflinger/Android.mk
@@ -40,7 +40,13 @@
 	buffer.cpp
 
 ifeq ($(TARGET_ARCH),arm)
+ifeq ($(TARGET_ARCH_VERSION),armv7-a)
+PIXELFLINGER_SRC_FILES += col32cb16blend_neon.S
+PIXELFLINGER_SRC_FILES += col32cb16blend.S
+else
 PIXELFLINGER_SRC_FILES += t32cb16blend.S
+PIXELFLINGER_SRC_FILES += col32cb16blend.S
+endif
 endif
 
 ifeq ($(TARGET_ARCH),arm)
diff --git a/libpixelflinger/col32cb16blend.S b/libpixelflinger/col32cb16blend.S
new file mode 100644
index 0000000..1450bde
--- /dev/null
+++ b/libpixelflinger/col32cb16blend.S
@@ -0,0 +1,78 @@
+/* libs/pixelflinger/col32cb16blend.S
+**
+** (C) COPYRIGHT 2009 ARM Limited.
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+**
+*/
+
+    .text
+    .align
+
+    .global scanline_col32cb16blend_arm
+
+//
+// This function alpha blends a fixed color into a destination scanline, using
+// the formula:
+//
+//     d = s + (((a + (a >> 7)) * d) >> 8)
+//
+// where d is the destination pixel,
+//       s is the source color,
+//       a is the alpha channel of the source color.
+//
+
+// r0 = destination buffer pointer
+// r1 = color value
+// r2 = count
+
+
+scanline_col32cb16blend_arm:
+    push        {r4-r10, lr}                    // stack ARM regs
+
+    mov         r5, r1, lsr #24                 // shift down alpha
+    mov         r9, #0xff                       // create mask
+    add         r5, r5, r5, lsr #7              // add in top bit
+    rsb         r5, r5, #256                    // invert alpha
+    and         r10, r1, #0xff                  // extract red
+    and         r12, r9, r1, lsr #8             // extract green
+    and         r4, r9, r1, lsr #16             // extract blue
+    mov         r10, r10, lsl #5                // prescale red
+    mov         r12, r12, lsl #6                // prescale green
+    mov         r4, r4, lsl #5                  // prescale blue
+    mov         r9, r9, lsr #2                  // create dest green mask
+
+1:
+    ldrh        r8, [r0]                        // load dest pixel
+    subs        r2, r2, #1                      // decrement loop counter
+    mov         r6, r8, lsr #11                 // extract dest red
+    and         r7, r9, r8, lsr #5              // extract dest green
+    and         r8, r8, #0x1f                   // extract dest blue
+
+    smlabb      r6, r6, r5, r10                 // dest red * alpha + src red
+    smlabb      r7, r7, r5, r12                 // dest green * alpha + src green
+    smlabb      r8, r8, r5, r4                  // dest blue * alpha + src blue
+
+    mov         r6, r6, lsr #8                  // shift down red
+    mov         r7, r7, lsr #8                  // shift down green
+    mov         r6, r6, lsl #11                 // shift red into 565
+    orr         r6, r7, lsl #5                  // shift green into 565
+    orr         r6, r8, lsr #8                  // shift blue into 565
+
+    strh        r6, [r0], #2                    // store pixel to dest, update ptr
+    bne         1b                              // if count != 0, loop
+
+    pop         {r4-r10, pc}                    // return
+
+
+
diff --git a/libpixelflinger/col32cb16blend_neon.S b/libpixelflinger/col32cb16blend_neon.S
new file mode 100644
index 0000000..17b0d01
--- /dev/null
+++ b/libpixelflinger/col32cb16blend_neon.S
@@ -0,0 +1,153 @@
+/* libs/pixelflinger/col32cb16blend_neon.S
+**
+** (C) COPYRIGHT 2009 ARM Limited.
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+**
+*/
+
+    .text
+    .align
+
+    .global scanline_col32cb16blend_neon
+
+//
+// This function alpha blends a fixed color into a destination scanline, using
+// the formula:
+//
+//     d = s + (((a + (a >> 7)) * d) >> 8)
+//
+// where d is the destination pixel,
+//       s is the source color,
+//       a is the alpha channel of the source color.
+//
+// The NEON implementation processes 16 pixels per iteration. The remaining 0 - 15
+// pixels are processed in ARM code.
+//
+
+// r0 = destination buffer pointer
+// r1 = color pointer
+// r2 = count
+
+
+scanline_col32cb16blend_neon:
+    push        {r4-r11, lr}                    // stack ARM regs
+
+    vmov.u16    q15, #256                       // create alpha constant
+    movs        r3, r2, lsr #4                  // calc. sixteens iterations
+    vmov.u16    q14, #0x1f                      // create blue mask
+
+    beq         2f                              // if r3 == 0, branch to singles
+
+    vld4.8      {d0[], d2[], d4[], d6[]}, [r1]  // load color into four registers
+                                                //  split and duplicate them, such that
+                                                //  d0 = 8 equal red values
+                                                //  d2 = 8 equal green values
+                                                //  d4 = 8 equal blue values
+                                                //  d6 = 8 equal alpha values
+    vshll.u8    q0, d0, #5                      // shift up red and widen
+    vshll.u8    q1, d2, #6                      // shift up green and widen
+    vshll.u8    q2, d4, #5                      // shift up blue and widen
+
+    vshr.u8     d7, d6, #7                      // extract top bit of alpha
+    vaddl.u8    q3, d6, d7                      // add top bit into alpha
+    vsub.u16    q3, q15, q3                     // invert alpha
+
+1:
+    // This loop processes 16 pixels per iteration. In the comments, references to
+    // the first eight pixels are suffixed with "0" (red0, green0, blue0), 
+    // the second eight are suffixed "1".
+                                                // q8  = dst red0
+                                                // q9  = dst green0
+                                                // q10 = dst blue0
+                                                // q13 = dst red1
+                                                // q12 = dst green1
+                                                // q11 = dst blue1
+
+    vld1.16     {d20, d21, d22, d23}, [r0]      // load 16 dest pixels
+    vshr.u16    q8, q10, #11                    // shift dst red0 to low 5 bits
+    pld         [r0, #63]                       // preload next dest pixels
+    vshl.u16    q9, q10, #5                     // shift dst green0 to top 6 bits
+    vand        q10, q10, q14                   // extract dst blue0
+    vshr.u16    q9, q9, #10                     // shift dst green0 to low 6 bits
+    vmul.u16    q8, q8, q3                      // multiply dst red0 by src alpha
+    vshl.u16    q12, q11, #5                    // shift dst green1 to top 6 bits
+    vmul.u16    q9, q9, q3                      // multiply dst green0 by src alpha
+    vshr.u16    q13, q11, #11                   // shift dst red1 to low 5 bits
+    vmul.u16    q10, q10, q3                    // multiply dst blue0 by src alpha
+    vshr.u16    q12, q12, #10                   // shift dst green1 to low 6 bits
+    vand        q11, q11, q14                   // extract dst blue1
+    vadd.u16    q8, q8, q0                      // add src red to dst red0
+    vmul.u16    q13, q13, q3                    // multiply dst red1 by src alpha
+    vadd.u16    q9, q9, q1                      // add src green to dst green0 
+    vmul.u16    q12, q12, q3                    // multiply dst green1 by src alpha
+    vadd.u16    q10, q10, q2                    // add src blue to dst blue0
+    vmul.u16    q11, q11, q3                    // multiply dst blue1 by src alpha
+    vshr.u16    q8, q8, #8                      // shift down red0
+    vadd.u16    q13, q13, q0                    // add src red to dst red1
+    vshr.u16    q9, q9, #8                      // shift down green0
+    vadd.u16    q12, q12, q1                    // add src green to dst green1
+    vshr.u16    q10, q10, #8                    // shift down blue0
+    vadd.u16    q11, q11, q2                    // add src blue to dst blue1
+    vsli.u16    q10, q9, #5                     // shift & insert green0 into blue0
+    vshr.u16    q13, q13, #8                    // shift down red1
+    vsli.u16    q10, q8, #11                    // shift & insert red0 into blue0    
+    vshr.u16    q12, q12, #8                    // shift down green1
+    vshr.u16    q11, q11, #8                    // shift down blue1
+    subs        r3, r3, #1                      // decrement loop counter
+    vsli.u16    q11, q12, #5                    // shift & insert green1 into blue1
+    vsli.u16    q11, q13, #11                   // shift & insert red1 into blue1
+
+    vst1.16     {d20, d21, d22, d23}, [r0]!     // write 16 pixels back to dst
+    bne         1b                              // if count != 0, loop
+
+2:
+    ands        r3, r2, #15                     // calc. single iterations 
+    beq         4f                              // if r3 == 0, exit
+
+    ldr         r4, [r1]                        // load source color
+    mov         r5, r4, lsr #24                 // shift down alpha
+    add         r5, r5, r5, lsr #7              // add in top bit
+    rsb         r5, r5, #256                    // invert alpha
+    and         r11, r4, #0xff                  // extract red
+    ubfx        r12, r4, #8, #8                 // extract green
+    ubfx        r4, r4, #16, #8                 // extract blue
+    mov         r11, r11, lsl #5                // prescale red
+    mov         r12, r12, lsl #6                // prescale green
+    mov         r4, r4, lsl #5                  // prescale blue
+
+3:
+    ldrh        r8, [r0]                        // load dest pixel
+    subs        r3, r3, #1                      // decrement loop counter
+    mov         r6, r8, lsr #11                 // extract dest red
+    ubfx        r7, r8, #5, #6                  // extract dest green
+    and         r8, r8, #0x1f                   // extract dest blue
+
+    smlabb      r6, r6, r5, r11                 // dest red * alpha + src red
+    smlabb      r7, r7, r5, r12                 // dest green * alpha + src green
+    smlabb      r8, r8, r5, r4                  // dest blue * alpha + src blue
+
+    mov         r6, r6, lsr #8                  // shift down red
+    mov         r7, r7, lsr #8                  // shift down green
+    mov         r6, r6, lsl #11                 // shift red into 565
+    orr         r6, r7, lsl #5                  // shift green into 565
+    orr         r6, r8, lsr #8                  // shift blue into 565
+
+    strh        r6, [r0], #2                    // store pixel to dest, update ptr
+    bne         3b                              // if count != 0, loop
+4:
+
+    pop         {r4-r11, pc}                    // return
+
+
+
diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp
index f700306..a2f43eb 100644
--- a/libpixelflinger/scanline.cpp
+++ b/libpixelflinger/scanline.cpp
@@ -80,6 +80,7 @@
 static void scanline_perspective_single(context_t* c);
 static void scanline_t32cb16blend(context_t* c);
 static void scanline_t32cb16(context_t* c);
+static void scanline_col32cb16blend(context_t* c);
 static void scanline_memcpy(context_t* c);
 static void scanline_memset8(context_t* c);
 static void scanline_memset16(context_t* c);
@@ -93,6 +94,8 @@
 
 extern "C" void scanline_t32cb16blend_arm(uint16_t*, uint32_t*, size_t);
 extern "C" void scanline_t32cb16_arm(uint16_t *dst, uint32_t *src, size_t ct);
+extern "C" void scanline_col32cb16blend_neon(uint16_t *dst, uint32_t *col, size_t ct);
+extern "C" void scanline_col32cb16blend_arm(uint16_t *dst, uint32_t col, size_t ct);
 
 // ----------------------------------------------------------------------------
 
@@ -111,6 +114,9 @@
     { { { 0x03010104, 0x00000077, { 0x00000A01, 0x00000000 } },
         { 0xFFFFFFFF, 0xFFFFFFFF, { 0xFFFFFFFF, 0x0000003F } } },
         "565 fb, 8888 tx", scanline_t32cb16, init_y_noop  },  
+    { { { 0x03515104, 0x00000077, { 0x00000000, 0x00000000 } },
+        { 0xFFFFFFFF, 0xFFFFFFFF, { 0xFFFFFFFF, 0xFFFFFFFF } } },
+        "565 fb, 8888 fixed color", scanline_col32cb16blend, init_y_packed  },  
     { { { 0x00000000, 0x00000000, { 0x00000000, 0x00000000 } },
         { 0x00000000, 0x00000007, { 0x00000000, 0x00000000 } } },
         "(nop) alpha test", scanline_noop, init_y_noop },
@@ -943,6 +949,8 @@
     uint8_t f = c->state.buffers.color.format;
     c->packed = ggl_pack_color(c, f,
             c->shade.r0, c->shade.g0, c->shade.b0, c->shade.a0);
+    c->packed8888 = ggl_pack_color(c, GGL_PIXEL_FORMAT_RGBA_8888,
+            c->shade.r0, c->shade.g0, c->shade.b0, c->shade.a0);
     c->iterators.y = y0;
     c->step_y = step_y__nop;
     // choose the rectangle blitter
@@ -1253,6 +1261,45 @@
 
 // ----------------------------------------------------------------------------
 
+void scanline_col32cb16blend(context_t* c)
+{
+    int32_t x = c->iterators.xl;
+    size_t ct = c->iterators.xr - x;
+    int32_t y = c->iterators.y;
+    surface_t* cb = &(c->state.buffers.color);
+    union {
+        uint16_t* dst;
+        uint32_t* dst32;
+    };
+    dst = reinterpret_cast<uint16_t*>(cb->data) + (x+(cb->stride*y));
+
+#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && defined(__arm__))
+#if defined(__ARM_HAVE_NEON) && BYTE_ORDER == LITTLE_ENDIAN
+    scanline_col32cb16blend_neon(dst, &(c->packed8888), ct);
+#else  // defined(__ARM_HAVE_NEON) && BYTE_ORDER == LITTLE_ENDIAN
+    scanline_col32cb16blend_arm(dst, GGL_RGBA_TO_HOST(c->packed8888), ct);
+#endif // defined(__ARM_HAVE_NEON) && BYTE_ORDER == LITTLE_ENDIAN
+#else
+    uint32_t s = GGL_RGBA_TO_HOST(c->packed8888);
+    int sA = (s>>24);
+    int f = 0x100 - (sA + (sA>>7));
+    while (ct--) {
+        uint16_t d = *dst;
+        int dR = (d>>11)&0x1f;
+        int dG = (d>>5)&0x3f;
+        int dB = (d)&0x1f;
+        int sR = (s >> (   3))&0x1F;
+        int sG = (s >> ( 8+2))&0x3F;
+        int sB = (s >> (16+3))&0x1F;
+        sR += (f*dR)>>8;
+        sG += (f*dG)>>8;
+        sB += (f*dB)>>8;
+        *dst++ = uint16_t((sR<<11)|(sG<<5)|sB);
+    }
+#endif
+
+}
+
 void scanline_t32cb16(context_t* c)
 {
     int32_t x = c->iterators.xl;
diff --git a/logcat/event-log-tags b/logcat/event-log-tags
index 2140b37..5c4c962 100644
--- a/logcat/event-log-tags
+++ b/logcat/event-log-tags
@@ -282,6 +282,8 @@
 30035 am_schedule_service_restart (Component Name|3),(Time|2|3)
 # A client was waiting for a content provider, but its process was lost
 30036 am_provider_lost_process (Package Name|3),(UID|1|5),(Name|3)
+# The activity manager gave up on a new process taking too long to start
+30037 am_process_start_timeout (PID|1|5),(UID|1|5),(Process Name|3)
 
 # Out of memory for surfaces.
 31000 wm_no_surface_memory (Window|3),(PID|1|5),(Operation|3)
@@ -369,6 +371,9 @@
 # CDMA data network drop
 50111 cdma_data_drop (cid|1|5), (network_type|1|5)
 
+# GSM radio access technology switched
+50112 gsm_rat_switched (cid|1|5), (network_from|1|5), (network_to|1|5)
+
 # Do not change these names without updating tag in:
 #//device/dalvik/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.c
 51000 socket_stats (send|1|2),(recv|1|2),(ip|1|5),(port|1|5),(close|1|5)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index f62d1d8..925347d 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -86,11 +86,6 @@
 
     write /proc/apanic_console 1
 
-    # Collect ramconsole data
-    copy /proc/last_kmsg /data/dontpanic/last_kmsg
-    chown root log /data/dontpanic/last_kmsg
-    chmod 0640 /data/dontpanic/last_kmsg
-
     # Same reason as /data above
     mount yaffs2 mtd@cache /cache nosuid nodev
     chown system cache /cache
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 70b13dc..bf7cfde 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -50,6 +50,7 @@
 	top \
 	iftop \
 	id \
+	uptime \
 	vmstat
 
 LOCAL_SRC_FILES:= \
diff --git a/toolbox/uptime.c b/toolbox/uptime.c
new file mode 100644
index 0000000..8b1983d
--- /dev/null
+++ b/toolbox/uptime.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/time.h>
+#include <linux/ioctl.h>
+#include <linux/rtc.h>
+#include <linux/android_alarm.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+
+static void format_time(int time, char* buffer) {
+    int seconds, minutes, hours, days;
+
+    seconds = time % 60;
+    time /= 60;
+    minutes = time % 60;
+    time /= 60;
+    hours = time % 24;
+    days = time / 24;
+
+    if (days > 0)
+        sprintf(buffer, "%d days, %02d:%02d:%02d", days, hours, minutes, seconds);
+    else
+        sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds);
+}
+
+int64_t elapsedRealtime()
+{
+    struct timespec ts;
+    int fd, result;
+
+    fd = open("/dev/alarm", O_RDONLY);
+    if (fd < 0)
+        return fd;
+
+   result = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
+   close(fd);
+
+    if (result == 0)
+        return ts.tv_sec;
+    return -1;
+}
+
+int uptime_main(int argc, char *argv[])
+{
+    float up_time, idle_time;
+    char up_string[100], idle_string[100], sleep_string[100];
+    int elapsed;
+
+    FILE* file = fopen("/proc/uptime", "r");
+    if (!file) {
+        fprintf(stderr, "Could not open /proc/uptime\n");
+        return -1;
+    }
+    if (fscanf(file, "%f %f", &up_time, &idle_time) != 2) {
+        fprintf(stderr, "Could not parse /proc/uptime\n");
+        fclose(file);
+        return -1;
+    }
+    fclose(file);
+
+    elapsed = elapsedRealtime();
+    if (elapsed < 0) {
+        fprintf(stderr, "elapsedRealtime failed\n");
+        return -1;
+    }
+
+    format_time(elapsed, up_string);
+    format_time((int)idle_time, idle_string);
+    format_time((int)(elapsed - up_time), sleep_string);
+    printf("up time: %s, idle time: %s, sleep time: %s\n", up_string, idle_string, sleep_string);
+
+    return 0;
+}
diff --git a/vold/volmgr.c b/vold/volmgr.c
index deb680e..a635b8e 100644
--- a/vold/volmgr.c
+++ b/vold/volmgr.c
@@ -1053,7 +1053,7 @@
             break;
     }
 
-    if (!fs) {
+    if (!fs->name) {
         LOGE("No supported filesystems on %d:%d", dev->major, dev->minor);
         volume_setstate(vol, volstate_nofs);
         return -ENODATA;