xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/vendor.c (revision 5ce558eee1d84a2b85f2bbc4c4547c8ea1c1dae4)
1 /*
2  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <malloc.h>
9 #include <asm/arch/vendor.h>
10 
11 #include "rockchip_blk.h"
12 
13 /* tag for vendor check */
14 #define VENDOR_TAG		0x524B5644
15 /* The Vendor partition contains the number of Vendor blocks */
16 #define VENDOR_PART_NUM		4
17 /* align to 64 bytes */
18 #define VENDOR_BTYE_ALIGN	0x3F
19 #define VENDOR_BLOCK_SIZE	512
20 
21 /* --- Emmc define --- */
22 /* Starting address of the Vendor in memory. */
23 #define EMMC_VENDOR_PART_OFFSET		(1024 * 7)
24 /*
25  * The number of memory blocks used by each
26  * Vendor structure(128 * 512B = 64KB)
27  */
28 #define EMMC_VENDOR_PART_BLKS		128
29 /* The maximum number of items in each Vendor block */
30 #define EMMC_VENDOR_ITEM_NUM		126
31 
32 /* --- Spi/Spi Nand/SLC/MLC define --- */
33 /* The Vendor partition contains the number of Vendor blocks */
34 #define	FLASH_VENDOR_PART_OFFSET	8
35 /*
36  * The number of memory blocks used by each
37  * Vendor structure(8 * 512B = 4KB)
38  */
39 #define FLASH_VENDOR_PART_BLKS		8
40 /* The maximum number of items in each Vendor block */
41 #define FLASH_VENDOR_ITEM_NUM		62
42 
43 /* Vendor uinit test define */
44 /* #define VENDOR_STORAGE_TEST */
45 #ifdef VENDOR_STORAGE_TEST
46 int vendor_storage_test(void);
47 #endif /* VENDOR_STORAGE_TEST */
48 
49 struct vendor_item {
50 	u16  id;
51 	u16  offset;
52 	u16  size;
53 	u16  flag;
54 };
55 
56 struct vendor_hdr {
57 	u32	tag;
58 	u32	version;
59 	u16	next_index;
60 	u16	item_num;
61 	u16	free_offset; /* Free space offset */
62 	u16	free_size; /* Free space size */
63 };
64 
65 /*
66  * Different types of Flash vendor info are different.
67  * EMMC:EMMC_VENDOR_PART_BLKS * BLOCK_SIZE(512) = 64KB;
68  * Spi Nor/Spi Nand/SLC/MLC: FLASH_VENDOR_PART_BLKS *
69  * BLOCK_SIZE(512) = 4KB.
70  * hash: For future expansion.
71  * version2: Together with hdr->version, it is used to
72  * ensure the current Vendor block content integrity.
73  *   (version2 == hdr->version):Data valid;
74  *   (version2 != hdr->version):Data invalid.
75  */
76 struct vendor_info {
77 	struct vendor_hdr *hdr;
78 	struct vendor_item *item;
79 	u8 *data;
80 	u32 *hash;
81 	u32 *version2;
82 };
83 /*
84  * Calculate the offset of each field for emmc.
85  * Emmc vendor info size: 64KB
86  */
87 #define EMMC_VENDOR_INFO_SIZE	(EMMC_VENDOR_PART_BLKS * VENDOR_BLOCK_SIZE)
88 #define EMMC_VENDOR_DATA_OFFSET	(sizeof(struct vendor_hdr) + EMMC_VENDOR_ITEM_NUM * sizeof(struct vendor_item))
89 #define EMMC_VENDOR_HASH_OFFSET (EMMC_VENDOR_INFO_SIZE - 8)
90 #define EMMC_VENDOR_VERSION2_OFFSET (EMMC_VENDOR_INFO_SIZE - 4)
91 /*
92  * Calculate the offset of each field for spi nor/spi nand/slc/mlc.
93  * Flash vendor info size: 4KB
94  */
95 #define FLASH_VENDOR_INFO_SIZE	(FLASH_VENDOR_PART_BLKS * VENDOR_BLOCK_SIZE)
96 #define FLASH_VENDOR_DATA_OFFSET	(sizeof(struct vendor_hdr) + FLASH_VENDOR_ITEM_NUM * sizeof(struct vendor_item))
97 #define FLASH_VENDOR_HASH_OFFSET (FLASH_VENDOR_INFO_SIZE - 8)
98 #define FLASH_VENDOR_VERSION2_OFFSET (FLASH_VENDOR_INFO_SIZE - 4)
99 
100 /* vendor info */
101 static struct vendor_info vendor_info;
102 /* The storage type of the device */
103 static int bootdev_type;
104 
105 /**********************************************************/
106 /*              vendor API implementation                 */
107 /**********************************************************/
108 static int vendor_ops(u8 *buffer, u32 addr, u32 n_sec, int write)
109 {
110 	unsigned int lba = 0;
111 	int ret = 0;
112 
113 	/* Get the offset address according to the device type */
114 	switch (bootdev_type) {
115 	case BOOT_FROM_EMMC:
116 		/*
117 		 * The location of VendorStorage in Flash is shown in the
118 		 * following figure. The starting address of the VendorStorage
119 		 * partition is 3.5MB(EMMC_VENDOR_PART_OFFSET*BLOCK_SIZE(512)),
120 		 * and the partition size is 256KB.
121 		 * ----------------------------------------------------
122 		 * |   3.5MB    |  VendorStorage  |                   |
123 		 * ----------------------------------------------------
124 		 */
125 		lba = EMMC_VENDOR_PART_OFFSET;
126 		debug("[Vednor INFO]:VendorStorage offset address=0x%x\n", lba);
127 		break;
128 	case BOOT_FROM_FLASH:
129 	case BOOT_FROM_SPI_NOR:
130 	case BOOT_FROM_SPI_NAND:
131 		/*
132 		 * The location of VendorStorage in Flash is shown in the
133 		 * following figure. The starting address of the VendorStorage
134 		 * partition is 4KB (FLASH_VENDOR_PART_OFFSET * BLOCK_SIZE),
135 		 * and the partition size is 16KB.
136 		 * ----------------------------------------------------
137 		 * |   4KB    |  VendorStorage  |                     |
138 		 * ----------------------------------------------------
139 		 */
140 		lba = FLASH_VENDOR_PART_OFFSET;
141 		debug("[Vednor INFO]:VendorStorage offset address=0x%x\n", lba);
142 		break;
143 	default:
144 		debug("[Vednor ERROR]:Boot device type is invalid!\n");
145 		ret = -ENODEV;
146 		break;
147 	}
148 	if (!ret) {
149 		if (write)
150 			ret = blkdev_write(buffer, lba + addr, n_sec);
151 		else
152 			ret = blkdev_read(buffer, lba + addr, n_sec);
153 	}
154 	debug("[Vednor INFO]:op=%s, ret=%d\n", write ? "write" : "read", ret);
155 
156 	return ret;
157 }
158 
159 /*
160  * The VendorStorage partition is divided into four parts
161  * (vendor 0-3) and its structure is shown in the following figure.
162  * The init function is used to select the latest and valid vendor.
163  *
164  * |******************** FLASH ********************|
165  * -------------------------------------------------
166  * |  vendor0  |  vendor1  |  vendor2  |  vendor3  |
167  * -------------------------------------------------
168  * Notices:
169  *   1. "version" and "version2" are used to verify that the vendor
170  *      is valid (equal is valid).
171  *   2. the "version" value is larger, indicating that the current
172  *      verndor data is new.
173  */
174 int vendor_storage_init(void)
175 {
176 	int ret = 0;
177 	u8 *buffer;
178 	u32 size, i;
179 	u32 max_ver = 0;
180 	u32 max_index = 0;
181 	u16 data_offset, hash_offset;
182 	u16 version2_offset, part_size;
183 
184 	bootdev_type = get_bootdev_type();
185 	if (!bootdev_type) {
186 		printf("[Vednor ERROR]:Invalid boot device type(%d)\n",
187 		       bootdev_type);
188 		return -ENODEV;
189 	}
190 
191 	switch (bootdev_type) {
192 	case BOOT_FROM_EMMC:
193 		size = EMMC_VENDOR_INFO_SIZE;
194 		part_size = EMMC_VENDOR_PART_BLKS;
195 		data_offset = EMMC_VENDOR_DATA_OFFSET;
196 		hash_offset = EMMC_VENDOR_HASH_OFFSET;
197 		version2_offset = EMMC_VENDOR_VERSION2_OFFSET;
198 		break;
199 	case BOOT_FROM_FLASH:
200 	case BOOT_FROM_SPI_NOR:
201 	case BOOT_FROM_SPI_NAND:
202 		size = FLASH_VENDOR_INFO_SIZE;
203 		part_size = FLASH_VENDOR_PART_BLKS;
204 		data_offset = FLASH_VENDOR_DATA_OFFSET;
205 		hash_offset = FLASH_VENDOR_HASH_OFFSET;
206 		version2_offset = FLASH_VENDOR_VERSION2_OFFSET;
207 		break;
208 	default:
209 		debug("[Vednor ERROR]:Boot device type is invalid!\n");
210 		ret = -ENODEV;
211 		break;
212 	}
213 	/* Invalid bootdev type */
214 	if (ret)
215 		return ret;
216 	/* Always use, no need to release */
217 	buffer = (u8 *)malloc(size);
218 	if (!buffer) {
219 		printf("[Vednor ERROR]:Malloc failed!\n");
220 		return -ENOMEM;
221 	}
222 	/* Pointer initialization */
223 	vendor_info.hdr = (struct vendor_hdr *)buffer;
224 	vendor_info.item = (struct vendor_item *)(buffer + sizeof(struct vendor_hdr));
225 	vendor_info.data = buffer + data_offset;
226 	vendor_info.hash = (u32 *)(buffer + hash_offset);
227 	vendor_info.version2 = (u32 *)(buffer + version2_offset);
228 
229 	/* Find valid and up-to-date one from (vendor0 - vendor3) */
230 	for (i = 0; i < VENDOR_PART_NUM; i++) {
231 		ret = vendor_ops((u8 *)vendor_info.hdr, part_size * i, part_size, 0);
232 		if (ret)
233 			return ret;
234 
235 		if ((vendor_info.hdr->tag == VENDOR_TAG) &&
236 		    (*(vendor_info.version2) == vendor_info.hdr->version)) {
237 			if (max_ver < vendor_info.hdr->version) {
238 				max_index = i;
239 				max_ver = vendor_info.hdr->version;
240 			}
241 		}
242 	}
243 	if (max_ver) {
244 		debug("[Vednor INFO]:max_ver=%d, vendor_id=%d.\n", max_ver, max_index);
245 		/*
246 		 * Keep vendor_info the same as the largest
247 		 * version of vendor
248 		 */
249 		if (max_index != (VENDOR_PART_NUM - 1))
250 			ret = vendor_ops((u8 *)vendor_info.hdr, part_size * max_index, part_size, 0);
251 	} else {
252 		debug("[Vednor INFO]:Reset vendor info...\n");
253 		memset((u8 *)vendor_info.hdr, 0, size);
254 		vendor_info.hdr->version = 1;
255 		vendor_info.hdr->tag = VENDOR_TAG;
256 		/* data field length */
257 		vendor_info.hdr->free_size = ((u32)vendor_info.hash - (u32)vendor_info.data);
258 		*(vendor_info.version2) = vendor_info.hdr->version;
259 	}
260 	debug("[Vednor INFO]:ret=%d.\n", ret);
261 
262 #ifdef VENDOR_STORAGE_TEST
263 	if (vendor_storage_test())
264 		printf("[Vendor ERROR]:Vendor test result:failure\n");
265 #endif
266 
267 	return ret;
268 }
269 
270 int vendor_storage_read(u16 id, void *pbuf, u16 size)
271 {
272 	int ret = 0;
273 	u32 i;
274 	u16 offset;
275 	struct vendor_item *item;
276 
277 	/* init vendor storage */
278 	if (!bootdev_type) {
279 		ret = vendor_storage_init();
280 		if (ret)
281 			return ret;
282 	}
283 
284 	item = vendor_info.item;
285 	for (i = 0; i < vendor_info.hdr->item_num; i++) {
286 		if ((item + i)->id == id) {
287 			debug("[Vednor INFO]:Find the matching item, id=%d\n", id);
288 			/* Correct the size value */
289 			if (size > (item + i)->size)
290 				size = (item + i)->size;
291 			offset = (item + i)->offset;
292 			memcpy(pbuf, (vendor_info.data + offset), size);
293 			return size;
294 		}
295 	}
296 	debug("[Vednor ERROR]:No matching item, id=%d\n", id);
297 
298 	return -EINVAL;
299 }
300 
301 int vendor_storage_write(u16 id, void *pbuf, u16 size)
302 {
303 	int ret = 0;
304 	u32 i, next_index, align_size;
305 	struct vendor_item *item;
306 	u16 part_size, max_item_num, offset;
307 
308 	/* init vendor storage */
309 	if (!bootdev_type) {
310 		ret = vendor_storage_init();
311 		if (ret)
312 			return ret;
313 	}
314 
315 	switch (bootdev_type) {
316 	case BOOT_FROM_EMMC:
317 		part_size = EMMC_VENDOR_PART_BLKS;
318 		max_item_num = EMMC_VENDOR_ITEM_NUM;
319 		break;
320 	case BOOT_FROM_FLASH:
321 	case BOOT_FROM_SPI_NOR:
322 	case BOOT_FROM_SPI_NAND:
323 		part_size = FLASH_VENDOR_PART_BLKS;
324 		max_item_num = FLASH_VENDOR_ITEM_NUM;
325 		break;
326 	default:
327 		ret = -ENODEV;
328 		break;
329 	}
330 	/* Invalid bootdev? */
331 	if (ret)
332 		return ret;
333 
334 	next_index = vendor_info.hdr->next_index;
335 	/* algin to 64 bytes*/
336 	align_size = (size + VENDOR_BTYE_ALIGN) & (~VENDOR_BTYE_ALIGN);
337 	if (size > align_size)
338 		return -EINVAL;
339 
340 	item = vendor_info.item;
341 	/* If item already exist, update the item data */
342 	for (i = 0; i < vendor_info.hdr->item_num; i++) {
343 		if ((item + i)->id == id) {
344 			debug("[Vednor INFO]:Find the matching item, id=%d\n", id);
345 			offset = (item + i)->offset;
346 			memcpy((vendor_info.data + offset), pbuf, size);
347 			(item + i)->size = size;
348 			vendor_info.hdr->version++;
349 			*(vendor_info.version2) = vendor_info.hdr->version;
350 			vendor_info.hdr->next_index++;
351 			if (vendor_info.hdr->next_index >= VENDOR_PART_NUM)
352 				vendor_info.hdr->next_index = 0;
353 			return vendor_ops((u8 *)vendor_info.hdr, part_size * next_index, part_size, 1);
354 		}
355 	}
356 	/*
357 	 * If item does not exist, and free size is enough,
358 	 * creat a new one
359 	 */
360 	if ((vendor_info.hdr->item_num < max_item_num) &&
361 	    (vendor_info.hdr->free_size >= align_size)) {
362 		debug("[Vednor INFO]:Create new Item, id=%d\n", id);
363 		item = vendor_info.item + vendor_info.hdr->item_num;
364 		item->id = id;
365 		item->offset = vendor_info.hdr->free_offset;
366 		item->size = size;
367 
368 		vendor_info.hdr->free_offset += align_size;
369 		vendor_info.hdr->free_size -= align_size;
370 		memcpy((vendor_info.data + item->offset), pbuf, size);
371 		vendor_info.hdr->item_num++;
372 		vendor_info.hdr->version++;
373 		vendor_info.hdr->next_index++;
374 		*(vendor_info.version2) = vendor_info.hdr->version;
375 		if (vendor_info.hdr->next_index >= VENDOR_PART_NUM)
376 			vendor_info.hdr->next_index = 0;
377 
378 		return vendor_ops((u8 *)vendor_info.hdr, part_size * next_index, part_size, 1);
379 	}
380 	debug("[Vednor ERROR]:Vendor has no space left!\n");
381 
382 	return -ENOMEM;
383 }
384 
385 /**********************************************************/
386 /*              vendor API uinit test                      */
387 /**********************************************************/
388 #ifdef VENDOR_STORAGE_TEST
389 /* Reset the vendor storage space to the initial state */
390 void vendor_test_reset(void)
391 {
392 	u16 i, part_size;
393 	u32 size;
394 
395 	switch (bootdev_type) {
396 	case BOOT_FROM_EMMC:
397 		size = EMMC_VENDOR_INFO_SIZE;
398 		part_size = EMMC_VENDOR_PART_BLKS;
399 		break;
400 	case BOOT_FROM_FLASH:
401 	case BOOT_FROM_SPI_NOR:
402 	case BOOT_FROM_SPI_NAND:
403 		size = FLASH_VENDOR_INFO_SIZE;
404 		part_size = FLASH_VENDOR_PART_BLKS;
405 		break;
406 	default:
407 		size = 0;
408 		part_size = 0;
409 		break;
410 	}
411 	/* Invalid bootdev? */
412 	if (!size)
413 		return;
414 
415 	memset((u8 *)vendor_info.hdr, 0, size);
416 	vendor_info.hdr->version = 1;
417 	vendor_info.hdr->tag = VENDOR_TAG;
418 	/* data field length */
419 	vendor_info.hdr->free_size =
420 		((u32)vendor_info.hash - (u32)vendor_info.data);
421 	*(vendor_info.version2) = vendor_info.hdr->version;
422 	/* write to flash. */
423 	for (i = 0; i < VENDOR_PART_NUM; i++)
424 		vendor_ops((u8 *)vendor_info.hdr, part_size * i, part_size, 1);
425 }
426 
427 /*
428  * A total of four tests
429  * 1.All items test.
430  * 2.Overrides the maximum number of items test.
431  * 3.Single Item memory overflow test.
432  * 4.Total memory overflow test.
433  */
434 int vendor_storage_test(void)
435 {
436 	u16 id, size, j, item_num;
437 	u32 total_size;
438 	u8 *buffer = NULL;
439 	int ret = 0;
440 
441 	/*
442 	 * Calculate the maximum number of items and the maximum
443 	 * allocable memory for each item.
444 	 */
445 	switch (bootdev_type) {
446 	case BOOT_FROM_EMMC:
447 		item_num = EMMC_VENDOR_ITEM_NUM;
448 		total_size = (u32)vendor_info.hash - (u32)vendor_info.data;
449 		size = total_size/item_num;
450 		break;
451 	case BOOT_FROM_FLASH:
452 	case BOOT_FROM_SPI_NOR:
453 	case BOOT_FROM_SPI_NAND:
454 		item_num = FLASH_VENDOR_ITEM_NUM;
455 		total_size = (u32)vendor_info.hash - (u32)vendor_info.data;
456 		size = total_size/item_num;
457 		break;
458 	default:
459 		total_size = 0;
460 		break;
461 	}
462 	/* Invalid bootdev? */
463 	if (!total_size)
464 		return -ENODEV;
465 	/* 64 bytes are aligned and rounded down */
466 	size = (size/64)*64;
467 	/* malloc memory */
468 	buffer = (u8 *)malloc(size);
469 	if (!buffer) {
470 		printf("[Vendor Test]:Malloc failed(size=%d)!\n", size);
471 		return -ENOMEM;
472 	}
473 	printf("[Vendor Test]:Test Start...\n");
474 	printf("[Vendor Test]:Before Test, Vendor Resetting.\n");
475 	vendor_test_reset();
476 
477 	/* FIRST TEST: test all items can be used correctly */
478 	printf("[Vendor Test]:<All Items Used> Test Start...\n");
479 	printf("[Vendor Test]:item_num=%d, size=%d.\n",
480 	       item_num, size);
481 	/*
482 	 * Write data, then read the data, and compare the
483 	 * data consistency
484 	 */
485 	for (id = 0; id < item_num; id++) {
486 		memset(buffer, id, size);
487 		ret = vendor_storage_write(id, buffer, size);
488 		if (ret) {
489 			printf("[Vendor Test]:vendor write failed(id=%d)!\n", id);
490 			free(buffer);
491 			return ret;
492 		}
493 	}
494 	/* Read data */
495 	for (id = 0; id < item_num; id++) {
496 		memset(buffer, 0, size);
497 		ret = vendor_storage_read(id, buffer, size);
498 		if (ret != size) {
499 			printf("[Vendor Test]:vendor read failed(id=%d)!\n", id);
500 			free(buffer);
501 			return ret;
502 		}
503 		/* check data Correctness */
504 		for (j = 0; j < size; j++) {
505 			if (*(buffer + j) != id) {
506 				printf("[Vendor Test]:Unexpected error occurs(id=%d)\n", id);
507 				printf("the data content is:\n");
508 				print_buffer(0, buffer, 1, size, 16);
509 
510 				free(buffer);
511 				return -1;
512 			}
513 		}
514 		debug("\t#id=%03d success,data=0x%02x,size=%d.\n", id, *buffer, size);
515 	}
516 	printf("[Vendor Test]:<All Items Used> Test End,States:OK\n");
517 
518 	/*
519 	 * SECOND TEST: Overrides the maximum number of items to see if the
520 	 * return value matches the expectation
521 	 */
522 	printf("[Vendor Test]:<Overflow Items Cnt> Test Start...\n");
523 	/* Any id value that was not used before */
524 	id = item_num;
525 	printf("[Vendor Test]:id=%d, size=%d.\n", id, size);
526 	ret = vendor_storage_write(id, buffer, size);
527 	if (ret == -ENOMEM)
528 		printf("[Vendor Test]:<Overflow Items Cnt> Test End,States:OK\n");
529 	else
530 		printf("[Vendor Test]:<Overflow Items Cnt> Test End,States:Failed\n");
531 
532 	/* free buffer, remalloc later */
533 	free(buffer);
534 	buffer = NULL;
535 	/*
536 	 * remalloc memory and recalculate size to test memory overflow
537 	 * (1) item_num > 10: Memory is divided into 10 blocks,
538 	 * 11th memory will overflow.
539 	 * (2) 10 > item_num > 1: Memory is divided into item_num-1
540 	 * blocks. item_num block, memory will overflow.
541 	 * (3) item_num = 1: size = total_size + 512 Bytes, The first
542 	 * block, memory will overflow.
543 	 * The reason to do so is to minimize the size of the memory,
544 	 * making malloc easier to perform successfully.
545 	 */
546 	item_num = (item_num > 10) ? 10 : (item_num - 1);
547 	size = item_num ? (total_size / item_num) : (total_size + 512);
548 	size = (size + VENDOR_BTYE_ALIGN) & (~VENDOR_BTYE_ALIGN);
549 	/* Find item_num value that can make the memory overflow */
550 	for (id = 0; id <= item_num; id++) {
551 		if (((id + 1) * size) > total_size) {
552 			item_num = id;
553 			break;
554 		}
555 	}
556 	/* malloc */
557 	buffer = (u8 *)malloc(size);
558 	if (buffer == NULL) {
559 		printf("[Vendor Test]:Malloc failed(size=%d)!\n", size);
560 		return -ENOMEM;
561 	}
562 
563 	/* THIRD TEST: Single Item memory overflow test */
564 	printf("[Vendor Test]:<Single Item Memory Overflow> Test Start...\n");
565 	/* The value can be arbitrary */
566 	memset(buffer, 'a', size);
567 	/* Any id value that was used before */
568 	id = 0;
569 	printf("[Vendor Test]:id=%d, size=%d.\n", id, size);
570 	ret = vendor_storage_write(id, buffer, size);
571 	if (!ret)
572 		printf("[Vendor Test]:<Single Item Memory Overflow> Test End, States:OK\n");
573 	else
574 		printf("[Vendor Test]:<Single Item Memory Overflow> Test End, States:Failed\n");
575 
576 	/* FORTH TEST: Total memory overflow test */
577 	printf("[Vendor Test]:<Total memory overflow> Test Start...\n");
578 	printf("[Vendor Test]:item_num=%d, size=%d.\n", item_num, size);
579 
580 	vendor_test_reset();
581 	for (id = 0; id <= item_num; id++) {
582 		memset(buffer, id, size);
583 		ret = vendor_storage_write(id, buffer, size);
584 		if (ret) {
585 			if ((id == item_num) && (ret == -ENOMEM)) {
586 				printf("[Vendor Test]:<Total memory overflow> Test End, States:OK\n");
587 				break;
588 			} else {
589 				printf("[Vendor Test]:<Total memory overflow> Test End, States:Failed\n");
590 				break;
591 			}
592 		}
593 		debug("\t#id=%03d success,data=0x%02x,size=%d.\n", id, *buffer, size);
594 	}
595 
596 	/* Test end */
597 	printf("[Vendor Test]:After Test, Vendor Resetting...\n");
598 	vendor_test_reset();
599 	printf("[Vendor Test]:Test End.\n");
600 	free(buffer);
601 
602 	return 0;
603 }
604 #endif /* VENDOR_STORAGE_TEST */
605