diff options
Diffstat (limited to 'drivers/fastboot')
-rw-r--r-- | drivers/fastboot/fastboot.c | 1127 |
1 files changed, 0 insertions, 1127 deletions
diff --git a/drivers/fastboot/fastboot.c b/drivers/fastboot/fastboot.c deleted file mode 100644 index 0b5bebb..0000000 --- a/drivers/fastboot/fastboot.c +++ /dev/null @@ -1,1127 +0,0 @@ -/* - * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <config.h> -#include <malloc.h> -#include <fastboot.h> -#include <usb/imx_udc.h> -#include <asm/io.h> -#include <usbdevice.h> -#include <mmc.h> -#include <sata.h> -#ifdef CONFIG_ANDROID_RECOVERY -#include <recovery.h> -#endif - -/* - * Defines - */ -#define NUM_ENDPOINTS 2 - -#define CONFIG_USBD_OUT_PKTSIZE 0x200 -#define CONFIG_USBD_IN_PKTSIZE 0x200 -#define MAX_BUFFER_SIZE 0x200 - -/* - * imx family android layout - * mbr - 0 ~ 0x3FF byte - * bootloader - 0x400 ~ 0xFFFFF byte - * kernel - 0x100000 ~ 5FFFFF byte - * uramedisk - 0x600000 ~ 0x6FFFFF supposing 1M temporarily - * SYSTEM partition - /dev/mmcblk0p2 or /dev/sda2 - * RECOVERY parittion - dev/mmcblk0p4 or /dev/sda4 - */ -#define ANDROID_MBR_OFFSET 0 -#define ANDROID_MBR_SIZE 0x200 -#define ANDROID_BOOTLOADER_OFFSET 0x400 -#define ANDROID_BOOTLOADER_SIZE 0xFFC00 -#define ANDROID_KERNEL_OFFSET 0x100000 -#define ANDROID_KERNEL_SIZE 0x500000 -#define ANDROID_URAMDISK_OFFSET 0x600000 -#define ANDROID_URAMDISK_SIZE 0x100000 - -#define STR_LANG_INDEX 0x00 -#define STR_MANUFACTURER_INDEX 0x01 -#define STR_PRODUCT_INDEX 0x02 -#define STR_SERIAL_INDEX 0x03 -#define STR_CONFIG_INDEX 0x04 -#define STR_DATA_INTERFACE_INDEX 0x05 -#define STR_CTRL_INTERFACE_INDEX 0x06 -#define STR_COUNT 0x07 - -#define FASTBOOT_FBPARTS_ENV_MAX_LEN 1024 -/* To support the Android-style naming of flash */ -#define MAX_PTN 16 - - -/*pentry index internally*/ -enum { - PTN_MBR_INDEX = 0, - PTN_BOOTLOADER_INDEX, - PTN_KERNEL_INDEX, - PTN_URAMDISK_INDEX, - PTN_SYSTEM_INDEX, - PTN_RECOVERY_INDEX -}; - -struct fastboot_device_info fastboot_devinfo; - -/* defined and used by gadget/ep0.c */ -extern struct usb_string_descriptor **usb_strings; - -static struct usb_device_instance device_instance[1]; -static struct usb_bus_instance bus_instance[1]; -static struct usb_configuration_instance config_instance[1]; -static struct usb_interface_instance interface_instance[1]; -static struct usb_alternate_instance alternate_instance[1]; -/* one extra for control endpoint */ -static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1]; - -static struct cmd_fastboot_interface *fastboot_interface; -static int fastboot_configured_flag; -static int usb_disconnected; - -/* Indicies, References */ -static u8 rx_endpoint; -static u8 tx_endpoint; -static struct usb_string_descriptor *fastboot_string_table[STR_COUNT]; - -/* USB Descriptor Strings */ -static u8 wstrLang[4] = {4, USB_DT_STRING, 0x9, 0x4}; -static u8 wstrManufacturer[2 * (sizeof(CONFIG_FASTBOOT_MANUFACTURER_STR))]; -static u8 wstrProduct[2 * (sizeof(CONFIG_FASTBOOT_PRODUCT_NAME_STR))]; -static u8 wstrSerial[2*(sizeof(CONFIG_FASTBOOT_SERIAL_NUM))]; -static u8 wstrConfiguration[2 * (sizeof(CONFIG_FASTBOOT_CONFIGURATION_STR))]; -static u8 wstrDataInterface[2 * (sizeof(CONFIG_FASTBOOT_INTERFACE_STR))]; - -/* Standard USB Data Structures */ -static struct usb_interface_descriptor interface_descriptors[1]; -static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS]; -static struct usb_configuration_descriptor *configuration_descriptor; -static struct usb_device_descriptor device_descriptor = { - .bLength = sizeof(struct usb_device_descriptor), - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(USB_BCD_VERSION), - .bDeviceClass = 0xff, - .bDeviceSubClass = 0xff, - .bDeviceProtocol = 0xff, - .bMaxPacketSize0 = 0x40, - .idVendor = cpu_to_le16(CONFIG_FASTBOOT_VENDOR_ID), - .idProduct = cpu_to_le16(CONFIG_FASTBOOT_PRODUCT_ID), - .bcdDevice = cpu_to_le16(CONFIG_FASTBOOT_BCD_DEVICE), - .iManufacturer = STR_MANUFACTURER_INDEX, - .iProduct = STR_PRODUCT_INDEX, - .iSerialNumber = STR_SERIAL_INDEX, - .bNumConfigurations = 1 -}; - -/* - * Static Generic Serial specific data - */ - -struct fastboot_config_desc { - struct usb_configuration_descriptor configuration_desc; - struct usb_interface_descriptor interface_desc[1]; - struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS]; -}; - -static struct fastboot_config_desc -fastboot_configuration_descriptors[1] = { - { - .configuration_desc = { - .bLength = sizeof(struct usb_configuration_descriptor), - .bDescriptorType = USB_DT_CONFIG, - .wTotalLength = - cpu_to_le16(sizeof(struct fastboot_config_desc)), - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = STR_CONFIG_INDEX, - .bmAttributes = - BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, - .bMaxPower = 0x32 - }, - .interface_desc = { - { - .bLength = - sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = NUM_ENDPOINTS, - .bInterfaceClass = - FASTBOOT_INTERFACE_CLASS, - .bInterfaceSubClass = - FASTBOOT_INTERFACE_SUB_CLASS, - .bInterfaceProtocol = - FASTBOOT_INTERFACE_PROTOCOL, - .iInterface = STR_DATA_INTERFACE_INDEX - }, - }, - .data_endpoints = { - { - .bLength = - sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = UDC_OUT_ENDPOINT | - USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = - cpu_to_le16(CONFIG_USBD_OUT_PKTSIZE), - .bInterval = 0x00, - }, - { - .bLength = - sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = UDC_IN_ENDPOINT | - USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = - cpu_to_le16(CONFIG_USBD_IN_PKTSIZE), - .bInterval = 0x00, - }, - }, - }, -}; - - - -static struct fastboot_ptentry ptable[MAX_PTN]; -static unsigned int pcount; - - -/* Static Function Prototypes */ -static void _fastboot_init_strings(void); -static void _fastboot_init_instances(void); -static void _fastboot_init_endpoints(void); -static void _fastboot_event_handler(struct usb_device_instance *device, - usb_device_event_t event, int data); -static int _fastboot_cdc_setup(struct usb_device_request *request, - struct urb *urb); -static int _fastboot_usb_configured(void); -#if defined(CONFIG_FASTBOOT_STORAGE_SATA) \ - || defined(CONFIG_FASTBOOT_STORAGE_MMC) -static int _fastboot_parts_load_from_ptable(void); -#endif -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) -static int _fastboot_parts_load_from_env(void); -#endif -static int _fastboot_setup_dev(void); -static void _fastboot_load_partitions(void); - -/* utility function for converting char* to wide string used by USB */ -static void str2wide(char *str, u16 * wide) -{ - int i; - for (i = 0; i < strlen(str) && str[i]; i++) { - #if defined(__LITTLE_ENDIAN) - wide[i] = (u16) str[i]; - #elif defined(__BIG_ENDIAN) - wide[i] = ((u16)(str[i])<<8); - #else - #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined" - #endif - } -} - -/* - Get mmc control number from passed string, eg, "mmc1" mean device 1. Only - support "mmc0" to "mmc9" currently. It will be treated as device 0 for - other string. -*/ -static int _fastboot_get_mmc_no(char *env_str) -{ - int digit = 0; - unsigned char a; - - if (env_str && (strlen(env_str) >= 4) && - !strncmp(env_str, "mmc", 3)) { - a = env_str[3]; - if (a >= '0' && a <= '9') - digit = a - '0'; - } - - return digit; -} - -static int _fastboot_setup_dev(void) -{ - char *fastboot_env; - fastboot_env = getenv("fastboot_dev"); - - if (fastboot_env) { - if (!strcmp(fastboot_env, "sata")) { - fastboot_devinfo.type = DEV_SATA; - fastboot_devinfo.dev_id = 0; - } else if (!strcmp(fastboot_env, "nand")) { - fastboot_devinfo.type = DEV_NAND; - fastboot_devinfo.dev_id = 0; - } else if (!strncmp(fastboot_env, "mmc", 3)) { - fastboot_devinfo.type = DEV_MMC; - fastboot_devinfo.dev_id = _fastboot_get_mmc_no(fastboot_env); - } - } else { - return 1; - } - - return 0; -} - - -/* - * Initialize fastboot - */ -int fastboot_init(struct cmd_fastboot_interface *interface) -{ - printf("fastboot is in init......"); - - fastboot_interface = interface; - fastboot_interface->product_name = CONFIG_FASTBOOT_PRODUCT_NAME_STR; - fastboot_interface->serial_no = CONFIG_FASTBOOT_SERIAL_NUM; - fastboot_interface->nand_block_size = 4096; - fastboot_interface->transfer_buffer = - (unsigned char *)CONFIG_FASTBOOT_TRANSFER_BUF; - fastboot_interface->transfer_buffer_size = - CONFIG_FASTBOOT_TRANSFER_BUF_SIZE; - - _fastboot_init_strings(); - /* Basic USB initialization */ - udc_init(); - - _fastboot_init_instances(); - - udc_startup_events(device_instance); - udc_connect(); /* Enable pullup for host detection */ - - return 0; -} - -static void _fastboot_init_strings(void) -{ - struct usb_string_descriptor *string; - - fastboot_string_table[STR_LANG_INDEX] = - (struct usb_string_descriptor *)wstrLang; - - string = (struct usb_string_descriptor *)wstrManufacturer; - string->bLength = sizeof(wstrManufacturer); - string->bDescriptorType = USB_DT_STRING; - str2wide(CONFIG_FASTBOOT_MANUFACTURER_STR, string->wData); - fastboot_string_table[STR_MANUFACTURER_INDEX] = string; - - string = (struct usb_string_descriptor *)wstrProduct; - string->bLength = sizeof(wstrProduct); - string->bDescriptorType = USB_DT_STRING; - str2wide(CONFIG_FASTBOOT_PRODUCT_NAME_STR, string->wData); - fastboot_string_table[STR_PRODUCT_INDEX] = string; - - string = (struct usb_string_descriptor *)wstrSerial; - string->bLength = sizeof(wstrSerial); - string->bDescriptorType = USB_DT_STRING; - str2wide(CONFIG_FASTBOOT_SERIAL_NUM, string->wData); - fastboot_string_table[STR_SERIAL_INDEX] = string; - - string = (struct usb_string_descriptor *)wstrConfiguration; - string->bLength = sizeof(wstrConfiguration); - string->bDescriptorType = USB_DT_STRING; - str2wide(CONFIG_FASTBOOT_CONFIGURATION_STR, string->wData); - fastboot_string_table[STR_CONFIG_INDEX] = string; - - string = (struct usb_string_descriptor *) wstrDataInterface; - string->bLength = sizeof(wstrDataInterface); - string->bDescriptorType = USB_DT_STRING; - str2wide(CONFIG_FASTBOOT_INTERFACE_STR, string->wData); - fastboot_string_table[STR_DATA_INTERFACE_INDEX] = string; - - /* Now, initialize the string table for ep0 handling */ - usb_strings = fastboot_string_table; -} - -static void _fastboot_init_instances(void) -{ - int i; - u16 temp; - - /* Assign endpoint descriptors */ - ep_descriptor_ptrs[0] = - &fastboot_configuration_descriptors[0].data_endpoints[0]; - ep_descriptor_ptrs[1] = - &fastboot_configuration_descriptors[0].data_endpoints[1]; - - /* Configuration Descriptor */ - configuration_descriptor = - (struct usb_configuration_descriptor *) - &fastboot_configuration_descriptors; - - fastboot_configured_flag = 0; - - /* initialize device instance */ - memset(device_instance, 0, sizeof(struct usb_device_instance)); - device_instance->device_state = STATE_INIT; - device_instance->device_descriptor = &device_descriptor; - device_instance->event = _fastboot_event_handler; - device_instance->cdc_recv_setup = _fastboot_cdc_setup; - device_instance->bus = bus_instance; - device_instance->configurations = 1; - device_instance->configuration_instance_array = config_instance; - - /* initialize bus instance */ - memset(bus_instance, 0, sizeof(struct usb_bus_instance)); - bus_instance->device = device_instance; - bus_instance->endpoint_array = endpoint_instance; - bus_instance->max_endpoints = NUM_ENDPOINTS + 1; - bus_instance->maxpacketsize = 0xFF; - bus_instance->serial_number_str = CONFIG_FASTBOOT_SERIAL_NUM; - - /* configuration instance */ - memset(config_instance, 0, - sizeof(struct usb_configuration_instance)); - config_instance->interfaces = 1; - config_instance->configuration_descriptor = configuration_descriptor; - config_instance->interface_instance_array = interface_instance; - - /* interface instance */ - memset(interface_instance, 0, - sizeof(struct usb_interface_instance)); - interface_instance->alternates = 1; - interface_instance->alternates_instance_array = alternate_instance; - - /* alternates instance */ - memset(alternate_instance, 0, - sizeof(struct usb_alternate_instance)); - alternate_instance->interface_descriptor = interface_descriptors; - alternate_instance->endpoints = NUM_ENDPOINTS; - alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs; - - /* endpoint instances */ - memset(&endpoint_instance[0], 0, - sizeof(struct usb_endpoint_instance)); - endpoint_instance[0].endpoint_address = 0; - endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE; - endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL; - endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE; - endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL; - udc_setup_ep(device_instance, 0, &endpoint_instance[0]); - - for (i = 1; i <= NUM_ENDPOINTS; i++) { - memset(&endpoint_instance[i], 0, - sizeof(struct usb_endpoint_instance)); - - endpoint_instance[i].endpoint_address = - ep_descriptor_ptrs[i - 1]->bEndpointAddress; - - endpoint_instance[i].rcv_attributes = - ep_descriptor_ptrs[i - 1]->bmAttributes; - - /*fix the abort caused by unalignment*/ - temp = *(u8 *)&ep_descriptor_ptrs[i - 1]->wMaxPacketSize; - temp |= - (*(((u8 *)&ep_descriptor_ptrs[i - 1]->wMaxPacketSize) + 1) << 8); - - endpoint_instance[i].rcv_packetSize = - le16_to_cpu(temp); - - endpoint_instance[i].tx_attributes = - ep_descriptor_ptrs[i - 1]->bmAttributes; - - endpoint_instance[i].tx_packetSize = - le16_to_cpu(temp); - - endpoint_instance[i].tx_attributes = - ep_descriptor_ptrs[i - 1]->bmAttributes; - - urb_link_init(&endpoint_instance[i].rcv); - urb_link_init(&endpoint_instance[i].rdy); - urb_link_init(&endpoint_instance[i].tx); - urb_link_init(&endpoint_instance[i].done); - - if (endpoint_instance[i].endpoint_address & USB_DIR_IN) { - tx_endpoint = i; - endpoint_instance[i].tx_urb = - usbd_alloc_urb(device_instance, - &endpoint_instance[i]); - } else { - rx_endpoint = i; - endpoint_instance[i].rcv_urb = - usbd_alloc_urb(device_instance, - &endpoint_instance[i]); - } - } -} - -static void _fastboot_init_endpoints(void) -{ - int i; - - bus_instance->max_endpoints = NUM_ENDPOINTS + 1; - for (i = 1; i <= NUM_ENDPOINTS; i++) - udc_setup_ep(device_instance, i, &endpoint_instance[i]); -} - -static void _fastboot_destroy_endpoints(void) -{ - int i; - struct urb *tx_urb; - - for (i = 1; i <= NUM_ENDPOINTS; i++) { - /*dealloc urb*/ - if (endpoint_instance[i].endpoint_address & USB_DIR_IN) { - if (endpoint_instance[i].tx_urb) - usbd_dealloc_urb(endpoint_instance[i].tx_urb); - - while (endpoint_instance[i].tx_queue) { - tx_urb = first_urb_detached(&endpoint_instance[i].tx); - if (tx_urb) { - usbd_dealloc_urb(tx_urb); - endpoint_instance[i].tx_queue--; - } else { - break; - } - } - endpoint_instance[i].tx_queue = 0; - - do { - tx_urb = first_urb_detached(&endpoint_instance[i].done); - if (tx_urb) - usbd_dealloc_urb(tx_urb); - } while (tx_urb); - - } else { - if (endpoint_instance[i].rcv_urb) - usbd_dealloc_urb(endpoint_instance[i].rcv_urb); - } - - udc_destroy_ep(device_instance, &endpoint_instance[i]); - } -} - - -static int _fill_buffer(u8 *buf) -{ - struct usb_endpoint_instance *endpoint = - &endpoint_instance[rx_endpoint]; - - if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) { - unsigned int nb = 0; - char *src = (char *)endpoint->rcv_urb->buffer; - unsigned int rx_avail = MAX_BUFFER_SIZE; - - if (rx_avail >= endpoint->rcv_urb->actual_length) { - nb = endpoint->rcv_urb->actual_length; - memcpy(buf, src, nb); - endpoint->rcv_urb->actual_length = 0; - } - return nb; - } - return 0; -} - -static struct urb *_next_urb(struct usb_device_instance *device, - struct usb_endpoint_instance *endpoint) -{ - struct urb *current_urb = NULL; - int space; - - /* If there's a queue, then we should add to the last urb */ - if (!endpoint->tx_queue) - current_urb = endpoint->tx_urb; - else - /* Last urb from tx chain */ - current_urb = - p2surround(struct urb, link, endpoint->tx.prev); - - /* Make sure this one has enough room */ - space = current_urb->buffer_length - current_urb->actual_length; - if (space > 0) - return current_urb; - else { /* No space here */ - /* First look at done list */ - current_urb = first_urb_detached(&endpoint->done); - if (!current_urb) - current_urb = usbd_alloc_urb(device, endpoint); - - urb_append(&endpoint->tx, current_urb); - endpoint->tx_queue++; - } - return current_urb; -} - -static int _fastboot_usb_configured(void) -{ - return fastboot_configured_flag; -} - -static void _fastboot_event_handler(struct usb_device_instance *device, - usb_device_event_t event, int data) -{ - switch (event) { - case DEVICE_RESET: - case DEVICE_BUS_INACTIVE: - fastboot_configured_flag = 0; - break; - case DEVICE_CONFIGURED: - fastboot_configured_flag = 1; - _fastboot_init_endpoints(); - break; - case DEVICE_ADDRESS_ASSIGNED: - default: - break; - } -} - -static int _fastboot_cdc_setup(struct usb_device_request *request, - struct urb *urb) -{ - return 0; -} - - -/*! - * Function to receive data from host through channel - * - * @buf buffer to fill in - * @count read data size - * - * @return 0 - */ -int fastboot_usb_recv(u8 *buf, int count) -{ - int len = 0; - - while (!_fastboot_usb_configured()) - udc_irq(); - - /* update rxqueue to wait new data */ - mxc_udc_rxqueue_update(2, count); - - while (!len) { - if (is_usb_disconnected()) { - /*it will not unconfigure when disconnect - from host, so here needs manual unconfigure - anyway, it's just a workaround*/ - fastboot_configured_flag = 0; - usb_disconnected = 1; - return 0; - } - udc_irq(); - if (_fastboot_usb_configured()) - len = _fill_buffer(buf); - } - return len; -} - -int fastboot_getvar(const char *rx_buffer, char *tx_buffer) -{ - /* Place board specific variables here */ - return 0; -} - -int fastboot_poll() -{ - u8 buffer[MAX_BUFFER_SIZE]; - int length = 0; - - memset(buffer, 0, MAX_BUFFER_SIZE); - - length = fastboot_usb_recv(buffer, MAX_BUFFER_SIZE); - - /* If usb disconnected, blocked here to wait */ - if (usb_disconnected) { - udc_disconnect(); - udc_connect(); - /*the udc_connect will be blocked until connect to host - so, the usb_disconnect should be 0 after udc_connect, - and should be set manually. Anyway, it's just a workaround*/ - usb_disconnected = 0; - } - - if (!length) - return FASTBOOT_INACTIVE; - - /* Pass this up to the interface's handler */ - if (fastboot_interface && fastboot_interface->rx_handler) { - if (!fastboot_interface->rx_handler(buffer, length)) - return FASTBOOT_OK; - } - return FASTBOOT_OK; -} - -int fastboot_tx(unsigned char *buffer, unsigned int buffer_size) -{ - /* Not realized yet */ - return 0; -} - -static int _fastboot_write_buffer(const char *buffer, - unsigned int buffer_size) -{ - struct usb_endpoint_instance *endpoint = - (struct usb_endpoint_instance *)&endpoint_instance[tx_endpoint]; - struct urb *current_urb = NULL; - - if (!_fastboot_usb_configured()) - return 0; - - current_urb = _next_urb(device_instance, endpoint); - if (buffer_size) { - char *dest; - int space_avail, popnum, count, total = 0; - - /* Break buffer into urb sized pieces, - * and link each to the endpoint - */ - count = buffer_size; - while (count > 0) { - if (!current_urb) { - printf("current_urb is NULL, buffer_size %d\n", - buffer_size); - return total; - } - - dest = (char *)current_urb->buffer + - current_urb->actual_length; - - space_avail = current_urb->buffer_length - - current_urb->actual_length; - popnum = min(space_avail, count); - if (popnum == 0) - break; - - memcpy(dest, buffer + total, popnum); - printf("send: %s\n", (char *)buffer); - - current_urb->actual_length += popnum; - total += popnum; - - if (udc_endpoint_write(endpoint)) - /* Write pre-empted by RX */ - return 0; - count -= popnum; - } /* end while */ - return total; - } - return 0; -} - -int fastboot_tx_status(const char *buffer, unsigned int buffer_size) -{ - int len = 0; - - while (buffer_size > 0) { - len = _fastboot_write_buffer(buffer + len, buffer_size); - buffer_size -= len; - - udc_irq(); - } - udc_irq(); - - return 0; -} - -void fastboot_shutdown(void) -{ - usb_shutdown(); - - /* Reset interface*/ - if (fastboot_interface && - fastboot_interface->reset_handler) { - fastboot_interface->reset_handler(); - } - - /* Reset some globals */ - _fastboot_destroy_endpoints(); - fastboot_interface = NULL; - fastboot_configured_flag = 0; - usb_disconnected = 0; - - /*free memory*/ - udc_destroy(); -} - -/* - * CPU and board-specific fastboot initializations. Aliased function - * signals caller to move on - */ -static void __def_fastboot_setup(void) -{ - /*do nothing here*/ -} -void board_fastboot_setup(void) \ - __attribute__((weak, alias("__def_fastboot_setup"))); - - -void fastboot_setup(void) -{ - /*execute board relevant initilizations for preparing fastboot */ - board_fastboot_setup(); - - /*get the fastboot dev*/ - _fastboot_setup_dev(); - - /*check if we need to setup recovery*/ -#ifdef CONFIG_ANDROID_RECOVERY - check_recovery_mode(); -#endif - - /*load partitions information for the fastboot dev*/ - _fastboot_load_partitions(); -} - -/* export to lib_arm/board.c */ -void check_fastboot(void) -{ - if (fastboot_check_and_clean_flag()) - do_fastboot(NULL, 0, 0, 0); -} - -#if defined(CONFIG_FASTBOOT_STORAGE_SATA) \ - || defined(CONFIG_FASTBOOT_STORAGE_MMC) -/** - @mmc_dos_partition_index: the partition index in mbr. - @mmc_partition_index: the boot partition or user partition index, - not related to the partition table. - */ -static int _fastboot_parts_add_ptable_entry(int ptable_index, - int mmc_dos_partition_index, - int mmc_partition_index, - const char *name, - block_dev_desc_t *dev_desc, - struct fastboot_ptentry *ptable) -{ - disk_partition_t info; - strcpy(ptable[ptable_index].name, name); - - if (get_partition_info(dev_desc, - mmc_dos_partition_index, &info)) { - printf("Bad partition index:%d for partition:%s\n", - mmc_dos_partition_index, name); - return -1; - } else { - ptable[ptable_index].start = info.start; - ptable[ptable_index].length = info.size; - ptable[ptable_index].partition_id = mmc_partition_index; - } - return 0; -} - -static int _fastboot_parts_load_from_ptable(void) -{ - int i; -#ifdef CONFIG_CMD_SATA - int sata_device_no; -#endif - - /* mmc boot partition: -1 means no partition, 0 user part., 1 boot part. - * default is no partition, for emmc default user part, except emmc*/ - int boot_partition = FASTBOOT_MMC_NONE_PARTITION_ID; - int user_partition = FASTBOOT_MMC_NONE_PARTITION_ID; - - struct mmc *mmc; - block_dev_desc_t *dev_desc; - struct fastboot_ptentry ptable[PTN_RECOVERY_INDEX + 1]; - - /* sata case in env */ - if (fastboot_devinfo.type == DEV_SATA) { -#ifdef CONFIG_CMD_SATA - puts("flash target is SATA\n"); - if (sata_initialize()) - return -1; - sata_device_no = CONFIG_FASTBOOT_SATA_NO; - if (sata_device_no >= CONFIG_SYS_SATA_MAX_DEVICE) { - printf("Unknown SATA(%d) device for fastboot\n", - sata_device_no); - return -1; - } - dev_desc = sata_get_dev(sata_device_no); -#else /*! CONFIG_CMD_SATA*/ - puts("SATA isn't buildin\n"); - return -1; -#endif /*! CONFIG_CMD_SATA*/ - } else if (fastboot_devinfo.type == DEV_MMC) { - int mmc_no = 0; - mmc_no = fastboot_devinfo.dev_id; - - printf("flash target is MMC:%d\n", mmc_no); - mmc = find_mmc_device(mmc_no); - if (mmc && mmc_init(mmc)) - printf("MMC card init failed!\n"); - - dev_desc = get_dev("mmc", mmc_no); - if (NULL == dev_desc) { - printf("** Block device MMC %d not supported\n", - mmc_no); - return -1; - } - - /* multiple boot paritions for eMMC 4.3 later */ - if (mmc->part_config != MMCPART_NOAVAILABLE) { - boot_partition = FASTBOOT_MMC_BOOT_PARTITION_ID; - user_partition = FASTBOOT_MMC_USER_PARTITION_ID; - } - } else { - printf("Can't setup partition table on this device %d\n", - fastboot_devinfo.type); - return -1; - } - - memset((char *)ptable, 0, - sizeof(struct fastboot_ptentry) * (PTN_RECOVERY_INDEX + 1)); - /* MBR */ - strcpy(ptable[PTN_MBR_INDEX].name, "mbr"); - ptable[PTN_MBR_INDEX].start = ANDROID_MBR_OFFSET / dev_desc->blksz; - ptable[PTN_MBR_INDEX].length = ANDROID_MBR_SIZE / dev_desc->blksz; - ptable[PTN_MBR_INDEX].partition_id = user_partition; - /* Bootloader */ - strcpy(ptable[PTN_BOOTLOADER_INDEX].name, "bootloader"); - ptable[PTN_BOOTLOADER_INDEX].start = - ANDROID_BOOTLOADER_OFFSET / dev_desc->blksz; - ptable[PTN_BOOTLOADER_INDEX].length = - ANDROID_BOOTLOADER_SIZE / dev_desc->blksz; - ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition; - - _fastboot_parts_add_ptable_entry(PTN_KERNEL_INDEX, - CONFIG_ANDROID_BOOT_PARTITION_MMC, - user_partition, "boot", dev_desc, ptable); - _fastboot_parts_add_ptable_entry(PTN_RECOVERY_INDEX, - CONFIG_ANDROID_RECOVERY_PARTITION_MMC, - user_partition, - "recovery", dev_desc, ptable); - _fastboot_parts_add_ptable_entry(PTN_SYSTEM_INDEX, - CONFIG_ANDROID_SYSTEM_PARTITION_MMC, - user_partition, - "system", dev_desc, ptable); - - for (i = 0; i <= PTN_RECOVERY_INDEX; i++) - fastboot_flash_add_ptn(&ptable[i]); - - return 0; -} -#endif /*CONFIG_FASTBOOT_STORAGE_SATA || CONFIG_FASTBOOT_STORAGE_MMC*/ - -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) -static unsigned long long _memparse(char *ptr, char **retptr) -{ - char *endptr; /* local pointer to end of parsed string */ - - unsigned long ret = simple_strtoul(ptr, &endptr, 0); - - switch (*endptr) { - case 'M': - case 'm': - ret <<= 10; - case 'K': - case 'k': - ret <<= 10; - endptr++; - default: - break; - } - - if (retptr) - *retptr = endptr; - - return ret; -} - -static int _fastboot_parts_add_env_entry(char *s, char **retptr) -{ - unsigned long size; - unsigned long offset = 0; - char *name; - int name_len; - int delim; - unsigned int flags; - struct fastboot_ptentry part; - - size = _memparse(s, &s); - if (0 == size) { - printf("Error:FASTBOOT size of parition is 0\n"); - return 1; - } - - /* fetch partition name and flags */ - flags = 0; /* this is going to be a regular partition */ - delim = 0; - /* check for offset */ - if (*s == '@') { - s++; - offset = _memparse(s, &s); - } else { - printf("Error:FASTBOOT offset of parition is not given\n"); - return 1; - } - - /* now look for name */ - if (*s == '(') - delim = ')'; - - if (delim) { - char *p; - - name = ++s; - p = strchr((const char *)name, delim); - if (!p) { - printf("Error:FASTBOOT no closing %c found in partition name\n", - delim); - return 1; - } - name_len = p - name; - s = p + 1; - } else { - printf("Error:FASTBOOT no partition name for \'%s\'\n", s); - return 1; - } - - /* check for options */ - while (1) { - if (strncmp(s, "i", 1) == 0) { - flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_I; - s += 1; - } else if (strncmp(s, "ubifs", 5) == 0) { - /* ubifs */ - flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_TRIMFFS; - s += 5; - } else { - break; - } - if (strncmp(s, "|", 1) == 0) - s += 1; - } - - /* enter this partition (offset will be calculated later if it is zero at this point) */ - part.length = size; - part.start = offset; - part.flags = flags; - - if (name) { - if (name_len >= sizeof(part.name)) { - printf("Error:FASTBOOT partition name is too long\n"); - return 1; - } - strncpy(&part.name[0], name, name_len); - /* name is not null terminated */ - part.name[name_len] = '\0'; - } else { - printf("Error:FASTBOOT no name\n"); - return 1; - } - - fastboot_flash_add_ptn(&part); - - /*if the nand partitions envs are not initialized, try to init them*/ - if (check_parts_values(&part)) - save_parts_values(&part, part.start, part.length); - - /* return (updated) pointer command line string */ - *retptr = s; - - /* return partition table */ - return 0; -} - -static int _fastboot_parts_load_from_env(void) -{ - char fbparts[FASTBOOT_FBPARTS_ENV_MAX_LEN], *env; - - env = getenv("fbparts"); - if (env) { - unsigned int len; - len = strlen(env); - if (len && len < FASTBOOT_FBPARTS_ENV_MAX_LEN) { - char *s, *e; - - memcpy(&fbparts[0], env, len + 1); - printf("Fastboot: Adding partitions from environment\n"); - s = &fbparts[0]; - e = s + len; - while (s < e) { - if (_fastboot_parts_add_env_entry(s, &s)) { - printf("Error:Fastboot: Abort adding partitions\n"); - pcount = 0; - return 1; - } - /* Skip a bunch of delimiters */ - while (s < e) { - if ((' ' == *s) || - ('\t' == *s) || - ('\n' == *s) || - ('\r' == *s) || - (',' == *s)) { - s++; - } else { - break; - } - } - } - } - } - - return 0; -} -#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ - -static void _fastboot_load_partitions(void) -{ - pcount = 0; -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) - _fastboot_parts_load_from_env(); -#elif defined(CONFIG_FASTBOOT_STORAGE_SATA) \ - || defined(CONFIG_FASTBOOT_STORAGE_MMC) - _fastboot_parts_load_from_ptable(); -#endif -} - -/* - * Android style flash utilties */ -void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn) -{ - if (pcount < MAX_PTN) { - memcpy(ptable + pcount, ptn, sizeof(struct fastboot_ptentry)); - pcount++; - } -} - -void fastboot_flash_dump_ptn(void) -{ - unsigned int n; - for (n = 0; n < pcount; n++) { - struct fastboot_ptentry *ptn = ptable + n; - printf("ptn %d name='%s' start=%d len=%d\n", - n, ptn->name, ptn->start, ptn->length); - } -} - - -struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name) -{ - unsigned int n; - - for (n = 0; n < pcount; n++) { - /* Make sure a substring is not accepted */ - if (strlen(name) == strlen(ptable[n].name)) { - if (0 == strcmp(ptable[n].name, name)) - return ptable + n; - } - } - - printf("can't find partition: %s, dump the partition table\n", name); - fastboot_flash_dump_ptn(); - return 0; -} - -struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned int n) -{ - if (n < pcount) - return ptable + n; - else - return 0; -} - -unsigned int fastboot_flash_get_ptn_count(void) -{ - return pcount; -} |