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