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