1 /*
2  * Copyright (c) 2016 Intel Corporation.
3  * Copyright (c) 2023 Husqvarna AB
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include "test_fat.h"
9 #ifdef CONFIG_DISK_DRIVER_FLASH
10 #include <zephyr/storage/flash_map.h>
11 #else
12 #include <zephyr/storage/disk_access.h>
13 #endif
14 
15 /* FatFs work area */
16 FATFS fat_fs;
17 struct fs_file_t filep;
18 const char test_str[] = "hello world!";
19 
20 /* For large disks, we only send 1024 erase requests
21  * This assumption relies on the fact that any filesystem headers will be
22  * stored within this range, and is made to improve execution time of this
23  * test
24  */
25 #define MAX_ERASES 1024
26 
check_file_dir_exists(const char * path)27 int check_file_dir_exists(const char *path)
28 {
29 	int res;
30 	struct fs_dirent entry;
31 
32 	/* Verify fs_stat() */
33 	res = fs_stat(path, &entry);
34 
35 	return !res;
36 }
37 
38 #ifdef CONFIG_DISK_DRIVER_FLASH
wipe_partition(void)39 int wipe_partition(void)
40 {
41 	/* In this test the first partition on flash device is used for FAT */
42 	unsigned int id = 0;
43 	const struct flash_area *pfa;
44 	int rc = flash_area_open(id, &pfa);
45 
46 	if (rc < 0) {
47 		TC_PRINT("Error accessing flash area %u [%d]\n",
48 			 id, rc);
49 		return TC_FAIL;
50 	}
51 
52 	TC_PRINT("Erasing %zu (0x%zx) bytes\n", pfa->fa_size, pfa->fa_size);
53 	rc = flash_area_flatten(pfa, 0, pfa->fa_size);
54 	(void)flash_area_close(pfa);
55 
56 	if (rc < 0) {
57 		TC_PRINT("Error wiping flash area %u [%d]\n",
58 			 id, rc);
59 		return TC_FAIL;
60 	}
61 
62 	return TC_PASS;
63 }
64 #else
65 static uint8_t erase_buffer[4096] = { 0 };
66 
wipe_partition(void)67 int wipe_partition(void)
68 {
69 	uint32_t sector_size;
70 	uint32_t sector_count;
71 	uint32_t sector_wr_jmp;
72 	uint32_t sector_wr_size;
73 
74 	if (disk_access_init(DISK_NAME)) {
75 		TC_PRINT("Failed to init disk "DISK_NAME"\n");
76 		return TC_FAIL;
77 	}
78 	if (disk_access_ioctl(DISK_NAME, DISK_IOCTL_GET_SECTOR_COUNT, &sector_count)) {
79 		TC_PRINT("Failed to get disk "DISK_NAME" sector count\n");
80 		return TC_FAIL;
81 	}
82 	if (disk_access_ioctl(DISK_NAME, DISK_IOCTL_GET_SECTOR_SIZE, &sector_size)) {
83 		TC_PRINT("Failed to get disk "DISK_NAME" sector size\n");
84 		return TC_FAIL;
85 	}
86 
87 	if (sector_size > ARRAY_SIZE(erase_buffer)) {
88 		TC_PRINT("Predefined \"erase_buffer\" to small to handle single sector\n");
89 		return TC_FAIL;
90 	}
91 
92 	sector_wr_size = MIN(sector_size, ARRAY_SIZE(erase_buffer));
93 	sector_wr_jmp = sector_wr_size / sector_wr_size;
94 	TC_PRINT("For "DISK_NAME" using sector write size %"PRIu32" to write %"PRIu32" at once\n",
95 		 sector_wr_size, sector_wr_jmp);
96 
97 	for (uint32_t sector_idx = 0; sector_idx < sector_count; sector_idx += sector_wr_jmp) {
98 		if (disk_access_write(DISK_NAME, erase_buffer, sector_idx, 1)) {
99 			TC_PRINT("Failed to \"erase\" sector %"PRIu32" to "DISK_NAME"\n",
100 				 sector_idx);
101 			return TC_FAIL;
102 		}
103 	}
104 
105 	return TC_PASS;
106 }
107 #endif
108