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