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