xref: /rkdeveloptool/RKComm.cpp (revision 76af099afcbcafd97801028de2ba3421d3c12865)
1*76af099aSliuyi /*
2*76af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
3*76af099aSliuyi  * Seth Liu 2017.03.01
4*76af099aSliuyi  *
5*76af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
6*76af099aSliuyi  */
7*76af099aSliuyi 
8*76af099aSliuyi #include "RKComm.h"
9*76af099aSliuyi #include "RKLog.h"
10*76af099aSliuyi #include "Endian.h"
11*76af099aSliuyi extern unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber);
12*76af099aSliuyi CRKComm::CRKComm(CRKLog *pLog)
13*76af099aSliuyi {
14*76af099aSliuyi 	memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC));
15*76af099aSliuyi 	m_log = pLog;
16*76af099aSliuyi }
17*76af099aSliuyi CRKComm::~CRKComm()
18*76af099aSliuyi {
19*76af099aSliuyi }
20*76af099aSliuyi 
21*76af099aSliuyi CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog)
22*76af099aSliuyi {
23*76af099aSliuyi 	bRet = InitializeUsb(devDesc);
24*76af099aSliuyi }
25*76af099aSliuyi CRKUsbComm::~CRKUsbComm()
26*76af099aSliuyi {
27*76af099aSliuyi 	UninitializeUsb();
28*76af099aSliuyi }
29*76af099aSliuyi 
30*76af099aSliuyi bool CRKUsbComm::InitializeUsb(STRUCT_RKDEVICE_DESC devDesc)
31*76af099aSliuyi {
32*76af099aSliuyi 	m_pUsbHandle = NULL;
33*76af099aSliuyi 	m_pipeBulkIn = m_pipeBulkOut = 0;
34*76af099aSliuyi 	m_interfaceNum = -1;
35*76af099aSliuyi 	if (!devDesc.pUsbHandle) {
36*76af099aSliuyi 		return false;
37*76af099aSliuyi 	}
38*76af099aSliuyi 	memcpy(&m_deviceDesc, &devDesc, sizeof(STRUCT_RKDEVICE_DESC));
39*76af099aSliuyi 	int iRet;
40*76af099aSliuyi 	iRet = libusb_open((libusb_device *)devDesc.pUsbHandle, (libusb_device_handle **)&m_pUsbHandle);
41*76af099aSliuyi 	if (iRet!=0) {
42*76af099aSliuyi 		if (m_log) {
43*76af099aSliuyi 			m_log->Record("Error:InitializeUsb-->open device failed,err=%d", iRet);
44*76af099aSliuyi 		}
45*76af099aSliuyi 		return false;
46*76af099aSliuyi 	}
47*76af099aSliuyi 	struct libusb_config_descriptor *pConfigDesc=NULL;
48*76af099aSliuyi 	iRet = libusb_get_active_config_descriptor((libusb_device *)devDesc.pUsbHandle, &pConfigDesc);
49*76af099aSliuyi 	if (iRet!=0) {
50*76af099aSliuyi 		if (m_log) {
51*76af099aSliuyi 			m_log->Record("Error:InitializeUsb-->get device config descriptor failed, err=%d", iRet);
52*76af099aSliuyi 		}
53*76af099aSliuyi 		return false;
54*76af099aSliuyi 	}
55*76af099aSliuyi 	int i, j, k;
56*76af099aSliuyi 	const struct libusb_interface *pInterface;
57*76af099aSliuyi 	const struct libusb_endpoint_descriptor *pEndpointDesc;
58*76af099aSliuyi 	const struct libusb_interface_descriptor *pInterfaceDesc;
59*76af099aSliuyi 	for(i = 0; i < pConfigDesc->bNumInterfaces; i++) {
60*76af099aSliuyi 		pInterface = pConfigDesc->interface + i;
61*76af099aSliuyi 		for(j = 0; j < pInterface->num_altsetting; j++) {
62*76af099aSliuyi 			pInterfaceDesc = pInterface->altsetting+j;
63*76af099aSliuyi 			if (m_deviceDesc.emUsbType == RKUSB_MSC) {
64*76af099aSliuyi 				if( (pInterfaceDesc->bInterfaceClass != 8) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 0x50))
65*76af099aSliuyi 					continue;
66*76af099aSliuyi 			}
67*76af099aSliuyi 			else
68*76af099aSliuyi 			{
69*76af099aSliuyi 				if( (pInterfaceDesc->bInterfaceClass != 0xff) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 5))
70*76af099aSliuyi 					continue;
71*76af099aSliuyi 			}
72*76af099aSliuyi 			for(k = 0; k < pInterfaceDesc->bNumEndpoints; k++) {
73*76af099aSliuyi 				pEndpointDesc = pInterfaceDesc->endpoint+k;
74*76af099aSliuyi 				if ((pEndpointDesc->bEndpointAddress & 0x80) == 0) {
75*76af099aSliuyi 					if (m_pipeBulkOut == 0)
76*76af099aSliuyi 						m_pipeBulkOut = pEndpointDesc->bEndpointAddress;
77*76af099aSliuyi 				}
78*76af099aSliuyi 				else {
79*76af099aSliuyi 					if (m_pipeBulkIn == 0)
80*76af099aSliuyi 						m_pipeBulkIn = pEndpointDesc->bEndpointAddress;
81*76af099aSliuyi 				}
82*76af099aSliuyi 				if ((m_pipeBulkIn != 0) && (m_pipeBulkOut != 0)) {//found it
83*76af099aSliuyi 					m_interfaceNum = i;
84*76af099aSliuyi 					libusb_free_config_descriptor(pConfigDesc);
85*76af099aSliuyi 					iRet = libusb_claim_interface((libusb_device_handle *)m_pUsbHandle, m_interfaceNum);
86*76af099aSliuyi 					if (iRet != 0) {
87*76af099aSliuyi 						if (m_log) {
88*76af099aSliuyi 					    	m_log->Record("Error:libusb_claim_interface failed,err=%d", iRet);
89*76af099aSliuyi 					    }
90*76af099aSliuyi 					    return false;
91*76af099aSliuyi 					}
92*76af099aSliuyi 					return true;
93*76af099aSliuyi 				}
94*76af099aSliuyi 			}
95*76af099aSliuyi 		}
96*76af099aSliuyi 	}
97*76af099aSliuyi 	libusb_free_config_descriptor(pConfigDesc);
98*76af099aSliuyi 	return false;
99*76af099aSliuyi }
100*76af099aSliuyi void CRKUsbComm::UninitializeUsb()
101*76af099aSliuyi {
102*76af099aSliuyi 	if (m_pUsbHandle) {
103*76af099aSliuyi 		libusb_close((libusb_device_handle *)m_pUsbHandle);
104*76af099aSliuyi 		m_pUsbHandle = NULL;
105*76af099aSliuyi 	}
106*76af099aSliuyi 	memset(&m_deviceDesc, 0, sizeof(STRUCT_RKDEVICE_DESC));
107*76af099aSliuyi 	m_pipeBulkIn = m_pipeBulkOut = 0;
108*76af099aSliuyi 	return ;
109*76af099aSliuyi }
110*76af099aSliuyi bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc)
111*76af099aSliuyi {
112*76af099aSliuyi     bool bRet;
113*76af099aSliuyi     UninitializeUsb();
114*76af099aSliuyi     bRet = InitializeUsb(devDesc);
115*76af099aSliuyi     return bRet;
116*76af099aSliuyi }
117*76af099aSliuyi bool CRKUsbComm::Reset_Usb_Device()
118*76af099aSliuyi {
119*76af099aSliuyi 	int iRet = -1;
120*76af099aSliuyi     if (m_pUsbHandle) {
121*76af099aSliuyi 		iRet=libusb_reset_device((libusb_device_handle *)m_pUsbHandle);
122*76af099aSliuyi 	}
123*76af099aSliuyi     return (iRet == 0) ? true : false;
124*76af099aSliuyi }
125*76af099aSliuyi 
126*76af099aSliuyi bool CRKUsbComm::RKU_Read(BYTE* lpBuffer, DWORD dwSize)
127*76af099aSliuyi {
128*76af099aSliuyi 	int  iRet;
129*76af099aSliuyi 	int  nRead;
130*76af099aSliuyi 	iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, CMD_TIMEOUT);
131*76af099aSliuyi 	if (iRet!=0) {
132*76af099aSliuyi 	    if (m_log) {
133*76af099aSliuyi 	        m_log->Record("Error:RKU_Read failed,err=%d", iRet);
134*76af099aSliuyi 	    }
135*76af099aSliuyi 	    return false;
136*76af099aSliuyi 	}
137*76af099aSliuyi 	if (nRead != (int)dwSize) {
138*76af099aSliuyi        	if (m_log) {
139*76af099aSliuyi             m_log->Record("Error:RKU_Read failed, size=%d, read=%d", dwSize, nRead);
140*76af099aSliuyi         }
141*76af099aSliuyi         return false;
142*76af099aSliuyi     }
143*76af099aSliuyi 	return true;
144*76af099aSliuyi }
145*76af099aSliuyi 
146*76af099aSliuyi bool CRKUsbComm::RKU_Write(BYTE* lpBuffer, DWORD dwSize)
147*76af099aSliuyi {
148*76af099aSliuyi 	int  iRet;
149*76af099aSliuyi 	int nWrite;
150*76af099aSliuyi 	iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkOut, lpBuffer, dwSize, &nWrite, CMD_TIMEOUT);
151*76af099aSliuyi 	if (iRet != 0) {
152*76af099aSliuyi 	    if (m_log) {
153*76af099aSliuyi 	        m_log->Record("Error:RKU_Write failed, err=%d", iRet);
154*76af099aSliuyi 	    }
155*76af099aSliuyi 	    return false;
156*76af099aSliuyi 	}
157*76af099aSliuyi     if (nWrite != (int)dwSize) {
158*76af099aSliuyi        	if (m_log) {
159*76af099aSliuyi         	m_log->Record("Error:RKU_Write failed, size=%d, read=%d", dwSize, nWrite);
160*76af099aSliuyi     	}
161*76af099aSliuyi         return false;
162*76af099aSliuyi     }
163*76af099aSliuyi 	return true;
164*76af099aSliuyi }
165*76af099aSliuyi int CRKUsbComm::RandomInteger(int low, int high)
166*76af099aSliuyi {
167*76af099aSliuyi 	int k;
168*76af099aSliuyi 	double d;
169*76af099aSliuyi 
170*76af099aSliuyi 	d = (double)rand() / ((double)RAND_MAX + 1);
171*76af099aSliuyi 	k = (int)(d * (high - low + 1));
172*76af099aSliuyi 	return (low + k);
173*76af099aSliuyi }
174*76af099aSliuyi DWORD CRKUsbComm::MakeCBWTag()
175*76af099aSliuyi {
176*76af099aSliuyi 	DWORD tag = 0;
177*76af099aSliuyi 	int i = 0;
178*76af099aSliuyi 
179*76af099aSliuyi 	for(i=0; i<4; i++){
180*76af099aSliuyi 		tag <<= 8;
181*76af099aSliuyi 		tag += RandomInteger(0, 0xFF);
182*76af099aSliuyi 	}
183*76af099aSliuyi 	return tag;
184*76af099aSliuyi }
185*76af099aSliuyi void CRKUsbComm::InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code)
186*76af099aSliuyi {
187*76af099aSliuyi 	memset(pCBW,0, sizeof(CBW));
188*76af099aSliuyi 
189*76af099aSliuyi 	pCBW->dwCBWSignature = CBW_SIGN;
190*76af099aSliuyi 	pCBW->dwCBWTag = MakeCBWTag();
191*76af099aSliuyi 	pCBW->cbwcb.ucOperCode = code;
192*76af099aSliuyi 
193*76af099aSliuyi 	switch(code) {
194*76af099aSliuyi 		case TEST_UNIT_READY:	/* Test Unit Ready	: 0 */
195*76af099aSliuyi 		case READ_FLASH_ID:		/* Read Flash ID	: 1 */
196*76af099aSliuyi 		case READ_FLASH_INFO:
197*76af099aSliuyi 		case READ_CHIP_INFO:
198*76af099aSliuyi 		case READ_EFUSE:
199*76af099aSliuyi 			pCBW->ucCBWFlags= DIRECTION_IN;
200*76af099aSliuyi 			pCBW->ucCBWCBLength = 0x06;
201*76af099aSliuyi 			break;
202*76af099aSliuyi 		case DEVICE_RESET:		/* Reset Device		: 0xff */
203*76af099aSliuyi 		case ERASE_SYSTEMDISK:
204*76af099aSliuyi 		case SET_RESET_FLAG:
205*76af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_OUT;
206*76af099aSliuyi 			pCBW->ucCBWCBLength = 0x06;
207*76af099aSliuyi 			break;
208*76af099aSliuyi 		case TEST_BAD_BLOCK:	/* Test Bad Block	: 3 */
209*76af099aSliuyi 		case READ_SECTOR:		/* Read Pages		: 4 */
210*76af099aSliuyi 		case READ_LBA:		/* Read Pages		: 4 */
211*76af099aSliuyi 		case READ_SDRAM:		/* Write Pages		: 15 */
212*76af099aSliuyi 		case READ_SPI_FLASH:
213*76af099aSliuyi 		case READ_NEW_EFUSE:
214*76af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_IN;
215*76af099aSliuyi 			pCBW->ucCBWCBLength = 0x0a;
216*76af099aSliuyi 			break;
217*76af099aSliuyi 		case WRITE_SECTOR:		/* Write Pages		: 5 */
218*76af099aSliuyi 		case WRITE_LBA:		/* Write Pages		: 15 */
219*76af099aSliuyi 		case WRITE_SDRAM:		/* Write Pages		: 15 */
220*76af099aSliuyi 		case EXECUTE_SDRAM:
221*76af099aSliuyi 		case ERASE_NORMAL:		/* Erase Blocks		: 6 */
222*76af099aSliuyi 		case ERASE_FORCE:		/* Read Spare		: 11 */
223*76af099aSliuyi 		case WRITE_EFUSE:
224*76af099aSliuyi 		case WRITE_SPI_FLASH:
225*76af099aSliuyi 		case WRITE_NEW_EFUSE:
226*76af099aSliuyi 			pCBW->ucCBWFlags = DIRECTION_OUT;
227*76af099aSliuyi 			pCBW->ucCBWCBLength = 0x0a;
228*76af099aSliuyi 			break;
229*76af099aSliuyi 		default:
230*76af099aSliuyi 			break;
231*76af099aSliuyi 	}
232*76af099aSliuyi }
233*76af099aSliuyi 
234*76af099aSliuyi 
235*76af099aSliuyi bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw)
236*76af099aSliuyi {
237*76af099aSliuyi 	DWORD dwReadBytes=0;
238*76af099aSliuyi 	DWORD dwTotalRead=0;
239*76af099aSliuyi 	int iTryCount;
240*76af099aSliuyi 	iTryCount = 3;
241*76af099aSliuyi 	do {
242*76af099aSliuyi 		dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) );
243*76af099aSliuyi 
244*76af099aSliuyi 		if (UFI_CHECK_SIGN(cbw,csw))
245*76af099aSliuyi 		{
246*76af099aSliuyi 			return true;
247*76af099aSliuyi 		}
248*76af099aSliuyi 		if (dwReadBytes != sizeof(CSW))
249*76af099aSliuyi 		{
250*76af099aSliuyi 			iTryCount--;
251*76af099aSliuyi 			sleep(3);
252*76af099aSliuyi 		}
253*76af099aSliuyi 		dwTotalRead += dwReadBytes;
254*76af099aSliuyi 		if (dwTotalRead >= MAX_CLEAR_LEN)
255*76af099aSliuyi 		{
256*76af099aSliuyi 			break;
257*76af099aSliuyi 		}
258*76af099aSliuyi 	}while ( iTryCount > 0 );
259*76af099aSliuyi 	return false;
260*76af099aSliuyi }
261*76af099aSliuyi 
262*76af099aSliuyi DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize)
263*76af099aSliuyi {
264*76af099aSliuyi 	int  iRet;
265*76af099aSliuyi 	int  nRead;
266*76af099aSliuyi 	iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000);
267*76af099aSliuyi 	if (iRet != 0) {
268*76af099aSliuyi 	    if (m_log) {
269*76af099aSliuyi 	        m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet);
270*76af099aSliuyi 	    }
271*76af099aSliuyi 	    return 0;
272*76af099aSliuyi 	}
273*76af099aSliuyi 	return nRead;
274*76af099aSliuyi }
275*76af099aSliuyi 
276*76af099aSliuyi int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType)
277*76af099aSliuyi {
278*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
279*76af099aSliuyi         if (m_log) {
280*76af099aSliuyi             m_log->Record("Error:RKU_EraseBlock failed,device not support");
281*76af099aSliuyi         }
282*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
283*76af099aSliuyi     }
284*76af099aSliuyi 	CBW cbw;
285*76af099aSliuyi 	CSW csw;
286*76af099aSliuyi 	USHORT usCount;
287*76af099aSliuyi 	usCount = dwCount;
288*76af099aSliuyi 	if(dwCount > MAX_ERASE_BLOCKS)
289*76af099aSliuyi 		return ERR_CROSS_BORDER;
290*76af099aSliuyi 
291*76af099aSliuyi 	InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType);
292*76af099aSliuyi 	cbw.ucCBWLUN = ucFlashCS;
293*76af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
294*76af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
295*76af099aSliuyi 
296*76af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
297*76af099aSliuyi 	{
298*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
299*76af099aSliuyi 	}
300*76af099aSliuyi 
301*76af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
302*76af099aSliuyi 	{
303*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
304*76af099aSliuyi 	}
305*76af099aSliuyi 
306*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
307*76af099aSliuyi 		return ERR_CMD_NOTMATCH;
308*76af099aSliuyi 
309*76af099aSliuyi 	if(csw.ucCSWStatus == 1)
310*76af099aSliuyi 		return ERR_FOUND_BAD_BLOCK;
311*76af099aSliuyi 
312*76af099aSliuyi 	return ERR_SUCCESS;
313*76af099aSliuyi }
314*76af099aSliuyi int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer)
315*76af099aSliuyi {
316*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
317*76af099aSliuyi         if (m_log) {
318*76af099aSliuyi             m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
319*76af099aSliuyi         }
320*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
321*76af099aSliuyi     }
322*76af099aSliuyi 
323*76af099aSliuyi 	CBW cbw;
324*76af099aSliuyi 	CSW csw;
325*76af099aSliuyi 
326*76af099aSliuyi 	InitializeCBW(&cbw, READ_CHIP_INFO);
327*76af099aSliuyi 
328*76af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
329*76af099aSliuyi 	{
330*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
331*76af099aSliuyi 	}
332*76af099aSliuyi 
333*76af099aSliuyi 	if(!RKU_Read(lpBuffer, 16))
334*76af099aSliuyi 	{
335*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
336*76af099aSliuyi 	}
337*76af099aSliuyi 
338*76af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
339*76af099aSliuyi 	{
340*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
341*76af099aSliuyi 	}
342*76af099aSliuyi 
343*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
344*76af099aSliuyi 		return ERR_CMD_NOTMATCH;
345*76af099aSliuyi 
346*76af099aSliuyi 	return ERR_SUCCESS;
347*76af099aSliuyi }
348*76af099aSliuyi int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer)
349*76af099aSliuyi {
350*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
351*76af099aSliuyi         if (m_log) {
352*76af099aSliuyi             m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
353*76af099aSliuyi         }
354*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
355*76af099aSliuyi     }
356*76af099aSliuyi 
357*76af099aSliuyi 	CBW cbw;
358*76af099aSliuyi 	CSW csw;
359*76af099aSliuyi 
360*76af099aSliuyi 	InitializeCBW(&cbw, READ_FLASH_ID);
361*76af099aSliuyi 
362*76af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
363*76af099aSliuyi 	{
364*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
365*76af099aSliuyi 	}
366*76af099aSliuyi 
367*76af099aSliuyi 	if(!RKU_Read(lpBuffer, 5))
368*76af099aSliuyi 	{
369*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
370*76af099aSliuyi 	}
371*76af099aSliuyi 
372*76af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
373*76af099aSliuyi 	{
374*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
375*76af099aSliuyi 	}
376*76af099aSliuyi 
377*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
378*76af099aSliuyi 		return ERR_CMD_NOTMATCH;
379*76af099aSliuyi 
380*76af099aSliuyi 	return ERR_SUCCESS;
381*76af099aSliuyi }
382*76af099aSliuyi int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead)
383*76af099aSliuyi {
384*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
385*76af099aSliuyi         if (m_log) {
386*76af099aSliuyi             m_log->Record("Error:RKU_ReadFlashInfo failed,device not support");
387*76af099aSliuyi         }
388*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
389*76af099aSliuyi     }
390*76af099aSliuyi 	CBW cbw;
391*76af099aSliuyi 	CSW csw;
392*76af099aSliuyi 
393*76af099aSliuyi 	InitializeCBW(&cbw, READ_FLASH_INFO);
394*76af099aSliuyi 
395*76af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
396*76af099aSliuyi 	{
397*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
398*76af099aSliuyi 	}
399*76af099aSliuyi 
400*76af099aSliuyi 	DWORD dwRead;
401*76af099aSliuyi 	dwRead = RKU_Read_EX(lpBuffer, 512);
402*76af099aSliuyi 	if ((dwRead < 11) || (dwRead > 512))
403*76af099aSliuyi 	{
404*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
405*76af099aSliuyi 	}
406*76af099aSliuyi 	if (puiRead)
407*76af099aSliuyi 	{
408*76af099aSliuyi 		*puiRead = dwRead;
409*76af099aSliuyi 	}
410*76af099aSliuyi /*
411*76af099aSliuyi 	if(!RKU_Read(hDev, lpBuffer, 11))
412*76af099aSliuyi 	{
413*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
414*76af099aSliuyi 	}
415*76af099aSliuyi */
416*76af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
417*76af099aSliuyi 	{
418*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
419*76af099aSliuyi 	}
420*76af099aSliuyi 
421*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
422*76af099aSliuyi 		return ERR_CMD_NOTMATCH;
423*76af099aSliuyi 
424*76af099aSliuyi 	return ERR_SUCCESS;
425*76af099aSliuyi }
426*76af099aSliuyi int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
427*76af099aSliuyi {
428*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
429*76af099aSliuyi         if (m_log) {
430*76af099aSliuyi             m_log->Record("Error:RKU_ReadLBA failed,device not support");
431*76af099aSliuyi         }
432*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
433*76af099aSliuyi     }
434*76af099aSliuyi 	CBW cbw;
435*76af099aSliuyi 	CSW csw;
436*76af099aSliuyi 	USHORT wSectorSize;
437*76af099aSliuyi 	USHORT usSectorLen;
438*76af099aSliuyi 	wSectorSize = 512;
439*76af099aSliuyi 	usSectorLen=dwCount;
440*76af099aSliuyi 
441*76af099aSliuyi 	InitializeCBW(&cbw, READ_LBA);
442*76af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
443*76af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen);
444*76af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
445*76af099aSliuyi 
446*76af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
447*76af099aSliuyi 	{
448*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
449*76af099aSliuyi 	}
450*76af099aSliuyi 	DWORD dwTotal;
451*76af099aSliuyi 	dwTotal = usSectorLen * wSectorSize;
452*76af099aSliuyi 
453*76af099aSliuyi 	if(!RKU_Read(lpBuffer, dwTotal))
454*76af099aSliuyi 	{
455*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
456*76af099aSliuyi 	}
457*76af099aSliuyi 
458*76af099aSliuyi 	if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
459*76af099aSliuyi 	{
460*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
461*76af099aSliuyi 	}
462*76af099aSliuyi 
463*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
464*76af099aSliuyi 		return ERR_CMD_NOTMATCH;
465*76af099aSliuyi 
466*76af099aSliuyi 	if(csw.ucCSWStatus == 1)
467*76af099aSliuyi 		return ERR_FAILED;
468*76af099aSliuyi 
469*76af099aSliuyi 	return ERR_SUCCESS;
470*76af099aSliuyi }
471*76af099aSliuyi 
472*76af099aSliuyi int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode)
473*76af099aSliuyi {
474*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
475*76af099aSliuyi         if (m_log) {
476*76af099aSliuyi             m_log->Record("Error:RKU_ResetDevice failed,device not support");
477*76af099aSliuyi         }
478*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
479*76af099aSliuyi     }
480*76af099aSliuyi 
481*76af099aSliuyi 	CBW cbw;
482*76af099aSliuyi 	CSW csw;
483*76af099aSliuyi 
484*76af099aSliuyi 	InitializeCBW(&cbw, DEVICE_RESET);
485*76af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
486*76af099aSliuyi 
487*76af099aSliuyi 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
488*76af099aSliuyi 	{
489*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
490*76af099aSliuyi 	}
491*76af099aSliuyi 
492*76af099aSliuyi 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
493*76af099aSliuyi 	{
494*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
495*76af099aSliuyi 	}
496*76af099aSliuyi 
497*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
498*76af099aSliuyi 		bool bRet;
499*76af099aSliuyi 		bRet = RKU_ClearBuffer(cbw, csw);
500*76af099aSliuyi 		if (!bRet) {
501*76af099aSliuyi 			return ERR_CMD_NOTMATCH;
502*76af099aSliuyi 		}
503*76af099aSliuyi 	}
504*76af099aSliuyi 
505*76af099aSliuyi 	if(csw.ucCSWStatus == 1)
506*76af099aSliuyi 		return ERR_FAILED;
507*76af099aSliuyi 
508*76af099aSliuyi 	return ERR_SUCCESS;
509*76af099aSliuyi }
510*76af099aSliuyi 
511*76af099aSliuyi int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode)
512*76af099aSliuyi {
513*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
514*76af099aSliuyi         if (m_log) {
515*76af099aSliuyi             m_log->Record("Error:RKU_TestDeviceReady failed,device not support");
516*76af099aSliuyi         }
517*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
518*76af099aSliuyi     }
519*76af099aSliuyi 	CBW cbw;
520*76af099aSliuyi 	CSW csw;
521*76af099aSliuyi 
522*76af099aSliuyi 	InitializeCBW(&cbw, TEST_UNIT_READY);
523*76af099aSliuyi 
524*76af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
525*76af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
526*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
527*76af099aSliuyi 	}
528*76af099aSliuyi 
529*76af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
530*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
531*76af099aSliuyi 	}
532*76af099aSliuyi 
533*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
534*76af099aSliuyi 		bool bRet;
535*76af099aSliuyi 		bRet = RKU_ClearBuffer(cbw ,csw);
536*76af099aSliuyi 		if (!bRet) {
537*76af099aSliuyi 			return ERR_CMD_NOTMATCH;
538*76af099aSliuyi 		}
539*76af099aSliuyi 	}
540*76af099aSliuyi 
541*76af099aSliuyi 	if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) {
542*76af099aSliuyi 		*dwCurrent = (csw.dwCBWDataResidue >>16);
543*76af099aSliuyi 		*dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF);
544*76af099aSliuyi 
545*76af099aSliuyi 		*dwTotal = EndianU16_BtoL(*dwTotal);
546*76af099aSliuyi 		*dwCurrent = EndianU16_BtoL(*dwCurrent);
547*76af099aSliuyi 	}
548*76af099aSliuyi 	if(csw.ucCSWStatus == 1) {
549*76af099aSliuyi 		return ERR_DEVICE_UNREADY;
550*76af099aSliuyi 	}
551*76af099aSliuyi 
552*76af099aSliuyi 	return ERR_DEVICE_READY;
553*76af099aSliuyi }
554*76af099aSliuyi int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
555*76af099aSliuyi {
556*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
557*76af099aSliuyi         if (m_log) {
558*76af099aSliuyi             m_log->Record("Error:RKU_WriteLBA failed,device not support");
559*76af099aSliuyi         }
560*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
561*76af099aSliuyi     }
562*76af099aSliuyi 	CBW cbw;
563*76af099aSliuyi 	CSW csw;
564*76af099aSliuyi 	USHORT wSectorSize;
565*76af099aSliuyi 	USHORT usCount;
566*76af099aSliuyi 	wSectorSize = 512;
567*76af099aSliuyi 	usCount = dwCount;
568*76af099aSliuyi 	DWORD dwTotal = usCount * wSectorSize;
569*76af099aSliuyi 
570*76af099aSliuyi 	InitializeCBW(&cbw, WRITE_LBA);
571*76af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
572*76af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
573*76af099aSliuyi 	cbw.cbwcb.ucReserved = bySubCode;
574*76af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
575*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
576*76af099aSliuyi 	}
577*76af099aSliuyi 
578*76af099aSliuyi 	if(!RKU_Write( lpBuffer, dwTotal)) {
579*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
580*76af099aSliuyi 	}
581*76af099aSliuyi 
582*76af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
583*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
584*76af099aSliuyi 	}
585*76af099aSliuyi 
586*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
587*76af099aSliuyi 		return ERR_CMD_NOTMATCH;
588*76af099aSliuyi 
589*76af099aSliuyi 	if(csw.ucCSWStatus == 1)
590*76af099aSliuyi 		return ERR_FAILED;
591*76af099aSliuyi 
592*76af099aSliuyi 	return ERR_SUCCESS;
593*76af099aSliuyi }
594*76af099aSliuyi int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer)
595*76af099aSliuyi {
596*76af099aSliuyi     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
597*76af099aSliuyi         if (m_log) {
598*76af099aSliuyi             m_log->Record("Error:RKU_WriteSector failed,device not support");
599*76af099aSliuyi         }
600*76af099aSliuyi         return ERR_DEVICE_NOT_SUPPORT;
601*76af099aSliuyi     }
602*76af099aSliuyi 	CBW cbw;
603*76af099aSliuyi 	CSW csw;
604*76af099aSliuyi 	USHORT wSectorSize;
605*76af099aSliuyi 	USHORT usCount;
606*76af099aSliuyi 	usCount=dwCount;
607*76af099aSliuyi 	if(usCount > 32)
608*76af099aSliuyi 		return ERR_CROSS_BORDER;
609*76af099aSliuyi 
610*76af099aSliuyi 	wSectorSize = 528;
611*76af099aSliuyi 	InitializeCBW(&cbw, WRITE_SECTOR);
612*76af099aSliuyi 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
613*76af099aSliuyi 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
614*76af099aSliuyi 
615*76af099aSliuyi 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
616*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
617*76af099aSliuyi 	}
618*76af099aSliuyi 
619*76af099aSliuyi 	if(!RKU_Write( lpBuffer, usCount * wSectorSize)) {
620*76af099aSliuyi 		return ERR_DEVICE_WRITE_FAILED;
621*76af099aSliuyi 	}
622*76af099aSliuyi 
623*76af099aSliuyi 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
624*76af099aSliuyi 		return ERR_DEVICE_READ_FAILED;
625*76af099aSliuyi 	}
626*76af099aSliuyi 
627*76af099aSliuyi 	if( !UFI_CHECK_SIGN(cbw, csw) )
628*76af099aSliuyi 		return ERR_CMD_NOTMATCH;
629*76af099aSliuyi 
630*76af099aSliuyi 	if(csw.ucCSWStatus == 1)
631*76af099aSliuyi 		return ERR_FAILED;
632*76af099aSliuyi 
633*76af099aSliuyi 	return ERR_SUCCESS;
634*76af099aSliuyi }
635*76af099aSliuyi 
636*76af099aSliuyi 
637*76af099aSliuyi int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize)
638*76af099aSliuyi {
639*76af099aSliuyi 	if (m_deviceDesc.emUsbType != RKUSB_MASKROM) {
640*76af099aSliuyi 	    if (m_log) {
641*76af099aSliuyi 	        m_log->Record("Error:RKU_DeviceRequest failed,device not support");
642*76af099aSliuyi 	    }
643*76af099aSliuyi 	    return ERR_DEVICE_NOT_SUPPORT;
644*76af099aSliuyi 	}
645*76af099aSliuyi 	if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) {
646*76af099aSliuyi 		if (m_log) {
647*76af099aSliuyi 	        m_log->Record("Error:RKU_DeviceRequest failed,request not support");
648*76af099aSliuyi 	    }
649*76af099aSliuyi 	    return ERR_REQUEST_NOT_SUPPORT;
650*76af099aSliuyi 	}
651*76af099aSliuyi 
652*76af099aSliuyi 	bool bSendPendPacket = false;
653*76af099aSliuyi 	USHORT crcValue = 0xffff;
654*76af099aSliuyi 	BYTE *pData = NULL;
655*76af099aSliuyi 	pData = new BYTE[dwDataSize + 5];
656*76af099aSliuyi 	memset(pData, 0, dwDataSize + 5);
657*76af099aSliuyi 	memcpy(pData, lpBuffer, dwDataSize);
658*76af099aSliuyi 
659*76af099aSliuyi 	switch(dwDataSize % 4096) {
660*76af099aSliuyi 		case 4095:
661*76af099aSliuyi 			++dwDataSize;
662*76af099aSliuyi 			break;
663*76af099aSliuyi 		case 4094:
664*76af099aSliuyi 			bSendPendPacket = true;
665*76af099aSliuyi 			break;
666*76af099aSliuyi 		case 0:
667*76af099aSliuyi 		default:
668*76af099aSliuyi 			break;
669*76af099aSliuyi 	}
670*76af099aSliuyi 
671*76af099aSliuyi 	crcValue = CRC_CCITT(pData, dwDataSize);
672*76af099aSliuyi 	pData[dwDataSize] = (crcValue & 0xff00) >> 8;
673*76af099aSliuyi 	pData[dwDataSize+1] = crcValue & 0x00ff;
674*76af099aSliuyi 	dwDataSize += 2;
675*76af099aSliuyi 
676*76af099aSliuyi 	UINT nSendBytes = 0;
677*76af099aSliuyi 	DWORD dwTotalSended = 0;
678*76af099aSliuyi 	int iRet;
679*76af099aSliuyi 
680*76af099aSliuyi 	while(dwTotalSended < dwDataSize) {
681*76af099aSliuyi 		nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended);
682*76af099aSliuyi 		iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT);
683*76af099aSliuyi 		if (iRet != (int)nSendBytes) {
684*76af099aSliuyi 			if (m_log) {
685*76af099aSliuyi 				m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet);
686*76af099aSliuyi 			}
687*76af099aSliuyi 			delete []pData;
688*76af099aSliuyi 			return ERR_REQUEST_FAIL;
689*76af099aSliuyi 		}
690*76af099aSliuyi 		dwTotalSended += nSendBytes;
691*76af099aSliuyi 	}
692*76af099aSliuyi 
693*76af099aSliuyi 	if(bSendPendPacket) {
694*76af099aSliuyi 		BYTE ucFillByte = 0;
695*76af099aSliuyi 		iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT);
696*76af099aSliuyi 		if (iRet != 0) {
697*76af099aSliuyi 			if (m_log) {
698*76af099aSliuyi 				m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet);
699*76af099aSliuyi 			}
700*76af099aSliuyi 			delete []pData;
701*76af099aSliuyi 			return ERR_REQUEST_FAIL;
702*76af099aSliuyi 		}
703*76af099aSliuyi 	}
704*76af099aSliuyi 
705*76af099aSliuyi 	delete []pData;
706*76af099aSliuyi 
707*76af099aSliuyi     return ERR_SUCCESS;
708*76af099aSliuyi }
709*76af099aSliuyi 
710*76af099aSliuyi 
711