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