xref: /rkdeveloptool/RKComm.cpp (revision 554066a0898de0aaf5ea9a5157753dd09ab9c0ef)
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:
199081d237aSliuyi 		case READ_CAPABILITY:
200*554066a0SArnaud Mouiche 		case READ_STORAGE:
20176af099aSliuyi 			pCBW->ucCBWFlags= DIRECTION_IN;
20276af099aSliuyi 			pCBW->ucCBWCBLength = 0x06;
20376af099aSliuyi 			break;
20476af099aSliuyi 		case DEVICE_RESET:		/* Reset Device		: 0xff */
20576af099aSliuyi 		case ERASE_SYSTEMDISK:
20676af099aSliuyi 		case SET_RESET_FLAG:
207*554066a0SArnaud Mouiche 		case CHANGE_STORAGE:
20876af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_OUT;
20976af099aSliuyi 			pCBW->ucCBWCBLength = 0x06;
21076af099aSliuyi 			break;
21176af099aSliuyi 		case TEST_BAD_BLOCK:	/* Test Bad Block	: 3 */
21276af099aSliuyi 		case READ_SECTOR:		/* Read Pages		: 4 */
21376af099aSliuyi 		case READ_LBA:		/* Read Pages		: 4 */
21476af099aSliuyi 		case READ_SDRAM:		/* Write Pages		: 15 */
21576af099aSliuyi 		case READ_SPI_FLASH:
21676af099aSliuyi 		case READ_NEW_EFUSE:
21776af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_IN;
21876af099aSliuyi 			pCBW->ucCBWCBLength = 0x0a;
21976af099aSliuyi 			break;
22076af099aSliuyi 		case WRITE_SECTOR:		/* Write Pages		: 5 */
22176af099aSliuyi 		case WRITE_LBA:		/* Write Pages		: 15 */
22276af099aSliuyi 		case WRITE_SDRAM:		/* Write Pages		: 15 */
22376af099aSliuyi 		case EXECUTE_SDRAM:
22476af099aSliuyi 		case ERASE_NORMAL:		/* Erase Blocks		: 6 */
22576af099aSliuyi 		case ERASE_FORCE:		/* Read Spare		: 11 */
22676af099aSliuyi 		case WRITE_EFUSE:
22776af099aSliuyi 		case WRITE_SPI_FLASH:
22876af099aSliuyi 		case WRITE_NEW_EFUSE:
229c29e5f0fSliuyi 		case ERASE_LBA:
23076af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_OUT;
23176af099aSliuyi 			pCBW->ucCBWCBLength = 0x0a;
23276af099aSliuyi 			break;
23376af099aSliuyi 		default:
23476af099aSliuyi 			break;
23576af099aSliuyi 	}
23676af099aSliuyi }
23776af099aSliuyi 
23876af099aSliuyi 
23976af099aSliuyi bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw)
24076af099aSliuyi {
24176af099aSliuyi 	DWORD dwReadBytes=0;
24276af099aSliuyi 	DWORD dwTotalRead=0;
24376af099aSliuyi 	int iTryCount;
24476af099aSliuyi 	iTryCount = 3;
24576af099aSliuyi 	do {
24676af099aSliuyi 		dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) );
24776af099aSliuyi 
24876af099aSliuyi 		if (UFI_CHECK_SIGN(cbw,csw))
24976af099aSliuyi 		{
25076af099aSliuyi 			return true;
25176af099aSliuyi 		}
25276af099aSliuyi 		if (dwReadBytes != sizeof(CSW))
25376af099aSliuyi 		{
25476af099aSliuyi 			iTryCount--;
25576af099aSliuyi 			sleep(3);
25676af099aSliuyi 		}
25776af099aSliuyi 		dwTotalRead += dwReadBytes;
25876af099aSliuyi 		if (dwTotalRead >= MAX_CLEAR_LEN)
25976af099aSliuyi 		{
26076af099aSliuyi 			break;
26176af099aSliuyi 		}
26276af099aSliuyi 	}while ( iTryCount > 0 );
26376af099aSliuyi 	return false;
26476af099aSliuyi }
26576af099aSliuyi 
26676af099aSliuyi DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize)
26776af099aSliuyi {
26876af099aSliuyi 	int  iRet;
26976af099aSliuyi 	int  nRead;
27076af099aSliuyi 	iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000);
27176af099aSliuyi 	if (iRet != 0) {
27276af099aSliuyi 	    if (m_log) {
27376af099aSliuyi 	        m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet);
27476af099aSliuyi 	    }
27576af099aSliuyi 	    return 0;
27676af099aSliuyi 	}
27776af099aSliuyi 	return nRead;
27876af099aSliuyi }
27976af099aSliuyi 
28076af099aSliuyi int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType)
28176af099aSliuyi {
28276af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
28376af099aSliuyi         if (m_log) {
28476af099aSliuyi             m_log->Record("Error:RKU_EraseBlock failed,device not support");
28576af099aSliuyi         }
28676af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
28776af099aSliuyi     }
28876af099aSliuyi 	CBW cbw;
28976af099aSliuyi 	CSW csw;
29076af099aSliuyi 	USHORT usCount;
29176af099aSliuyi 	usCount = dwCount;
29276af099aSliuyi 	if(dwCount > MAX_ERASE_BLOCKS)
29376af099aSliuyi 		return ERR_CROSS_BORDER;
29476af099aSliuyi 
29576af099aSliuyi 	InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType);
29676af099aSliuyi 	cbw.ucCBWLUN = ucFlashCS;
29776af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
29876af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
29976af099aSliuyi 
30076af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
30176af099aSliuyi 	{
30276af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
30376af099aSliuyi 	}
30476af099aSliuyi 
30576af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
30676af099aSliuyi 	{
30776af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
30876af099aSliuyi 	}
30976af099aSliuyi 
31076af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
31176af099aSliuyi 		return ERR_CMD_NOTMATCH;
31276af099aSliuyi 
31376af099aSliuyi 	if(csw.ucCSWStatus == 1)
31476af099aSliuyi 		return ERR_FOUND_BAD_BLOCK;
31576af099aSliuyi 
31676af099aSliuyi 	return ERR_SUCCESS;
31776af099aSliuyi }
31876af099aSliuyi int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer)
31976af099aSliuyi {
32076af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
32176af099aSliuyi         if (m_log) {
32276af099aSliuyi             m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
32376af099aSliuyi         }
32476af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
32576af099aSliuyi     }
32676af099aSliuyi 
32776af099aSliuyi 	CBW cbw;
32876af099aSliuyi 	CSW csw;
32976af099aSliuyi 
33076af099aSliuyi 	InitializeCBW(&cbw, READ_CHIP_INFO);
331b5200da5Sliuyi 	cbw.dwCBWTransferLength = 16;
33276af099aSliuyi 
33376af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
33476af099aSliuyi 	{
33576af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
33676af099aSliuyi 	}
33776af099aSliuyi 
33876af099aSliuyi 	if(!RKU_Read(lpBuffer, 16))
33976af099aSliuyi 	{
34076af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
34176af099aSliuyi 	}
34276af099aSliuyi 
34376af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
34476af099aSliuyi 	{
34576af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
34676af099aSliuyi 	}
34776af099aSliuyi 
34876af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
34976af099aSliuyi 		return ERR_CMD_NOTMATCH;
35076af099aSliuyi 
35176af099aSliuyi 	return ERR_SUCCESS;
35276af099aSliuyi }
35376af099aSliuyi int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer)
35476af099aSliuyi {
35576af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
35676af099aSliuyi         if (m_log) {
35776af099aSliuyi             m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
35876af099aSliuyi         }
35976af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
36076af099aSliuyi     }
36176af099aSliuyi 
36276af099aSliuyi 	CBW cbw;
36376af099aSliuyi 	CSW csw;
36476af099aSliuyi 
36576af099aSliuyi 	InitializeCBW(&cbw, READ_FLASH_ID);
366b5200da5Sliuyi 	cbw.dwCBWTransferLength = 5;
36776af099aSliuyi 
36876af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
36976af099aSliuyi 	{
37076af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
37176af099aSliuyi 	}
37276af099aSliuyi 
37376af099aSliuyi 	if(!RKU_Read(lpBuffer, 5))
37476af099aSliuyi 	{
37576af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
37676af099aSliuyi 	}
37776af099aSliuyi 
37876af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
37976af099aSliuyi 	{
38076af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
38176af099aSliuyi 	}
38276af099aSliuyi 
38376af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
38476af099aSliuyi 		return ERR_CMD_NOTMATCH;
38576af099aSliuyi 
38676af099aSliuyi 	return ERR_SUCCESS;
38776af099aSliuyi }
38876af099aSliuyi int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead)
38976af099aSliuyi {
39076af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
39176af099aSliuyi         if (m_log) {
39276af099aSliuyi             m_log->Record("Error:RKU_ReadFlashInfo failed,device not support");
39376af099aSliuyi         }
39476af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
39576af099aSliuyi     }
39676af099aSliuyi 	CBW cbw;
39776af099aSliuyi 	CSW csw;
39876af099aSliuyi 
39976af099aSliuyi 	InitializeCBW(&cbw, READ_FLASH_INFO);
400b5200da5Sliuyi 	cbw.dwCBWTransferLength = 11;
40176af099aSliuyi 
40276af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
40376af099aSliuyi 	{
40476af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
40576af099aSliuyi 	}
40676af099aSliuyi 
40776af099aSliuyi 	DWORD dwRead;
40876af099aSliuyi 	dwRead = RKU_Read_EX(lpBuffer, 512);
40976af099aSliuyi 	if ((dwRead < 11) || (dwRead > 512))
41076af099aSliuyi 	{
41176af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
41276af099aSliuyi 	}
41376af099aSliuyi 	if (puiRead)
41476af099aSliuyi 	{
41576af099aSliuyi 		*puiRead = dwRead;
41676af099aSliuyi 	}
41776af099aSliuyi /*
41876af099aSliuyi 	if(!RKU_Read(hDev, lpBuffer, 11))
41976af099aSliuyi 	{
42076af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
42176af099aSliuyi 	}
42276af099aSliuyi */
42376af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
42476af099aSliuyi 	{
42576af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
42676af099aSliuyi 	}
42776af099aSliuyi 
42876af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
42976af099aSliuyi 		return ERR_CMD_NOTMATCH;
43076af099aSliuyi 
43176af099aSliuyi 	return ERR_SUCCESS;
43276af099aSliuyi }
433081d237aSliuyi int CRKUsbComm::RKU_ReadCapability(BYTE* lpBuffer)
434081d237aSliuyi {
435081d237aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
436081d237aSliuyi         if (m_log) {
437081d237aSliuyi             m_log->Record("Error:RKU_ReadCapability failed,device not support");
438081d237aSliuyi         }
439081d237aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
440081d237aSliuyi     }
441081d237aSliuyi 
442081d237aSliuyi 	CBW cbw;
443081d237aSliuyi 	CSW csw;
444081d237aSliuyi 	DWORD dwRead;
445081d237aSliuyi 
446081d237aSliuyi 	InitializeCBW(&cbw, READ_CAPABILITY);
447081d237aSliuyi 	cbw.dwCBWTransferLength = 8;
448081d237aSliuyi 
449081d237aSliuyi 	if(!RKU_Write((BYTE*)&cbw, sizeof(CBW)))
450081d237aSliuyi 	{
451081d237aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
452081d237aSliuyi 	}
453081d237aSliuyi 
454081d237aSliuyi 	dwRead = RKU_Read_EX((BYTE*)&csw, sizeof(CSW));
455081d237aSliuyi 
456081d237aSliuyi 	if(dwRead != 8)
457081d237aSliuyi 	{
458081d237aSliuyi 		return ERR_DEVICE_READ_FAILED;
459081d237aSliuyi 	}
460081d237aSliuyi 	memcpy(lpBuffer, (BYTE*)&csw, 8);
461081d237aSliuyi 
462081d237aSliuyi 	if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
463081d237aSliuyi 	{
464081d237aSliuyi 		return ERR_DEVICE_READ_FAILED;
465081d237aSliuyi 	}
466081d237aSliuyi 
467081d237aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
468081d237aSliuyi 		return ERR_CMD_NOTMATCH;
469081d237aSliuyi 
470081d237aSliuyi 	return ERR_SUCCESS;
471081d237aSliuyi }
472081d237aSliuyi 
47376af099aSliuyi int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
47476af099aSliuyi {
47576af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
47676af099aSliuyi         if (m_log) {
47776af099aSliuyi             m_log->Record("Error:RKU_ReadLBA failed,device not support");
47876af099aSliuyi         }
47976af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
48076af099aSliuyi     }
48176af099aSliuyi 	CBW cbw;
48276af099aSliuyi 	CSW csw;
48376af099aSliuyi 	USHORT wSectorSize;
48476af099aSliuyi 	USHORT usSectorLen;
48576af099aSliuyi 	wSectorSize = 512;
48676af099aSliuyi 	usSectorLen=dwCount;
48776af099aSliuyi 
48876af099aSliuyi 	InitializeCBW(&cbw, READ_LBA);
489b5200da5Sliuyi 	cbw.dwCBWTransferLength = dwCount * wSectorSize;
49076af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
49176af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen);
49276af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
49376af099aSliuyi 
49476af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
49576af099aSliuyi 	{
49676af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
49776af099aSliuyi 	}
49876af099aSliuyi 	DWORD dwTotal;
49976af099aSliuyi 	dwTotal = usSectorLen * wSectorSize;
50076af099aSliuyi 
50176af099aSliuyi 	if(!RKU_Read(lpBuffer, dwTotal))
50276af099aSliuyi 	{
50376af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
50476af099aSliuyi 	}
50576af099aSliuyi 
50676af099aSliuyi 	if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
50776af099aSliuyi 	{
50876af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
50976af099aSliuyi 	}
51076af099aSliuyi 
51176af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
51276af099aSliuyi 		return ERR_CMD_NOTMATCH;
51376af099aSliuyi 
51476af099aSliuyi 	if(csw.ucCSWStatus == 1)
51576af099aSliuyi 		return ERR_FAILED;
51676af099aSliuyi 
51776af099aSliuyi 	return ERR_SUCCESS;
51876af099aSliuyi }
51976af099aSliuyi 
52076af099aSliuyi int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode)
52176af099aSliuyi {
52276af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
52376af099aSliuyi         if (m_log) {
52476af099aSliuyi             m_log->Record("Error:RKU_ResetDevice failed,device not support");
52576af099aSliuyi         }
52676af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
52776af099aSliuyi     }
52876af099aSliuyi 
52976af099aSliuyi 	CBW cbw;
53076af099aSliuyi 	CSW csw;
53176af099aSliuyi 
53276af099aSliuyi 	InitializeCBW(&cbw, DEVICE_RESET);
53376af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
53476af099aSliuyi 
53576af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
53676af099aSliuyi 	{
53776af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
53876af099aSliuyi 	}
53976af099aSliuyi 
54076af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
54176af099aSliuyi 	{
54276af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
54376af099aSliuyi 	}
54476af099aSliuyi 
54576af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
54676af099aSliuyi 		bool bRet;
54776af099aSliuyi 		bRet = RKU_ClearBuffer(cbw, csw);
54876af099aSliuyi 		if (!bRet) {
54976af099aSliuyi 			return ERR_CMD_NOTMATCH;
55076af099aSliuyi 		}
55176af099aSliuyi 	}
55276af099aSliuyi 
55376af099aSliuyi 	if(csw.ucCSWStatus == 1)
55476af099aSliuyi 		return ERR_FAILED;
55576af099aSliuyi 
55676af099aSliuyi 	return ERR_SUCCESS;
55776af099aSliuyi }
55876af099aSliuyi 
559*554066a0SArnaud Mouiche int CRKUsbComm::RKU_ChangeStorage(BYTE storage)
560*554066a0SArnaud Mouiche {
561*554066a0SArnaud Mouiche     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
562*554066a0SArnaud Mouiche         if (m_log) {
563*554066a0SArnaud Mouiche             m_log->Record("Error:RKU_ChangeStorage failed,device not support");
564*554066a0SArnaud Mouiche         }
565*554066a0SArnaud Mouiche         return ERR_DEVICE_NOT_SUPPORT;
566*554066a0SArnaud Mouiche     }
567*554066a0SArnaud Mouiche 
568*554066a0SArnaud Mouiche 	CBW cbw;
569*554066a0SArnaud Mouiche 	CSW csw;
570*554066a0SArnaud Mouiche 
571*554066a0SArnaud Mouiche 	InitializeCBW(&cbw, CHANGE_STORAGE);
572*554066a0SArnaud Mouiche 	cbw.cbwcb.ucReserved = storage;
573*554066a0SArnaud Mouiche 
574*554066a0SArnaud Mouiche 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
575*554066a0SArnaud Mouiche 	{
576*554066a0SArnaud Mouiche 		printf("AMO: ERR_DEVICE_WRITE_FAILED\n");
577*554066a0SArnaud Mouiche 		return ERR_DEVICE_WRITE_FAILED;
578*554066a0SArnaud Mouiche 	}
579*554066a0SArnaud Mouiche 
580*554066a0SArnaud Mouiche 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
581*554066a0SArnaud Mouiche 	{
582*554066a0SArnaud Mouiche 		return ERR_DEVICE_READ_FAILED;
583*554066a0SArnaud Mouiche 	}
584*554066a0SArnaud Mouiche 
585*554066a0SArnaud Mouiche 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
586*554066a0SArnaud Mouiche 		bool bRet;
587*554066a0SArnaud Mouiche 		bRet = RKU_ClearBuffer(cbw, csw);
588*554066a0SArnaud Mouiche 		if (!bRet) {
589*554066a0SArnaud Mouiche 			return ERR_CMD_NOTMATCH;
590*554066a0SArnaud Mouiche 		}
591*554066a0SArnaud Mouiche 	}
592*554066a0SArnaud Mouiche 
593*554066a0SArnaud Mouiche 	if(csw.ucCSWStatus == 1)
594*554066a0SArnaud Mouiche 		return ERR_FAILED;
595*554066a0SArnaud Mouiche 
596*554066a0SArnaud Mouiche 	return ERR_SUCCESS;
597*554066a0SArnaud Mouiche }
598*554066a0SArnaud Mouiche 
599*554066a0SArnaud Mouiche int CRKUsbComm::RKU_ReadStorage(BYTE* storage)
600*554066a0SArnaud Mouiche {
601*554066a0SArnaud Mouiche     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
602*554066a0SArnaud Mouiche         if (m_log) {
603*554066a0SArnaud Mouiche             m_log->Record("Error:RKU_ReadCapability failed,device not support");
604*554066a0SArnaud Mouiche         }
605*554066a0SArnaud Mouiche         return ERR_DEVICE_NOT_SUPPORT;
606*554066a0SArnaud Mouiche     }
607*554066a0SArnaud Mouiche 
608*554066a0SArnaud Mouiche 	CBW cbw;
609*554066a0SArnaud Mouiche 	CSW csw;
610*554066a0SArnaud Mouiche 	DWORD dwRead;
611*554066a0SArnaud Mouiche 
612*554066a0SArnaud Mouiche 	InitializeCBW(&cbw, READ_STORAGE);
613*554066a0SArnaud Mouiche 	cbw.dwCBWTransferLength = 4;
614*554066a0SArnaud Mouiche 
615*554066a0SArnaud Mouiche 	if(!RKU_Write((BYTE*)&cbw, sizeof(CBW)))
616*554066a0SArnaud Mouiche 	{
617*554066a0SArnaud Mouiche 		return ERR_DEVICE_WRITE_FAILED;
618*554066a0SArnaud Mouiche 	}
619*554066a0SArnaud Mouiche 
620*554066a0SArnaud Mouiche 	DWORD storage_bits;
621*554066a0SArnaud Mouiche 	dwRead = RKU_Read_EX((BYTE*)&storage_bits, sizeof(storage_bits));
622*554066a0SArnaud Mouiche 
623*554066a0SArnaud Mouiche 	if(dwRead != 4)
624*554066a0SArnaud Mouiche 	{
625*554066a0SArnaud Mouiche 		return ERR_DEVICE_READ_FAILED;
626*554066a0SArnaud Mouiche 	}
627*554066a0SArnaud Mouiche 
628*554066a0SArnaud Mouiche 	if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
629*554066a0SArnaud Mouiche 	{
630*554066a0SArnaud Mouiche 		return ERR_DEVICE_READ_FAILED;
631*554066a0SArnaud Mouiche 	}
632*554066a0SArnaud Mouiche 
633*554066a0SArnaud Mouiche 	if( !UFI_CHECK_SIGN(cbw, csw) )
634*554066a0SArnaud Mouiche 		return ERR_CMD_NOTMATCH;
635*554066a0SArnaud Mouiche 
636*554066a0SArnaud Mouiche 	/* search the bit index */
637*554066a0SArnaud Mouiche 	*storage = 255;
638*554066a0SArnaud Mouiche 	for (unsigned i=0; i < 32; i++) {
639*554066a0SArnaud Mouiche 		if (storage_bits & (1<<i)) {
640*554066a0SArnaud Mouiche 			*storage = i;
641*554066a0SArnaud Mouiche 			break;
642*554066a0SArnaud Mouiche 		}
643*554066a0SArnaud Mouiche 	}
644*554066a0SArnaud Mouiche 	return ERR_SUCCESS;
645*554066a0SArnaud Mouiche }
646*554066a0SArnaud Mouiche 
647*554066a0SArnaud Mouiche 
64876af099aSliuyi int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode)
64976af099aSliuyi {
65076af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
65176af099aSliuyi         if (m_log) {
65276af099aSliuyi             m_log->Record("Error:RKU_TestDeviceReady failed,device not support");
65376af099aSliuyi         }
65476af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
65576af099aSliuyi     }
65676af099aSliuyi 	CBW cbw;
65776af099aSliuyi 	CSW csw;
65876af099aSliuyi 
65976af099aSliuyi 	InitializeCBW(&cbw, TEST_UNIT_READY);
66076af099aSliuyi 
66176af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
66276af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
66376af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
66476af099aSliuyi 	}
66576af099aSliuyi 
66676af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
66776af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
66876af099aSliuyi 	}
66976af099aSliuyi 
67076af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
67176af099aSliuyi 		bool bRet;
67276af099aSliuyi 		bRet = RKU_ClearBuffer(cbw ,csw);
67376af099aSliuyi 		if (!bRet) {
67476af099aSliuyi 			return ERR_CMD_NOTMATCH;
67576af099aSliuyi 		}
67676af099aSliuyi 	}
67776af099aSliuyi 
67876af099aSliuyi 	if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) {
67976af099aSliuyi 		*dwCurrent = (csw.dwCBWDataResidue >>16);
68076af099aSliuyi 		*dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF);
68176af099aSliuyi 
68276af099aSliuyi 		*dwTotal = EndianU16_BtoL(*dwTotal);
68376af099aSliuyi 		*dwCurrent = EndianU16_BtoL(*dwCurrent);
68476af099aSliuyi 	}
68576af099aSliuyi 	if(csw.ucCSWStatus == 1) {
68676af099aSliuyi 		return ERR_DEVICE_UNREADY;
68776af099aSliuyi 	}
68876af099aSliuyi 
68976af099aSliuyi 	return ERR_DEVICE_READY;
69076af099aSliuyi }
69176af099aSliuyi int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
69276af099aSliuyi {
69376af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
69476af099aSliuyi         if (m_log) {
69576af099aSliuyi             m_log->Record("Error:RKU_WriteLBA failed,device not support");
69676af099aSliuyi         }
69776af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
69876af099aSliuyi     }
69976af099aSliuyi 	CBW cbw;
70076af099aSliuyi 	CSW csw;
70176af099aSliuyi 	USHORT wSectorSize;
70276af099aSliuyi 	USHORT usCount;
70376af099aSliuyi 	wSectorSize = 512;
70476af099aSliuyi 	usCount = dwCount;
70576af099aSliuyi 	DWORD dwTotal = usCount * wSectorSize;
70676af099aSliuyi 
70776af099aSliuyi 	InitializeCBW(&cbw, WRITE_LBA);
708b5200da5Sliuyi 	cbw.dwCBWTransferLength = dwCount * wSectorSize;
70976af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
71076af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
71176af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
71276af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
71376af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
71476af099aSliuyi 	}
71576af099aSliuyi 
71676af099aSliuyi 	if(!RKU_Write( lpBuffer, dwTotal)) {
71776af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
71876af099aSliuyi 	}
71976af099aSliuyi 
72076af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
72176af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
72276af099aSliuyi 	}
72376af099aSliuyi 
72476af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
72576af099aSliuyi 		return ERR_CMD_NOTMATCH;
72676af099aSliuyi 
72776af099aSliuyi 	if(csw.ucCSWStatus == 1)
72876af099aSliuyi 		return ERR_FAILED;
72976af099aSliuyi 
73076af099aSliuyi 	return ERR_SUCCESS;
73176af099aSliuyi }
732c29e5f0fSliuyi int CRKUsbComm::RKU_EraseLBA(DWORD dwPos, DWORD dwCount)
733c29e5f0fSliuyi {
734c29e5f0fSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
735c29e5f0fSliuyi         if (m_log) {
736c29e5f0fSliuyi             m_log->Record("Error:RKU_WriteLBA failed,device not support");
737c29e5f0fSliuyi         }
738c29e5f0fSliuyi         return ERR_DEVICE_NOT_SUPPORT;
739c29e5f0fSliuyi     }
740c29e5f0fSliuyi 	CBW cbw;
741c29e5f0fSliuyi 	CSW csw;
742c29e5f0fSliuyi 	USHORT usCount;
743c29e5f0fSliuyi 	usCount = dwCount;
744c29e5f0fSliuyi 
745c29e5f0fSliuyi 
746c29e5f0fSliuyi 	InitializeCBW(&cbw, ERASE_LBA);
747c29e5f0fSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
748c29e5f0fSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
749c29e5f0fSliuyi 
750c29e5f0fSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
751c29e5f0fSliuyi 		return ERR_DEVICE_WRITE_FAILED;
752c29e5f0fSliuyi 	}
753c29e5f0fSliuyi 
754c29e5f0fSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
755c29e5f0fSliuyi 		return ERR_DEVICE_READ_FAILED;
756c29e5f0fSliuyi 	}
757c29e5f0fSliuyi 
758c29e5f0fSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
759c29e5f0fSliuyi 		return ERR_CMD_NOTMATCH;
760c29e5f0fSliuyi 
761c29e5f0fSliuyi 	if(csw.ucCSWStatus == 1)
762c29e5f0fSliuyi 		return ERR_FAILED;
763c29e5f0fSliuyi 
764c29e5f0fSliuyi 	return ERR_SUCCESS;
765c29e5f0fSliuyi }
766c29e5f0fSliuyi 
76776af099aSliuyi int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer)
76876af099aSliuyi {
76976af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
77076af099aSliuyi         if (m_log) {
77176af099aSliuyi             m_log->Record("Error:RKU_WriteSector failed,device not support");
77276af099aSliuyi         }
77376af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
77476af099aSliuyi     }
77576af099aSliuyi 	CBW cbw;
77676af099aSliuyi 	CSW csw;
77776af099aSliuyi 	USHORT wSectorSize;
77876af099aSliuyi 	USHORT usCount;
77976af099aSliuyi 	usCount=dwCount;
78076af099aSliuyi 	if(usCount > 32)
78176af099aSliuyi 		return ERR_CROSS_BORDER;
78276af099aSliuyi 
78376af099aSliuyi 	wSectorSize = 528;
78476af099aSliuyi 	InitializeCBW(&cbw, WRITE_SECTOR);
785b5200da5Sliuyi 	cbw.dwCBWTransferLength = dwCount * wSectorSize;
78676af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
78776af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
78876af099aSliuyi 
78976af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
79076af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
79176af099aSliuyi 	}
79276af099aSliuyi 
79376af099aSliuyi 	if(!RKU_Write( lpBuffer, usCount * wSectorSize)) {
79476af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
79576af099aSliuyi 	}
79676af099aSliuyi 
79776af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
79876af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
79976af099aSliuyi 	}
80076af099aSliuyi 
80176af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
80276af099aSliuyi 		return ERR_CMD_NOTMATCH;
80376af099aSliuyi 
80476af099aSliuyi 	if(csw.ucCSWStatus == 1)
80576af099aSliuyi 		return ERR_FAILED;
80676af099aSliuyi 
80776af099aSliuyi 	return ERR_SUCCESS;
80876af099aSliuyi }
80976af099aSliuyi 
81076af099aSliuyi 
81176af099aSliuyi int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize)
81276af099aSliuyi {
81376af099aSliuyi 	if (m_deviceDesc.emUsbType != RKUSB_MASKROM) {
81476af099aSliuyi 	    if (m_log) {
81576af099aSliuyi 	        m_log->Record("Error:RKU_DeviceRequest failed,device not support");
81676af099aSliuyi 	    }
81776af099aSliuyi 	    return ERR_DEVICE_NOT_SUPPORT;
81876af099aSliuyi 	}
81976af099aSliuyi 	if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) {
82076af099aSliuyi 		if (m_log) {
82176af099aSliuyi 	        m_log->Record("Error:RKU_DeviceRequest failed,request not support");
82276af099aSliuyi 	    }
82376af099aSliuyi 	    return ERR_REQUEST_NOT_SUPPORT;
82476af099aSliuyi 	}
82576af099aSliuyi 
82676af099aSliuyi 	bool bSendPendPacket = false;
82776af099aSliuyi 	USHORT crcValue = 0xffff;
82876af099aSliuyi 	BYTE *pData = NULL;
82976af099aSliuyi 	pData = new BYTE[dwDataSize + 5];
83076af099aSliuyi 	memset(pData, 0, dwDataSize + 5);
83176af099aSliuyi 	memcpy(pData, lpBuffer, dwDataSize);
83276af099aSliuyi 
83376af099aSliuyi 	switch(dwDataSize % 4096) {
83476af099aSliuyi 		case 4095:
83576af099aSliuyi 			++dwDataSize;
83676af099aSliuyi 			break;
83776af099aSliuyi 		case 4094:
83876af099aSliuyi 			bSendPendPacket = true;
83976af099aSliuyi 			break;
84076af099aSliuyi 		case 0:
84176af099aSliuyi 		default:
84276af099aSliuyi 			break;
84376af099aSliuyi 	}
84476af099aSliuyi 
84576af099aSliuyi 	crcValue = CRC_CCITT(pData, dwDataSize);
84676af099aSliuyi 	pData[dwDataSize] = (crcValue & 0xff00) >> 8;
84776af099aSliuyi 	pData[dwDataSize+1] = crcValue & 0x00ff;
84876af099aSliuyi 	dwDataSize += 2;
84976af099aSliuyi 
85076af099aSliuyi 	UINT nSendBytes = 0;
85176af099aSliuyi 	DWORD dwTotalSended = 0;
85276af099aSliuyi 	int iRet;
85376af099aSliuyi 
85476af099aSliuyi 	while(dwTotalSended < dwDataSize) {
85576af099aSliuyi 		nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended);
85676af099aSliuyi 		iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT);
85776af099aSliuyi 		if (iRet != (int)nSendBytes) {
85876af099aSliuyi 			if (m_log) {
85976af099aSliuyi 				m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet);
86076af099aSliuyi 			}
86176af099aSliuyi 			delete []pData;
86276af099aSliuyi 			return ERR_REQUEST_FAIL;
86376af099aSliuyi 		}
86476af099aSliuyi 		dwTotalSended += nSendBytes;
86576af099aSliuyi 	}
86676af099aSliuyi 
86776af099aSliuyi 	if(bSendPendPacket) {
86876af099aSliuyi 		BYTE ucFillByte = 0;
86976af099aSliuyi 		iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT);
87076af099aSliuyi 		if (iRet != 0) {
87176af099aSliuyi 			if (m_log) {
87276af099aSliuyi 				m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet);
87376af099aSliuyi 			}
87476af099aSliuyi 			delete []pData;
87576af099aSliuyi 			return ERR_REQUEST_FAIL;
87676af099aSliuyi 		}
87776af099aSliuyi 	}
87876af099aSliuyi 
87976af099aSliuyi 	delete []pData;
88076af099aSliuyi 
88176af099aSliuyi     return ERR_SUCCESS;
88276af099aSliuyi }
88376af099aSliuyi 
88476af099aSliuyi 
885