1988 lines
63 KiB
C
Executable File
1988 lines
63 KiB
C
Executable File
/*
|
||
* (C) Copyright 2007-2013
|
||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||
* Jerry Wang <wangflord@allwinnertech.com>
|
||
*
|
||
* See file CREDITS for list of people who contributed to this
|
||
* project.
|
||
*
|
||
* This program is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU General Public License as
|
||
* published by the Free Software Foundation; either version 2 of
|
||
* the License, or (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||
* MA 02111-1307 USA
|
||
*/
|
||
#include "usb_base.h"
|
||
#include <scsi.h>
|
||
#include <asm/arch/dma.h>
|
||
#include <sys_partition.h>
|
||
#include <sys_config.h>
|
||
#include <sprite.h>
|
||
#include <boot_type.h>
|
||
#include "usb_efex.h"
|
||
#include <pmu.h>
|
||
#include <asm/io.h>
|
||
#include "efex_queue.h"
|
||
#include <asm/arch/timer.h>
|
||
#ifndef CONFIG_SUNXI_SPINOR
|
||
#define _EFEX_USE_BUF_QUEUE_
|
||
#endif
|
||
|
||
#define SUNXI_USB_EFEX_IDLE (0)
|
||
#define SUNXI_USB_EFEX_SETUP (1)
|
||
#define SUNXI_USB_EFEX_SEND_DATA (2)
|
||
#define SUNXI_USB_EFEX_RECEIVE_DATA (3)
|
||
#define SUNXI_USB_EFEX_STATUS (4)
|
||
#define SUNXI_USB_EFEX_EXIT (5)
|
||
|
||
#define SUNXI_USB_EFEX_SETUP_NEW (11)
|
||
#define SUNXI_USB_EFEX_SEND_DATA_NEW (12)
|
||
#define SUNXI_USB_EFEX_RECEIVE_DATA_NEW (13)
|
||
#define FES_NEW_CMD_LEN (20)
|
||
|
||
|
||
|
||
#define SUNXI_USB_EFEX_APPS_MAST (0xf0000)
|
||
|
||
#define SUNXI_USB_EFEX_APPS_IDLE (0x10000)
|
||
#define SUNXI_USB_EFEX_APPS_CMD (0x20000)
|
||
#define SUNXI_USB_EFEX_APPS_DATA (0x30000)
|
||
#define SUNXI_USB_EFEX_APPS_SEND_DATA (SUNXI_USB_EFEX_APPS_DATA | SUNXI_USB_EFEX_SEND_DATA)
|
||
#define SUNXI_USB_EFEX_APPS_RECEIVE_DATA (SUNXI_USB_EFEX_APPS_DATA | SUNXI_USB_EFEX_RECEIVE_DATA)
|
||
#define SUNXI_USB_EFEX_APPS_STATUS ((0x40000) | SUNXI_USB_EFEX_STATUS)
|
||
#define SUNXI_USB_EFEX_APPS_EXIT ((0x50000) | SUNXI_USB_EFEX_EXIT)
|
||
|
||
static int sunxi_usb_efex_write_enable = 0;
|
||
static int sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
static int sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_IDLE;
|
||
static efex_trans_set_t trans_data;
|
||
static u8 *cmd_buf;
|
||
static u32 sunxi_efex_next_action = 0;
|
||
static struct pmu_config_t pmu_config;
|
||
static struct multi_unseq_mem_s global_unseq_mem_addr;
|
||
#if defined(SUNXI_USB_30)
|
||
static int sunxi_usb_efex_status_enable = 1;
|
||
#endif
|
||
#ifdef CONFIG_SUNXI_SPINOR
|
||
static u32 fullimg_size = 0;
|
||
extern u32 total_write_bytes ;
|
||
#endif
|
||
|
||
extern int sunxi_sprite_store_private_data(void);
|
||
extern int spinor_erase_all_blocks(int erase);
|
||
|
||
int efex_suspend_flag = 0;
|
||
|
||
DECLARE_GLOBAL_DATA_PTR;
|
||
/*
|
||
*******************************************************************************
|
||
* do_usb_req_set_interface
|
||
*
|
||
* Description:
|
||
* void
|
||
*
|
||
* Parameters:
|
||
* void
|
||
*
|
||
* Return value:
|
||
* void
|
||
*
|
||
* note:
|
||
* void
|
||
*
|
||
*******************************************************************************
|
||
*/
|
||
static int __usb_set_interface(struct usb_device_request *req)
|
||
{
|
||
sunxi_usb_dbg("set interface\n");
|
||
/* Only support interface 0, alternate 0 */
|
||
if((0 == req->wIndex) && (0 == req->wValue))
|
||
{
|
||
sunxi_udc_ep_reset();
|
||
}
|
||
else
|
||
{
|
||
printf("err: invalid wIndex and wValue, (0, %d), (0, %d)\n", req->wIndex, req->wValue);
|
||
return SUNXI_USB_REQ_OP_ERR;
|
||
}
|
||
|
||
return SUNXI_USB_REQ_SUCCESSED;
|
||
}
|
||
|
||
/*
|
||
*******************************************************************************
|
||
* do_usb_req_set_address
|
||
*
|
||
* Description:
|
||
* void
|
||
*
|
||
* Parameters:
|
||
* void
|
||
*
|
||
* Return value:
|
||
* void
|
||
*
|
||
* note:
|
||
* void
|
||
*
|
||
*******************************************************************************
|
||
*/
|
||
static int __usb_set_address(struct usb_device_request *req)
|
||
{
|
||
uchar address;
|
||
|
||
address = req->wValue & 0x7f;
|
||
printf("set address 0x%x\n", address);
|
||
|
||
__usdelay(10);
|
||
sunxi_udc_set_address(address);
|
||
|
||
return SUNXI_USB_REQ_SUCCESSED;
|
||
}
|
||
|
||
/*
|
||
*******************************************************************************
|
||
* do_usb_req_set_configuration
|
||
*
|
||
* Description:
|
||
* void
|
||
*
|
||
* Parameters:
|
||
* void
|
||
*
|
||
* Return value:
|
||
* void
|
||
*
|
||
* note:
|
||
* void
|
||
*
|
||
*******************************************************************************
|
||
*/
|
||
static int __usb_set_configuration(struct usb_device_request *req)
|
||
{
|
||
sunxi_usb_dbg("set configuration\n");
|
||
/* Only support 1 configuration so nak anything else */
|
||
if (1 == req->wValue)
|
||
{
|
||
sunxi_udc_ep_reset();
|
||
}
|
||
else
|
||
{
|
||
printf("err: invalid wValue, (0, %d)\n", req->wValue);
|
||
|
||
return SUNXI_USB_REQ_OP_ERR;
|
||
}
|
||
|
||
sunxi_udc_set_configuration(req->wValue);
|
||
|
||
return SUNXI_USB_REQ_SUCCESSED;
|
||
}
|
||
/*
|
||
*******************************************************************************
|
||
* do_usb_req_get_descriptor
|
||
*
|
||
* Description:
|
||
* void
|
||
*
|
||
* Parameters:
|
||
* void
|
||
*
|
||
* Return value:
|
||
* void
|
||
*
|
||
* note:
|
||
* void
|
||
*
|
||
*******************************************************************************
|
||
*/
|
||
static int __usb_get_descriptor(struct usb_device_request *req, uchar *buffer)
|
||
{
|
||
int ret = SUNXI_USB_REQ_SUCCESSED;
|
||
|
||
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
switch(req->wValue >> 8)
|
||
{
|
||
case USB_DT_DEVICE: //<2F>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
struct usb_device_descriptor *dev_dscrptr;
|
||
|
||
sunxi_usb_dbg("get device descriptor\n");
|
||
|
||
dev_dscrptr = (struct usb_device_descriptor *)buffer;
|
||
memset((void *)dev_dscrptr, 0, sizeof(struct usb_device_descriptor));
|
||
|
||
dev_dscrptr->bLength = MIN(req->wLength, sizeof (struct usb_device_descriptor));
|
||
dev_dscrptr->bDescriptorType = USB_DT_DEVICE;
|
||
#ifdef CONFIG_USB_1_1_DEVICE
|
||
dev_dscrptr->bcdUSB = 0x110;
|
||
#else
|
||
dev_dscrptr->bcdUSB = 0x200;
|
||
#endif
|
||
dev_dscrptr->bDeviceClass = 0;
|
||
dev_dscrptr->bDeviceSubClass = 0;
|
||
dev_dscrptr->bDeviceProtocol = 0;
|
||
dev_dscrptr->bMaxPacketSize0 = 0x40;
|
||
dev_dscrptr->idVendor = DRIVER_VENDOR_ID;
|
||
dev_dscrptr->idProduct = DRIVER_PRODUCT_ID;
|
||
dev_dscrptr->bcdDevice = 0xffff;
|
||
//ignored
|
||
//dev_dscrptr->iManufacturer = SUNXI_USB_STRING_IMANUFACTURER;
|
||
//dev_dscrptr->iProduct = SUNXI_USB_STRING_IPRODUCT;
|
||
//dev_dscrptr->iSerialNumber = SUNXI_USB_STRING_ISERIALNUMBER;
|
||
dev_dscrptr->iManufacturer = 0;
|
||
dev_dscrptr->iProduct = 0;
|
||
dev_dscrptr->iSerialNumber = 0;
|
||
dev_dscrptr->bNumConfigurations = 1;
|
||
|
||
sunxi_udc_send_setup(dev_dscrptr->bLength, buffer);
|
||
}
|
||
break;
|
||
|
||
case USB_DT_CONFIG: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
struct usb_configuration_descriptor *config_dscrptr;
|
||
struct usb_interface_descriptor *inter_dscrptr;
|
||
struct usb_endpoint_descriptor *ep_in, *ep_out;
|
||
unsigned char bytes_remaining = req->wLength;
|
||
unsigned char bytes_total = 0;
|
||
|
||
sunxi_usb_dbg("get config descriptor\n");
|
||
|
||
bytes_total = sizeof (struct usb_configuration_descriptor) + \
|
||
sizeof (struct usb_interface_descriptor) + \
|
||
sizeof (struct usb_endpoint_descriptor) + \
|
||
sizeof (struct usb_endpoint_descriptor);
|
||
|
||
memset(buffer, 0, bytes_total);
|
||
|
||
config_dscrptr = (struct usb_configuration_descriptor *)(buffer + 0);
|
||
inter_dscrptr = (struct usb_interface_descriptor *)(buffer + \
|
||
sizeof(struct usb_configuration_descriptor));
|
||
ep_in = (struct usb_endpoint_descriptor *)(buffer + \
|
||
sizeof(struct usb_configuration_descriptor) + \
|
||
sizeof(struct usb_interface_descriptor));
|
||
ep_out = (struct usb_endpoint_descriptor *)(buffer + \
|
||
sizeof(struct usb_configuration_descriptor) + \
|
||
sizeof(struct usb_interface_descriptor) + \
|
||
sizeof(struct usb_endpoint_descriptor));
|
||
|
||
/* configuration */
|
||
config_dscrptr->bLength = MIN(bytes_remaining, sizeof (struct usb_configuration_descriptor));
|
||
config_dscrptr->bDescriptorType = USB_DT_CONFIG;
|
||
config_dscrptr->wTotalLength = bytes_total;
|
||
config_dscrptr->bNumInterfaces = 1;
|
||
config_dscrptr->bConfigurationValue = 1;
|
||
config_dscrptr->iConfiguration = 0;
|
||
config_dscrptr->bmAttributes = 0x80; //not self powered
|
||
config_dscrptr->bMaxPower = 0xFA; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>500ms(0xfa * 2)
|
||
|
||
bytes_remaining -= config_dscrptr->bLength;
|
||
/* interface */
|
||
inter_dscrptr->bLength = MIN (bytes_remaining, sizeof(struct usb_interface_descriptor));
|
||
inter_dscrptr->bDescriptorType = USB_DT_INTERFACE;
|
||
inter_dscrptr->bInterfaceNumber = 0x00;
|
||
inter_dscrptr->bAlternateSetting = 0x00;
|
||
inter_dscrptr->bNumEndpoints = 0x02;
|
||
inter_dscrptr->bInterfaceClass = 0xff;
|
||
inter_dscrptr->bInterfaceSubClass = 0xff;
|
||
inter_dscrptr->bInterfaceProtocol = 0xff;
|
||
inter_dscrptr->iInterface = 0;
|
||
|
||
bytes_remaining -= inter_dscrptr->bLength;
|
||
/* ep_in */
|
||
ep_in->bLength = MIN (bytes_remaining, sizeof (struct usb_endpoint_descriptor));
|
||
ep_in->bDescriptorType = USB_DT_ENDPOINT;
|
||
ep_in->bEndpointAddress = sunxi_udc_get_ep_in_type(); /* IN */
|
||
ep_in->bmAttributes = USB_ENDPOINT_XFER_BULK;
|
||
ep_in->wMaxPacketSize = sunxi_udc_get_ep_max();
|
||
ep_in->bInterval = 0x00;
|
||
|
||
bytes_remaining -= ep_in->bLength;
|
||
/* ep_out */
|
||
ep_out->bLength = MIN (bytes_remaining, sizeof (struct usb_endpoint_descriptor));
|
||
ep_out->bDescriptorType = USB_DT_ENDPOINT;
|
||
ep_out->bEndpointAddress = sunxi_udc_get_ep_out_type(); /* OUT */
|
||
ep_out->bmAttributes = USB_ENDPOINT_XFER_BULK;
|
||
ep_out->wMaxPacketSize = sunxi_udc_get_ep_max();
|
||
ep_out->bInterval = 0x00;
|
||
|
||
bytes_remaining -= ep_out->bLength;
|
||
|
||
sunxi_udc_send_setup(MIN(req->wLength, bytes_total), buffer);
|
||
}
|
||
break;
|
||
|
||
case USB_DT_STRING:
|
||
{
|
||
unsigned char bLength = 0;
|
||
unsigned char string_index = req->wValue & 0xff;
|
||
|
||
sunxi_usb_dbg("get string descriptor\n");
|
||
|
||
/* Language ID */
|
||
if(string_index == 0)
|
||
{
|
||
bLength = MIN(4, req->wLength);
|
||
|
||
buffer[0] = bLength;
|
||
buffer[1] = USB_DT_STRING;
|
||
buffer[2] = 9;
|
||
buffer[3] = 4;
|
||
sunxi_udc_send_setup(bLength, (void *)buffer);
|
||
}
|
||
else
|
||
{
|
||
printf("sunxi usb err: string line %d is not supported\n", string_index);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case USB_DT_DEVICE_QUALIFIER:
|
||
{
|
||
#ifdef CONFIG_USB_1_1_DEVICE
|
||
/* This is an invalid request for usb 1.1, nak it */
|
||
USBC_Dev_EpSendStall(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_EP0);
|
||
#else
|
||
struct usb_qualifier_descriptor *qua_dscrpt;
|
||
|
||
sunxi_usb_dbg("get qualifier descriptor\n");
|
||
|
||
qua_dscrpt = (struct usb_qualifier_descriptor *)buffer;
|
||
memset(&buffer, 0, sizeof(struct usb_qualifier_descriptor));
|
||
|
||
qua_dscrpt->bLength = MIN(req->wLength, sizeof(sizeof(struct usb_qualifier_descriptor)));
|
||
qua_dscrpt->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
|
||
qua_dscrpt->bcdUSB = 0x200;
|
||
qua_dscrpt->bDeviceClass = 0xff;
|
||
qua_dscrpt->bDeviceSubClass = 0xff;
|
||
qua_dscrpt->bDeviceProtocol = 0xff;
|
||
qua_dscrpt->bMaxPacketSize0 = 0x40;
|
||
qua_dscrpt->bNumConfigurations = 1;
|
||
qua_dscrpt->bRESERVED = 0;
|
||
|
||
sunxi_udc_send_setup(qua_dscrpt->bLength, buffer);
|
||
#endif
|
||
}
|
||
break;
|
||
|
||
default:
|
||
printf("err: unkown wValue(%d)\n", req->wValue);
|
||
|
||
ret = SUNXI_USB_REQ_OP_ERR;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
/*
|
||
*******************************************************************************
|
||
* do_usb_req_get_status
|
||
*
|
||
* Description:
|
||
* void
|
||
*
|
||
* Parameters:
|
||
* void
|
||
*
|
||
* Return value:
|
||
* void
|
||
*
|
||
* note:
|
||
* void
|
||
*
|
||
*******************************************************************************
|
||
*/
|
||
static int __usb_get_status(struct usb_device_request *req, uchar *buffer)
|
||
{
|
||
unsigned char bLength = 0;
|
||
|
||
sunxi_usb_dbg("get status\n");
|
||
if(0 == req->wLength)
|
||
{
|
||
/* sent zero packet */
|
||
sunxi_udc_send_setup(0, NULL);
|
||
|
||
return SUNXI_USB_REQ_OP_ERR;
|
||
}
|
||
|
||
bLength = MIN(req->wValue, 2);
|
||
|
||
buffer[0] = 1;
|
||
buffer[1] = 0;
|
||
|
||
sunxi_udc_send_setup(bLength, buffer);
|
||
|
||
return SUNXI_USB_REQ_SUCCESSED;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int __sunxi_efex_send_status(void *buffer, unsigned int buffer_size)
|
||
{
|
||
return sunxi_udc_send_data((uchar *)buffer, buffer_size);
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int sunxi_efex_init(void)
|
||
{
|
||
sunxi_usb_dbg("sunxi_efex_init\n");
|
||
memset(&trans_data, 0, sizeof(efex_trans_set_t));
|
||
sunxi_usb_efex_write_enable = 0;
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_IDLE;
|
||
|
||
cmd_buf = (u8 *)malloc(CBW_MAX_CMD_SIZE);
|
||
if(!cmd_buf)
|
||
{
|
||
printf("sunxi usb efex err: unable to malloc memory for cmd\n");
|
||
|
||
return -1;
|
||
}
|
||
trans_data.base_recv_buffer = (u8 *)malloc(SUNXI_EFEX_RECV_MEM_SIZE);
|
||
if(!trans_data.base_recv_buffer)
|
||
{
|
||
printf("sunxi usb efex err: unable to malloc memory for efex receive\n");
|
||
free(cmd_buf);
|
||
|
||
return -1;
|
||
}
|
||
|
||
trans_data.base_send_buffer = (u8 *)malloc(SUNXI_EFEX_RECV_MEM_SIZE);
|
||
if(!trans_data.base_send_buffer)
|
||
{
|
||
printf("sunxi usb efex err: unable to malloc memory for efex send\n");
|
||
free(trans_data.base_recv_buffer);
|
||
free(cmd_buf);
|
||
|
||
return -1;
|
||
}
|
||
sunxi_usb_dbg("recv addr 0x%x\n", (uint)trans_data.base_recv_buffer);
|
||
sunxi_usb_dbg("send addr 0x%x\n", (uint)trans_data.base_send_buffer);
|
||
|
||
#ifdef _EFEX_USE_BUF_QUEUE_
|
||
if(efex_queue_init())
|
||
{
|
||
return -1;
|
||
}
|
||
#endif
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int sunxi_efex_exit(void)
|
||
{
|
||
sunxi_usb_dbg("sunxi_efex_exit\n");
|
||
if(trans_data.base_recv_buffer)
|
||
{
|
||
free(trans_data.base_recv_buffer);
|
||
}
|
||
if(trans_data.base_send_buffer)
|
||
{
|
||
free(trans_data.base_send_buffer);
|
||
}
|
||
if(cmd_buf)
|
||
{
|
||
free(cmd_buf);
|
||
}
|
||
#ifdef _EFEX_USE_BUF_QUEUE_
|
||
efex_queue_exit();
|
||
#endif
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static void sunxi_efex_reset(void)
|
||
{
|
||
sunxi_usb_efex_write_enable = 0;
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_IDLE;
|
||
trans_data.to_be_recved_size = 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static void sunxi_efex_usb_rx_dma_isr(void *p_arg)
|
||
{
|
||
sunxi_usb_dbg("dma int for usb rx occur\n");
|
||
//֪ͨ<CDA8><D6AA>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
sunxi_usb_efex_write_enable = 1;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static void sunxi_efex_usb_tx_dma_isr(void *p_arg)
|
||
{
|
||
sunxi_usb_dbg("dma int for usb tx occur\n");
|
||
|
||
#if defined(SUNXI_USB_30)
|
||
sunxi_usb_efex_status_enable ++;
|
||
#endif
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int sunxi_efex_standard_req_op(uint cmd, struct usb_device_request *req, uchar *buffer)
|
||
{
|
||
int ret = SUNXI_USB_REQ_OP_ERR;
|
||
|
||
switch(cmd)
|
||
{
|
||
case USB_REQ_GET_STATUS:
|
||
{
|
||
ret = __usb_get_status(req, buffer);
|
||
|
||
break;
|
||
}
|
||
//case USB_REQ_CLEAR_FEATURE:
|
||
//case USB_REQ_SET_FEATURE:
|
||
case USB_REQ_SET_ADDRESS:
|
||
{
|
||
ret = __usb_set_address(req);
|
||
|
||
break;
|
||
}
|
||
case USB_REQ_GET_DESCRIPTOR:
|
||
//case USB_REQ_SET_DESCRIPTOR:
|
||
case USB_REQ_GET_CONFIGURATION:
|
||
{
|
||
ret = __usb_get_descriptor(req, buffer);
|
||
|
||
break;
|
||
}
|
||
case USB_REQ_SET_CONFIGURATION:
|
||
{
|
||
ret = __usb_set_configuration(req);
|
||
|
||
break;
|
||
}
|
||
//case USB_REQ_GET_INTERFACE:
|
||
case USB_REQ_SET_INTERFACE:
|
||
{
|
||
ret = __usb_set_interface(req);
|
||
|
||
break;
|
||
}
|
||
//case USB_REQ_SYNCH_FRAME:
|
||
default:
|
||
{
|
||
printf("sunxi efex error: standard req is not supported\n");
|
||
|
||
ret = SUNXI_USB_REQ_DEVICE_NOT_SUPPORTED;
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int sunxi_efex_nonstandard_req_op(uint cmd, struct usb_device_request *req, uchar *buffer, uint data_status)
|
||
{
|
||
int ret = SUNXI_USB_REQ_SUCCESSED;
|
||
|
||
switch(req->bmRequestType)
|
||
{
|
||
case 161:
|
||
if(req->bRequest == 0xFE)
|
||
{
|
||
sunxi_usb_dbg("efex ask for max lun\n");
|
||
|
||
buffer[0] = 0;
|
||
|
||
sunxi_udc_send_setup(1, buffer);
|
||
}
|
||
else
|
||
{
|
||
printf("sunxi usb err: unknown ep0 req in efex\n");
|
||
|
||
ret = SUNXI_USB_REQ_DEVICE_NOT_SUPPORTED;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
printf("sunxi usb err: unknown non standard ep0 req\n");
|
||
|
||
ret = SUNXI_USB_REQ_DEVICE_NOT_SUPPORTED;
|
||
|
||
break;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static void __sunxi_usb_efex_fill_status(void)
|
||
{
|
||
Status_t *efex_status;
|
||
|
||
efex_status = (Status_t *)trans_data.base_send_buffer;
|
||
memset(efex_status, 0, sizeof(Status_t));
|
||
efex_status->mark = 0xffff;
|
||
efex_status->tag = 0;
|
||
efex_status->state = 0;
|
||
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = sizeof(Status_t);
|
||
|
||
return;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int __sunxi_usb_efex_op_cmd(u8 *cmd_buffer)
|
||
{
|
||
struct global_cmd_s *cmd = (struct global_cmd_s *)cmd_buffer;
|
||
|
||
switch(cmd->app_cmd)
|
||
{
|
||
case APP_LAYER_COMMEN_CMD_VERIFY_DEV:
|
||
sunxi_usb_dbg("APP_LAYER_COMMEN_CMD_VERIFY_DEV\n");
|
||
{
|
||
struct verify_dev_data_s *app_verify_dev;
|
||
|
||
app_verify_dev = (struct verify_dev_data_s *)trans_data.base_send_buffer;
|
||
|
||
memcpy(app_verify_dev->tag, AL_VERIFY_DEV_TAG_DATA, sizeof(AL_VERIFY_DEV_TAG_DATA));
|
||
app_verify_dev->platform_id_hw = FES_PLATFORM_HW_ID;
|
||
app_verify_dev->platform_id_fw = 0x0001;
|
||
app_verify_dev->mode = AL_VERIFY_DEV_MODE_SRV;//<2F>̶<EFBFBD><CCB6>ģ<EFBFBD>
|
||
app_verify_dev->pho_data_flag = 'D';
|
||
app_verify_dev->pho_data_len = PHOENIX_PRIV_DATA_LEN_NR;
|
||
app_verify_dev->pho_data_start_addr = PHOENIX_PRIV_DATA_ADDR;
|
||
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = sizeof(struct verify_dev_data_s);
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
}
|
||
|
||
break;
|
||
|
||
case APP_LAYER_COMMEN_CMD_SWITCH_ROLE:
|
||
sunxi_usb_dbg("APP_LAYER_COMMEN_CMD_SWITCH_ROLE\n");
|
||
sunxi_usb_dbg("not supported\n");
|
||
|
||
trans_data.last_err = -1;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
|
||
break;
|
||
|
||
case APP_LAYER_COMMEN_CMD_IS_READY:
|
||
sunxi_usb_dbg("APP_LAYER_COMMEN_CMD_IS_READY\n");
|
||
|
||
{
|
||
struct is_ready_data_s *app_is_ready_data;
|
||
|
||
app_is_ready_data = (struct is_ready_data_s *)trans_data.base_send_buffer;
|
||
|
||
app_is_ready_data->interval_ms = 500;
|
||
app_is_ready_data->state = AL_IS_READY_STATE_READY;
|
||
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = sizeof(struct is_ready_data_s);
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
}
|
||
|
||
break;
|
||
|
||
case APP_LAYER_COMMEN_CMD_GET_CMD_SET_VER:
|
||
sunxi_usb_dbg("APP_LAYER_COMMEN_CMD_GET_CMD_SET_VER\n");
|
||
|
||
{
|
||
struct get_cmd_set_ver_data_s *app_get_cmd_ver_data;
|
||
|
||
app_get_cmd_ver_data = (struct get_cmd_set_ver_data_s *)trans_data.base_send_buffer;
|
||
|
||
app_get_cmd_ver_data->ver_high = 1;
|
||
app_get_cmd_ver_data->ver_low = 0;
|
||
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = sizeof(struct get_cmd_set_ver_data_s);
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
}
|
||
|
||
break;
|
||
|
||
case APP_LAYER_COMMEN_CMD_DISCONNECT:
|
||
sunxi_usb_dbg("APP_LAYER_COMMEN_CMD_DISCONNECT\n");
|
||
sunxi_usb_dbg("not supported\n");
|
||
|
||
trans_data.last_err = -1;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_trans:
|
||
sunxi_usb_dbg("FEX_CMD_fes_trans\n");
|
||
|
||
//<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
fes_trans_old_t *fes_old_data = (fes_trans_old_t *)cmd_buf;
|
||
|
||
if(fes_old_data->len)
|
||
{
|
||
if(fes_old_data->u2.DOU == 2) //<2F>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
#ifdef SUNXI_USB_DEBUG
|
||
uint value;
|
||
|
||
value = *(uint *)fes_old_data->addr;
|
||
#endif
|
||
sunxi_usb_dbg("send id 0x%x, addr 0x%x, length 0x%x\n", value, fes_old_data->addr, fes_old_data->len);
|
||
trans_data.act_send_buffer = fes_old_data->addr; //<2F><><EFBFBD>÷<EFBFBD><C3B7>͵<EFBFBD>ַ
|
||
trans_data.send_size = fes_old_data->len; //<2F><><EFBFBD>÷<EFBFBD><C3B7>ͳ<EFBFBD><CDB3><EFBFBD>
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
}
|
||
else //(fes_old_data->u2.DOU == (0 or 1)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
#ifdef SUNXI_USB_DEBUG
|
||
uint value;
|
||
|
||
value = *(uint *)fes_old_data->addr;
|
||
#endif
|
||
sunxi_usb_dbg("receive id 0x%x, addr 0x%x, length 0x%x\n", value, fes_old_data->addr, fes_old_data->len);
|
||
|
||
trans_data.type = SUNXI_EFEX_DRAM_TAG; //д<><D0B4>dram<61><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
trans_data.act_recv_buffer = fes_old_data->addr; //<2F><><EFBFBD>ý<EFBFBD><C3BD>յ<EFBFBD>ַ
|
||
trans_data.recv_size = fes_old_data->len; //<2F><><EFBFBD>ý<EFBFBD><C3BD>ճ<EFBFBD><D5B3><EFBFBD>
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_RECEIVE_DATA;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("FEX_CMD_fes_trans: no data need to send or receive\n");
|
||
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
}
|
||
}
|
||
trans_data.last_err = 0;
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_run:
|
||
sunxi_usb_dbg("FEX_CMD_fes_run\n");
|
||
{
|
||
#ifdef CONFIG_CMD_ELF
|
||
fes_run_t *runs = (fes_run_t *)cmd_buf;
|
||
int *app_ret;
|
||
char run_addr[32] = {0};
|
||
char paras[8][16];
|
||
char *const usb_runs_args[12] = {NULL, run_addr, \
|
||
(char *)¶s[0][0], \
|
||
(char *)¶s[1][0], \
|
||
(char *)¶s[2][0], \
|
||
(char *)¶s[3][0], \
|
||
(char *)¶s[4][0], \
|
||
(char *)¶s[5][0], \
|
||
(char *)¶s[6][0], \
|
||
(char *)¶s[7][0]};
|
||
|
||
sprintf(run_addr, "%x", runs->addr);
|
||
printf("usb run addr = %s\n", run_addr);
|
||
printf("usb run paras max = %d\n", runs->max_para);
|
||
{
|
||
int i;
|
||
int *data;
|
||
|
||
data = runs->para_addr;
|
||
for(i=0;i<runs->max_para;i++)
|
||
{
|
||
printf("usb run paras[%d] = 0x%x\n", i, data[i]);
|
||
sprintf((char *)¶s[i][0], "%x", data[i]);
|
||
}
|
||
}
|
||
|
||
app_ret = (int *)trans_data.base_send_buffer;
|
||
*app_ret = do_bootelf(NULL, 0, runs->max_para + 1, usb_runs_args);
|
||
printf("usb get result = %d\n", *app_ret);
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = 4;
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
#else
|
||
int *app_ret;
|
||
|
||
app_ret = (int *)trans_data.base_send_buffer;
|
||
*app_ret = -1;
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = 4;
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
#endif
|
||
}
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_down:
|
||
sunxi_usb_dbg("FEX_CMD_fes_down\n");
|
||
{
|
||
fes_trans_t *trans = (fes_trans_t *)cmd_buf;
|
||
|
||
trans_data.type = trans->type; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>MBR,BOOT1,BOOT0...<2E>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if((trans->type & SUNXI_EFEX_DRAM_MASK) == SUNXI_EFEX_DRAM_MASK) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
if((SUNXI_EFEX_DRAM_MASK | SUNXI_EFEX_TRANS_FINISH_TAG) == trans->type)
|
||
{
|
||
trans_data.act_recv_buffer = (uint)trans_data.base_recv_buffer;
|
||
trans_data.dram_trans_buffer = trans->addr;
|
||
//printf("dram write: start 0x%x: length 0x%x\n", trans->addr, trans->len);
|
||
}
|
||
else
|
||
{
|
||
trans_data.act_recv_buffer = (uint)trans_data.base_recv_buffer + trans_data.to_be_recved_size; //<2F><><EFBFBD>ý<EFBFBD><C3BD>յ<EFBFBD>ַ
|
||
}
|
||
trans_data.recv_size = trans->len; //<2F><><EFBFBD>ý<EFBFBD><C3BD>ճ<EFBFBD><D5B3>ȣ<EFBFBD><C8A3>ֽڵ<D6BD>λ
|
||
trans_data.to_be_recved_size += trans->len;
|
||
sunxi_usb_dbg("down dram: start 0x%x, sectors 0x%x\n", trans_data.flash_start, trans_data.flash_sectors);
|
||
}
|
||
else //<2F><><EFBFBD><EFBFBD>flash<73><68><EFBFBD>ݣ<EFBFBD><DDA3>ֱ<EFBFBD><D6B1><EFBFBD>ʾ<EFBFBD><CABE>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
trans_data.act_recv_buffer = (uint)(trans_data.base_recv_buffer + SUNXI_EFEX_RECV_MEM_SIZE/2); //<2F><><EFBFBD>ý<EFBFBD><C3BD>յ<EFBFBD>ַ
|
||
trans_data.recv_size = trans->len; //<2F><><EFBFBD>ý<EFBFBD><C3BD>ճ<EFBFBD><D5B3>ȣ<EFBFBD><C8A3>ֽڵ<D6BD>λ
|
||
|
||
trans_data.flash_start = trans->addr;
|
||
trans_data.flash_sectors = (trans->len + 511) >> 9;
|
||
sunxi_usb_dbg("down flash: start 0x%x, sectors 0x%x\n", trans_data.flash_start, trans_data.flash_sectors);
|
||
}
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_RECEIVE_DATA;
|
||
}
|
||
|
||
break;
|
||
case FEX_CMD_fes_up:
|
||
sunxi_usb_dbg("FEX_CMD_fes_up\n");
|
||
|
||
{
|
||
fes_trans_t *trans = (fes_trans_t *)cmd_buf;
|
||
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
trans_data.type = trans->type; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>MBR,BOOT1,BOOT0...<2E>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if((trans->type & SUNXI_EFEX_DRAM_MASK) == SUNXI_EFEX_DRAM_MASK) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
#if 0
|
||
if((SUNXI_EFEX_DRAM_MASK | SUNXI_EFEX_TRANS_FINISH_TAG) == trans->type)
|
||
{
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.dram_trans_buffer = trans->addr;
|
||
printf("dram write: start 0x%x: length 0x%x\n", trans->addr, trans->len);
|
||
}
|
||
else
|
||
{
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer + trans_data.send_size; //<2F><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַ
|
||
}
|
||
#endif
|
||
|
||
trans_data.act_send_buffer = trans->addr; //<2F><><EFBFBD>÷<EFBFBD><C3B7>͵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڵ<D6BD>λ
|
||
trans_data.send_size = trans->len; //<2F><><EFBFBD>ý<EFBFBD><C3BD>ճ<EFBFBD><D5B3>ȣ<EFBFBD><C8A3>ֽڵ<D6BD>λ
|
||
sunxi_usb_dbg("dram read: start 0x%x: length 0x%x\n", trans->addr, trans->len);
|
||
}
|
||
else //<2F><><EFBFBD><EFBFBD>flash<73><68><EFBFBD>ݣ<EFBFBD><DDA3>ֱ<EFBFBD><D6B1><EFBFBD>ʾ<EFBFBD><CABE>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer; //<2F><><EFBFBD>÷<EFBFBD><C3B7>͵<EFBFBD>ַ
|
||
trans_data.send_size = trans->len; //<2F><><EFBFBD>ý<EFBFBD><C3BD>ճ<EFBFBD><D5B3>ȣ<EFBFBD><C8A3>ֽڵ<D6BD>λ
|
||
|
||
trans_data.flash_start = trans->addr; //<2F><><EFBFBD>÷<EFBFBD><C3B7>͵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
|
||
trans_data.flash_sectors = (trans->len + 511) >> 9;
|
||
|
||
sunxi_usb_dbg("upload flash: start 0x%x, sectors 0x%x\n", trans_data.flash_start, trans_data.flash_sectors);
|
||
if(!sunxi_sprite_read(trans_data.flash_start, trans_data.flash_sectors, (void *)trans_data.act_send_buffer))
|
||
{
|
||
printf("flash read err: start 0x%x, sectors 0x%x\n", trans_data.flash_start, trans_data.flash_sectors);
|
||
|
||
trans_data.last_err = -1;
|
||
}
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
// case FEX_CMD_fes_verify:
|
||
// printf("FEX_CMD_fes_verify\n");
|
||
// {
|
||
// fes_cmd_verify_t *cmd_verify = (fes_cmd_verify_t *)cmd_buf;
|
||
// fes_efex_verify_t *verify_data= (fes_efex_verify_t *)trans_data.base_send_buffer;
|
||
//
|
||
// printf("FEX_CMD_fes_verify cmd tag = 0x%x\n", cmd_verify->tag);
|
||
// if(cmd_verify->tag == 0) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>flash<73><68>У<EFBFBD><D0A3>
|
||
// {
|
||
// verify_data->media_crc = sunxi_sprite_part_rawdata_verify(cmd_verify->start, cmd_verify->size);
|
||
// }
|
||
// else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD>ݵ<EFBFBD>У<EFBFBD><D0A3>
|
||
// {
|
||
// verify_data->media_crc = trans_data.last_err;
|
||
// }
|
||
// verify_data->flag = EFEX_CRC32_VALID_FLAG;
|
||
// printf("FEX_CMD_fes_verify last err=%d\n", verify_data->media_crc);
|
||
//
|
||
// trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
// trans_data.send_size = sizeof(fes_efex_verify_t);
|
||
// trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
//// //Ŀǰֻ֧<D6BB><D6A7>У<EFBFBD><D0A3><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>߲鿴״̬<D7B4>ķ<EFBFBD>ʽ
|
||
//// if(data_type == SUNXI_EFEX_MBR_TAG) //<2F><><EFBFBD><EFBFBD>MBR<42>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
|
||
//// {
|
||
//// verify_data->flag = EFEX_CRC32_VALID_FLAG;
|
||
//// }
|
||
//// else if(data_type == SUNXI_EFEX_BOOT1_TAG) //<2F><><EFBFBD><EFBFBD>BOOT1<54>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
|
||
//// {
|
||
//// verify_data->flag = EFEX_CRC32_VALID_FLAG;
|
||
//// }
|
||
//// else if(data_type == SUNXI_EFEX_BOOT0_TAG) //<2F><><EFBFBD><EFBFBD>BOOT0<54>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
|
||
//// {
|
||
//// verify_data->flag = EFEX_CRC32_VALID_FLAG;
|
||
//// }
|
||
//// else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>ֱ<EFBFBD><D6B1>д<EFBFBD><D0B4><EFBFBD>ڴ<EFBFBD>
|
||
//// {
|
||
//// memcpy((void *)trans_data.start, sunxi_ubuf->rx_data_buffer, trans_data.size);
|
||
//// }
|
||
// }
|
||
// break;
|
||
|
||
case FEX_CMD_fes_verify_value:
|
||
sunxi_usb_dbg("FEX_CMD_fes_verify_value\n");
|
||
{
|
||
fes_cmd_verify_value_t *cmd_verify = (fes_cmd_verify_value_t *)cmd_buf;
|
||
fes_efex_verify_t *verify_data= (fes_efex_verify_t *)trans_data.base_send_buffer;
|
||
|
||
verify_data->media_crc = sunxi_sprite_part_rawdata_verify(cmd_verify->start, cmd_verify->size);
|
||
verify_data->flag = EFEX_CRC32_VALID_FLAG;
|
||
|
||
printf("FEX_CMD_fes_verify_value, start 0x%x, size high 0x%x:low 0x%x\n", cmd_verify->start, (uint)(cmd_verify->size>>32), (uint)(cmd_verify->size));
|
||
printf("FEX_CMD_fes_verify_value 0x%x\n", verify_data->media_crc);
|
||
}
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = sizeof(fes_efex_verify_t);
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
|
||
break;
|
||
case FEX_CMD_fes_verify_status:
|
||
printf("FEX_CMD_fes_verify_status\n");
|
||
{
|
||
// fes_cmd_verify_status_t *cmd_verify = (fes_cmd_verify_status_t *)cmd_buf;
|
||
fes_efex_verify_t *verify_data= (fes_efex_verify_t *)trans_data.base_send_buffer;
|
||
|
||
verify_data->flag = EFEX_CRC32_VALID_FLAG;
|
||
verify_data->media_crc = trans_data.last_err;
|
||
|
||
printf("FEX_CMD_fes_verify last err=%d\n", verify_data->media_crc);
|
||
}
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = sizeof(fes_efex_verify_t);
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
|
||
break;
|
||
case FEX_CMD_fes_query_storage:
|
||
sunxi_usb_dbg("FEX_CMD_fes_query_storage\n");
|
||
|
||
{
|
||
uint *storage_type = (uint *)trans_data.base_send_buffer;
|
||
|
||
*storage_type = uboot_spare_head.boot_data.storage_type;
|
||
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = 4;
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
}
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_flash_set_on:
|
||
sunxi_usb_dbg("FEX_CMD_fes_flash_set_on\n");
|
||
|
||
trans_data.last_err = sunxi_sprite_init(0);
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_flash_set_off:
|
||
sunxi_usb_dbg("FEX_CMD_fes_flash_set_off\n");
|
||
|
||
trans_data.last_err = sunxi_sprite_exit(1);
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_flash_size_probe:
|
||
sunxi_usb_dbg("FEX_CMD_fes_flash_size_probe\n");
|
||
|
||
{
|
||
uint *flash_size = (uint *)trans_data.base_send_buffer;
|
||
|
||
*flash_size = sunxi_sprite_size();
|
||
printf("flash sectors: 0x%x\n", *flash_size);
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = 4;
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
}
|
||
break;
|
||
|
||
case FEX_CMD_fes_tool_mode:
|
||
sunxi_usb_dbg("FEX_CMD_fes_tool_mode\n");
|
||
|
||
{
|
||
fes_efex_tool_t *fes_work = (fes_efex_tool_t *)cmd_buf;
|
||
|
||
if(fes_work->tool_mode== WORK_MODE_USB_TOOL_UPDATE)
|
||
{ //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if(fes_work->next_mode == 0)
|
||
{
|
||
sunxi_efex_next_action = SUNXI_UPDATE_NEXT_ACTION_REBOOT;
|
||
}
|
||
else
|
||
{
|
||
sunxi_efex_next_action = fes_work->next_mode;
|
||
}
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_EXIT;
|
||
}
|
||
else if(fes_work->tool_mode == WORK_MODE_ERASE_KEY)
|
||
{
|
||
sunxi_efex_next_action = SUNXI_UPDATE_NEXT_ACTION_SHUTDOWN;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_EXIT;
|
||
}
|
||
else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
|
||
{
|
||
if(!fes_work->next_mode)
|
||
{
|
||
if(script_parser_fetch("platform", "next_work", (int *)&sunxi_efex_next_action, 1))
|
||
{ //<2F><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><F2B2BBB4><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD>
|
||
sunxi_efex_next_action = SUNXI_UPDATE_NEXT_ACTION_NORMAL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
sunxi_efex_next_action = SUNXI_UPDATE_NEXT_ACTION_REBOOT;
|
||
}
|
||
if((sunxi_efex_next_action <= SUNXI_UPDATE_NEXT_ACTION_NORMAL) || (sunxi_efex_next_action > SUNXI_UPDATE_NEXT_ACTION_REUPDATE))
|
||
{
|
||
sunxi_efex_next_action = SUNXI_UPDATE_NEXT_ACTION_NORMAL;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
}
|
||
else
|
||
{
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_EXIT;
|
||
}
|
||
}
|
||
}
|
||
printf("sunxi_efex_next_action=%d\n", sunxi_efex_next_action);
|
||
trans_data.last_err = 0;
|
||
//before product finish, clear suspend flag
|
||
efex_suspend_flag = 0;
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_memset:
|
||
sunxi_usb_dbg("FEX_CMD_fes_memset\n");
|
||
{
|
||
fes_efex_memset_t *fes_memset = (fes_efex_memset_t *)cmd_buf;
|
||
|
||
sunxi_usb_dbg("start 0x%x, value 0x%x, length 0x%x\n", fes_memset->start_addr, fes_memset->value & 0xff, fes_memset->length);
|
||
memset((void *)fes_memset->start_addr, fes_memset->value & 0xff, fes_memset->length);
|
||
}
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_pmu:
|
||
sunxi_usb_dbg("FEX_CMD_fes_pmu\n");
|
||
{
|
||
fes_efex_pmu_t *fes_pmu = (fes_efex_pmu_t *)cmd_buf;
|
||
|
||
trans_data.recv_size = fes_pmu->size;
|
||
trans_data.type = fes_pmu->type;
|
||
|
||
memset(&pmu_config, 0, sizeof(struct pmu_config_t));
|
||
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_RECEIVE_DATA;
|
||
}
|
||
|
||
break;
|
||
|
||
case FEX_CMD_fes_unseqmem_read:
|
||
sunxi_usb_dbg("FEX_CMD_fes_unseqmem_read\n");
|
||
{
|
||
tag_efex_unseq_mem_t *fes_unseq = (tag_efex_unseq_mem_t *)cmd_buf;
|
||
|
||
trans_data.recv_size = fes_unseq->size;
|
||
trans_data.type = fes_unseq->type;
|
||
|
||
if(global_unseq_mem_addr.unseq_mem == NULL)
|
||
{
|
||
printf("there is no memory to load unsequence data\n");
|
||
trans_data.last_err = -1;
|
||
trans_data.act_send_buffer = CONFIG_SYS_SDRAM_BASE;
|
||
}
|
||
else
|
||
{
|
||
int i;
|
||
struct unseq_mem_config *unseq_mem = global_unseq_mem_addr.unseq_mem;
|
||
|
||
for(i=0;i<global_unseq_mem_addr.count;i++)
|
||
{
|
||
unseq_mem[i].value = readl(unseq_mem[i].addr);
|
||
sunxi_usb_dbg("read 0x%x, value 0x%x\n", unseq_mem[i].addr, unseq_mem[i].value);
|
||
}
|
||
trans_data.last_err = 0;
|
||
trans_data.act_send_buffer = (u32)global_unseq_mem_addr.unseq_mem;
|
||
|
||
}
|
||
trans_data.send_size = global_unseq_mem_addr.count * sizeof(struct unseq_mem_config);
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
}
|
||
|
||
break;
|
||
case FEX_CMD_fes_unseqmem_write:
|
||
sunxi_usb_dbg("FEX_CMD_fes_unseqmem_write\n");
|
||
{
|
||
tag_efex_unseq_mem_t *fes_unseq = (tag_efex_unseq_mem_t *)cmd_buf;
|
||
|
||
trans_data.recv_size = fes_unseq->size;
|
||
trans_data.type = fes_unseq->type;
|
||
|
||
if(global_unseq_mem_addr.unseq_mem != NULL)
|
||
{
|
||
free(global_unseq_mem_addr.unseq_mem);
|
||
}
|
||
global_unseq_mem_addr.unseq_mem = (struct unseq_mem_config *)malloc(fes_unseq->count * sizeof(struct unseq_mem_config));
|
||
memset(global_unseq_mem_addr.unseq_mem, 0, fes_unseq->count * sizeof(struct unseq_mem_config));
|
||
global_unseq_mem_addr.count = fes_unseq->count;
|
||
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_RECEIVE_DATA;
|
||
}
|
||
break;
|
||
|
||
case FEX_CMD_fes_force_erase:
|
||
printf("FEX_CMD_fes_force_erase\n");
|
||
{
|
||
trans_data.last_err = sunxi_sprite_force_erase();
|
||
printf("FEX_CMD_fes_force_erase last err=%d\n", trans_data.last_err);
|
||
}
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
|
||
break;
|
||
case FEX_CMD_fes_force_erase_key:
|
||
printf("FEX_CMD_fes_force_erase_key \n");
|
||
{
|
||
trans_data.last_err = sunxi_sprite_force_erase_key();
|
||
printf("FEX_CMD_fes_force_erase_key last err = %d \n",trans_data.last_err);
|
||
}
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS ;
|
||
break;
|
||
|
||
case FEX_CMD_fes_query_secure:
|
||
{
|
||
uint *secure_type = (uint *)trans_data.base_send_buffer;
|
||
|
||
*secure_type = gd->bootfile_mode;
|
||
|
||
printf("securemode=%d\n", gd->bootfile_mode);
|
||
trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
|
||
trans_data.send_size = 4;
|
||
trans_data.last_err = 0;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_SEND_DATA;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
printf("not supported command 0x%x now\n", cmd->app_cmd);
|
||
|
||
trans_data.last_err = -1;
|
||
trans_data.app_next_status = SUNXI_USB_EFEX_APPS_STATUS;
|
||
|
||
break;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static void dram_data_recv_finish(uint data_type)
|
||
{
|
||
if(data_type == SUNXI_EFEX_MBR_TAG) //<2F><><EFBFBD><EFBFBD>MBR<42>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
//<2F><><EFBFBD><EFBFBD>MBR<42><52><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>
|
||
if(uboot_spare_head.boot_data.storage_type != 3 )
|
||
{
|
||
trans_data.last_err = sunxi_sprite_verify_mbr((void *)trans_data.base_recv_buffer);
|
||
if(!trans_data.last_err )
|
||
{
|
||
nand_get_mbr((char *)trans_data.base_recv_buffer, 16 * 1024);
|
||
//<><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if(!sunxi_sprite_erase_flash((void *)trans_data.base_recv_buffer))
|
||
{ //<2F><>¼mbr
|
||
printf("SUNXI_EFEX_MBR_TAG\n");
|
||
printf("mbr size = 0x%x\n", trans_data.to_be_recved_size);
|
||
trans_data.last_err = sunxi_sprite_download_mbr((void *)trans_data.base_recv_buffer, trans_data.to_be_recved_size);
|
||
}
|
||
else
|
||
{
|
||
trans_data.last_err = -1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
trans_data.last_err = 0;
|
||
}
|
||
else if(data_type == SUNXI_EFEX_BOOT1_TAG) //<2F><><EFBFBD><EFBFBD>BOOT1<54>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
printf("SUNXI_EFEX_BOOT1_TAG\n");
|
||
printf("boot1 size = 0x%x\n", trans_data.to_be_recved_size);
|
||
trans_data.last_err = sunxi_sprite_download_uboot((void *)trans_data.base_recv_buffer, uboot_spare_head.boot_data.storage_type, 0);
|
||
}
|
||
else if(data_type == SUNXI_EFEX_BOOT0_TAG) //<2F><><EFBFBD><EFBFBD>BOOT0<54>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
printf("SUNXI_EFEX_BOOT0_TAG\n");
|
||
printf("boot0 size = 0x%x\n", trans_data.to_be_recved_size);
|
||
trans_data.last_err = sunxi_sprite_download_boot0((void *)trans_data.base_recv_buffer, uboot_spare_head.boot_data.storage_type);
|
||
}
|
||
else if(data_type == SUNXI_EFEX_ERASE_TAG)
|
||
{
|
||
uint erase_flag;
|
||
int sys_config_erase_flag;
|
||
printf("SUNXI_EFEX_ERASE_TAG\n");
|
||
erase_flag = *(uint *)trans_data.base_recv_buffer;
|
||
if(erase_flag)
|
||
{
|
||
erase_flag = 1;
|
||
}
|
||
printf("erase_flag = 0x%x\n", erase_flag);
|
||
script_parser_fetch("platform", "eraseflag", &sys_config_erase_flag , 1);
|
||
if(sys_config_erase_flag == 0 || sys_config_erase_flag == 1)
|
||
script_parser_patch("platform", "eraseflag", &erase_flag , 1);
|
||
}
|
||
else if(data_type == SUNXI_EFEX_PMU_SET)
|
||
{
|
||
memcpy(&pmu_config, (void *)trans_data.act_recv_buffer, trans_data.recv_size);
|
||
|
||
trans_data.last_err = axp_set_supply_status_byname(pmu_config.pmu_type, pmu_config.vol_name, pmu_config.voltage, pmu_config.gate);
|
||
}
|
||
else if(data_type == SUNXI_EFEX_UNSEQ_MEM_FOR_WRITE)
|
||
{
|
||
int i;
|
||
struct unseq_mem_config *unseq_mem = global_unseq_mem_addr.unseq_mem;
|
||
|
||
printf("begin to load data to unsequency memory\n");
|
||
memcpy(unseq_mem, (void *)trans_data.act_recv_buffer, trans_data.recv_size);
|
||
for(i=0;i<global_unseq_mem_addr.count;i++)
|
||
{
|
||
sunxi_usb_dbg("write 0x%x, value 0x%x\n", unseq_mem[i].addr, unseq_mem[i].value);
|
||
writel(unseq_mem[i].value, unseq_mem[i].addr);
|
||
}
|
||
}
|
||
else if(data_type == SUNXI_EFEX_UNSEQ_MEM_FOR_READ)
|
||
{
|
||
struct unseq_mem_config *unseq_mem = global_unseq_mem_addr.unseq_mem;
|
||
|
||
printf("begin to set address to unsequency memory\n");
|
||
memcpy(unseq_mem, (void *)trans_data.act_recv_buffer, trans_data.recv_size);
|
||
}
|
||
#ifdef CONFIG_SUNXI_SPINOR
|
||
else if(data_type == SUNXI_EFEX_FULLIMG_SIZE_TAG)
|
||
{
|
||
fullimg_size = *(uint *)trans_data.base_recv_buffer;
|
||
if(fullimg_size % 512 != 0)
|
||
fullimg_size = (fullimg_size + 512)&(~0x1ff) ;
|
||
printf("algin 512 byte fullimg_size %d \n",fullimg_size); //add by young
|
||
if(!fullimg_size)
|
||
trans_data.last_err = -1;
|
||
else {
|
||
int need_erase_flag = 0;
|
||
script_parser_fetch("platform", "eraseflag", &need_erase_flag, 1);
|
||
if(need_erase_flag != 0x11)
|
||
/* not force erase, need to store private data */
|
||
sunxi_sprite_store_private_data();
|
||
#ifndef CONFIG_SMALL_MEMSIZE
|
||
/*
|
||
* for fix spinor_datafinish. if not define CONFIG_SMALL_MEMSIZE,
|
||
* spinor_datafinish will use __spinor_sector_write to write spinor
|
||
* and we need to erase flash before call __spinor_sector_write.
|
||
* if erase flash in spinor_datafinish, we may erase the flash twice.
|
||
* so we erase here.
|
||
* TODO:use spinor_write in spinor_datafinish, then remove this code
|
||
*/
|
||
need_erase_flag = 1;
|
||
#endif
|
||
if(need_erase_flag)
|
||
spinor_erase_all_blocks(1);
|
||
|
||
trans_data.last_err = 0;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
else//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>ֱ<EFBFBD><D6B1>д<EFBFBD><D0B4><EFBFBD>ڴ<EFBFBD>
|
||
{
|
||
memcpy((void *)trans_data.dram_trans_buffer, (void *)trans_data.act_recv_buffer, trans_data.recv_size);
|
||
|
||
sunxi_usb_dbg("SUNXI_EFEX_DRAM_TAG\n");
|
||
|
||
trans_data.last_err = 0;
|
||
}
|
||
trans_data.to_be_recved_size = 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int sunxi_efex_state_loop(void *buffer)
|
||
{
|
||
static struct sunxi_efex_cbw_t *cbw;
|
||
static struct sunxi_efex_csw_t csw;
|
||
sunxi_ubuf_t *sunxi_ubuf = (sunxi_ubuf_t *)buffer;
|
||
int efex_write_error_flag = 0;
|
||
|
||
switch(sunxi_usb_efex_status)
|
||
{
|
||
case SUNXI_USB_EFEX_IDLE:
|
||
if(sunxi_ubuf->rx_ready_for_data == 1)
|
||
{
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_SETUP;
|
||
}
|
||
//when product finish and usb disconnect ,shutdown machine
|
||
if( sunxi_efex_next_action == SUNXI_UPDATE_NEXT_ACTION_NORMAL ||
|
||
sunxi_efex_next_action > SUNXI_UPDATE_NEXT_ACTION_REUPDATE )
|
||
{
|
||
if(efex_suspend_flag)
|
||
{
|
||
return SUNXI_UPDATE_NEXT_ACTION_SHUTDOWN;
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
case SUNXI_USB_EFEX_SETUP: //cbw
|
||
|
||
sunxi_usb_dbg("SUNXI_USB_EFEX_SETUP\n");
|
||
|
||
if((sunxi_ubuf->rx_req_length == sizeof(struct sunxi_efex_cbw_t)))
|
||
{
|
||
cbw = (struct sunxi_efex_cbw_t *)sunxi_ubuf->rx_req_buffer;
|
||
if(CBW_MAGIC != cbw->magic)
|
||
{
|
||
printf("sunxi usb error: the cbw signature 0x%x is bad, need 0x%x\n", cbw->magic, CBW_MAGIC);
|
||
sunxi_ubuf->rx_ready_for_data = 0;
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
return -1;
|
||
}
|
||
}
|
||
else if(sunxi_ubuf->rx_req_length == FES_NEW_CMD_LEN)
|
||
{
|
||
sunxi_usb_dbg("----------new cmd format--------\n");
|
||
if(CBW_MAGIC != ((u32*)(sunxi_ubuf->rx_req_buffer))[4])
|
||
{
|
||
printf("sunxi usb error: the cmd signature 0x%x is bad, need 0x%x\n",
|
||
((u32*)(sunxi_ubuf->rx_req_buffer))[4],CBW_MAGIC);
|
||
|
||
|
||
sunxi_ubuf->rx_ready_for_data = 0;
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
//data value err
|
||
return -1;
|
||
}
|
||
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_SETUP_NEW;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
printf("sunxi usb error: received bytes 0x%x is not equal cbw struct size 0x%x or new cmd size 0x%x\n",
|
||
sunxi_ubuf->rx_req_length, sizeof(struct sunxi_efex_cbw_t),FES_NEW_CMD_LEN);
|
||
sunxi_ubuf->rx_ready_for_data = 0;
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
return -1;
|
||
}
|
||
|
||
csw.magic = CSW_MAGIC; //"AWUS"
|
||
csw.tag = cbw->tag;
|
||
|
||
#if defined(SUNXI_USB_30)
|
||
sunxi_usb_efex_status_enable = 1;
|
||
#endif
|
||
|
||
sunxi_usb_dbg("usb cbw trans direction = 0x%x\n", cbw->cmd_package.direction);
|
||
if(sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_IDLE)
|
||
{
|
||
sunxi_usb_dbg("APPS: SUNXI_USB_EFEX_APPS_IDLE\n");
|
||
if(cbw->cmd_package.direction == TL_CMD_RECEIVE) //С<><D0A1><EFBFBD>˽<EFBFBD><CBBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
sunxi_usb_dbg("APPS: SUNXI_USB_EFEX_APPS_IDLE: TL_CMD_RECEIVE\n");
|
||
sunxi_ubuf->request_size = min(cbw->data_transfer_len, CBW_MAX_CMD_SIZE);
|
||
sunxi_usb_dbg("try to receive data 0x%x\n", sunxi_ubuf->request_size);
|
||
sunxi_usb_efex_write_enable = 0;
|
||
if(sunxi_ubuf->request_size)
|
||
{
|
||
sunxi_udc_start_recv_by_dma((uint)cmd_buf, sunxi_ubuf->request_size); //start dma to receive data
|
||
}
|
||
else
|
||
{
|
||
printf("APPS: SUNXI_USB_EFEX_APPS_IDLE: the send data length is 0\n");
|
||
|
||
return -1;
|
||
}
|
||
//<2F><>һ<EFBFBD>ν<D7B6><CEBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>app
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_RECEIVE_DATA; //<2F><><EFBFBD><EFBFBD><EFBFBD>Σ<D7B6><CEA3><EFBFBD>һ<EFBFBD>ν<D7B6><CEBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_CMD; //<2F><><EFBFBD><EFBFBD><EFBFBD>Σ<D7B6><CEA3><EFBFBD>һ<EFBFBD>ν<D7B6><CEBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
else //setup<75>μ<D7B6>usb<73><62>bulk<6C><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>Σ<D7B6>ֻ<EFBFBD>ܽ<EFBFBD><DCBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>
|
||
{
|
||
printf("APPS: SUNXI_USB_EFEX_APPS_IDLE: INVALID direction\n");
|
||
printf("sunxi usb efex app cmd err: usb transfer direction is receive only\n");
|
||
|
||
return -1;
|
||
}
|
||
}
|
||
else if((sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_SEND_DATA) || \
|
||
(sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_RECEIVE_DATA)) //<2F>յ<EFBFBD><D5B5>ĵڶ<C4B5><DAB6>Σ<D7B6><CEA3><EFBFBD>ʱ<EFBFBD><CAB1>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
sunxi_usb_dbg("APPS: SUNXI_USB_EFEX_APPS_DATA\n");
|
||
if(cbw->cmd_package.direction == TL_CMD_RECEIVE) //<2F><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dma<6D><61>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
||
{
|
||
sunxi_usb_dbg("APPS: SUNXI_USB_EFEX_APPS_DATA: TL_CMD_RECEIVE\n");
|
||
sunxi_ubuf->request_size = MIN(cbw->data_transfer_len, trans_data.recv_size); //<2F><><EFBFBD>ճ<EFBFBD><D5B3><EFBFBD>
|
||
//sunxi_usb_dbg("try to receive data 0x%x\n", sunxi_ubuf->request_size);
|
||
sunxi_usb_efex_write_enable = 0; //<2F><><EFBFBD>ñ<EFBFBD>־
|
||
if(sunxi_ubuf->request_size)
|
||
{
|
||
sunxi_usb_dbg("dma recv addr = 0x%x\n", trans_data.act_recv_buffer);
|
||
sunxi_udc_start_recv_by_dma(trans_data.act_recv_buffer, sunxi_ubuf->request_size); //start dma to receive data
|
||
}
|
||
else
|
||
{
|
||
printf("APPS: SUNXI_USB_EFEX_APPS_DATA: the send data length is 0\n");
|
||
|
||
return -1;
|
||
}
|
||
}
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<D7B6><CEB5><EFBFBD>һ<EFBFBD><D2BB>״̬
|
||
sunxi_usb_efex_app_step = trans_data.app_next_status; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEA3AC>ȡ<EFBFBD><C8A1>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
|
||
//sunxi_usb_dbg("APPS: SUNXI_USB_EFEX_APPS_CMD_DECODE finish\n");
|
||
//sunxi_usb_dbg("sunxi_usb_efex_app_step = 0x%x\n", sunxi_usb_efex_app_step);
|
||
sunxi_usb_efex_status = sunxi_usb_efex_app_step & 0xffff; //ʶ<><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7B6><EFBFBD>һ<EFBFBD><EFBFBD>״̬
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>״̬(csw)
|
||
}
|
||
else if(sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_STATUS)
|
||
{
|
||
sunxi_usb_dbg("APPS: SUNXI_USB_EFEX_APPS_STATUS\n");
|
||
if(cbw->cmd_package.direction == TL_CMD_TRANSMIT) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
sunxi_usb_dbg("APPS: SUNXI_USB_EFEX_APPS_STATUS: TL_CMD_TRANSMIT\n");
|
||
__sunxi_usb_efex_fill_status();
|
||
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_SEND_DATA;
|
||
sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_IDLE;
|
||
}
|
||
else //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Σ<D7B6>ֻ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD>ܽ<EFBFBD><DCBD><EFBFBD>
|
||
{
|
||
printf("APPS: SUNXI_USB_EFEX_APPS_STATUS: INVALID direction\n");
|
||
printf("sunxi usb efex app status err: usb transfer direction is transmit only\n");
|
||
}
|
||
}
|
||
else if(sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_EXIT)
|
||
{
|
||
sunxi_usb_dbg("APPS: SUNXI_USB_EFEX_APPS_EXIT\n");
|
||
__sunxi_usb_efex_fill_status();
|
||
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_SEND_DATA;
|
||
}
|
||
|
||
break;
|
||
|
||
case SUNXI_USB_EFEX_SEND_DATA:
|
||
|
||
sunxi_usb_dbg("SUNXI_USB_EFEX_SEND_DATA\n");
|
||
{
|
||
uint tx_length = MIN(cbw->data_transfer_len, trans_data.send_size);
|
||
|
||
#if defined(SUNXI_USB_30)
|
||
sunxi_usb_efex_status_enable = 0;
|
||
#endif
|
||
sunxi_usb_dbg("send data start 0x%x, size 0x%x\n", trans_data.act_send_buffer, tx_length);
|
||
if(tx_length)
|
||
{
|
||
sunxi_udc_send_data((void *)trans_data.act_send_buffer, tx_length);
|
||
}
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_STATUS;
|
||
if(sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_SEND_DATA)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Σ<D7B6>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>һ<EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>״̬(status_t)
|
||
{
|
||
sunxi_usb_dbg("SUNXI_USB_EFEX_SEND_DATA next: SUNXI_USB_EFEX_APPS_STATUS\n");
|
||
sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_STATUS;
|
||
}
|
||
else if(sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_EXIT)
|
||
{
|
||
sunxi_usb_dbg("SUNXI_USB_EFEX_SEND_DATA next: SUNXI_USB_EFEX_APPS_EXIT\n");
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_EXIT;
|
||
//sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_EXIT;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case SUNXI_USB_EFEX_RECEIVE_DATA:
|
||
|
||
sunxi_usb_dbg("SUNXI_USB_RECEIVE_DATA\n");
|
||
if(sunxi_usb_efex_write_enable == 1) //<2F><><EFBFBD>ݲ<EFBFBD><DDB2>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
csw.status = 0;
|
||
//<2F><><EFBFBD>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEBBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if(sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_CMD)
|
||
{
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cmd_buf<75><66><EFBFBD>´δ<C2B4><CEB4><EFBFBD>Ҳ<EFBFBD><D2B2>Ҫ
|
||
sunxi_usb_dbg("SUNXI_USB_RECEIVE_DATA: SUNXI_USB_EFEX_APPS_CMD\n");
|
||
if(sunxi_ubuf->request_size != CBW_MAX_CMD_SIZE) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>
|
||
{
|
||
printf("sunxi usb efex err: received cmd size 0x%x is not equal to CBW_MAX_CMD_SIZE 0x%x\n", sunxi_ubuf->request_size, CBW_MAX_CMD_SIZE);
|
||
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
csw.status = -1;
|
||
}
|
||
else
|
||
{
|
||
__sunxi_usb_efex_op_cmd(cmd_buf);
|
||
csw.status = trans_data.last_err;
|
||
}
|
||
//sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_DATA; //<2F><><EFBFBD><EFBFBD><EFBFBD>Σ<D7B6><CEA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD>һ<EFBFBD>δ<D7B6><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
sunxi_usb_efex_app_step = trans_data.app_next_status;
|
||
}
|
||
else if(sunxi_usb_efex_app_step == SUNXI_USB_EFEX_APPS_RECEIVE_DATA)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Σ<D7B6>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>һ<EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>״̬(status_t)
|
||
{
|
||
//<2F><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
uint data_type = trans_data.type & SUNXI_EFEX_DATA_TYPE_MASK;
|
||
|
||
sunxi_usb_dbg("SUNXI_USB_RECEIVE_DATA: SUNXI_USB_EFEX_APPS_RECEIVE_DATA\n");
|
||
sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_STATUS;
|
||
if(trans_data.type & SUNXI_EFEX_DRAM_MASK) //<2F><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ȱ<EFBFBD><C8B1>浽<EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>
|
||
{
|
||
sunxi_usb_dbg("SUNXI_EFEX_DRAM_MASK\n");
|
||
if(trans_data.type & SUNXI_EFEX_TRANS_FINISH_TAG) //<2F><>ʾ<EFBFBD><CABE>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
dram_data_recv_finish(data_type);
|
||
}
|
||
//<2F><><EFBFBD>ݻ<EFBFBD>û<EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
else //<2F><>ʾ<EFBFBD><CABE>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫд<D2AA><D0B4>flash
|
||
{
|
||
sunxi_usb_dbg("SUNXI_EFEX_FLASH_MASK\n");
|
||
if(!sunxi_sprite_write(trans_data.flash_start, trans_data.flash_sectors, (void *)trans_data.act_recv_buffer))
|
||
{
|
||
printf("sunxi usb efex err: write flash from 0x%x, sectors 0x%x failed\n", trans_data.flash_start, trans_data.flash_sectors);
|
||
csw.status = -1;
|
||
trans_data.last_err = -1;
|
||
|
||
sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_IDLE;
|
||
}
|
||
#ifdef CONFIG_SUNXI_SPINOR
|
||
if((uboot_spare_head.boot_data.storage_type == 3)&&(trans_data.type & SUNXI_EFEX_TRANS_FINISH_TAG)&&(fullimg_size == total_write_bytes))
|
||
{
|
||
//sunxi_usb_dbg("sunxi usb efex trans finish\n");
|
||
printf("before sunxi_sprite_setdata_finish\n");
|
||
|
||
if(sunxi_sprite_setdata_finish())
|
||
{
|
||
printf("burn nor img error \n");
|
||
csw.status = -1;
|
||
trans_data.last_err = -1;
|
||
sunxi_usb_efex_app_step = SUNXI_USB_EFEX_APPS_IDLE;
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_STATUS; //<2F><><EFBFBD><EFBFBD><EFBFBD>Σ<D7B6><CEA3><EFBFBD>һ<EFBFBD>δ<D7B6><CEB4><EFBFBD>״̬(csw)
|
||
}
|
||
|
||
break;
|
||
|
||
case SUNXI_USB_EFEX_SETUP_NEW: //
|
||
{
|
||
sunxi_usb_dbg("SUNXI_USB_EFEX_SETUP_NEW\n");
|
||
|
||
memcpy(cmd_buf,sunxi_ubuf->rx_req_buffer,FES_NEW_CMD_LEN);
|
||
#ifdef _EFEX_USE_BUF_QUEUE_
|
||
//flush queue buff when verify cmd or flash set off cmd coming
|
||
if(FEX_CMD_fes_verify_value == ((struct global_cmd_s *)cmd_buf)->app_cmd
|
||
|| FEX_CMD_fes_flash_set_off== ((struct global_cmd_s *)cmd_buf)->app_cmd )
|
||
{
|
||
if(efex_queue_write_all_page())
|
||
{
|
||
printf("efex queue error: buf_queue_write_all_page fail\n");
|
||
efex_write_error_flag = 1;
|
||
}
|
||
}
|
||
#endif
|
||
__sunxi_usb_efex_op_cmd(cmd_buf);
|
||
csw.status = trans_data.last_err;
|
||
csw.magic = CSW_MAGIC; //"AWUS"
|
||
csw.tag = 0;
|
||
|
||
if(csw.status != 0 )
|
||
{
|
||
printf("sunxi usb cmd error: 0x%x\n",csw.status);
|
||
sunxi_ubuf->rx_ready_for_data = 0;
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
return -1;
|
||
}
|
||
|
||
#if defined(SUNXI_USB_30)
|
||
sunxi_usb_efex_status_enable = 1;
|
||
#endif
|
||
if(trans_data.app_next_status == SUNXI_USB_EFEX_APPS_SEND_DATA)
|
||
{
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_SEND_DATA_NEW;
|
||
}
|
||
else if(trans_data.app_next_status == SUNXI_USB_EFEX_APPS_RECEIVE_DATA)
|
||
{
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_RECEIVE_DATA_NEW;
|
||
|
||
sunxi_ubuf->request_size = trans_data.recv_size; //<2F><><EFBFBD>ճ<EFBFBD><D5B3><EFBFBD>
|
||
sunxi_usb_efex_write_enable = 0; //<2F><><EFBFBD>ñ<EFBFBD>־
|
||
if(sunxi_ubuf->request_size)
|
||
{
|
||
sunxi_usb_dbg("dma recv addr = 0x%x, size =0x%x\n", trans_data.act_recv_buffer,sunxi_ubuf->request_size);
|
||
sunxi_udc_start_recv_by_dma(trans_data.act_recv_buffer, sunxi_ubuf->request_size); //start dma to receive data
|
||
}
|
||
else
|
||
{
|
||
printf("sunxi usb trans error: the request data length is 0\n");
|
||
|
||
return -1;
|
||
}
|
||
|
||
}
|
||
else if(trans_data.app_next_status == SUNXI_USB_EFEX_APPS_STATUS)
|
||
{
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_STATUS;
|
||
}
|
||
else if(trans_data.app_next_status == SUNXI_USB_EFEX_APPS_EXIT)
|
||
{
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_EXIT;
|
||
}
|
||
else
|
||
{
|
||
printf("sunxi usb next status set error:0x%x\n", trans_data.app_next_status);
|
||
sunxi_ubuf->rx_ready_for_data = 0;
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
|
||
return -1;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case SUNXI_USB_EFEX_SEND_DATA_NEW:
|
||
sunxi_usb_dbg("SUNXI_USB_EFEX_SEND_DATA_NEW\n");
|
||
{
|
||
uint tx_length = trans_data.send_size;
|
||
#if defined(SUNXI_USB_30)
|
||
sunxi_usb_efex_status_enable = 0;
|
||
#endif
|
||
sunxi_usb_dbg("dma send data start 0x%x, size 0x%x\n", trans_data.act_send_buffer, tx_length);
|
||
if(tx_length)
|
||
{
|
||
sunxi_udc_send_data((void *)trans_data.act_send_buffer, tx_length);
|
||
}
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_STATUS;
|
||
}
|
||
break;
|
||
|
||
case SUNXI_USB_EFEX_RECEIVE_DATA_NEW:
|
||
{
|
||
sunxi_usb_dbg("wait dma recv finish...\n");
|
||
//wait for dma recv finish
|
||
if(!sunxi_usb_efex_write_enable)
|
||
{
|
||
#ifdef _EFEX_USE_BUF_QUEUE_
|
||
if(efex_queue_write_one_page())
|
||
{
|
||
printf("sunxi efex queue: buf_queue_write_one_page() err\n");
|
||
efex_write_error_flag = 1;
|
||
}
|
||
#endif
|
||
break;
|
||
}
|
||
sunxi_usb_dbg("SUNXI_USB_RECEIVE_DATA_NEW\n");
|
||
|
||
//<2F><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
uint data_type = trans_data.type & SUNXI_EFEX_DATA_TYPE_MASK;
|
||
if(trans_data.type & SUNXI_EFEX_DRAM_MASK) //<2F><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ȱ<EFBFBD><C8B1>浽<EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>
|
||
{
|
||
sunxi_usb_dbg("SUNXI_EFEX_DRAM_MASK\n");
|
||
if(trans_data.type & SUNXI_EFEX_TRANS_FINISH_TAG) //<2F><>ʾ<EFBFBD><CABE>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
dram_data_recv_finish(data_type);
|
||
}
|
||
//<2F><><EFBFBD>ݻ<EFBFBD>û<EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
else //<2F><>ʾ<EFBFBD><CABE>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫд<D2AA><D0B4>flash
|
||
{
|
||
sunxi_usb_dbg("SUNXI_EFEX_FLASH_MASK\n");
|
||
#ifdef _EFEX_USE_BUF_QUEUE_
|
||
if(0 != efex_save_buff_to_queue(trans_data.flash_start,trans_data.flash_sectors,(void *)trans_data.act_recv_buffer))
|
||
{
|
||
printf("efex queue not enough space...\n");
|
||
trans_data.last_err = -1;
|
||
}
|
||
|
||
#else
|
||
if(!sunxi_sprite_write(trans_data.flash_start, trans_data.flash_sectors, (void *)trans_data.act_recv_buffer))
|
||
{
|
||
printf("sunxi usb efex err: write flash from 0x%x, sectors 0x%x failed\n", trans_data.flash_start, trans_data.flash_sectors);
|
||
trans_data.last_err = -1;
|
||
}
|
||
|
||
#ifdef CONFIG_SUNXI_SPINOR
|
||
if((uboot_spare_head.boot_data.storage_type == 3)&&(trans_data.type & SUNXI_EFEX_TRANS_FINISH_TAG)&&(fullimg_size == total_write_bytes))
|
||
{
|
||
//sunxi_usb_dbg("sunxi usb efex trans finish\n");
|
||
printf("before sunxi_sprite_setdata_finish\n");
|
||
sunxi_sprite_setdata_finish();
|
||
}
|
||
#endif
|
||
#endif
|
||
}
|
||
csw.status = trans_data.last_err;
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_STATUS;
|
||
}
|
||
break;
|
||
|
||
case SUNXI_USB_EFEX_STATUS:
|
||
sunxi_usb_dbg("SUNXI_USB_EFEX_STATUS\n");
|
||
#if defined(SUNXI_USB_30)
|
||
if(sunxi_usb_efex_status_enable)
|
||
#endif
|
||
{
|
||
sunxi_usb_efex_status = SUNXI_USB_EFEX_IDLE;
|
||
|
||
sunxi_ubuf->rx_ready_for_data = 0;
|
||
//when call efex queue write error,set stauts to tell usbtools
|
||
if(efex_write_error_flag)
|
||
{
|
||
csw.status = -1;
|
||
}
|
||
__sunxi_efex_send_status(&csw, sizeof(struct sunxi_efex_csw_t));
|
||
}
|
||
|
||
break;
|
||
|
||
case SUNXI_USB_EFEX_EXIT:
|
||
sunxi_usb_dbg("SUNXI_USB_EFEX_EXIT\n");
|
||
|
||
//when call efex queue write error,set stauts to tell usbtools
|
||
if(efex_write_error_flag)
|
||
{
|
||
csw.status = -1;
|
||
}
|
||
#if defined(SUNXI_USB_30)
|
||
if(sunxi_usb_efex_status_enable == 1)
|
||
{
|
||
sunxi_ubuf->rx_ready_for_data = 0;
|
||
|
||
__sunxi_efex_send_status(&csw, sizeof(struct sunxi_efex_csw_t));
|
||
}
|
||
else if(sunxi_usb_efex_status_enable >= 2)
|
||
{
|
||
return sunxi_efex_next_action;
|
||
}
|
||
#else
|
||
sunxi_ubuf->rx_ready_for_data = 0;
|
||
|
||
__sunxi_efex_send_status(&csw, sizeof(struct sunxi_efex_csw_t));
|
||
|
||
return sunxi_efex_next_action;
|
||
#endif
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
sunxi_usb_module_init(SUNXI_USB_DEVICE_EFEX, \
|
||
sunxi_efex_init, \
|
||
sunxi_efex_exit, \
|
||
sunxi_efex_reset, \
|
||
sunxi_efex_standard_req_op, \
|
||
sunxi_efex_nonstandard_req_op, \
|
||
sunxi_efex_state_loop, \
|
||
sunxi_efex_usb_rx_dma_isr, \
|
||
sunxi_efex_usb_tx_dma_isr \
|
||
);
|