diff options
35 files changed, 1336 insertions, 46 deletions
diff --git a/adb/Android.mk b/adb/Android.mk index f3eaa6e0..6325e53f 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -25,6 +25,12 @@ ifeq ($(HOST_OS),darwin) LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon endif +ifeq ($(HOST_OS),freebsd) + USB_SRCS := usb_libusb.c + EXTRA_SRCS := get_my_path_freebsd.c + LOCAL_LDLIBS += -lpthread -lusb +endif + ifeq ($(HOST_OS),windows) USB_SRCS := usb_windows.c EXTRA_SRCS := get_my_path_windows.c @@ -783,7 +783,7 @@ int launch_server() fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); return -1; } - get_my_path(path); + get_my_path(path, PATH_MAX); pid_t pid = fork(); if(pid < 0) return -1; @@ -236,7 +236,7 @@ void fatal_errno(const char *fmt, ...); void handle_packet(apacket *p, atransport *t); void send_packet(apacket *p, atransport *t); -void get_my_path(char s[PATH_MAX]); +void get_my_path(char *s, size_t maxLen); int launch_server(); int adb_main(int is_daemon); diff --git a/adb/commandline.c b/adb/commandline.c index 055aa104..7cd77e0b 100644 --- a/adb/commandline.c +++ b/adb/commandline.c @@ -50,7 +50,7 @@ enum { static int do_cmd(transport_type ttype, char* serial, char *cmd, ...); -void get_my_path(char s[PATH_MAX]); +void get_my_path(char *s, size_t maxLen); int find_sync_dirs(const char *srcarg, char **android_srcdir_out, char **data_srcdir_out); int install_app(transport_type transport, char* serial, int argc, char** argv); @@ -151,8 +151,9 @@ void help() " 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" @@ -673,7 +674,7 @@ static char *find_top(char path_buf[PATH_MAX]) /* If the CWD isn't under a good-looking top, see if the * executable is. */ - get_my_path(dir); + get_my_path(dir, PATH_MAX); top = find_top_from(dir, path_buf); } return top; @@ -929,10 +930,13 @@ top: } 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]); @@ -990,9 +994,13 @@ top: 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()); diff --git a/adb/get_my_path_darwin.c b/adb/get_my_path_darwin.c index 6125cb42..5b95d153 100644 --- a/adb/get_my_path_darwin.c +++ b/adb/get_my_path_darwin.c @@ -17,7 +17,7 @@ #import <Carbon/Carbon.h> #include <unistd.h> -void get_my_path(char s[PATH_MAX]) +void get_my_path(char *s, size_t maxLen) { ProcessSerialNumber psn; GetCurrentProcess(&psn); @@ -25,6 +25,6 @@ void get_my_path(char s[PATH_MAX]) dict = ProcessInformationCopyDictionary(&psn, 0xffffffff); CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict, CFSTR("CFBundleExecutable")); - CFStringGetCString(value, s, PATH_MAX - 1, kCFStringEncodingUTF8); + CFStringGetCString(value, s, maxLen, kCFStringEncodingUTF8); } diff --git a/adb/get_my_path_freebsd.c b/adb/get_my_path_freebsd.c new file mode 100644 index 00000000..b06ec669 --- /dev/null +++ b/adb/get_my_path_freebsd.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2009 bsdroid project + * Alexey Tarasov <tarasov@dodologics.com> + * + * Copyright (C) 2007 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/types.h> +#include <unistd.h> +#include <limits.h> +#include <stdio.h> + +void +get_my_path(char *exe, size_t maxLen) +{ + char proc[64]; + + snprintf(proc, sizeof(proc), "/proc/%d/file", getpid()); + + int err = readlink(proc, exe, maxLen - 1); + + exe[err > 0 ? err : 0] = '\0'; +} + diff --git a/adb/get_my_path_linux.c b/adb/get_my_path_linux.c index f516e591..179c3dda 100644 --- a/adb/get_my_path_linux.c +++ b/adb/get_my_path_linux.c @@ -19,15 +19,15 @@ #include <limits.h> #include <stdio.h> -void get_my_path(char exe[PATH_MAX]) +void get_my_path(char *exe, size_t maxLen) { char proc[64]; snprintf(proc, sizeof proc, "/proc/%d/exe", getpid()); - int err = readlink(proc, exe, PATH_MAX - 1); + int err = readlink(proc, exe, maxLen - 1); if(err > 0) { - exe[err] = 0; + exe[err] = '\0'; } else { - exe[0] = 0; + exe[0] = '\0'; } } diff --git a/adb/get_my_path_windows.c b/adb/get_my_path_windows.c index fc7143c1..ddf28161 100644 --- a/adb/get_my_path_windows.c +++ b/adb/get_my_path_windows.c @@ -18,14 +18,17 @@ #include <assert.h> #include <windows.h> -void get_my_path(char exe[PATH_MAX]) +void get_my_path(char *exe, size_t maxLen) { - char* r; + char *r; - GetModuleFileName( NULL, exe, PATH_MAX-1 ); - exe[PATH_MAX-1] = 0; - r = strrchr( exe, '\\' ); - if (r) - *r = 0; + /* XXX: should be GetModuleFileNameA */ + if (GetModuleFileName(NULL, exe, maxLen) > 0) { + r = strrchr(exe, '\\'); + if (r != NULL) + *r = '\0'; + } else { + exe[0] = '\0'; + } } diff --git a/adb/usb_libusb.c b/adb/usb_libusb.c new file mode 100644 index 00000000..8c752662 --- /dev/null +++ b/adb/usb_libusb.c @@ -0,0 +1,657 @@ +/* + * Copyright (C) 2009 bsdroid project + * Alexey Tarasov <tarasov@dodologics.com> + * + * Copyright (C) 2007 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/endian.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/uio.h> + +#include <err.h> +#include <errno.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> +#include <libusb.h> +#include "sysdeps.h" + +#define TRACE_TAG TRACE_USB +#include "adb.h" + +static adb_mutex_t usb_lock = ADB_MUTEX_INITIALIZER; +static libusb_context *ctx = NULL; + +struct usb_handle +{ + usb_handle *prev; + usb_handle *next; + + libusb_device *dev; + libusb_device_handle *devh; + int interface; + uint8_t dev_bus; + uint8_t dev_addr; + + int zero_mask; + unsigned char end_point_address[2]; + char serial[128]; + + adb_cond_t notify; + adb_mutex_t lock; +}; + +static struct usb_handle handle_list = { + .prev = &handle_list, + .next = &handle_list, +}; + +void +usb_cleanup() +{ + libusb_exit(ctx); +} + +void +report_bulk_libusb_error(int r) +{ + switch (r) { + case LIBUSB_ERROR_TIMEOUT: + D("Transfer timeout\n"); + break; + + case LIBUSB_ERROR_PIPE: + D("Control request is not supported\n"); + break; + + case LIBUSB_ERROR_OVERFLOW: + D("Device offered more data\n"); + break; + + case LIBUSB_ERROR_NO_DEVICE : + D("Device was disconnected\n"); + break; + + default: + D("Error %d during transfer\n", r); + break; + }; +} + +static int +usb_bulk_write(usb_handle *uh, const void *data, int len) +{ + int r = 0; + int transferred = 0; + + r = libusb_bulk_transfer(uh->devh, uh->end_point_address[1], (void *)data, len, + &transferred, 0); + + if (r != 0) { + D("usb_bulk_write(): "); + report_bulk_libusb_error(r); + return r; + } + + return (transferred); +} + +static int +usb_bulk_read(usb_handle *uh, void *data, int len) +{ + int r = 0; + int transferred = 0; + + r = libusb_bulk_transfer(uh->devh, uh->end_point_address[0], data, len, + &transferred, 0); + + if (r != 0) { + D("usb_bulk_read(): "); + report_bulk_libusb_error(r); + return r; + } + + return (transferred); +} + +int +usb_write(struct usb_handle *uh, const void *_data, int len) +{ + unsigned char *data = (unsigned char*) _data; + int n; + int need_zero = 0; + + if (uh->zero_mask == 1) { + if (!(len & uh->zero_mask)) { + need_zero = 1; + } + } + + D("usb_write(): %p:%d -> transport %p\n", _data, len, uh); + + while (len > 0) { + int xfer = (len > 4096) ? 4096 : len; + + n = usb_bulk_write(uh, data, xfer); + + if (n != xfer) { + D("usb_write(): failed for transport %p (%d bytes left)\n", uh, len); + return -1; + } + + len -= xfer; + data += xfer; + } + + if (need_zero){ + n = usb_bulk_write(uh, _data, 0); + + if (n < 0) { + D("usb_write(): failed to finish operation for transport %p\n", uh); + } + return n; + } + + return 0; +} + +int +usb_read(struct usb_handle *uh, void *_data, int len) +{ + unsigned char *data = (unsigned char*) _data; + int n; + + D("usb_read(): %p:%d <- transport %p\n", _data, len, uh); + + while (len > 0) { + int xfer = (len > 4096) ? 4096 : len; + + n = usb_bulk_read(uh, data, xfer); + + if (n != xfer) { + if (n > 0) { + data += n; + len -= n; + continue; + } + + D("usb_read(): failed for transport %p (%d bytes left)\n", uh, len); + return -1; + } + + len -= xfer; + data += xfer; + } + + return 0; + } + +int +usb_close(struct usb_handle *h) +{ + D("usb_close(): closing transport %p\n", h); + adb_mutex_lock(&usb_lock); + + h->next->prev = h->prev; + h->prev->next = h->next; + h->prev = NULL; + h->next = NULL; + + libusb_release_interface(h->devh, h->interface); + libusb_close(h->devh); + libusb_unref_device(h->dev); + + adb_mutex_unlock(&usb_lock); + + free(h); + + return (0); +} + +void usb_kick(struct usb_handle *h) +{ + D("usb_cick(): kicking transport %p\n", h); + + adb_mutex_lock(&h->lock); + unregister_usb_transport(h); + adb_mutex_unlock(&h->lock); + + h->next->prev = h->prev; + h->prev->next = h->next; + h->prev = NULL; + h->next = NULL; + + libusb_release_interface(h->devh, h->interface); + libusb_close(h->devh); + libusb_unref_device(h->dev); + free(h); +} + +int +check_usb_interface(libusb_interface *interface, + libusb_device_descriptor *desc, + struct usb_handle *uh) +{ + int e; + + if (interface->num_altsetting == 0) { + D("check_usb_interface(): No interface settings\n"); + return -1; + } + + libusb_interface_descriptor *idesc = &interface->altsetting[0]; + + if (idesc->bNumEndpoints != 2) { + D("check_usb_interface(): Interface have not 2 endpoints, ignoring\n"); + return -1; + } + + for (e = 0; e < idesc->bNumEndpoints; e++) { + libusb_endpoint_descriptor *edesc = &idesc->endpoint[e]; + + if (edesc->bmAttributes != LIBUSB_TRANSFER_TYPE_BULK) { + D("check_usb_interface(): Endpoint (%u) is not bulk (%u), ignoring\n", + edesc->bmAttributes, LIBUSB_TRANSFER_TYPE_BULK); + return -1; + } + + if (edesc->bEndpointAddress & LIBUSB_ENDPOINT_IN) + uh->end_point_address[0] = edesc->bEndpointAddress; + else + uh->end_point_address[1] = edesc->bEndpointAddress; + + /* aproto 01 needs 0 termination */ + if (idesc->bInterfaceProtocol == 0x01) { + uh->zero_mask = edesc->wMaxPacketSize - 1; + D("check_usb_interface(): Forced Android interface protocol v.1\n"); + } + } + + D("check_usb_interface(): Device: %04x:%04x " + "iclass: %x, isclass: %x, iproto: %x ep: %x/%x-> ", + desc->idVendor, desc->idProduct, idesc->bInterfaceClass, + idesc->bInterfaceSubClass, idesc->bInterfaceProtocol, + uh->end_point_address[0], uh->end_point_address[1]); + + if (!is_adb_interface(desc->idVendor, desc->idProduct, + idesc->bInterfaceClass, idesc->bInterfaceSubClass, + idesc->bInterfaceProtocol)) + { + D("not matches\n"); + return -1; + } + + D("matches\n"); + return 1; +} + +int +check_usb_interfaces(libusb_config_descriptor *config, + libusb_device_descriptor *desc, struct usb_handle *uh) +{ + int i; + + for (i = 0; i < config->bNumInterfaces; ++i) { + if (check_usb_interface(&config->interface[i], desc, uh) != -1) { + /* found some interface and saved information about it */ + D("check_usb_interfaces(): Interface %d of %04x:%04x " + "matches Android device\n", i, desc->idVendor, + desc->idProduct); + + return i; + } + } + + return -1; +} + +int +register_device(struct usb_handle *uh, const char *serial) +{ + D("register_device(): Registering %p [%s] as USB transport\n", + uh, serial); + + struct usb_handle *usb= NULL; + + usb = calloc(1, sizeof(struct usb_handle)); + memcpy(usb, uh, sizeof(struct usb_handle)); + strcpy(usb->serial, uh->serial); + + adb_cond_init(&usb->notify, 0); + adb_mutex_init(&usb->lock, 0); + + adb_mutex_lock(&usb_lock); + + usb->next = &handle_list; + usb->prev = handle_list.prev; + usb->prev->next = usb; + usb->next->prev = usb; + + adb_mutex_unlock(&usb_lock); + + register_usb_transport(usb, serial, 1); + + return (1); +} + +int +already_registered(usb_handle *uh) +{ + struct usb_handle *usb= NULL; + int exists = 0; + + adb_mutex_lock(&usb_lock); + + for (usb = handle_list.next; usb != &handle_list; usb = usb->next) { + if ((usb->dev_bus == uh->dev_bus) && + (usb->dev_addr == uh->dev_addr)) + { + exists = 1; + break; + } + } + + adb_mutex_unlock(&usb_lock); + + return exists; +} + +void +check_device(libusb_device *dev) +{ + struct usb_handle uh; + int i = 0; + int found = -1; + char serial[256] = {0}; + + libusb_device_descriptor desc; + libusb_config_descriptor *config = NULL; + + int r = libusb_get_device_descriptor(dev, &desc); + + if (r != LIBUSB_SUCCESS) { + D("check_device(): Failed to get device descriptor\n"); + return; + } + + if ((desc.idVendor == 0) && (desc.idProduct == 0)) + return; + + D("check_device(): Probing usb device %04x:%04x\n", + desc.idVendor, desc.idProduct); + + if (!is_adb_interface (desc.idVendor, desc.idProduct, + ADB_CLASS, ADB_SUBCLASS, ADB_PROTOCOL)) + { + D("check_device(): Ignored due unknown vendor id\n"); + return; + } + + uh.dev_bus = libusb_get_bus_number(dev); + uh.dev_addr = libusb_get_device_address(dev); + + if (already_registered(&uh)) { + D("check_device(): Device (bus: %d, address: %d) " + "is already registered\n", uh.dev_bus, uh.dev_addr); + return; + } + + D("check_device(): Device bus: %d, address: %d\n", + uh.dev_bus, uh.dev_addr); + + r = libusb_get_active_config_descriptor(dev, &config); + + if (r != 0) { + if (r == LIBUSB_ERROR_NOT_FOUND) { + D("check_device(): Device %4x:%4x is unconfigured\n", + desc.idVendor, desc.idProduct); + return; + } + + D("check_device(): Failed to get configuration for %4x:%4x\n", + desc.idVendor, desc.idProduct); + return; + } + + if (config == NULL) { + D("check_device(): Sanity check failed after " + "getting active config\n"); + return; + } + + if (config->interface != NULL) { + found = check_usb_interfaces(config, &desc, &uh); + } + + /* not needed anymore */ + libusb_free_config_descriptor(config); + + r = libusb_open(dev, &uh.devh); + uh.dev = dev; + + if (r != 0) { + switch (r) { + case LIBUSB_ERROR_NO_MEM: + D("check_device(): Memory allocation problem\n"); + break; + + case LIBUSB_ERROR_ACCESS: + D("check_device(): Permissions problem, " + "current user priveleges are messed up?\n"); + break; + + case LIBUSB_ERROR_NO_DEVICE: + D("check_device(): Device disconected, bad cable?\n"); + break; + + default: + D("check_device(): libusb triggered error %d\n", r); + } + // skip rest + found = -1; + } + + if (found >= 0) { + D("check_device(): Device matches Android interface\n"); + // read the device's serial number + memset(serial, 0, sizeof(serial)); + uh.interface = found; + + r = libusb_claim_interface(uh.devh, uh.interface); + + if (r < 0) { + D("check_device(): Failed to claim interface %d\n", + uh.interface); + + goto fail; + } + + if (desc.iSerialNumber) { + // reading serial + uint16_t buffer[128] = {0}; + uint16_t languages[128] = {0}; + int languageCount = 0; + + memset(languages, 0, sizeof(languages)); + r = libusb_control_transfer(uh.devh, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE, + LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_STRING << 8, + 0, (uint8_t *)languages, sizeof(languages), 0); + + if (r <= 0) { + D("check_device(): Failed to get languages count\n"); + goto fail; + } + + languageCount = (r - 2) / 2; + + for (i = 1; i <= languageCount; ++i) { + memset(buffer, 0, sizeof(buffer)); + + r = libusb_control_transfer(uh.devh, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE, + LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | desc.iSerialNumber, + languages[i], (uint8_t *)buffer, sizeof(buffer), 0); + + if (r > 0) { /* converting serial */ + int j = 0; + r /= 2; + + for (j = 1; j < r; ++j) + serial[j - 1] = buffer[j]; + + serial[j - 1] = '\0'; + break; /* languagesCount cycle */ + } + } + + if (register_device(&uh, serial) == 0) { + D("check_device(): Failed to register device\n"); + goto fail_interface; + } + + libusb_ref_device(dev); + } + } + + return; + +fail_interface: + libusb_release_interface(uh.devh, uh.interface); + +fail: + libusb_close(uh.devh); + uh.devh = NULL; +} + +int +check_device_connected(struct usb_handle *uh) +{ + int r = libusb_kernel_driver_active(uh->devh, uh->interface); + + if (r == LIBUSB_ERROR_NO_DEVICE) + return 0; + + if (r < 0) + return -1; + + return 1; +} + +void +kick_disconnected() +{ + struct usb_handle *usb= NULL; + + adb_mutex_lock(&usb_lock); + + for (usb = handle_list.next; usb != &handle_list; usb = usb->next) { + + if (check_device_connected(usb) == 0) { + D("kick_disconnected(): Transport %p is not online anymore\n", + usb); + + usb_kick(usb); + } + } + + adb_mutex_unlock(&usb_lock); +} + +void +scan_usb_devices() +{ + D("scan_usb_devices(): started\n"); + + libusb_device **devs= NULL; + libusb_device *dev= NULL; + ssize_t cnt = libusb_get_device_list(ctx, &devs); + + if (cnt < 0) { + D("scan_usb_devices(): Failed to get device list (error: %d)\n", + cnt); + + return; + } + + int i = 0; + + while ((dev = devs[i++]) != NULL) { + check_device(dev); + } + + libusb_free_device_list(devs, 1); +} + +void * +device_poll_thread(void* unused) +{ + D("device_poll_thread(): Created USB scan thread\n"); + + for (;;) { + sleep(5); + kick_disconnected(); + scan_usb_devices(); + } + + /* never reaching this point */ + return (NULL); +} + +static void +sigalrm_handler(int signo) +{ + /* nothing */ +} + +void +usb_init() +{ + D("usb_init(): started\n"); + adb_thread_t tid; + struct sigaction actions; + + int r = libusb_init(&ctx); + + if (r != LIBUSB_SUCCESS) { + err(EX_IOERR, "Failed to init libusb\n"); + } + + memset(&actions, 0, sizeof(actions)); + + sigemptyset(&actions.sa_mask); + + actions.sa_flags = 0; + actions.sa_handler = sigalrm_handler; + + sigaction(SIGALRM, &actions, NULL); + + /* initial device scan */ + scan_usb_devices(); + + /* starting USB event polling thread */ + if (adb_thread_create(&tid, device_poll_thread, NULL)) { + err(EX_IOERR, "cannot create USB scan thread\n"); + } + + D("usb_init(): finished\n"); +} + diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c index bd586d01..203c006b 100644 --- a/adb/usb_vendors.c +++ b/adb/usb_vendors.c @@ -51,9 +51,12 @@ #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 + /** built-in vendor list */ int builtInVendorIds[] = { VENDOR_ID_GOOGLE, @@ -64,6 +67,7 @@ int builtInVendorIds[] = { VENDOR_ID_HUAWEI, VENDOR_ID_ACER, VENDOR_ID_SONY_ERICSSON, + VENDOR_ID_FOXCONN, VENDOR_ID_DELL, }; diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c index 9fab38c4..1308f26e 100644 --- a/fastboot/fastboot.c +++ b/fastboot/fastboot.c @@ -150,6 +150,7 @@ int match_fastboot(usb_ifc_info *info) (info->dev_vendor != 0x18d1) && // Google (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; diff --git a/include/arch/darwin-x86/AndroidConfig.h b/include/arch/darwin-x86/AndroidConfig.h index ad16e0c2..363a8f73 100644 --- a/include/arch/darwin-x86/AndroidConfig.h +++ b/include/arch/darwin-x86/AndroidConfig.h @@ -86,6 +86,11 @@ #define HAVE_TERMIO_H /* + * Define this if you have <sys/sendfile.h> + */ +/* #define HAVE_SYS_SENDFILE_H 1 */ + +/* * Define this if you build against MSVCRT.DLL */ /* #define HAVE_MS_C_RUNTIME */ @@ -141,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 @@ -214,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/include/arch/freebsd-x86/AndroidConfig.h b/include/arch/freebsd-x86/AndroidConfig.h index 39c564b9..b01a854f 100644 --- a/include/arch/freebsd-x86/AndroidConfig.h +++ b/include/arch/freebsd-x86/AndroidConfig.h @@ -91,6 +91,11 @@ /* #define HAVE_TERMIO_H */ /* + * Define this if you have <sys/sendfile.h> + */ +/* #define HAVE_SYS_SENDFILE_H 1 */ + +/* * Define this if you build against MSVCRT.DLL */ /* #define HAVE_MS_C_RUNTIME */ diff --git a/include/arch/linux-arm/AndroidConfig.h b/include/arch/linux-arm/AndroidConfig.h index 82e39c01..26547a21 100644 --- a/include/arch/linux-arm/AndroidConfig.h +++ b/include/arch/linux-arm/AndroidConfig.h @@ -92,6 +92,11 @@ #define HAVE_TERMIO_H /* + * Define this if you have <sys/sendfile.h> + */ +#define HAVE_SYS_SENDFILE_H 1 + +/* * Define this if you build against MSVCRT.DLL */ /* #define HAVE_MS_C_RUNTIME */ diff --git a/include/arch/linux-sh/AndroidConfig.h b/include/arch/linux-sh/AndroidConfig.h new file mode 100644 index 00000000..67ac2777 --- /dev/null +++ b/include/arch/linux-sh/AndroidConfig.h @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2009 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. + */ + +/* + * Android config -- "android-sh". Used for SuperH device builds. + */ +#ifndef _ANDROID_CONFIG_H +#define _ANDROID_CONFIG_H + +/* + * =========================================================================== + * !!! IMPORTANT !!! + * =========================================================================== + * + * This file is included by ALL C/C++ source files. Don't put anything in + * here unless you are absolutely certain it can't go anywhere else. + * + * Any C++ stuff must be wrapped with "#ifdef __cplusplus". Do not use "//" + * comments. + */ + +/* + * Threading model. Choose one: + * + * HAVE_PTHREADS - use the pthreads library. + * HAVE_WIN32_THREADS - use Win32 thread primitives. + * -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX + */ +#define HAVE_PTHREADS + +/* + * Do we have the futex syscall? + */ + +#define HAVE_FUTEX + +/* + * Define if we already have the futex wrapper functions defined. Yes if + * compiling against bionic. + */ +#define HAVE_FUTEX_WRAPPERS 1 + +/* + * Process creation model. Choose one: + * + * HAVE_FORKEXEC - use fork() and exec() + * HAVE_WIN32_PROC - use CreateProcess() + */ +#define HAVE_FORKEXEC + +/* + * Process out-of-memory adjustment. Set if running on Linux, + * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory + * badness adjustment. + */ +#define HAVE_OOM_ADJ + +/* + * IPC model. Choose one: + * + * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget). + * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap). + * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping). + * HAVE_ANDROID_IPC - use Android versions (?, mmap). + */ +#define HAVE_ANDROID_IPC + +/* + * Memory-mapping model. Choose one: + * + * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h + * HAVE_WIN32_FILEMAP - use Win32 filemaps + */ +#define HAVE_POSIX_FILEMAP + +/* + * Define this if you have <termio.h> + */ +#define HAVE_TERMIO_H + +/* + * Define this if you have <sys/sendfile.h> + */ +#define HAVE_SYS_SENDFILE_H 1 + +/* + * Define this if you build against MSVCRT.DLL + */ +/* #define HAVE_MS_C_RUNTIME */ + +/* + * Define this if you have sys/uio.h + */ +#define HAVE_SYS_UIO_H + +/* + * Define this if your platforms implements symbolic links + * in its filesystems + */ +#define HAVE_SYMLINKS + +/* + * Define this if we have localtime_r(). + */ +/* #define HAVE_LOCALTIME_R */ + +/* + * Define this if we have gethostbyname_r(). + */ +/* #define HAVE_GETHOSTBYNAME_R */ + +/* + * Define this if we have ioctl(). + */ +#define HAVE_IOCTL + +/* + * Define this if we want to use WinSock. + */ +/* #define HAVE_WINSOCK */ + +/* + * Define this if have clock_gettime() and friends + */ +#define HAVE_POSIX_CLOCKS + +/* + * Define this if we have pthread_cond_timedwait_monotonic() and + * clock_gettime(CLOCK_MONOTONIC). + */ +/* #define HAVE_TIMEDWAIT_MONOTONIC */ + +/* + * Define this if we have linux style epoll() + */ +#define HAVE_EPOLL + +/* + * Endianness of the target machine. Choose one: + * + * HAVE_ENDIAN_H -- have endian.h header we can include. + * HAVE_LITTLE_ENDIAN -- we are little endian. + * HAVE_BIG_ENDIAN -- we are big endian. + */ +#define HAVE_ENDIAN_H +#define HAVE_LITTLE_ENDIAN + +/* + * We need to choose between 32-bit and 64-bit off_t. All of our code should + * agree on the same size. For desktop systems, use 64-bit values, + * because some of our libraries (e.g. wxWidgets) expect to be built that way. + */ +/* #define _FILE_OFFSET_BITS 64 */ +/* #define _LARGEFILE_SOURCE 1 */ + +/* + * Defined if we have the backtrace() call for retrieving a stack trace. + * Needed for CallStack to operate; if not defined, CallStack is + * non-functional. + */ +#define HAVE_BACKTRACE 0 + +/* + * Defined if we have the dladdr() call for retrieving the symbol associated + * with a memory address. If not defined, stack crawls will not have symbolic + * information. + */ +#define HAVE_DLADDR 0 + +/* + * Defined if we have the cxxabi.h header for demangling C++ symbols. If + * not defined, stack crawls will be displayed with raw mangled symbols + */ +#define HAVE_CXXABI 0 + +/* + * Defined if we have the gettid() system call. + */ +#define HAVE_GETTID + +/* + * Defined if we have the sched_setscheduler() call + */ +#define HAVE_SCHED_SETSCHEDULER + +/* + * Add any extra platform-specific defines here. + */ +/* #define __linux__ */ /* for SuperH */ + +/* + * Define if we have <malloc.h> header + */ +#define HAVE_MALLOC_H + +/* + * Define if we're running on *our* linux on device or emulator. + */ +#define HAVE_ANDROID_OS 1 + +/* + * Define if we have Linux-style non-filesystem Unix Domain Sockets + */ +#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1 + +/* + * Define if we have Linux's inotify in <sys/inotify.h>. + */ +#define HAVE_INOTIFY 1 + +/* + * Define if we have madvise() in <sys/mman.h> + */ +#define HAVE_MADVISE 1 + +/* + * Define if tm struct has tm_gmtoff field + */ +#define HAVE_TM_GMTOFF 1 + +/* + * Define if dirent struct has d_type field + */ +#define HAVE_DIRENT_D_TYPE 1 + +/* + * Define if libc includes Android system properties implementation. + */ +#define HAVE_LIBC_SYSTEM_PROPERTIES 1 + +/* + * Define if system provides a system property server (should be + * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES). + */ +/* #define HAVE_SYSTEM_PROPERTY_SERVER */ + +/* + * What CPU architecture does this platform use? + */ +#define ARCH_SH + +/* + * Define if the size of enums is as short as possible, + */ +/* #define HAVE_SHORT_ENUMS */ + +/* + * sprintf() format string for shared library naming. + */ +#define OS_SHARED_LIB_FORMAT_STR "lib%s.so" + +/* + * Do we have __memcmp16()? + * + * TODO : Investigate the perfomance impact of __memcmp16() + * and implement it. + * This influences on dalvikVM's string performance. + * See dalvik/vm/InlineNative.c. + */ +/* #define HAVE__MEMCMP16 */ + +/* + * type for the third argument to mincore(). + */ +#define MINCORE_POINTER_TYPE unsigned char * + +/* + * Do we have the sigaction flag SA_NOCLDWAIT? + */ +#define HAVE_SA_NOCLDWAIT + +/* + * The default path separator for the platform + */ +#define OS_PATH_SEPARATOR '/' + +/* + * Is the filesystem case sensitive? + */ +#define OS_CASE_SENSITIVE + +/* + * Define if <sys/socket.h> exists. + */ +#define HAVE_SYS_SOCKET_H 1 + +/* + * Define if the strlcpy() function exists on the system. + */ +#define HAVE_STRLCPY 1 + +/* + * Define if prctl() exists + */ +#define HAVE_PRCTL 1 + +/* + * Define if writev() exists + */ +#define HAVE_WRITEV 1 + +/* + * For dalvik/libcore + */ +#define CANT_PASS_VALIST_AS_CHARPTR + +/* + * For external/bluez/utils/tools/hciattach.c + * TODO : This definition should be somewhere in bionic/libc/kernel/(*). + * Cosider the place and move it there. + */ +#define N_TTY 0 + +/* + * Whether or not _Unwind_Context is defined as a struct. + */ +#define HAVE_UNWIND_CONTEXT_STRUCT + +#endif /* _ANDROID_CONFIG_H */ diff --git a/include/arch/linux-x86/AndroidConfig.h b/include/arch/linux-x86/AndroidConfig.h index 557ec5f9..31bdb5f9 100644 --- a/include/arch/linux-x86/AndroidConfig.h +++ b/include/arch/linux-x86/AndroidConfig.h @@ -86,6 +86,11 @@ #define HAVE_TERMIO_H /* + * Define this if you have <sys/sendfile.h> + */ +#define HAVE_SYS_SENDFILE_H 1 + +/* * Define this if you build against MSVCRT.DLL */ /* #define HAVE_MS_C_RUNTIME */ diff --git a/include/arch/target_linux-x86/AndroidConfig.h b/include/arch/target_linux-x86/AndroidConfig.h index 66057232..d89d0547 100644 --- a/include/arch/target_linux-x86/AndroidConfig.h +++ b/include/arch/target_linux-x86/AndroidConfig.h @@ -78,6 +78,11 @@ #define HAVE_TERMIO_H 1 /* + * Define this if you have <sys/sendfile.h> + */ +#define HAVE_SYS_SENDFILE_H 1 + +/* * Define this if you build against have Microsoft C runtime (MSVCRT.DLL) */ /* #define HAVE_MS_C_RUNTIME */ diff --git a/include/arch/windows/AndroidConfig.h b/include/arch/windows/AndroidConfig.h index b240519a..0fc4955e 100644 --- a/include/arch/windows/AndroidConfig.h +++ b/include/arch/windows/AndroidConfig.h @@ -101,6 +101,13 @@ #endif /* + * Define this if you have <sys/sendfile.h> + */ +#ifdef __CYGWIN__ +# define HAVE_SYS_SENDFILE_H 1 +#endif + +/* * Define this if you build against MSVCRT.DLL */ #ifndef __CYGWIN__ diff --git a/include/sysutils/NetlinkListener.h b/include/sysutils/NetlinkListener.h index 6dcc005c..28800460 100644 --- a/include/sysutils/NetlinkListener.h +++ b/include/sysutils/NetlinkListener.h @@ -26,7 +26,9 @@ class NetlinkListener : public SocketListener { public: NetlinkListener(int socket); virtual ~NetlinkListener() {} + protected: virtual bool onDataAvailable(SocketClient *cli); + virtual void onEvent(NetlinkEvent *evt) = 0; }; #endif diff --git a/init/builtins.c b/init/builtins.c index 5a1b2637..b4af700b 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -131,6 +131,18 @@ static void service_start_if_not_disabled(struct service *svc) } } +int do_chdir(int nargs, char **args) +{ + chdir(args[1]); + return 0; +} + +int do_chroot(int nargs, char **args) +{ + chroot(args[1]); + return 0; +} + int do_class_start(int nargs, char **args) { /* Starting a class does not start services @@ -206,7 +218,7 @@ int do_insmod(int nargs, char **args) int do_import(int nargs, char **args) { - return -1; + return parse_config_file(args[1]); } int do_mkdir(int nargs, char **args) @@ -400,6 +412,8 @@ int do_restart(int nargs, char **args) int do_trigger(int nargs, char **args) { + action_for_each_trigger(args[1], action_add_queue_tail); + drain_action_queue(); return 0; } diff --git a/init/devices.c b/init/devices.c index ea1a825c..55c5ee46 100644 --- a/init/devices.c +++ b/init/devices.c @@ -121,6 +121,7 @@ static struct perms_ devperms[] = { { "/dev/pmem_camera", 0660, AID_SYSTEM, AID_CAMERA, 1 }, { "/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 }, { "/dev/adsp/", 0660, AID_SYSTEM, AID_AUDIO, 1 }, + { "/dev/snd/", 0660, AID_SYSTEM, AID_AUDIO, 1 }, { "/dev/mt9t013", 0660, AID_SYSTEM, AID_SYSTEM, 0 }, { "/dev/msm_camera/", 0660, AID_SYSTEM, AID_SYSTEM, 1 }, { "/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 }, @@ -309,7 +310,7 @@ static void make_device(const char *path, int block, int major, int minor) chown(path, uid, gid); } -#ifdef LOG_UEVENTS +#if LOG_UEVENTS static inline suseconds_t get_usecs(void) { diff --git a/init/init.c b/init/init.c index 8c2a0582..f76eb36b 100644..100755 --- a/init/init.c +++ b/init/init.c @@ -65,8 +65,6 @@ static struct input_keychord *keychords = 0; static int keychords_count = 0; static int keychords_length = 0; -static void drain_action_queue(void); - static void notify_service_state(const char *name, const char *state) { char pname[PROP_NAME_MAX]; @@ -391,12 +389,13 @@ static int wait_for_one_process(int block) } } + svc->flags |= SVC_RESTARTING; + /* Execute all onrestart commands for this service. */ list_for_each(node, &svc->onrestart.commands) { cmd = node_to_item(node, struct command, clist); cmd->func(cmd->nargs, cmd->args); } - svc->flags |= SVC_RESTARTING; notify_service_state(svc->name, "restarting"); return 0; } @@ -667,7 +666,7 @@ static void get_hardware_name(void) } } -static void drain_action_queue(void) +void drain_action_queue(void) { struct listnode *node; struct command *cmd; diff --git a/init/init.h b/init/init.h index f306b7bc..60c30555 100644 --- a/init/init.h +++ b/init/init.h @@ -165,6 +165,7 @@ void service_stop(struct service *svc); void service_start(struct service *svc, const char *dynamic_args); void property_changed(const char *name, const char *value); +void drain_action_queue(void); struct action *action_remove_queue_head(void); void action_add_queue_tail(struct action *act); void action_for_each_trigger(const char *trigger, diff --git a/init/keywords.h b/init/keywords.h index 641426ca..308118ef 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -1,5 +1,7 @@ #ifndef KEYWORD +int do_chroot(int nargs, char **args); +int do_chdir(int nargs, char **args); int do_class_start(int nargs, char **args); int do_class_stop(int nargs, char **args); int do_domainname(int nargs, char **args); @@ -32,6 +34,8 @@ enum { K_UNKNOWN, #endif KEYWORD(capability, OPTION, 0, 0) + KEYWORD(chdir, COMMAND, 1, do_chdir) + KEYWORD(chroot, COMMAND, 1, do_chroot) KEYWORD(class, OPTION, 0, 0) KEYWORD(class_start, COMMAND, 1, do_class_start) KEYWORD(class_stop, COMMAND, 1, do_class_stop) diff --git a/init/parser.c b/init/parser.c index affc80c9..54622cce 100644 --- a/init/parser.c +++ b/init/parser.c @@ -129,6 +129,8 @@ int lookup_keyword(const char *s) case 'c': if (!strcmp(s, "opy")) return K_copy; if (!strcmp(s, "apability")) return K_capability; + if (!strcmp(s, "hdir")) return K_chdir; + if (!strcmp(s, "hroot")) return K_chroot; if (!strcmp(s, "lass")) return K_class; if (!strcmp(s, "lass_start")) return K_class_start; if (!strcmp(s, "lass_stop")) return K_class_stop; diff --git a/init/readme.txt b/init/readme.txt index 665090ba..a185790a 100644 --- a/init/readme.txt +++ b/init/readme.txt @@ -145,12 +145,18 @@ import <filename> hostname <name> Set the host name. +chdir <directory> + Change working directory. + chmod <octal-mode> <path> Change file access permissions. chown <owner> <group> <path> Change file owner and group. +chroot <directory> + Change process root directory. + class_start <serviceclass> Start all services of the specified class if they are not already running. diff --git a/libcutils/Android.mk b/libcutils/Android.mk index 1d1e5760..6418590b 100644 --- a/libcutils/Android.mk +++ b/libcutils/Android.mk @@ -104,7 +104,11 @@ LOCAL_SRC_FILES := $(commonSources) ashmem-dev.c mq.c ifeq ($(TARGET_ARCH),arm) LOCAL_SRC_FILES += memset32.S atomic-android-arm.S else # !arm +ifeq ($(TARGET_ARCH),sh) +LOCAL_SRC_FILES += memory.c atomic-android-sh.c +else # !sh LOCAL_SRC_FILES += memory.c +endif # !sh endif # !arm LOCAL_C_INCLUDES := $(KERNEL_HEADERS) diff --git a/libcutils/atomic-android-arm.S b/libcutils/atomic-android-arm.S index 7befd780..da5c26b0 100644 --- a/libcutils/atomic-android-arm.S +++ b/libcutils/atomic-android-arm.S @@ -17,8 +17,7 @@ #include <machine/cpu-features.h> /* - * NOTE: these atomic operations are SMP safe on all architectures, - * except swap(), see below. + * NOTE: these atomic operations are SMP safe on all architectures. */ .text @@ -228,11 +227,18 @@ android_atomic_or: * output: r0 = old value */ -/* FIXME: this is not safe on SMP systems - * a general way to do it is to use kernel_cmpxchg */ - +/* replaced swp instruction with ldrex/strex for ARMv6 & ARMv7 */ android_atomic_swap: +#if defined (_ARM_HAVE_LDREX_STREX) +1: ldrex r2, [r1] + strex r3, r0, [r1] + teq r3, #0 + bne 1b + mov r0, r2 + mcr p15, 0, r0, c7, c10, 5 /* or, use dmb */ +#else swp r0, r0, [r1] +#endif bx lr /* diff --git a/libcutils/atomic-android-sh.c b/libcutils/atomic-android-sh.c new file mode 100644 index 00000000..acbea976 --- /dev/null +++ b/libcutils/atomic-android-sh.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2007 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 <cutils/atomic.h> +#ifdef HAVE_WIN32_THREADS +#include <windows.h> +#else +#include <sched.h> +#endif + +/* + * Note : + * + * (1) SuperH does not have CMPXCHG. It has only TAS for atomic + * operations. It does not seem a good idea to implement CMPXCHG, + * with TAS. So, we choose to implemnt these operations with + * posix mutexes. Please be sure that this might cause performance + * problem for Android-SH. Using LL/SC instructions supported in SH-X3, + * best performnace would be realized. + * + * (2) Mutex initialization problem happens, which is commented for + * ARM implementation, in this file above. + * We follow the fact that the initializer for mutex is a simple zero + * value. + */ + +#include <pthread.h> + +#define SWAP_LOCK_COUNT 32U +static pthread_mutex_t _swap_locks[SWAP_LOCK_COUNT]; + +#define SWAP_LOCK(addr) \ + &_swap_locks[((unsigned)(void*)(addr) >> 3U) % SWAP_LOCK_COUNT] + + +void android_atomic_write(int32_t value, volatile int32_t* addr) { + int32_t oldValue; + do { + oldValue = *addr; + } while (android_atomic_cmpxchg(oldValue, value, addr)); +} + +int32_t android_atomic_inc(volatile int32_t* addr) { + int32_t oldValue; + do { + oldValue = *addr; + } while (android_atomic_cmpxchg(oldValue, oldValue+1, addr)); + return oldValue; +} + +int32_t android_atomic_dec(volatile int32_t* addr) { + int32_t oldValue; + do { + oldValue = *addr; + } while (android_atomic_cmpxchg(oldValue, oldValue-1, addr)); + return oldValue; +} + +int32_t android_atomic_add(int32_t value, volatile int32_t* addr) { + int32_t oldValue; + do { + oldValue = *addr; + } while (android_atomic_cmpxchg(oldValue, oldValue+value, addr)); + return oldValue; +} + +int32_t android_atomic_and(int32_t value, volatile int32_t* addr) { + int32_t oldValue; + do { + oldValue = *addr; + } while (android_atomic_cmpxchg(oldValue, oldValue&value, addr)); + return oldValue; +} + +int32_t android_atomic_or(int32_t value, volatile int32_t* addr) { + int32_t oldValue; + do { + oldValue = *addr; + } while (android_atomic_cmpxchg(oldValue, oldValue|value, addr)); + return oldValue; +} + +int32_t android_atomic_swap(int32_t value, volatile int32_t* addr) { + int32_t oldValue; + do { + oldValue = *addr; + } while (android_atomic_cmpxchg(oldValue, value, addr)); + return oldValue; +} + +int android_atomic_cmpxchg(int32_t oldvalue, int32_t newvalue, + volatile int32_t* addr) { + int result; + pthread_mutex_t* lock = SWAP_LOCK(addr); + + pthread_mutex_lock(lock); + + if (*addr == oldvalue) { + *addr = newvalue; + result = 0; + } else { + result = 1; + } + pthread_mutex_unlock(lock); + return result; +} + +int64_t android_quasiatomic_swap_64(int64_t value, volatile int64_t* addr) { + int64_t oldValue; + pthread_mutex_t* lock = SWAP_LOCK(addr); + + pthread_mutex_lock(lock); + + oldValue = *addr; + *addr = value; + + pthread_mutex_unlock(lock); + return oldValue; +} + +int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue, + volatile int64_t* addr) { + int result; + pthread_mutex_t* lock = SWAP_LOCK(addr); + + pthread_mutex_lock(lock); + + if (*addr == oldvalue) { + *addr = newvalue; + result = 0; + } else { + result = 1; + } + pthread_mutex_unlock(lock); + return result; +} + +int64_t android_quasiatomic_read_64(volatile int64_t* addr) { + int64_t result; + pthread_mutex_t* lock = SWAP_LOCK(addr); + + pthread_mutex_lock(lock); + result = *addr; + pthread_mutex_unlock(lock); + return result; +} diff --git a/libcutils/atomic.c b/libcutils/atomic.c index 65d7af0a..41faaa28 100644 --- a/libcutils/atomic.c +++ b/libcutils/atomic.c @@ -245,6 +245,10 @@ int64_t android_quasiatomic_read_64(volatile int64_t* addr) { return result; } +/*****************************************************************************/ +#elif __sh__ +// implementation for SuperH is in atomic-android-sh.c. + #else #error "Unsupported atomic operations for this platform" diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp index 5573c3f0..5f959a7b 100644 --- a/libsysutils/src/NetlinkEvent.cpp +++ b/libsysutils/src/NetlinkEvent.cpp @@ -28,6 +28,9 @@ const int NetlinkEvent::NlActionChange = 3; NetlinkEvent::NetlinkEvent() { mAction = NlActionUnknown; + memset(mParams, 0, sizeof(mParams)); + mPath = NULL; + mSubsystem = NULL; } NetlinkEvent::~NetlinkEvent() { diff --git a/libsysutils/src/NetlinkListener.cpp b/libsysutils/src/NetlinkListener.cpp index 3ec9d9df..5586dccf 100644 --- a/libsysutils/src/NetlinkListener.cpp +++ b/libsysutils/src/NetlinkListener.cpp @@ -32,8 +32,6 @@ NetlinkListener::NetlinkListener(int socket) : bool NetlinkListener::onDataAvailable(SocketClient *cli) { int socket = cli->getSocket(); - LOGD("NetlinkListener::onDataAvailable()"); - int count; if ((count = recv(socket, mBuffer, sizeof(mBuffer), 0)) < 0) { @@ -47,8 +45,7 @@ bool NetlinkListener::onDataAvailable(SocketClient *cli) goto out; } - LOGD("Ignoring '%s' netlink event", evt->getSubsystem()); - + onEvent(evt); out: delete evt; return true; diff --git a/rootdir/etc/init.goldfish.sh b/rootdir/etc/init.goldfish.sh index f1b801d9..5ff0a3a4 100755 --- a/rootdir/etc/init.goldfish.sh +++ b/rootdir/etc/init.goldfish.sh @@ -3,16 +3,20 @@ ifconfig eth0 10.0.2.15 netmask 255.255.255.0 up route add default gw 10.0.2.2 dev eth0 -qemud=`getprop.ro.kernel.android.qemud` -if test -z "$qemud"; then +qemud=`getprop ro.kernel.android.qemud` +case "$qemud" in + "") radio_ril=`getprop ro.kernel.android.ril` - if test -z "$radio_ril"; then + case "$radio_ril" in + "") # no need for the radio interface daemon # telephony is entirely emulated in Java setprop ro.radio.noril yes stop ril-daemon - fi -fi + ;; + esac + ;; +esac num_dns=`getprop ro.kernel.android.ndns` case "$num_dns" in diff --git a/vold/blkdev.c b/vold/blkdev.c index 22d000e5..33fed1b8 100644 --- a/vold/blkdev.c +++ b/vold/blkdev.c @@ -113,7 +113,7 @@ int blkdev_refresh(blkdev_t *blk) goto out; } - for (i = 0; i < 4; i++) { + for (i = 0; i < NDOSPART; i++) { struct dos_partition part; dos_partition_dec(block + DOSPARTOFF + i * sizeof(struct dos_partition), &part); @@ -140,7 +140,7 @@ int blkdev_refresh(blkdev_t *blk) else part_no = blk->minor -1; - if (part_no < 4) { + if (part_no < NDOSPART) { dos_partition_dec(block + DOSPARTOFF + part_no * sizeof(struct dos_partition), &part); blk->part_type = part.dp_typ; } else { @@ -25,6 +25,7 @@ #include "vold.h" #include "mmc.h" #include "media.h" +#include "diskmbr.h" /* for NDOSPART */ #define DEBUG_BOOTSTRAP 0 @@ -157,6 +158,10 @@ static int mmc_bootstrap_card(char *sysfs_path) sprintf(filename, "/sys%s/name", devpath); p = read_file(filename, &sz); + if (!p) { + LOGE("Unable to read MMC name: %s", filename); + return -errno; + } p[strlen(p) - 1] = '\0'; sprintf(tmp, "MMC_NAME=%s", p); free(p); @@ -233,7 +238,7 @@ static int mmc_bootstrap_mmcblk(char *devpath) *mmcblk_devname != '/'; mmcblk_devname--); mmcblk_devname++; - for (part_no = 0; part_no < 4; part_no++) { + for (part_no = 1; part_no <= NDOSPART; part_no++) { char part_file[255]; sprintf(part_file, "/sys%s/%sp%d", devpath, mmcblk_devname, part_no); if (!access(part_file, F_OK)) { |
