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