xref: /rkdeveloptool/RKDevice.cpp (revision 21b25fd4a70331819b557fe93015b635b9594543)
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 "RKDevice.h"
9 
10 const char* szManufName[] =
11 {
12 	"SAMSUNG",
13 	"TOSHIBA",
14 	"HYNIX",
15 	"INFINEON",
16 	"MICRON",
17 	"RENESAS",
18 	"ST",
19 	"INTEL"
20 };
21 
22 void CRKDevice::SetVendorID(USHORT value)
23 {
24 	m_vid = value;
25 }
26 void CRKDevice::SetProductID(USHORT value)
27 {
28 	m_pid = value;
29 }
30 void CRKDevice::SetDeviceType(ENUM_RKDEVICE_TYPE value)
31 {
32 	m_device = value;
33 }
34 void CRKDevice::SetOsType(ENUM_OS_TYPE value)
35 {
36 	m_os = value;
37 }
38 
39 void CRKDevice::SetUsbType(ENUM_RKUSB_TYPE value)
40 {
41 	m_usb = value;
42 }
43 void CRKDevice::SetBcdUsb(USHORT value)
44 {
45 	m_bcdUsb = value;
46 }
47 void CRKDevice::SetLayerName(char *value)
48 {
49 	strcpy(m_layerName,value);
50 }
51 void CRKDevice::SetLocationID(DWORD value)
52 {
53 	m_locationID = value;
54 }
55 
56 void CRKDevice::SetCallBackPointer(ProgressPromptCB value)
57 {
58 	if (value)
59 	{
60 		m_callBackProc = value;
61 	}
62 }
63 CRKLog* CRKDevice::GetLogObjectPointer()
64 {
65 	return m_pLog;
66 }
67 
68 CRKComm* CRKDevice::GetCommObjectPointer()
69 {
70 	return m_pComm;
71 }
72 
73 USHORT CRKDevice::GetVendorID()
74 {
75 	return m_vid;
76 }
77 USHORT CRKDevice::GetProductID()
78 {
79 	return m_pid;
80 }
81 ENUM_RKDEVICE_TYPE CRKDevice::GetDeviceType()
82 {
83 	return m_device;
84 }
85 ENUM_OS_TYPE CRKDevice::GetOsType()
86 {
87 	return m_os;
88 }
89 
90 ENUM_RKUSB_TYPE CRKDevice::GetUsbType()
91 {
92 	return m_usb;
93 }
94 
95 USHORT CRKDevice::GetBcdUsb()
96 {
97 	return m_bcdUsb;
98 }
99 DWORD CRKDevice::GetLocationID()
100 {
101 	return m_locationID;
102 }
103 char* CRKDevice::GetLayerName()
104 {
105 	return m_layerName;
106 }
107 
108 string CRKDevice::GetLayerString(UINT dwLocationID)
109 {
110 	char szLocation[32] = "\0";
111 	sprintf(szLocation, "%d-%d", dwLocationID >> 8, dwLocationID & 0xff);
112 	return szLocation;
113 }
114 
115 CRKDevice::CRKDevice(STRUCT_RKDEVICE_DESC &device)
116 {
117 	VendorID.setContainer(this);
118     	VendorID.getter(&CRKDevice::GetVendorID);
119  	VendorID.setter(&CRKDevice::SetVendorID);
120 
121 	ProductID.setContainer(this);
122     	ProductID.getter(&CRKDevice::GetProductID);
123  	ProductID.setter(&CRKDevice::SetProductID);
124 
125 	DeviceType.setContainer(this);
126     	DeviceType.getter(&CRKDevice::GetDeviceType);
127  	DeviceType.setter(&CRKDevice::SetDeviceType);
128 
129 	UsbType.setContainer(this);
130     	UsbType.getter(&CRKDevice::GetUsbType);
131  	UsbType.setter(&CRKDevice::SetUsbType);
132 
133 	LayerName.setContainer(this);
134     	LayerName.getter(&CRKDevice::GetLayerName);
135  	LayerName.setter(&CRKDevice::SetLayerName);
136 
137 	BcdUsb.setContainer(this);
138     	BcdUsb.getter(&CRKDevice::GetBcdUsb);
139  	BcdUsb.setter(&CRKDevice::SetBcdUsb);
140 
141 	LocationID.setContainer(this);
142     	LocationID.getter(&CRKDevice::GetLocationID);
143 	LocationID.setter(&CRKDevice::SetLocationID);
144 
145 	OsType.setContainer(this);
146     	OsType.getter(&CRKDevice::GetOsType);
147  	OsType.setter(&CRKDevice::SetOsType);
148 
149 	LogObjectPointer.setContainer(this);
150     	LogObjectPointer.getter(&CRKDevice::GetLogObjectPointer);
151 
152 	CommObjectPointer.setContainer(this);
153     	CommObjectPointer.getter(&CRKDevice::GetCommObjectPointer);
154 
155 	CallBackPointer.setContainer(this);
156  	CallBackPointer.setter(&CRKDevice::SetCallBackPointer);
157 
158 	m_vid = device.usVid;
159 	m_pid = device.usPid;
160 	m_usb = device.emUsbType;
161 	m_device = device.emDeviceType;
162 	m_bcdUsb = device.usbcdUsb;
163 	m_locationID = device.uiLocationID;
164 	strcpy(m_layerName, GetLayerString(m_locationID).c_str());
165 
166 	memset(m_flashInfo.blockState, 0, IDBLOCK_TOP);
167 	m_flashInfo.usPhyBlokcPerIDB = 1;
168 	m_flashInfo.uiSecNumPerIDB = 0;
169 	m_callBackProc = NULL;
170 	m_chipData = NULL;
171 	m_pImage = NULL;
172 	m_pLog = NULL;
173 	m_pComm = NULL;
174 	m_pFlashInfoData = NULL;
175 	m_usFlashInfoDataLen = 0;
176 	m_usFlashInfoDataOffset = 0;
177 	m_bEmmc = false;
178 	m_bDirectLba = false;
179 	m_bFirst4mAccess = false;
180 }
181 CRKDevice::~CRKDevice()
182 {
183 	if (m_pComm) {
184 		delete m_pComm;
185 		m_pComm = NULL;
186 	}
187 	if (m_chipData) {
188 		delete []m_chipData;
189 		m_chipData = NULL;
190 	}
191 
192 	if (m_pFlashInfoData) {
193 		delete []m_pFlashInfoData;
194 		m_pFlashInfoData = NULL;
195 	}
196 }
197 bool CRKDevice::SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog)
198 {
199 	if (!pComm) {
200 		return false;
201 	}
202 	m_pImage = pImage;
203 	m_pComm = pComm;
204 	m_pLog = pLog;
205 	if (m_pImage) {
206 		m_os = m_pImage->OsType;
207 	} else
208 		m_os = RK_OS;
209 	return true;
210 }
211 int CRKDevice::EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount)
212 {
213 	int sectorOffset,nWrittenBlcok,iRet;
214 	BYTE emptyData[4 * (SECTOR_SIZE+SPARE_SIZE)];
215 	memset(emptyData, 0xff, 4 * (SECTOR_SIZE + SPARE_SIZE));
216 	nWrittenBlcok = 0;
217 	while (dwCount > 0) {
218  		sectorOffset = (ucFlashCS * m_flashInfo.uiBlockNum + dwPos + nWrittenBlcok) * m_flashInfo.uiSectorPerBlock;
219 		iRet = m_pComm->RKU_WriteSector(sectorOffset, 4, emptyData);
220 		if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
221 			if (m_pLog) {
222 				m_pLog->Record("<LAYER %s> ERROR:EraseEmmcBlock-->RKU_WriteSector failed, RetCode(%d)", m_layerName, iRet);
223 			}
224 			return iRet;
225 		}
226 		dwCount--;
227 		nWrittenBlcok++;
228 	}
229 	return ERR_SUCCESS;
230 }
231 int CRKDevice::EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount)
232 {
233 	int nWritten,iRet;
234 	BYTE emptyData[32 * SECTOR_SIZE];
235 	memset(emptyData, 0xff, 32 * SECTOR_SIZE);
236 
237 	while (dwCount > 0) {
238 		nWritten = (dwCount < 32) ? dwCount : 32;
239 		iRet = m_pComm->RKU_WriteLBA(dwSectorPos, nWritten, emptyData);
240 		if (iRet != ERR_SUCCESS) {
241 			if (m_pLog) {
242 				m_pLog->Record("<LAYER %s> ERROR:EraseEmmcByWriteLBA-->RKU_WriteLBA failed, RetCode(%d)", m_layerName, iRet);
243 			}
244 			return iRet;
245 		}
246 		dwCount -= nWritten;
247 		dwSectorPos += nWritten;
248 	}
249 	return ERR_SUCCESS;
250 }
251 bool CRKDevice::EraseEmmc()
252 {
253 	UINT uiCount,uiEraseCount,uiSectorOffset,uiTotalCount;
254 	UINT uiErase=1024*32;
255 	int iRet=ERR_SUCCESS,iLoopTimes=0;
256 	uiTotalCount = uiCount = m_flashInfo.uiFlashSize*2*1024;
257 	uiSectorOffset = 0;
258 	DWORD dwLayerID;
259 	dwLayerID = m_locationID;
260 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
261 
262 	while (uiCount)
263 	{
264 		if (uiCount >= uiErase)
265 		{
266 			uiEraseCount = uiErase;
267 		}
268 		else
269 			uiEraseCount = uiCount;
270 		iRet = m_pComm->RKU_EraseLBA(uiSectorOffset, uiEraseCount);
271 
272 		if (iRet != ERR_SUCCESS) {
273 			if (m_pLog) {
274 				m_pLog->Record("ERROR:EraseEmmc-->RKU_EraseLBA failed,RetCode(%d),offset=0x%x,count=0x%x",iRet, uiSectorOffset, uiEraseCount);
275 			}
276 			return false;
277 		}
278 		uiCount -= uiEraseCount;
279 		uiSectorOffset += uiEraseCount;
280 		iLoopTimes++;
281 		if (iLoopTimes % 8 == 0) {
282 			if (m_callBackProc) {
283 				m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiSectorOffset, emCallStep);
284 				emCallStep = CALL_MIDDLE;
285 			}
286 		}
287 	}
288 	if (m_callBackProc) {
289 		emCallStep = CALL_LAST;
290 		m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiTotalCount, emCallStep);
291 	}
292 	return true;
293 }
294 bool CRKDevice::GetFlashInfo()
295 {
296 	STRUCT_FLASHINFO_CMD info;
297 	BYTE flashID[5];
298 	int iRet;
299 	UINT uiRead;
300 	iRet = m_pComm->RKU_ReadFlashInfo((PBYTE)&info, &uiRead);
301 	if( ERR_SUCCESS == iRet ) {
302 		if ((info.usBlockSize == 0) || (info.bPageSize == 0)) {
303 			if (m_pLog) {
304 				m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,pagesize or blocksize is zero", m_layerName);
305 			}
306 			return false;
307 		}
308 		if (info.bManufCode <= 7) {
309 			strcpy(m_flashInfo.szManufacturerName, szManufName[info.bManufCode]);
310 		} else {
311 			strcpy(m_flashInfo.szManufacturerName, "UNKNOWN");
312 		}
313 		m_flashInfo.uiFlashSize = info.uiFlashSize / 2 / 1024;
314 		m_flashInfo.uiPageSize = info.bPageSize / 2;
315 		m_flashInfo.usBlockSize = info.usBlockSize / 2;
316 		m_flashInfo.bECCBits = info.bECCBits;
317 		m_flashInfo.bAccessTime = info.bAccessTime;
318 		m_flashInfo.uiBlockNum = m_flashInfo.uiFlashSize * 1024 / m_flashInfo.usBlockSize;
319 		m_flashInfo.uiSectorPerBlock = info.usBlockSize;
320 		m_flashInfo.bFlashCS = info.bFlashCS;
321 		m_flashInfo.usValidSecPerBlock = (info.usBlockSize / info.bPageSize) * 4;
322 		if (m_pFlashInfoData) {
323 			delete []m_pFlashInfoData;
324 			m_pFlashInfoData = NULL;
325 		}
326 		m_usFlashInfoDataLen = BYTE2SECTOR(uiRead);
327 		m_pFlashInfoData = new BYTE[SECTOR_SIZE * m_usFlashInfoDataLen];
328 		memset(m_pFlashInfoData, 0, SECTOR_SIZE * m_usFlashInfoDataLen);
329 		memcpy(m_pFlashInfoData, (PBYTE)&info, uiRead);
330 		if (m_pLog) {
331 			string strFlashInfo;
332 			m_pLog->PrintBuffer(strFlashInfo, m_pFlashInfoData, 11);
333 			m_pLog->Record("<LAYER %s> INFO:FlashInfo:%s", m_layerName, strFlashInfo.c_str());
334 		}
335 	} else {
336 		if (m_pLog) {
337 			m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed, RetCode(%d)", m_layerName, iRet);
338 		}
339 		return false;
340 	}
341 	iRet = m_pComm->RKU_ReadFlashID(flashID);
342 	if( ERR_SUCCESS == iRet ) {
343 		DWORD *pID = (DWORD *)flashID;
344 		if (*pID==0x434d4d45)/*emmc*/ {
345 			m_bEmmc = true;
346 		} else
347 			m_bEmmc = false;
348 	} else {
349 		if (m_pLog) {
350 			m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashID failed, RetCode(%d)", m_layerName, iRet);
351 		}
352 		return false;
353 	}
354 	return true;
355 }
356 bool CRKDevice::TestDevice()
357 {
358 	int iResult, iTryCount;
359 	DWORD dwTotal, dwCurrent, dwLayerID;
360 	dwLayerID = m_locationID;
361 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
362 	do {
363 		iTryCount = 3;
364 		while (iTryCount > 0) {
365 			iResult = m_pComm->RKU_TestDeviceReady(&dwTotal, &dwCurrent);
366 			if ((iResult == ERR_SUCCESS) || (iResult == ERR_DEVICE_UNREADY)) {
367 				break;
368 			}
369 			if (m_pLog) {
370 				m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, RetCode(%d)", m_layerName, iResult);
371 			}
372 			iTryCount--;
373 			sleep(1);
374 		}
375 		if (iTryCount <= 0) {
376 			return false;
377 		}
378 
379 		if (iResult == ERR_SUCCESS) {
380 			if (emCallStep == CALL_MIDDLE) {
381 				if (m_callBackProc) {
382 					dwCurrent = dwTotal;
383 					emCallStep = CALL_LAST;
384 					m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
385 				}
386 			}
387 			break;
388 		}
389 		if (dwCurrent>dwTotal) {
390 			if (m_pLog) {
391 				m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed,Total=%d, Current=%d", m_layerName, dwTotal, dwCurrent);
392 			}
393 			return false;
394 		}
395 		if (UsbType == RKUSB_LOADER) {
396 			if (dwTotal == 0) {
397 				if (m_pLog)
398 				{
399 					m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, Total is zero", m_layerName);
400 				}
401 				return false;
402 			}
403 		}
404 		if (m_callBackProc)
405 		{
406 			m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
407 			emCallStep = CALL_MIDDLE;
408 		}
409 		sleep(1);
410 	}while(iResult == ERR_DEVICE_UNREADY);
411 	return true;
412 }
413 bool CRKDevice::ResetDevice()
414 {
415 	int iRet;
416 	iRet = m_pComm->RKU_ResetDevice();
417 	if (iRet == ERR_SUCCESS) {
418 		return true;
419 	} else {
420 		bool bRet = false;
421 		if ((iRet == -2) || (iRet == -4)) {
422 			bRet = true;
423 		}
424 		if (m_pLog) {
425 			m_pLog->Record("<LAYER %s> ERROR:ResetDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
426 		}
427 		return bRet;
428 	}
429 }
430 
431 bool CRKDevice::PowerOffDevice()
432 {
433 	int iRet;
434 	iRet = m_pComm->RKU_ResetDevice(RST_POWEROFF_SUBCODE);
435 	if (iRet == ERR_SUCCESS) {
436 		return true;
437 	} else {
438 		if (m_pLog) {
439 			m_pLog->Record("<LAYER %s> ERROR:PowerOffDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
440 		}
441 		return false;
442 	}
443 }
444 bool CRKDevice::CheckChip()
445 {
446 	int iRet;
447 	BYTE bChipInfo[CHIPINFO_LEN];
448 	ENUM_RKDEVICE_TYPE curDeviceType = RKNONE_DEVICE;
449 	memset(bChipInfo, 0, CHIPINFO_LEN);
450 	iRet = m_pComm->RKU_ReadChipInfo(bChipInfo);
451 	if (iRet == ERR_SUCCESS) {
452 		if (!m_chipData) {
453 			m_chipData = new BYTE[CHIPINFO_LEN];
454 		}
455 		memset(m_chipData, 0, CHIPINFO_LEN);
456 		memcpy(m_chipData, bChipInfo, CHIPINFO_LEN);
457 		DWORD *pValue;
458 		pValue = (DWORD *)(&bChipInfo[0]);
459 
460 		if ((ENUM_RKDEVICE_TYPE)(*pValue) == m_device) {
461 			return true;
462 		}
463 		if (*pValue == 0x524B3237) {
464 			curDeviceType = RK27_DEVICE;
465 		} else if (*pValue == 0x32373341) {
466 			curDeviceType = RKCAYMAN_DEVICE;
467 		} else if (*pValue == 0x524B3238) {
468 			curDeviceType = RK28_DEVICE;
469 		} else if (*pValue == 0x32383158) {
470 			curDeviceType = RK281X_DEVICE;
471 		} else if (*pValue == 0x32383242) {
472 			curDeviceType = RKPANDA_DEVICE;
473 		} else if (*pValue == 0x32393058) {
474 			curDeviceType = RK29_DEVICE;
475 		} else if (*pValue == 0x32393258) {
476 			curDeviceType = RK292X_DEVICE;
477 		} else if (*pValue == 0x33303041) {
478 			curDeviceType = RK30_DEVICE;
479 		} else if (*pValue == 0x33313041) {
480 			curDeviceType = RK30B_DEVICE;
481 		} else if (*pValue == 0x33313042) {
482 			curDeviceType = RK31_DEVICE;
483 		} else if (*pValue == 0x33323041) {
484 			curDeviceType = RK32_DEVICE;
485 		} else if (*pValue == 0x32363243) {
486 			curDeviceType = RKSMART_DEVICE;
487 		} else if (*pValue == 0x6E616E6F) {
488 			curDeviceType = RKNANO_DEVICE;
489 		} else if (*pValue == 0x4E4F5243) {
490 			curDeviceType = RKCROWN_DEVICE;
491 		}
492 
493 		if (curDeviceType == m_device){
494 			return true;
495 		} else {
496 			if (m_pLog) {
497 				m_pLog->Record("<LAYER %s> ERROR:CheckChip-->Chip is not match, firmware(0x%x), device(0x%x)", m_layerName, m_device, *pValue);
498 			}
499 			return false;
500 		}
501 	}
502 	else {
503 		if (m_pLog) {
504 			m_pLog->Record("<LAYER %s> ERROR:CheckChip-->RKU_ReadChipInfo failed,RetCode(%d)", m_layerName, iRet);
505 		}
506 		return false;
507 	}
508 }
509 
510 int CRKDevice::DownloadBoot()
511 {
512 	UCHAR i;
513 	DWORD dwSize, dwDelay;
514 	PBYTE pBuffer = NULL;
515 	for ( i = 0; i < m_pImage->m_bootObject->Entry471Count; i++ ) {
516 		if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY471, i, dwSize, dwDelay) ) {
517 			if (m_pLog) {
518 				m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Property failed,index(%d)", m_layerName, i);
519 			}
520 			return -2;
521 		}
522 		if (dwSize>0) {
523 			pBuffer = new BYTE[dwSize];
524 			if ( !m_pImage->m_bootObject->GetEntryData(ENTRY471, i, pBuffer) ) {
525 				if (m_pLog) {
526 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Data failed,index(%d)", m_layerName, i);
527 				}
528 				delete []pBuffer;
529 				return -3;
530 			}
531 			if ( !Boot_VendorRequest(0x0471,pBuffer,dwSize) ) {
532 				if (m_pLog) {
533 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest471 failed,index(%d)", m_layerName, i);
534 				}
535 				delete []pBuffer;
536 				return -4;
537 			}
538 			delete []pBuffer;
539 			pBuffer = NULL;
540 			if (dwDelay>0) {
541 				usleep(dwDelay * 1000);
542 			}
543 
544 		}
545 	}
546 
547 	for ( i=0; i < m_pImage->m_bootObject->Entry472Count; i++ ) {
548 		if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY472, i, dwSize, dwDelay) ) {
549 			if (m_pLog) {
550 				m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Property failed,index(%d)", m_layerName, i);
551 			}
552 			return -2;
553 		}
554 		if (dwSize > 0) {
555 			pBuffer = new BYTE[dwSize];
556 			if ( !m_pImage->m_bootObject->GetEntryData(ENTRY472, i, pBuffer) ) {
557 				if (m_pLog) {
558 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Data failed,index(%d)", m_layerName, i);
559 				}
560 				delete []pBuffer;
561 				return -3;
562 			}
563 			if ( !Boot_VendorRequest(0x0472, pBuffer, dwSize) ) {
564 				if (m_pLog) {
565 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest472 failed,index(%d)", m_layerName, i);
566 				}
567 				delete []pBuffer;
568 				return -4;
569 			}
570 			delete []pBuffer;
571 			pBuffer = NULL;
572 			if (dwDelay > 0) {
573 				usleep(dwDelay * 1000);
574 			}
575 		}
576 	}
577 	sleep(1);
578 	return 0;
579 
580 }
581 bool CRKDevice::Boot_VendorRequest( DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize)
582 {
583 	int iRet;
584 	iRet = m_pComm->RKU_DeviceRequest(requestCode, pBuffer, dwDataSize);
585 	return (iRet == ERR_SUCCESS) ? true : false;
586 }
587 int CRKDevice::EraseAllBlocks(bool force_block_erase)
588 {
589 	int i;
590 	UINT uiBlockCount;
591 	int iRet = ERR_SUCCESS, iErasePos = 0, iEraseBlockNum = 0, iEraseTimes = 0, iCSIndex = 0;
592 	BYTE bCSCount = 0;
593 	for (i = 0; i < 8; i++) {
594 		if ( m_flashInfo.bFlashCS & (1 << i) ) {
595 			bCSCount++;
596 		}
597 	}
598 	ReadCapability();
599 	DWORD dwLayerID;
600 	dwLayerID = LocationID;
601 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
602 	if (!force_block_erase) {
603 		if ((m_bEmmc)||(m_bDirectLba)) {
604 			if (!EraseEmmc()) {
605 				if (m_pLog) {
606 					m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName);
607 				}
608 				return -1;
609 			}
610 			return 0;
611 		}
612 	}
613 	for (i = 0; i < 8; i++) {
614 		if ( m_flashInfo.bFlashCS & (1 << i) ) {
615 			uiBlockCount = m_flashInfo.uiBlockNum;
616 			iErasePos = 0;
617 			iEraseTimes = 0;
618 			while (uiBlockCount > 0) {
619 				iEraseBlockNum = (uiBlockCount < MAX_ERASE_BLOCKS) ? uiBlockCount : MAX_ERASE_BLOCKS;
620 				iRet = m_pComm->RKU_EraseBlock(i, iErasePos, iEraseBlockNum, ERASE_FORCE);
621 				if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
622 					if (m_pLog) {
623 						m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)", m_layerName, iRet);
624 					}
625 					return -1;
626 				}
627 				iErasePos += iEraseBlockNum;
628 				uiBlockCount -= iEraseBlockNum;
629 				iEraseTimes++;
630 				if (iEraseTimes % 8 == 0) {
631 					if (m_callBackProc) {
632 						m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum + iErasePos, emCallStep);
633 						emCallStep = CALL_MIDDLE;
634 					}
635 				}
636 			}
637 			iCSIndex++;
638 		}
639 	}
640 
641 	if (m_callBackProc) {
642 		emCallStep = CALL_LAST;
643 		m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum, emCallStep);
644 	}
645 	return 0;
646 }
647 bool CRKDevice::ReadCapability()
648 {
649 	int ret;
650 	BYTE data[8];
651 	ret = m_pComm->RKU_ReadCapability(data);
652 	if (ret != ERR_SUCCESS)
653 	{
654 		if (m_pLog)
655 		{
656 			m_pLog->Record("ERROR:ReadCapability-->RKU_ReadCapability failed,err(%d)", ret);
657 		}
658 		return false;
659 	}
660 	if (data[0] & 0x1)
661 	{
662 		m_bDirectLba = true;
663 	}
664 	else
665 		m_bDirectLba = false;
666 	if (data[0] & 0x4)
667 	{
668 		m_bFirst4mAccess = true;
669 	}
670 	else
671 		m_bFirst4mAccess = false;
672 	return true;
673 }
674 
675 
676