summaryrefslogtreecommitdiff
path: root/drivers/fastboot/fastboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fastboot/fastboot.c')
-rw-r--r--drivers/fastboot/fastboot.c1127
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;
-}