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