xref: /rkdeveloptool/RKComm.cpp (revision c29e5f0fb3abaf1286e0478b8fc93c6c4f41dd53)
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);
12 CRKComm::CRKComm(CRKLog *pLog)
13 {
14 	memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC));
15 	m_log = pLog;
16 }
17 CRKComm::~CRKComm()
18 {
19 }
20 
21 CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog)
22 {
23 	bRet = InitializeUsb(devDesc);
24 }
25 CRKUsbComm::~CRKUsbComm()
26 {
27 	UninitializeUsb();
28 }
29 
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 }
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 }
110 bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc)
111 {
112     bool bRet;
113     UninitializeUsb();
114     bRet = InitializeUsb(devDesc);
115     return bRet;
116 }
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 
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 
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 }
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 }
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 }
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 			pCBW->ucCBWFlags= DIRECTION_IN;
200 			pCBW->ucCBWCBLength = 0x06;
201 			break;
202 		case DEVICE_RESET:		/* Reset Device		: 0xff */
203 		case ERASE_SYSTEMDISK:
204 		case SET_RESET_FLAG:
205 			pCBW->ucCBWFlags = DIRECTION_OUT;
206 			pCBW->ucCBWCBLength = 0x06;
207 			break;
208 		case TEST_BAD_BLOCK:	/* Test Bad Block	: 3 */
209 		case READ_SECTOR:		/* Read Pages		: 4 */
210 		case READ_LBA:		/* Read Pages		: 4 */
211 		case READ_SDRAM:		/* Write Pages		: 15 */
212 		case READ_SPI_FLASH:
213 		case READ_NEW_EFUSE:
214 			pCBW->ucCBWFlags = DIRECTION_IN;
215 			pCBW->ucCBWCBLength = 0x0a;
216 			break;
217 		case WRITE_SECTOR:		/* Write Pages		: 5 */
218 		case WRITE_LBA:		/* Write Pages		: 15 */
219 		case WRITE_SDRAM:		/* Write Pages		: 15 */
220 		case EXECUTE_SDRAM:
221 		case ERASE_NORMAL:		/* Erase Blocks		: 6 */
222 		case ERASE_FORCE:		/* Read Spare		: 11 */
223 		case WRITE_EFUSE:
224 		case WRITE_SPI_FLASH:
225 		case WRITE_NEW_EFUSE:
226 		case ERASE_LBA:
227 			pCBW->ucCBWFlags = DIRECTION_OUT;
228 			pCBW->ucCBWCBLength = 0x0a;
229 			break;
230 		default:
231 			break;
232 	}
233 }
234 
235 
236 bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw)
237 {
238 	DWORD dwReadBytes=0;
239 	DWORD dwTotalRead=0;
240 	int iTryCount;
241 	iTryCount = 3;
242 	do {
243 		dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) );
244 
245 		if (UFI_CHECK_SIGN(cbw,csw))
246 		{
247 			return true;
248 		}
249 		if (dwReadBytes != sizeof(CSW))
250 		{
251 			iTryCount--;
252 			sleep(3);
253 		}
254 		dwTotalRead += dwReadBytes;
255 		if (dwTotalRead >= MAX_CLEAR_LEN)
256 		{
257 			break;
258 		}
259 	}while ( iTryCount > 0 );
260 	return false;
261 }
262 
263 DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize)
264 {
265 	int  iRet;
266 	int  nRead;
267 	iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000);
268 	if (iRet != 0) {
269 	    if (m_log) {
270 	        m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet);
271 	    }
272 	    return 0;
273 	}
274 	return nRead;
275 }
276 
277 int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType)
278 {
279     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
280         if (m_log) {
281             m_log->Record("Error:RKU_EraseBlock failed,device not support");
282         }
283         return ERR_DEVICE_NOT_SUPPORT;
284     }
285 	CBW cbw;
286 	CSW csw;
287 	USHORT usCount;
288 	usCount = dwCount;
289 	if(dwCount > MAX_ERASE_BLOCKS)
290 		return ERR_CROSS_BORDER;
291 
292 	InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType);
293 	cbw.ucCBWLUN = ucFlashCS;
294 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
295 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
296 
297 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
298 	{
299 		return ERR_DEVICE_WRITE_FAILED;
300 	}
301 
302 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
303 	{
304 		return ERR_DEVICE_READ_FAILED;
305 	}
306 
307 	if( !UFI_CHECK_SIGN(cbw, csw) )
308 		return ERR_CMD_NOTMATCH;
309 
310 	if(csw.ucCSWStatus == 1)
311 		return ERR_FOUND_BAD_BLOCK;
312 
313 	return ERR_SUCCESS;
314 }
315 int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer)
316 {
317     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
318         if (m_log) {
319             m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
320         }
321         return ERR_DEVICE_NOT_SUPPORT;
322     }
323 
324 	CBW cbw;
325 	CSW csw;
326 
327 	InitializeCBW(&cbw, READ_CHIP_INFO);
328 
329 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
330 	{
331 		return ERR_DEVICE_WRITE_FAILED;
332 	}
333 
334 	if(!RKU_Read(lpBuffer, 16))
335 	{
336 		return ERR_DEVICE_READ_FAILED;
337 	}
338 
339 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
340 	{
341 		return ERR_DEVICE_READ_FAILED;
342 	}
343 
344 	if( !UFI_CHECK_SIGN(cbw, csw) )
345 		return ERR_CMD_NOTMATCH;
346 
347 	return ERR_SUCCESS;
348 }
349 int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer)
350 {
351     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
352         if (m_log) {
353             m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
354         }
355         return ERR_DEVICE_NOT_SUPPORT;
356     }
357 
358 	CBW cbw;
359 	CSW csw;
360 
361 	InitializeCBW(&cbw, READ_FLASH_ID);
362 
363 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
364 	{
365 		return ERR_DEVICE_WRITE_FAILED;
366 	}
367 
368 	if(!RKU_Read(lpBuffer, 5))
369 	{
370 		return ERR_DEVICE_READ_FAILED;
371 	}
372 
373 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
374 	{
375 		return ERR_DEVICE_READ_FAILED;
376 	}
377 
378 	if( !UFI_CHECK_SIGN(cbw, csw) )
379 		return ERR_CMD_NOTMATCH;
380 
381 	return ERR_SUCCESS;
382 }
383 int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead)
384 {
385     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
386         if (m_log) {
387             m_log->Record("Error:RKU_ReadFlashInfo failed,device not support");
388         }
389         return ERR_DEVICE_NOT_SUPPORT;
390     }
391 	CBW cbw;
392 	CSW csw;
393 
394 	InitializeCBW(&cbw, READ_FLASH_INFO);
395 
396 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
397 	{
398 		return ERR_DEVICE_WRITE_FAILED;
399 	}
400 
401 	DWORD dwRead;
402 	dwRead = RKU_Read_EX(lpBuffer, 512);
403 	if ((dwRead < 11) || (dwRead > 512))
404 	{
405 		return ERR_DEVICE_READ_FAILED;
406 	}
407 	if (puiRead)
408 	{
409 		*puiRead = dwRead;
410 	}
411 /*
412 	if(!RKU_Read(hDev, lpBuffer, 11))
413 	{
414 		return ERR_DEVICE_READ_FAILED;
415 	}
416 */
417 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
418 	{
419 		return ERR_DEVICE_READ_FAILED;
420 	}
421 
422 	if( !UFI_CHECK_SIGN(cbw, csw) )
423 		return ERR_CMD_NOTMATCH;
424 
425 	return ERR_SUCCESS;
426 }
427 int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
428 {
429     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
430         if (m_log) {
431             m_log->Record("Error:RKU_ReadLBA failed,device not support");
432         }
433         return ERR_DEVICE_NOT_SUPPORT;
434     }
435 	CBW cbw;
436 	CSW csw;
437 	USHORT wSectorSize;
438 	USHORT usSectorLen;
439 	wSectorSize = 512;
440 	usSectorLen=dwCount;
441 
442 	InitializeCBW(&cbw, READ_LBA);
443 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
444 	cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen);
445 	cbw.cbwcb.ucReserved = bySubCode;
446 
447 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
448 	{
449 		return ERR_DEVICE_WRITE_FAILED;
450 	}
451 	DWORD dwTotal;
452 	dwTotal = usSectorLen * wSectorSize;
453 
454 	if(!RKU_Read(lpBuffer, dwTotal))
455 	{
456 		return ERR_DEVICE_READ_FAILED;
457 	}
458 
459 	if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
460 	{
461 		return ERR_DEVICE_READ_FAILED;
462 	}
463 
464 	if( !UFI_CHECK_SIGN(cbw, csw) )
465 		return ERR_CMD_NOTMATCH;
466 
467 	if(csw.ucCSWStatus == 1)
468 		return ERR_FAILED;
469 
470 	return ERR_SUCCESS;
471 }
472 
473 int CRKUsbComm::RKU_ResetDevice(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_ResetDevice failed,device not support");
478         }
479         return ERR_DEVICE_NOT_SUPPORT;
480     }
481 
482 	CBW cbw;
483 	CSW csw;
484 
485 	InitializeCBW(&cbw, DEVICE_RESET);
486 	cbw.cbwcb.ucReserved = bySubCode;
487 
488 	if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
489 	{
490 		return ERR_DEVICE_WRITE_FAILED;
491 	}
492 
493 	if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
494 	{
495 		return ERR_DEVICE_READ_FAILED;
496 	}
497 
498 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
499 		bool bRet;
500 		bRet = RKU_ClearBuffer(cbw, csw);
501 		if (!bRet) {
502 			return ERR_CMD_NOTMATCH;
503 		}
504 	}
505 
506 	if(csw.ucCSWStatus == 1)
507 		return ERR_FAILED;
508 
509 	return ERR_SUCCESS;
510 }
511 
512 int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode)
513 {
514     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
515         if (m_log) {
516             m_log->Record("Error:RKU_TestDeviceReady failed,device not support");
517         }
518         return ERR_DEVICE_NOT_SUPPORT;
519     }
520 	CBW cbw;
521 	CSW csw;
522 
523 	InitializeCBW(&cbw, TEST_UNIT_READY);
524 
525 	cbw.cbwcb.ucReserved = bySubCode;
526 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
527 		return ERR_DEVICE_WRITE_FAILED;
528 	}
529 
530 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
531 		return ERR_DEVICE_READ_FAILED;
532 	}
533 
534 	if( !UFI_CHECK_SIGN(cbw, csw) ) {
535 		bool bRet;
536 		bRet = RKU_ClearBuffer(cbw ,csw);
537 		if (!bRet) {
538 			return ERR_CMD_NOTMATCH;
539 		}
540 	}
541 
542 	if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) {
543 		*dwCurrent = (csw.dwCBWDataResidue >>16);
544 		*dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF);
545 
546 		*dwTotal = EndianU16_BtoL(*dwTotal);
547 		*dwCurrent = EndianU16_BtoL(*dwCurrent);
548 	}
549 	if(csw.ucCSWStatus == 1) {
550 		return ERR_DEVICE_UNREADY;
551 	}
552 
553 	return ERR_DEVICE_READY;
554 }
555 int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
556 {
557     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
558         if (m_log) {
559             m_log->Record("Error:RKU_WriteLBA failed,device not support");
560         }
561         return ERR_DEVICE_NOT_SUPPORT;
562     }
563 	CBW cbw;
564 	CSW csw;
565 	USHORT wSectorSize;
566 	USHORT usCount;
567 	wSectorSize = 512;
568 	usCount = dwCount;
569 	DWORD dwTotal = usCount * wSectorSize;
570 
571 	InitializeCBW(&cbw, WRITE_LBA);
572 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
573 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
574 	cbw.cbwcb.ucReserved = bySubCode;
575 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
576 		return ERR_DEVICE_WRITE_FAILED;
577 	}
578 
579 	if(!RKU_Write( lpBuffer, dwTotal)) {
580 		return ERR_DEVICE_WRITE_FAILED;
581 	}
582 
583 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
584 		return ERR_DEVICE_READ_FAILED;
585 	}
586 
587 	if( !UFI_CHECK_SIGN(cbw, csw) )
588 		return ERR_CMD_NOTMATCH;
589 
590 	if(csw.ucCSWStatus == 1)
591 		return ERR_FAILED;
592 
593 	return ERR_SUCCESS;
594 }
595 int CRKUsbComm::RKU_EraseLBA(DWORD dwPos, DWORD dwCount)
596 {
597     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
598         if (m_log) {
599             m_log->Record("Error:RKU_WriteLBA failed,device not support");
600         }
601         return ERR_DEVICE_NOT_SUPPORT;
602     }
603 	CBW cbw;
604 	CSW csw;
605 	USHORT usCount;
606 	usCount = dwCount;
607 
608 
609 	InitializeCBW(&cbw, ERASE_LBA);
610 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
611 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
612 
613 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
614 		return ERR_DEVICE_WRITE_FAILED;
615 	}
616 
617 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
618 		return ERR_DEVICE_READ_FAILED;
619 	}
620 
621 	if( !UFI_CHECK_SIGN(cbw, csw) )
622 		return ERR_CMD_NOTMATCH;
623 
624 	if(csw.ucCSWStatus == 1)
625 		return ERR_FAILED;
626 
627 	return ERR_SUCCESS;
628 }
629 
630 int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer)
631 {
632     if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
633         if (m_log) {
634             m_log->Record("Error:RKU_WriteSector failed,device not support");
635         }
636         return ERR_DEVICE_NOT_SUPPORT;
637     }
638 	CBW cbw;
639 	CSW csw;
640 	USHORT wSectorSize;
641 	USHORT usCount;
642 	usCount=dwCount;
643 	if(usCount > 32)
644 		return ERR_CROSS_BORDER;
645 
646 	wSectorSize = 528;
647 	InitializeCBW(&cbw, WRITE_SECTOR);
648 	cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
649 	cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
650 
651 	if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
652 		return ERR_DEVICE_WRITE_FAILED;
653 	}
654 
655 	if(!RKU_Write( lpBuffer, usCount * wSectorSize)) {
656 		return ERR_DEVICE_WRITE_FAILED;
657 	}
658 
659 	if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
660 		return ERR_DEVICE_READ_FAILED;
661 	}
662 
663 	if( !UFI_CHECK_SIGN(cbw, csw) )
664 		return ERR_CMD_NOTMATCH;
665 
666 	if(csw.ucCSWStatus == 1)
667 		return ERR_FAILED;
668 
669 	return ERR_SUCCESS;
670 }
671 
672 
673 int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize)
674 {
675 	if (m_deviceDesc.emUsbType != RKUSB_MASKROM) {
676 	    if (m_log) {
677 	        m_log->Record("Error:RKU_DeviceRequest failed,device not support");
678 	    }
679 	    return ERR_DEVICE_NOT_SUPPORT;
680 	}
681 	if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) {
682 		if (m_log) {
683 	        m_log->Record("Error:RKU_DeviceRequest failed,request not support");
684 	    }
685 	    return ERR_REQUEST_NOT_SUPPORT;
686 	}
687 
688 	bool bSendPendPacket = false;
689 	USHORT crcValue = 0xffff;
690 	BYTE *pData = NULL;
691 	pData = new BYTE[dwDataSize + 5];
692 	memset(pData, 0, dwDataSize + 5);
693 	memcpy(pData, lpBuffer, dwDataSize);
694 
695 	switch(dwDataSize % 4096) {
696 		case 4095:
697 			++dwDataSize;
698 			break;
699 		case 4094:
700 			bSendPendPacket = true;
701 			break;
702 		case 0:
703 		default:
704 			break;
705 	}
706 
707 	crcValue = CRC_CCITT(pData, dwDataSize);
708 	pData[dwDataSize] = (crcValue & 0xff00) >> 8;
709 	pData[dwDataSize+1] = crcValue & 0x00ff;
710 	dwDataSize += 2;
711 
712 	UINT nSendBytes = 0;
713 	DWORD dwTotalSended = 0;
714 	int iRet;
715 
716 	while(dwTotalSended < dwDataSize) {
717 		nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended);
718 		iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT);
719 		if (iRet != (int)nSendBytes) {
720 			if (m_log) {
721 				m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet);
722 			}
723 			delete []pData;
724 			return ERR_REQUEST_FAIL;
725 		}
726 		dwTotalSended += nSendBytes;
727 	}
728 
729 	if(bSendPendPacket) {
730 		BYTE ucFillByte = 0;
731 		iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT);
732 		if (iRet != 0) {
733 			if (m_log) {
734 				m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet);
735 			}
736 			delete []pData;
737 			return ERR_REQUEST_FAIL;
738 		}
739 	}
740 
741 	delete []pData;
742 
743     return ERR_SUCCESS;
744 }
745 
746 
747