xref: /rkdeveloptool/RKComm.cpp (revision 081d237ad5bf8f03170c9d60bd94ceefa0352aaf)
176af099aSliuyi /*
276af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi  * Seth Liu 2017.03.01
476af099aSliuyi  *
576af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
676af099aSliuyi  */
776af099aSliuyi 
876af099aSliuyi #include "RKComm.h"
976af099aSliuyi #include "RKLog.h"
1076af099aSliuyi #include "Endian.h"
1176af099aSliuyi extern unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber);
1276af099aSliuyi CRKComm::CRKComm(CRKLog *pLog)
1376af099aSliuyi {
1476af099aSliuyi 	memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC));
1576af099aSliuyi 	m_log = pLog;
1676af099aSliuyi }
1776af099aSliuyi CRKComm::~CRKComm()
1876af099aSliuyi {
1976af099aSliuyi }
2076af099aSliuyi 
2176af099aSliuyi CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog)
2276af099aSliuyi {
2376af099aSliuyi 	bRet = InitializeUsb(devDesc);
2476af099aSliuyi }
2576af099aSliuyi CRKUsbComm::~CRKUsbComm()
2676af099aSliuyi {
2776af099aSliuyi 	UninitializeUsb();
2876af099aSliuyi }
2976af099aSliuyi 
3076af099aSliuyi bool CRKUsbComm::InitializeUsb(STRUCT_RKDEVICE_DESC devDesc)
3176af099aSliuyi {
3276af099aSliuyi 	m_pUsbHandle = NULL;
3376af099aSliuyi 	m_pipeBulkIn = m_pipeBulkOut = 0;
3476af099aSliuyi 	m_interfaceNum = -1;
3576af099aSliuyi 	if (!devDesc.pUsbHandle) {
3676af099aSliuyi 		return false;
3776af099aSliuyi 	}
3876af099aSliuyi 	memcpy(&m_deviceDesc, &devDesc, sizeof(STRUCT_RKDEVICE_DESC));
3976af099aSliuyi 	int iRet;
4076af099aSliuyi 	iRet = libusb_open((libusb_device *)devDesc.pUsbHandle, (libusb_device_handle **)&m_pUsbHandle);
4176af099aSliuyi 	if (iRet!=0) {
4276af099aSliuyi 		if (m_log) {
4376af099aSliuyi 			m_log->Record("Error:InitializeUsb-->open device failed,err=%d", iRet);
4476af099aSliuyi 		}
4576af099aSliuyi 		return false;
4676af099aSliuyi 	}
4776af099aSliuyi 	struct libusb_config_descriptor *pConfigDesc=NULL;
4876af099aSliuyi 	iRet = libusb_get_active_config_descriptor((libusb_device *)devDesc.pUsbHandle, &pConfigDesc);
4976af099aSliuyi 	if (iRet!=0) {
5076af099aSliuyi 		if (m_log) {
5176af099aSliuyi 			m_log->Record("Error:InitializeUsb-->get device config descriptor failed, err=%d", iRet);
5276af099aSliuyi 		}
5376af099aSliuyi 		return false;
5476af099aSliuyi 	}
5576af099aSliuyi 	int i, j, k;
5676af099aSliuyi 	const struct libusb_interface *pInterface;
5776af099aSliuyi 	const struct libusb_endpoint_descriptor *pEndpointDesc;
5876af099aSliuyi 	const struct libusb_interface_descriptor *pInterfaceDesc;
5976af099aSliuyi 	for(i = 0; i < pConfigDesc->bNumInterfaces; i++) {
6076af099aSliuyi 		pInterface = pConfigDesc->interface + i;
6176af099aSliuyi 		for(j = 0; j < pInterface->num_altsetting; j++) {
6276af099aSliuyi 			pInterfaceDesc = pInterface->altsetting+j;
6376af099aSliuyi 			if (m_deviceDesc.emUsbType == RKUSB_MSC) {
6476af099aSliuyi 				if( (pInterfaceDesc->bInterfaceClass != 8) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 0x50))
6576af099aSliuyi 					continue;
6676af099aSliuyi 			}
6776af099aSliuyi 			else
6876af099aSliuyi 			{
6976af099aSliuyi 				if( (pInterfaceDesc->bInterfaceClass != 0xff) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 5))
7076af099aSliuyi 					continue;
7176af099aSliuyi 			}
7276af099aSliuyi 			for(k = 0; k < pInterfaceDesc->bNumEndpoints; k++) {
7376af099aSliuyi 				pEndpointDesc = pInterfaceDesc->endpoint+k;
7476af099aSliuyi 				if ((pEndpointDesc->bEndpointAddress & 0x80) == 0) {
7576af099aSliuyi 					if (m_pipeBulkOut == 0)
7676af099aSliuyi 						m_pipeBulkOut = pEndpointDesc->bEndpointAddress;
7776af099aSliuyi 				}
7876af099aSliuyi 				else {
7976af099aSliuyi 					if (m_pipeBulkIn == 0)
8076af099aSliuyi 						m_pipeBulkIn = pEndpointDesc->bEndpointAddress;
8176af099aSliuyi 				}
8276af099aSliuyi 				if ((m_pipeBulkIn != 0) && (m_pipeBulkOut != 0)) {//found it
8376af099aSliuyi 					m_interfaceNum = i;
8476af099aSliuyi 					libusb_free_config_descriptor(pConfigDesc);
8576af099aSliuyi 					iRet = libusb_claim_interface((libusb_device_handle *)m_pUsbHandle, m_interfaceNum);
8676af099aSliuyi 					if (iRet != 0) {
8776af099aSliuyi 						if (m_log) {
8876af099aSliuyi 					    	m_log->Record("Error:libusb_claim_interface failed,err=%d", iRet);
8976af099aSliuyi 					    }
9076af099aSliuyi 					    return false;
9176af099aSliuyi 					}
9276af099aSliuyi 					return true;
9376af099aSliuyi 				}
9476af099aSliuyi 			}
9576af099aSliuyi 		}
9676af099aSliuyi 	}
9776af099aSliuyi 	libusb_free_config_descriptor(pConfigDesc);
9876af099aSliuyi 	return false;
9976af099aSliuyi }
10076af099aSliuyi void CRKUsbComm::UninitializeUsb()
10176af099aSliuyi {
10276af099aSliuyi 	if (m_pUsbHandle) {
10376af099aSliuyi 		libusb_close((libusb_device_handle *)m_pUsbHandle);
10476af099aSliuyi 		m_pUsbHandle = NULL;
10576af099aSliuyi 	}
10676af099aSliuyi 	memset(&m_deviceDesc, 0, sizeof(STRUCT_RKDEVICE_DESC));
10776af099aSliuyi 	m_pipeBulkIn = m_pipeBulkOut = 0;
10876af099aSliuyi 	return ;
10976af099aSliuyi }
11076af099aSliuyi bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc)
11176af099aSliuyi {
11276af099aSliuyi     bool bRet;
11376af099aSliuyi     UninitializeUsb();
11476af099aSliuyi     bRet = InitializeUsb(devDesc);
11576af099aSliuyi     return bRet;
11676af099aSliuyi }
11776af099aSliuyi bool CRKUsbComm::Reset_Usb_Device()
11876af099aSliuyi {
11976af099aSliuyi 	int iRet = -1;
12076af099aSliuyi     if (m_pUsbHandle) {
12176af099aSliuyi 		iRet=libusb_reset_device((libusb_device_handle *)m_pUsbHandle);
12276af099aSliuyi 	}
12376af099aSliuyi     return (iRet == 0) ? true : false;
12476af099aSliuyi }
12576af099aSliuyi 
12676af099aSliuyi bool CRKUsbComm::RKU_Read(BYTE* lpBuffer, DWORD dwSize)
12776af099aSliuyi {
12876af099aSliuyi 	int  iRet;
12976af099aSliuyi 	int  nRead;
13076af099aSliuyi 	iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, CMD_TIMEOUT);
13176af099aSliuyi 	if (iRet!=0) {
13276af099aSliuyi 	    if (m_log) {
13376af099aSliuyi 	        m_log->Record("Error:RKU_Read failed,err=%d", iRet);
13476af099aSliuyi 	    }
13576af099aSliuyi 	    return false;
13676af099aSliuyi 	}
13776af099aSliuyi 	if (nRead != (int)dwSize) {
13876af099aSliuyi        	if (m_log) {
13976af099aSliuyi             m_log->Record("Error:RKU_Read failed, size=%d, read=%d", dwSize, nRead);
14076af099aSliuyi         }
14176af099aSliuyi         return false;
14276af099aSliuyi     }
14376af099aSliuyi 	return true;
14476af099aSliuyi }
14576af099aSliuyi 
14676af099aSliuyi bool CRKUsbComm::RKU_Write(BYTE* lpBuffer, DWORD dwSize)
14776af099aSliuyi {
14876af099aSliuyi 	int  iRet;
14976af099aSliuyi 	int nWrite;
15076af099aSliuyi 	iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkOut, lpBuffer, dwSize, &nWrite, CMD_TIMEOUT);
15176af099aSliuyi 	if (iRet != 0) {
15276af099aSliuyi 	    if (m_log) {
15376af099aSliuyi 	        m_log->Record("Error:RKU_Write failed, err=%d", iRet);
15476af099aSliuyi 	    }
15576af099aSliuyi 	    return false;
15676af099aSliuyi 	}
15776af099aSliuyi     if (nWrite != (int)dwSize) {
15876af099aSliuyi        	if (m_log) {
15976af099aSliuyi         	m_log->Record("Error:RKU_Write failed, size=%d, read=%d", dwSize, nWrite);
16076af099aSliuyi     	}
16176af099aSliuyi         return false;
16276af099aSliuyi     }
16376af099aSliuyi 	return true;
16476af099aSliuyi }
16576af099aSliuyi int CRKUsbComm::RandomInteger(int low, int high)
16676af099aSliuyi {
16776af099aSliuyi 	int k;
16876af099aSliuyi 	double d;
16976af099aSliuyi 
17076af099aSliuyi 	d = (double)rand() / ((double)RAND_MAX + 1);
17176af099aSliuyi 	k = (int)(d * (high - low + 1));
17276af099aSliuyi 	return (low + k);
17376af099aSliuyi }
17476af099aSliuyi DWORD CRKUsbComm::MakeCBWTag()
17576af099aSliuyi {
17676af099aSliuyi 	DWORD tag = 0;
17776af099aSliuyi 	int i = 0;
17876af099aSliuyi 
17976af099aSliuyi 	for(i=0; i<4; i++){
18076af099aSliuyi 		tag <<= 8;
18176af099aSliuyi 		tag += RandomInteger(0, 0xFF);
18276af099aSliuyi 	}
18376af099aSliuyi 	return tag;
18476af099aSliuyi }
18576af099aSliuyi void CRKUsbComm::InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code)
18676af099aSliuyi {
18776af099aSliuyi 	memset(pCBW,0, sizeof(CBW));
18876af099aSliuyi 
18976af099aSliuyi 	pCBW->dwCBWSignature = CBW_SIGN;
19076af099aSliuyi 	pCBW->dwCBWTag = MakeCBWTag();
19176af099aSliuyi 	pCBW->cbwcb.ucOperCode = code;
19276af099aSliuyi 
19376af099aSliuyi 	switch(code) {
19476af099aSliuyi 		case TEST_UNIT_READY:	/* Test Unit Ready	: 0 */
19576af099aSliuyi 		case READ_FLASH_ID:		/* Read Flash ID	: 1 */
19676af099aSliuyi 		case READ_FLASH_INFO:
19776af099aSliuyi 		case READ_CHIP_INFO:
19876af099aSliuyi 		case READ_EFUSE:
199*081d237aSliuyi 		case READ_CAPABILITY:
20076af099aSliuyi 			pCBW->ucCBWFlags= DIRECTION_IN;
20176af099aSliuyi 			pCBW->ucCBWCBLength = 0x06;
20276af099aSliuyi 			break;
20376af099aSliuyi 		case DEVICE_RESET:		/* Reset Device		: 0xff */
20476af099aSliuyi 		case ERASE_SYSTEMDISK:
20576af099aSliuyi 		case SET_RESET_FLAG:
20676af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_OUT;
20776af099aSliuyi 			pCBW->ucCBWCBLength = 0x06;
20876af099aSliuyi 			break;
20976af099aSliuyi 		case TEST_BAD_BLOCK:	/* Test Bad Block	: 3 */
21076af099aSliuyi 		case READ_SECTOR:		/* Read Pages		: 4 */
21176af099aSliuyi 		case READ_LBA:		/* Read Pages		: 4 */
21276af099aSliuyi 		case READ_SDRAM:		/* Write Pages		: 15 */
21376af099aSliuyi 		case READ_SPI_FLASH:
21476af099aSliuyi 		case READ_NEW_EFUSE:
21576af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_IN;
21676af099aSliuyi 			pCBW->ucCBWCBLength = 0x0a;
21776af099aSliuyi 			break;
21876af099aSliuyi 		case WRITE_SECTOR:		/* Write Pages		: 5 */
21976af099aSliuyi 		case WRITE_LBA:		/* Write Pages		: 15 */
22076af099aSliuyi 		case WRITE_SDRAM:		/* Write Pages		: 15 */
22176af099aSliuyi 		case EXECUTE_SDRAM:
22276af099aSliuyi 		case ERASE_NORMAL:		/* Erase Blocks		: 6 */
22376af099aSliuyi 		case ERASE_FORCE:		/* Read Spare		: 11 */
22476af099aSliuyi 		case WRITE_EFUSE:
22576af099aSliuyi 		case WRITE_SPI_FLASH:
22676af099aSliuyi 		case WRITE_NEW_EFUSE:
227c29e5f0fSliuyi 		case ERASE_LBA:
22876af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_OUT;
22976af099aSliuyi 			pCBW->ucCBWCBLength = 0x0a;
23076af099aSliuyi 			break;
23176af099aSliuyi 		default:
23276af099aSliuyi 			break;
23376af099aSliuyi 	}
23476af099aSliuyi }
23576af099aSliuyi 
23676af099aSliuyi 
23776af099aSliuyi bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw)
23876af099aSliuyi {
23976af099aSliuyi 	DWORD dwReadBytes=0;
24076af099aSliuyi 	DWORD dwTotalRead=0;
24176af099aSliuyi 	int iTryCount;
24276af099aSliuyi 	iTryCount = 3;
24376af099aSliuyi 	do {
24476af099aSliuyi 		dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) );
24576af099aSliuyi 
24676af099aSliuyi 		if (UFI_CHECK_SIGN(cbw,csw))
24776af099aSliuyi 		{
24876af099aSliuyi 			return true;
24976af099aSliuyi 		}
25076af099aSliuyi 		if (dwReadBytes != sizeof(CSW))
25176af099aSliuyi 		{
25276af099aSliuyi 			iTryCount--;
25376af099aSliuyi 			sleep(3);
25476af099aSliuyi 		}
25576af099aSliuyi 		dwTotalRead += dwReadBytes;
25676af099aSliuyi 		if (dwTotalRead >= MAX_CLEAR_LEN)
25776af099aSliuyi 		{
25876af099aSliuyi 			break;
25976af099aSliuyi 		}
26076af099aSliuyi 	}while ( iTryCount > 0 );
26176af099aSliuyi 	return false;
26276af099aSliuyi }
26376af099aSliuyi 
26476af099aSliuyi DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize)
26576af099aSliuyi {
26676af099aSliuyi 	int  iRet;
26776af099aSliuyi 	int  nRead;
26876af099aSliuyi 	iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000);
26976af099aSliuyi 	if (iRet != 0) {
27076af099aSliuyi 	    if (m_log) {
27176af099aSliuyi 	        m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet);
27276af099aSliuyi 	    }
27376af099aSliuyi 	    return 0;
27476af099aSliuyi 	}
27576af099aSliuyi 	return nRead;
27676af099aSliuyi }
27776af099aSliuyi 
27876af099aSliuyi int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType)
27976af099aSliuyi {
28076af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
28176af099aSliuyi         if (m_log) {
28276af099aSliuyi             m_log->Record("Error:RKU_EraseBlock failed,device not support");
28376af099aSliuyi         }
28476af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
28576af099aSliuyi     }
28676af099aSliuyi 	CBW cbw;
28776af099aSliuyi 	CSW csw;
28876af099aSliuyi 	USHORT usCount;
28976af099aSliuyi 	usCount = dwCount;
29076af099aSliuyi 	if(dwCount > MAX_ERASE_BLOCKS)
29176af099aSliuyi 		return ERR_CROSS_BORDER;
29276af099aSliuyi 
29376af099aSliuyi 	InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType);
29476af099aSliuyi 	cbw.ucCBWLUN = ucFlashCS;
29576af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
29676af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
29776af099aSliuyi 
29876af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
29976af099aSliuyi 	{
30076af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
30176af099aSliuyi 	}
30276af099aSliuyi 
30376af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
30476af099aSliuyi 	{
30576af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
30676af099aSliuyi 	}
30776af099aSliuyi 
30876af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
30976af099aSliuyi 		return ERR_CMD_NOTMATCH;
31076af099aSliuyi 
31176af099aSliuyi 	if(csw.ucCSWStatus == 1)
31276af099aSliuyi 		return ERR_FOUND_BAD_BLOCK;
31376af099aSliuyi 
31476af099aSliuyi 	return ERR_SUCCESS;
31576af099aSliuyi }
31676af099aSliuyi int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer)
31776af099aSliuyi {
31876af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
31976af099aSliuyi         if (m_log) {
32076af099aSliuyi             m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
32176af099aSliuyi         }
32276af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
32376af099aSliuyi     }
32476af099aSliuyi 
32576af099aSliuyi 	CBW cbw;
32676af099aSliuyi 	CSW csw;
32776af099aSliuyi 
32876af099aSliuyi 	InitializeCBW(&cbw, READ_CHIP_INFO);
329b5200da5Sliuyi 	cbw.dwCBWTransferLength = 16;
33076af099aSliuyi 
33176af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
33276af099aSliuyi 	{
33376af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
33476af099aSliuyi 	}
33576af099aSliuyi 
33676af099aSliuyi 	if(!RKU_Read(lpBuffer, 16))
33776af099aSliuyi 	{
33876af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
33976af099aSliuyi 	}
34076af099aSliuyi 
34176af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
34276af099aSliuyi 	{
34376af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
34476af099aSliuyi 	}
34576af099aSliuyi 
34676af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
34776af099aSliuyi 		return ERR_CMD_NOTMATCH;
34876af099aSliuyi 
34976af099aSliuyi 	return ERR_SUCCESS;
35076af099aSliuyi }
35176af099aSliuyi int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer)
35276af099aSliuyi {
35376af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
35476af099aSliuyi         if (m_log) {
35576af099aSliuyi             m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
35676af099aSliuyi         }
35776af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
35876af099aSliuyi     }
35976af099aSliuyi 
36076af099aSliuyi 	CBW cbw;
36176af099aSliuyi 	CSW csw;
36276af099aSliuyi 
36376af099aSliuyi 	InitializeCBW(&cbw, READ_FLASH_ID);
364b5200da5Sliuyi 	cbw.dwCBWTransferLength = 5;
36576af099aSliuyi 
36676af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
36776af099aSliuyi 	{
36876af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
36976af099aSliuyi 	}
37076af099aSliuyi 
37176af099aSliuyi 	if(!RKU_Read(lpBuffer, 5))
37276af099aSliuyi 	{
37376af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
37476af099aSliuyi 	}
37576af099aSliuyi 
37676af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
37776af099aSliuyi 	{
37876af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
37976af099aSliuyi 	}
38076af099aSliuyi 
38176af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
38276af099aSliuyi 		return ERR_CMD_NOTMATCH;
38376af099aSliuyi 
38476af099aSliuyi 	return ERR_SUCCESS;
38576af099aSliuyi }
38676af099aSliuyi int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead)
38776af099aSliuyi {
38876af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
38976af099aSliuyi         if (m_log) {
39076af099aSliuyi             m_log->Record("Error:RKU_ReadFlashInfo failed,device not support");
39176af099aSliuyi         }
39276af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
39376af099aSliuyi     }
39476af099aSliuyi 	CBW cbw;
39576af099aSliuyi 	CSW csw;
39676af099aSliuyi 
39776af099aSliuyi 	InitializeCBW(&cbw, READ_FLASH_INFO);
398b5200da5Sliuyi 	cbw.dwCBWTransferLength = 11;
39976af099aSliuyi 
40076af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
40176af099aSliuyi 	{
40276af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
40376af099aSliuyi 	}
40476af099aSliuyi 
40576af099aSliuyi 	DWORD dwRead;
40676af099aSliuyi 	dwRead = RKU_Read_EX(lpBuffer, 512);
40776af099aSliuyi 	if ((dwRead < 11) || (dwRead > 512))
40876af099aSliuyi 	{
40976af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
41076af099aSliuyi 	}
41176af099aSliuyi 	if (puiRead)
41276af099aSliuyi 	{
41376af099aSliuyi 		*puiRead = dwRead;
41476af099aSliuyi 	}
41576af099aSliuyi /*
41676af099aSliuyi 	if(!RKU_Read(hDev, lpBuffer, 11))
41776af099aSliuyi 	{
41876af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
41976af099aSliuyi 	}
42076af099aSliuyi */
42176af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
42276af099aSliuyi 	{
42376af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
42476af099aSliuyi 	}
42576af099aSliuyi 
42676af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
42776af099aSliuyi 		return ERR_CMD_NOTMATCH;
42876af099aSliuyi 
42976af099aSliuyi 	return ERR_SUCCESS;
43076af099aSliuyi }
431*081d237aSliuyi int CRKUsbComm::RKU_ReadCapability(BYTE* lpBuffer)
432*081d237aSliuyi {
433*081d237aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
434*081d237aSliuyi         if (m_log) {
435*081d237aSliuyi             m_log->Record("Error:RKU_ReadCapability failed,device not support");
436*081d237aSliuyi         }
437*081d237aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
438*081d237aSliuyi     }
439*081d237aSliuyi 
440*081d237aSliuyi 	CBW cbw;
441*081d237aSliuyi 	CSW csw;
442*081d237aSliuyi 	DWORD dwRead;
443*081d237aSliuyi 
444*081d237aSliuyi 	InitializeCBW(&cbw, READ_CAPABILITY);
445*081d237aSliuyi 	cbw.dwCBWTransferLength = 8;
446*081d237aSliuyi 
447*081d237aSliuyi 	if(!RKU_Write((BYTE*)&cbw, sizeof(CBW)))
448*081d237aSliuyi 	{
449*081d237aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
450*081d237aSliuyi 	}
451*081d237aSliuyi 
452*081d237aSliuyi 	dwRead = RKU_Read_EX((BYTE*)&csw, sizeof(CSW));
453*081d237aSliuyi 
454*081d237aSliuyi 	if(dwRead != 8)
455*081d237aSliuyi 	{
456*081d237aSliuyi 		return ERR_DEVICE_READ_FAILED;
457*081d237aSliuyi 	}
458*081d237aSliuyi 	memcpy(lpBuffer, (BYTE*)&csw, 8);
459*081d237aSliuyi 
460*081d237aSliuyi 	if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
461*081d237aSliuyi 	{
462*081d237aSliuyi 		return ERR_DEVICE_READ_FAILED;
463*081d237aSliuyi 	}
464*081d237aSliuyi 
465*081d237aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
466*081d237aSliuyi 		return ERR_CMD_NOTMATCH;
467*081d237aSliuyi 
468*081d237aSliuyi 	return ERR_SUCCESS;
469*081d237aSliuyi }
470*081d237aSliuyi 
47176af099aSliuyi int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
47276af099aSliuyi {
47376af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
47476af099aSliuyi         if (m_log) {
47576af099aSliuyi             m_log->Record("Error:RKU_ReadLBA failed,device not support");
47676af099aSliuyi         }
47776af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
47876af099aSliuyi     }
47976af099aSliuyi 	CBW cbw;
48076af099aSliuyi 	CSW csw;
48176af099aSliuyi 	USHORT wSectorSize;
48276af099aSliuyi 	USHORT usSectorLen;
48376af099aSliuyi 	wSectorSize = 512;
48476af099aSliuyi 	usSectorLen=dwCount;
48576af099aSliuyi 
48676af099aSliuyi 	InitializeCBW(&cbw, READ_LBA);
487b5200da5Sliuyi 	cbw.dwCBWTransferLength = dwCount * wSectorSize;
48876af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
48976af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen);
49076af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
49176af099aSliuyi 
49276af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
49376af099aSliuyi 	{
49476af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
49576af099aSliuyi 	}
49676af099aSliuyi 	DWORD dwTotal;
49776af099aSliuyi 	dwTotal = usSectorLen * wSectorSize;
49876af099aSliuyi 
49976af099aSliuyi 	if(!RKU_Read(lpBuffer, dwTotal))
50076af099aSliuyi 	{
50176af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
50276af099aSliuyi 	}
50376af099aSliuyi 
50476af099aSliuyi 	if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
50576af099aSliuyi 	{
50676af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
50776af099aSliuyi 	}
50876af099aSliuyi 
50976af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
51076af099aSliuyi 		return ERR_CMD_NOTMATCH;
51176af099aSliuyi 
51276af099aSliuyi 	if(csw.ucCSWStatus == 1)
51376af099aSliuyi 		return ERR_FAILED;
51476af099aSliuyi 
51576af099aSliuyi 	return ERR_SUCCESS;
51676af099aSliuyi }
51776af099aSliuyi 
51876af099aSliuyi int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode)
51976af099aSliuyi {
52076af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
52176af099aSliuyi         if (m_log) {
52276af099aSliuyi             m_log->Record("Error:RKU_ResetDevice failed,device not support");
52376af099aSliuyi         }
52476af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
52576af099aSliuyi     }
52676af099aSliuyi 
52776af099aSliuyi 	CBW cbw;
52876af099aSliuyi 	CSW csw;
52976af099aSliuyi 
53076af099aSliuyi 	InitializeCBW(&cbw, DEVICE_RESET);
53176af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
53276af099aSliuyi 
53376af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
53476af099aSliuyi 	{
53576af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
53676af099aSliuyi 	}
53776af099aSliuyi 
53876af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
53976af099aSliuyi 	{
54076af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
54176af099aSliuyi 	}
54276af099aSliuyi 
54376af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
54476af099aSliuyi 		bool bRet;
54576af099aSliuyi 		bRet = RKU_ClearBuffer(cbw, csw);
54676af099aSliuyi 		if (!bRet) {
54776af099aSliuyi 			return ERR_CMD_NOTMATCH;
54876af099aSliuyi 		}
54976af099aSliuyi 	}
55076af099aSliuyi 
55176af099aSliuyi 	if(csw.ucCSWStatus == 1)
55276af099aSliuyi 		return ERR_FAILED;
55376af099aSliuyi 
55476af099aSliuyi 	return ERR_SUCCESS;
55576af099aSliuyi }
55676af099aSliuyi 
55776af099aSliuyi int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode)
55876af099aSliuyi {
55976af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
56076af099aSliuyi         if (m_log) {
56176af099aSliuyi             m_log->Record("Error:RKU_TestDeviceReady failed,device not support");
56276af099aSliuyi         }
56376af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
56476af099aSliuyi     }
56576af099aSliuyi 	CBW cbw;
56676af099aSliuyi 	CSW csw;
56776af099aSliuyi 
56876af099aSliuyi 	InitializeCBW(&cbw, TEST_UNIT_READY);
56976af099aSliuyi 
57076af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
57176af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
57276af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
57376af099aSliuyi 	}
57476af099aSliuyi 
57576af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
57676af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
57776af099aSliuyi 	}
57876af099aSliuyi 
57976af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
58076af099aSliuyi 		bool bRet;
58176af099aSliuyi 		bRet = RKU_ClearBuffer(cbw ,csw);
58276af099aSliuyi 		if (!bRet) {
58376af099aSliuyi 			return ERR_CMD_NOTMATCH;
58476af099aSliuyi 		}
58576af099aSliuyi 	}
58676af099aSliuyi 
58776af099aSliuyi 	if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) {
58876af099aSliuyi 		*dwCurrent = (csw.dwCBWDataResidue >>16);
58976af099aSliuyi 		*dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF);
59076af099aSliuyi 
59176af099aSliuyi 		*dwTotal = EndianU16_BtoL(*dwTotal);
59276af099aSliuyi 		*dwCurrent = EndianU16_BtoL(*dwCurrent);
59376af099aSliuyi 	}
59476af099aSliuyi 	if(csw.ucCSWStatus == 1) {
59576af099aSliuyi 		return ERR_DEVICE_UNREADY;
59676af099aSliuyi 	}
59776af099aSliuyi 
59876af099aSliuyi 	return ERR_DEVICE_READY;
59976af099aSliuyi }
60076af099aSliuyi int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
60176af099aSliuyi {
60276af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
60376af099aSliuyi         if (m_log) {
60476af099aSliuyi             m_log->Record("Error:RKU_WriteLBA failed,device not support");
60576af099aSliuyi         }
60676af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
60776af099aSliuyi     }
60876af099aSliuyi 	CBW cbw;
60976af099aSliuyi 	CSW csw;
61076af099aSliuyi 	USHORT wSectorSize;
61176af099aSliuyi 	USHORT usCount;
61276af099aSliuyi 	wSectorSize = 512;
61376af099aSliuyi 	usCount = dwCount;
61476af099aSliuyi 	DWORD dwTotal = usCount * wSectorSize;
61576af099aSliuyi 
61676af099aSliuyi 	InitializeCBW(&cbw, WRITE_LBA);
617b5200da5Sliuyi 	cbw.dwCBWTransferLength = dwCount * wSectorSize;
61876af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
61976af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
62076af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
62176af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
62276af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
62376af099aSliuyi 	}
62476af099aSliuyi 
62576af099aSliuyi 	if(!RKU_Write( lpBuffer, dwTotal)) {
62676af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
62776af099aSliuyi 	}
62876af099aSliuyi 
62976af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
63076af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
63176af099aSliuyi 	}
63276af099aSliuyi 
63376af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
63476af099aSliuyi 		return ERR_CMD_NOTMATCH;
63576af099aSliuyi 
63676af099aSliuyi 	if(csw.ucCSWStatus == 1)
63776af099aSliuyi 		return ERR_FAILED;
63876af099aSliuyi 
63976af099aSliuyi 	return ERR_SUCCESS;
64076af099aSliuyi }
641c29e5f0fSliuyi int CRKUsbComm::RKU_EraseLBA(DWORD dwPos, DWORD dwCount)
642c29e5f0fSliuyi {
643c29e5f0fSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
644c29e5f0fSliuyi         if (m_log) {
645c29e5f0fSliuyi             m_log->Record("Error:RKU_WriteLBA failed,device not support");
646c29e5f0fSliuyi         }
647c29e5f0fSliuyi         return ERR_DEVICE_NOT_SUPPORT;
648c29e5f0fSliuyi     }
649c29e5f0fSliuyi 	CBW cbw;
650c29e5f0fSliuyi 	CSW csw;
651c29e5f0fSliuyi 	USHORT usCount;
652c29e5f0fSliuyi 	usCount = dwCount;
653c29e5f0fSliuyi 
654c29e5f0fSliuyi 
655c29e5f0fSliuyi 	InitializeCBW(&cbw, ERASE_LBA);
656c29e5f0fSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
657c29e5f0fSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
658c29e5f0fSliuyi 
659c29e5f0fSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
660c29e5f0fSliuyi 		return ERR_DEVICE_WRITE_FAILED;
661c29e5f0fSliuyi 	}
662c29e5f0fSliuyi 
663c29e5f0fSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
664c29e5f0fSliuyi 		return ERR_DEVICE_READ_FAILED;
665c29e5f0fSliuyi 	}
666c29e5f0fSliuyi 
667c29e5f0fSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
668c29e5f0fSliuyi 		return ERR_CMD_NOTMATCH;
669c29e5f0fSliuyi 
670c29e5f0fSliuyi 	if(csw.ucCSWStatus == 1)
671c29e5f0fSliuyi 		return ERR_FAILED;
672c29e5f0fSliuyi 
673c29e5f0fSliuyi 	return ERR_SUCCESS;
674c29e5f0fSliuyi }
675c29e5f0fSliuyi 
67676af099aSliuyi int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer)
67776af099aSliuyi {
67876af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
67976af099aSliuyi         if (m_log) {
68076af099aSliuyi             m_log->Record("Error:RKU_WriteSector failed,device not support");
68176af099aSliuyi         }
68276af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
68376af099aSliuyi     }
68476af099aSliuyi 	CBW cbw;
68576af099aSliuyi 	CSW csw;
68676af099aSliuyi 	USHORT wSectorSize;
68776af099aSliuyi 	USHORT usCount;
68876af099aSliuyi 	usCount=dwCount;
68976af099aSliuyi 	if(usCount > 32)
69076af099aSliuyi 		return ERR_CROSS_BORDER;
69176af099aSliuyi 
69276af099aSliuyi 	wSectorSize = 528;
69376af099aSliuyi 	InitializeCBW(&cbw, WRITE_SECTOR);
694b5200da5Sliuyi 	cbw.dwCBWTransferLength = dwCount * wSectorSize;
69576af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
69676af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
69776af099aSliuyi 
69876af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
69976af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
70076af099aSliuyi 	}
70176af099aSliuyi 
70276af099aSliuyi 	if(!RKU_Write( lpBuffer, usCount * wSectorSize)) {
70376af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
70476af099aSliuyi 	}
70576af099aSliuyi 
70676af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
70776af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
70876af099aSliuyi 	}
70976af099aSliuyi 
71076af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
71176af099aSliuyi 		return ERR_CMD_NOTMATCH;
71276af099aSliuyi 
71376af099aSliuyi 	if(csw.ucCSWStatus == 1)
71476af099aSliuyi 		return ERR_FAILED;
71576af099aSliuyi 
71676af099aSliuyi 	return ERR_SUCCESS;
71776af099aSliuyi }
71876af099aSliuyi 
71976af099aSliuyi 
72076af099aSliuyi int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize)
72176af099aSliuyi {
72276af099aSliuyi 	if (m_deviceDesc.emUsbType != RKUSB_MASKROM) {
72376af099aSliuyi 	    if (m_log) {
72476af099aSliuyi 	        m_log->Record("Error:RKU_DeviceRequest failed,device not support");
72576af099aSliuyi 	    }
72676af099aSliuyi 	    return ERR_DEVICE_NOT_SUPPORT;
72776af099aSliuyi 	}
72876af099aSliuyi 	if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) {
72976af099aSliuyi 		if (m_log) {
73076af099aSliuyi 	        m_log->Record("Error:RKU_DeviceRequest failed,request not support");
73176af099aSliuyi 	    }
73276af099aSliuyi 	    return ERR_REQUEST_NOT_SUPPORT;
73376af099aSliuyi 	}
73476af099aSliuyi 
73576af099aSliuyi 	bool bSendPendPacket = false;
73676af099aSliuyi 	USHORT crcValue = 0xffff;
73776af099aSliuyi 	BYTE *pData = NULL;
73876af099aSliuyi 	pData = new BYTE[dwDataSize + 5];
73976af099aSliuyi 	memset(pData, 0, dwDataSize + 5);
74076af099aSliuyi 	memcpy(pData, lpBuffer, dwDataSize);
74176af099aSliuyi 
74276af099aSliuyi 	switch(dwDataSize % 4096) {
74376af099aSliuyi 		case 4095:
74476af099aSliuyi 			++dwDataSize;
74576af099aSliuyi 			break;
74676af099aSliuyi 		case 4094:
74776af099aSliuyi 			bSendPendPacket = true;
74876af099aSliuyi 			break;
74976af099aSliuyi 		case 0:
75076af099aSliuyi 		default:
75176af099aSliuyi 			break;
75276af099aSliuyi 	}
75376af099aSliuyi 
75476af099aSliuyi 	crcValue = CRC_CCITT(pData, dwDataSize);
75576af099aSliuyi 	pData[dwDataSize] = (crcValue & 0xff00) >> 8;
75676af099aSliuyi 	pData[dwDataSize+1] = crcValue & 0x00ff;
75776af099aSliuyi 	dwDataSize += 2;
75876af099aSliuyi 
75976af099aSliuyi 	UINT nSendBytes = 0;
76076af099aSliuyi 	DWORD dwTotalSended = 0;
76176af099aSliuyi 	int iRet;
76276af099aSliuyi 
76376af099aSliuyi 	while(dwTotalSended < dwDataSize) {
76476af099aSliuyi 		nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended);
76576af099aSliuyi 		iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT);
76676af099aSliuyi 		if (iRet != (int)nSendBytes) {
76776af099aSliuyi 			if (m_log) {
76876af099aSliuyi 				m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet);
76976af099aSliuyi 			}
77076af099aSliuyi 			delete []pData;
77176af099aSliuyi 			return ERR_REQUEST_FAIL;
77276af099aSliuyi 		}
77376af099aSliuyi 		dwTotalSended += nSendBytes;
77476af099aSliuyi 	}
77576af099aSliuyi 
77676af099aSliuyi 	if(bSendPendPacket) {
77776af099aSliuyi 		BYTE ucFillByte = 0;
77876af099aSliuyi 		iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT);
77976af099aSliuyi 		if (iRet != 0) {
78076af099aSliuyi 			if (m_log) {
78176af099aSliuyi 				m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet);
78276af099aSliuyi 			}
78376af099aSliuyi 			delete []pData;
78476af099aSliuyi 			return ERR_REQUEST_FAIL;
78576af099aSliuyi 		}
78676af099aSliuyi 	}
78776af099aSliuyi 
78876af099aSliuyi 	delete []pData;
78976af099aSliuyi 
79076af099aSliuyi     return ERR_SUCCESS;
79176af099aSliuyi }
79276af099aSliuyi 
79376af099aSliuyi 
794