1 /*
2 * Copyright (c) 2017 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <drivers/flash.h>
8
flash_get_page_info(const struct device * dev,off_t offs,uint32_t index,struct flash_pages_info * info)9 static int flash_get_page_info(const struct device *dev, off_t offs,
10 uint32_t index, struct flash_pages_info *info)
11 {
12 const struct flash_driver_api *api = dev->api;
13 const struct flash_pages_layout *layout;
14 size_t layout_size;
15 uint32_t index_jmp;
16
17 info->start_offset = 0;
18 info->index = 0U;
19
20 api->page_layout(dev, &layout, &layout_size);
21
22 while (layout_size--) {
23 info->size = layout->pages_size;
24 if (offs == 0) {
25 index_jmp = index - info->index;
26 } else {
27 index_jmp = (offs - info->start_offset) / info->size;
28 }
29
30 index_jmp = MIN(index_jmp, layout->pages_count);
31 info->start_offset += (index_jmp * info->size);
32 info->index += index_jmp;
33 if (index_jmp < layout->pages_count) {
34 return 0;
35 }
36
37 layout++;
38 }
39
40 return -EINVAL; /* page at offs or idx doesn't exist */
41 }
42
z_impl_flash_get_page_info_by_offs(const struct device * dev,off_t offs,struct flash_pages_info * info)43 int z_impl_flash_get_page_info_by_offs(const struct device *dev, off_t offs,
44 struct flash_pages_info *info)
45 {
46 return flash_get_page_info(dev, offs, 0U, info);
47 }
48
z_impl_flash_get_page_info_by_idx(const struct device * dev,uint32_t page_index,struct flash_pages_info * info)49 int z_impl_flash_get_page_info_by_idx(const struct device *dev,
50 uint32_t page_index,
51 struct flash_pages_info *info)
52 {
53 return flash_get_page_info(dev, 0, page_index, info);
54 }
55
z_impl_flash_get_page_count(const struct device * dev)56 size_t z_impl_flash_get_page_count(const struct device *dev)
57 {
58 const struct flash_driver_api *api = dev->api;
59 const struct flash_pages_layout *layout;
60 size_t layout_size;
61 size_t count = 0;
62
63 api->page_layout(dev, &layout, &layout_size);
64
65 while (layout_size--) {
66 count += layout->pages_count;
67 layout++;
68 }
69
70 return count;
71 }
72
flash_page_foreach(const struct device * dev,flash_page_cb cb,void * data)73 void flash_page_foreach(const struct device *dev, flash_page_cb cb,
74 void *data)
75 {
76 const struct flash_driver_api *api = dev->api;
77 const struct flash_pages_layout *layout;
78 struct flash_pages_info page_info;
79 size_t block, num_blocks, page = 0, i;
80 off_t off = 0;
81
82 api->page_layout(dev, &layout, &num_blocks);
83
84 for (block = 0; block < num_blocks; block++) {
85 const struct flash_pages_layout *l = &layout[block];
86 page_info.size = l->pages_size;
87
88 for (i = 0; i < l->pages_count; i++) {
89 page_info.start_offset = off;
90 page_info.index = page;
91
92 if (!cb(&page_info, data)) {
93 return;
94 }
95
96 off += page_info.size;
97 page++;
98 }
99 }
100 }
101