xref: /rkdeveloptool/RKDevice.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 "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(DWORD 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 }
179 CRKDevice::~CRKDevice()
180 {
181 	if (m_pComm) {
182 		delete m_pComm;
183 		m_pComm = NULL;
184 	}
185 	if (m_chipData) {
186 		delete []m_chipData;
187 		m_chipData = NULL;
188 	}
189 
190 	if (m_pFlashInfoData) {
191 		delete []m_pFlashInfoData;
192 		m_pFlashInfoData = NULL;
193 	}
194 }
195 bool CRKDevice::SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog)
196 {
197 	if (!pComm) {
198 		return false;
199 	}
200 	m_pImage = pImage;
201 	m_pComm = pComm;
202 	m_pLog = pLog;
203 	if (m_pImage) {
204 		m_os = m_pImage->OsType;
205 	} else
206 		m_os = RK_OS;
207 	return true;
208 }
209 int CRKDevice::EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount)
210 {
211 	int sectorOffset,nWrittenBlcok,iRet;
212 	BYTE emptyData[4 * (SECTOR_SIZE+SPARE_SIZE)];
213 	memset(emptyData, 0xff, 4 * (SECTOR_SIZE + SPARE_SIZE));
214 	nWrittenBlcok = 0;
215 	while (dwCount > 0) {
216  		sectorOffset = (ucFlashCS * m_flashInfo.uiBlockNum + dwPos + nWrittenBlcok) * m_flashInfo.uiSectorPerBlock;
217 		iRet = m_pComm->RKU_WriteSector(sectorOffset, 4, emptyData);
218 		if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
219 			if (m_pLog) {
220 				m_pLog->Record("<LAYER %s> ERROR:EraseEmmcBlock-->RKU_WriteSector failed, RetCode(%d)", m_layerName, iRet);
221 			}
222 			return iRet;
223 		}
224 		dwCount--;
225 		nWrittenBlcok++;
226 	}
227 	return ERR_SUCCESS;
228 }
229 int CRKDevice::EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount)
230 {
231 	int nWritten,iRet;
232 	BYTE emptyData[32 * SECTOR_SIZE];
233 	memset(emptyData, 0xff, 32 * SECTOR_SIZE);
234 
235 	while (dwCount > 0) {
236 		nWritten = (dwCount < 32) ? dwCount : 32;
237 		iRet = m_pComm->RKU_WriteLBA(dwSectorPos, nWritten, emptyData);
238 		if (iRet != ERR_SUCCESS) {
239 			if (m_pLog) {
240 				m_pLog->Record("<LAYER %s> ERROR:EraseEmmcByWriteLBA-->RKU_WriteLBA failed, RetCode(%d)", m_layerName, iRet);
241 			}
242 			return iRet;
243 		}
244 		dwCount -= nWritten;
245 		dwSectorPos += nWritten;
246 	}
247 	return ERR_SUCCESS;
248 }
249 bool CRKDevice::EraseEmmc()
250 {
251 	UINT uiCount, uiEraseCount, uiSectorOffset;
252 	int iRet = ERR_SUCCESS, iLoopTimes = 0;
253 	uiCount = m_flashInfo.uiFlashSize;
254 
255 	DWORD dwLayerID;
256 	dwLayerID = m_locationID;
257 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
258 	uiEraseCount = 4;
259 	while (uiEraseCount < uiCount) {
260 		uiSectorOffset = uiEraseCount * 2048;
261 		if (uiEraseCount>8) {
262 			iRet = EraseEmmcByWriteLBA(uiSectorOffset, 32);
263 		} else
264 			iRet = EraseEmmcByWriteLBA(uiSectorOffset, 2048);
265 		if (iRet != ERR_SUCCESS) {
266 			if (m_pLog) {
267 				m_pLog->Record("<LAYER %s> ERROR:EraseEmmc-->EraseEmmcByWriteLBA failed, RetCode(%d)", m_layerName, iRet);
268 			}
269 			return false;
270 		}
271 		uiEraseCount++;
272 		iLoopTimes++;
273 		if (iLoopTimes%8 == 0) {
274 			if (m_callBackProc) {
275 				m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiCount, uiEraseCount, emCallStep);
276 				emCallStep = CALL_MIDDLE;
277 			}
278 		}
279 	}
280 	if (m_callBackProc) {
281 		emCallStep = CALL_LAST;
282 		m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiCount, uiCount, emCallStep);
283 	}
284 	return true;
285 }
286 bool CRKDevice::GetFlashInfo()
287 {
288 	STRUCT_FLASHINFO_CMD info;
289 	BYTE flashID[5];
290 	int iRet;
291 	UINT uiRead;
292 	iRet = m_pComm->RKU_ReadFlashInfo((PBYTE)&info, &uiRead);
293 	if( ERR_SUCCESS == iRet ) {
294 		if ((info.usBlockSize == 0) || (info.bPageSize == 0)) {
295 			if (m_pLog) {
296 				m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,pagesize or blocksize is zero", m_layerName);
297 			}
298 			return false;
299 		}
300 		if (info.bManufCode <= 7) {
301 			strcpy(m_flashInfo.szManufacturerName, szManufName[info.bManufCode]);
302 		} else {
303 			strcpy(m_flashInfo.szManufacturerName, "UNKNOWN");
304 		}
305 		m_flashInfo.uiFlashSize = info.uiFlashSize / 2 / 1024;
306 		m_flashInfo.uiPageSize = info.bPageSize / 2;
307 		m_flashInfo.usBlockSize = info.usBlockSize / 2;
308 		m_flashInfo.bECCBits = info.bECCBits;
309 		m_flashInfo.bAccessTime = info.bAccessTime;
310 		m_flashInfo.uiBlockNum = m_flashInfo.uiFlashSize * 1024 / m_flashInfo.usBlockSize;
311 		m_flashInfo.uiSectorPerBlock = info.usBlockSize;
312 		m_flashInfo.bFlashCS = info.bFlashCS;
313 		m_flashInfo.usValidSecPerBlock = (info.usBlockSize / info.bPageSize) * 4;
314 		if (m_pFlashInfoData) {
315 			delete []m_pFlashInfoData;
316 			m_pFlashInfoData = NULL;
317 		}
318 		m_usFlashInfoDataLen = BYTE2SECTOR(uiRead);
319 		m_pFlashInfoData = new BYTE[SECTOR_SIZE * m_usFlashInfoDataLen];
320 		memset(m_pFlashInfoData, 0, SECTOR_SIZE * m_usFlashInfoDataLen);
321 		memcpy(m_pFlashInfoData, (PBYTE)&info, uiRead);
322 		if (m_pLog) {
323 			string strFlashInfo;
324 			m_pLog->PrintBuffer(strFlashInfo, m_pFlashInfoData, 11);
325 			m_pLog->Record("<LAYER %s> INFO:FlashInfo:%s", m_layerName, strFlashInfo.c_str());
326 		}
327 	} else {
328 		if (m_pLog) {
329 			m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed, RetCode(%d)", m_layerName, iRet);
330 		}
331 		return false;
332 	}
333 	iRet = m_pComm->RKU_ReadFlashID(flashID);
334 	if( ERR_SUCCESS == iRet ) {
335 		DWORD *pID = (DWORD *)flashID;
336 		if (*pID==0x434d4d45)/*emmc*/ {
337 			m_bEmmc = true;
338 		} else
339 			m_bEmmc = false;
340 	} else {
341 		if (m_pLog) {
342 			m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashID failed, RetCode(%d)", m_layerName, iRet);
343 		}
344 		return false;
345 	}
346 	return true;
347 }
348 bool CRKDevice::TestDevice()
349 {
350 	int iResult, iTryCount;
351 	DWORD dwTotal, dwCurrent, dwLayerID;
352 	dwLayerID = m_locationID;
353 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
354 	do {
355 		iTryCount = 3;
356 		while (iTryCount > 0) {
357 			iResult = m_pComm->RKU_TestDeviceReady(&dwTotal, &dwCurrent);
358 			if ((iResult == ERR_SUCCESS) || (iResult == ERR_DEVICE_UNREADY)) {
359 				break;
360 			}
361 			if (m_pLog) {
362 				m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, RetCode(%d)", m_layerName, iResult);
363 			}
364 			iTryCount--;
365 			sleep(1);
366 		}
367 		if (iTryCount <= 0) {
368 			return false;
369 		}
370 
371 		if (iResult == ERR_SUCCESS) {
372 			if (emCallStep == CALL_MIDDLE) {
373 				if (m_callBackProc) {
374 					dwCurrent = dwTotal;
375 					emCallStep = CALL_LAST;
376 					m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
377 				}
378 			}
379 			break;
380 		}
381 		if (dwCurrent>dwTotal) {
382 			if (m_pLog) {
383 				m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed,Total=%d, Current=%d", m_layerName, dwTotal, dwCurrent);
384 			}
385 			return false;
386 		}
387 		if (UsbType == RKUSB_LOADER) {
388 			if (dwTotal == 0) {
389 				if (m_pLog)
390 				{
391 					m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, Total is zero", m_layerName);
392 				}
393 				return false;
394 			}
395 		}
396 		if (m_callBackProc)
397 		{
398 			m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
399 			emCallStep = CALL_MIDDLE;
400 		}
401 		sleep(1);
402 	}while(iResult == ERR_DEVICE_UNREADY);
403 	return true;
404 }
405 bool CRKDevice::ResetDevice()
406 {
407 	int iRet;
408 	iRet = m_pComm->RKU_ResetDevice();
409 	if (iRet == ERR_SUCCESS) {
410 		return true;
411 	} else {
412 		bool bRet = false;
413 		if ((iRet == -2) || (iRet == -4)) {
414 			bRet = true;
415 		}
416 		if (m_pLog) {
417 			m_pLog->Record("<LAYER %s> ERROR:ResetDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
418 		}
419 		return bRet;
420 	}
421 }
422 
423 bool CRKDevice::PowerOffDevice()
424 {
425 	int iRet;
426 	iRet = m_pComm->RKU_ResetDevice(RST_POWEROFF_SUBCODE);
427 	if (iRet == ERR_SUCCESS) {
428 		return true;
429 	} else {
430 		if (m_pLog) {
431 			m_pLog->Record("<LAYER %s> ERROR:PowerOffDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
432 		}
433 		return false;
434 	}
435 }
436 bool CRKDevice::CheckChip()
437 {
438 	int iRet;
439 	BYTE bChipInfo[CHIPINFO_LEN];
440 	ENUM_RKDEVICE_TYPE curDeviceType = RKNONE_DEVICE;
441 	memset(bChipInfo, 0, CHIPINFO_LEN);
442 	iRet = m_pComm->RKU_ReadChipInfo(bChipInfo);
443 	if (iRet == ERR_SUCCESS) {
444 		if (!m_chipData) {
445 			m_chipData = new BYTE[CHIPINFO_LEN];
446 		}
447 		memset(m_chipData, 0, CHIPINFO_LEN);
448 		memcpy(m_chipData, bChipInfo, CHIPINFO_LEN);
449 		DWORD *pValue;
450 		pValue = (DWORD *)(&bChipInfo[0]);
451 
452 		if ((ENUM_RKDEVICE_TYPE)(*pValue) == m_device) {
453 			return true;
454 		}
455 		if (*pValue == 0x524B3237) {
456 			curDeviceType = RK27_DEVICE;
457 		} else if (*pValue == 0x32373341) {
458 			curDeviceType = RKCAYMAN_DEVICE;
459 		} else if (*pValue == 0x524B3238) {
460 			curDeviceType = RK28_DEVICE;
461 		} else if (*pValue == 0x32383158) {
462 			curDeviceType = RK281X_DEVICE;
463 		} else if (*pValue == 0x32383242) {
464 			curDeviceType = RKPANDA_DEVICE;
465 		} else if (*pValue == 0x32393058) {
466 			curDeviceType = RK29_DEVICE;
467 		} else if (*pValue == 0x32393258) {
468 			curDeviceType = RK292X_DEVICE;
469 		} else if (*pValue == 0x33303041) {
470 			curDeviceType = RK30_DEVICE;
471 		} else if (*pValue == 0x33313041) {
472 			curDeviceType = RK30B_DEVICE;
473 		} else if (*pValue == 0x33313042) {
474 			curDeviceType = RK31_DEVICE;
475 		} else if (*pValue == 0x33323041) {
476 			curDeviceType = RK32_DEVICE;
477 		} else if (*pValue == 0x32363243) {
478 			curDeviceType = RKSMART_DEVICE;
479 		} else if (*pValue == 0x6E616E6F) {
480 			curDeviceType = RKNANO_DEVICE;
481 		} else if (*pValue == 0x4E4F5243) {
482 			curDeviceType = RKCROWN_DEVICE;
483 		}
484 
485 		if (curDeviceType == m_device){
486 			return true;
487 		} else {
488 			if (m_pLog) {
489 				m_pLog->Record("<LAYER %s> ERROR:CheckChip-->Chip is not match, firmware(0x%x), device(0x%x)", m_layerName, m_device, *pValue);
490 			}
491 			return false;
492 		}
493 	}
494 	else {
495 		if (m_pLog) {
496 			m_pLog->Record("<LAYER %s> ERROR:CheckChip-->RKU_ReadChipInfo failed,RetCode(%d)", m_layerName, iRet);
497 		}
498 		return false;
499 	}
500 }
501 
502 int CRKDevice::DownloadBoot()
503 {
504 	UCHAR i;
505 	DWORD dwSize, dwDelay;
506 	PBYTE pBuffer = NULL;
507 	for ( i = 0; i < m_pImage->m_bootObject->Entry471Count; i++ ) {
508 		if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY471, i, dwSize, dwDelay) ) {
509 			if (m_pLog) {
510 				m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Property failed,index(%d)", m_layerName, i);
511 			}
512 			return -2;
513 		}
514 		if (dwSize>0) {
515 			pBuffer = new BYTE[dwSize];
516 			if ( !m_pImage->m_bootObject->GetEntryData(ENTRY471, i, pBuffer) ) {
517 				if (m_pLog) {
518 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Data failed,index(%d)", m_layerName, i);
519 				}
520 				delete []pBuffer;
521 				return -3;
522 			}
523 			if ( !Boot_VendorRequest(0x0471,pBuffer,dwSize) ) {
524 				if (m_pLog) {
525 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest471 failed,index(%d)", m_layerName, i);
526 				}
527 				delete []pBuffer;
528 				return -4;
529 			}
530 			delete []pBuffer;
531 			pBuffer = NULL;
532 			if (dwDelay>0) {
533 				usleep(dwDelay * 1000);
534 			}
535 
536 		}
537 	}
538 
539 	for ( i=0; i < m_pImage->m_bootObject->Entry472Count; i++ ) {
540 		if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY472, i, dwSize, dwDelay) ) {
541 			if (m_pLog) {
542 				m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Property failed,index(%d)", m_layerName, i);
543 			}
544 			return -2;
545 		}
546 		if (dwSize > 0) {
547 			pBuffer = new BYTE[dwSize];
548 			if ( !m_pImage->m_bootObject->GetEntryData(ENTRY472, i, pBuffer) ) {
549 				if (m_pLog) {
550 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Data failed,index(%d)", m_layerName, i);
551 				}
552 				delete []pBuffer;
553 				return -3;
554 			}
555 			if ( !Boot_VendorRequest(0x0472, pBuffer, dwSize) ) {
556 				if (m_pLog) {
557 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest472 failed,index(%d)", m_layerName, i);
558 				}
559 				delete []pBuffer;
560 				return -4;
561 			}
562 			delete []pBuffer;
563 			pBuffer = NULL;
564 			if (dwDelay > 0) {
565 				usleep(dwDelay * 1000);
566 			}
567 		}
568 	}
569 	sleep(1);
570 	return 0;
571 
572 }
573 bool CRKDevice::Boot_VendorRequest( DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize)
574 {
575 	int iRet;
576 	iRet = m_pComm->RKU_DeviceRequest(requestCode, pBuffer, dwDataSize);
577 	return (iRet == ERR_SUCCESS) ? true : false;
578 }
579 int CRKDevice::EraseAllBlocks()
580 {
581 	int i;
582 	UINT uiBlockCount;
583 	int iRet = ERR_SUCCESS, iErasePos = 0, iEraseBlockNum = 0, iEraseTimes = 0, iCSIndex = 0;
584 	BYTE bCSCount = 0;
585 	for (i = 0; i < 8; i++) {
586 		if ( m_flashInfo.bFlashCS & (1 << i) ) {
587 			bCSCount++;
588 		}
589 	}
590 	DWORD dwLayerID;
591 	dwLayerID = LocationID;
592 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
593 	if (m_bEmmc) {
594 		iRet = EraseEmmcBlock(0, 0, IDBLOCK_TOP);
595 		if (iRet != ERR_SUCCESS) {
596 			if (m_pLog) {
597 				m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmcBlock failed,RetCode(%d)", m_layerName, iRet);
598 			}
599 			return -1;
600 		}
601 		if (!EraseEmmc()) {
602 			if (m_pLog) {
603 				m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName);
604 			}
605 			return -1;
606 		}
607 		return 0;
608 	}
609 	for (i = 0; i < 8; i++) {
610 		if ( m_flashInfo.bFlashCS & (1 << i) ) {
611 			uiBlockCount = m_flashInfo.uiBlockNum;
612 			iErasePos = 0;
613 			iEraseTimes = 0;
614 			while (uiBlockCount > 0) {
615 				iEraseBlockNum = (uiBlockCount < MAX_ERASE_BLOCKS) ? uiBlockCount : MAX_ERASE_BLOCKS;
616 				iRet = m_pComm->RKU_EraseBlock(i, iErasePos, iEraseBlockNum, ERASE_FORCE);
617 				if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
618 					if (m_pLog) {
619 						m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)", m_layerName, iRet);
620 					}
621 					return -1;
622 				}
623 				iErasePos += iEraseBlockNum;
624 				uiBlockCount -= iEraseBlockNum;
625 				iEraseTimes++;
626 				if (iEraseTimes % 8 == 0) {
627 					if (m_callBackProc) {
628 						m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum + iErasePos, emCallStep);
629 						emCallStep = CALL_MIDDLE;
630 					}
631 				}
632 			}
633 			iCSIndex++;
634 		}
635 	}
636 
637 	if (m_callBackProc) {
638 		emCallStep = CALL_LAST;
639 		m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum, emCallStep);
640 	}
641 	return 0;
642 }
643 
644