1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-02-25 GuEe-GUI the first version
9 */
10
11 #define DBG_TAG "blk.part"
12 #define DBG_LVL DBG_INFO
13 #include <rtdbg.h>
14
15 #include "blk_partition.h"
16
17 static rt_err_t (*partition_list[])(struct rt_blk_disk *) =
18 {
19 #ifdef RT_BLK_PARTITION_EFI
20 efi_partition,
21 #endif
22 #ifdef RT_BLK_PARTITION_DFS
23 dfs_partition,
24 #endif
25 };
26
blk_put_partition(struct rt_blk_disk * disk,const char * type,rt_size_t start,rt_size_t count,int partno)27 rt_err_t blk_put_partition(struct rt_blk_disk *disk, const char *type,
28 rt_size_t start, rt_size_t count, int partno)
29 {
30 rt_err_t err;
31
32 struct rt_blk_device *blk = rt_calloc(1, sizeof(*blk));
33
34 if (type && rt_strcmp(type, "dfs"))
35 {
36 rt_uint32_t ssz = rt_blk_disk_get_logical_block_size(disk);
37
38 rt_kprintf("found part[%u], begin: %lu, size: ", partno, start * ssz);
39
40 if ((count >> 11) == 0)
41 {
42 rt_kprintf("%u%cB\n", count >> 1, 'K'); /* KB */
43 }
44 else
45 {
46 rt_uint32_t size_mb = count >> 11; /* MB */
47
48 if ((size_mb >> 10) == 0)
49 {
50 rt_kprintf("%u.%u%cB\n", size_mb, (count >> 1) & 0x3ff, 'M');
51 }
52 else
53 {
54 rt_kprintf("%u.%u%cB\n", size_mb >> 10, size_mb & 0x3ff, 'G');
55 }
56 }
57 }
58
59 if (!blk)
60 {
61 err = -RT_ENOMEM;
62 goto _fail;
63 }
64
65 err = blk_dev_initialize(blk);
66
67 if (err)
68 {
69 goto _fail;
70 }
71
72 blk->partno = partno;
73 blk->sector_start = start;
74 blk->sector_count = count;
75
76 blk->partition.offset = start;
77 blk->partition.size = count;
78 blk->partition.lock = &disk->usr_lock;
79
80 err = disk_add_blk_dev(disk, blk);
81
82 if (err)
83 {
84 goto _fail;
85 }
86
87 ++disk->partitions;
88
89 return RT_EOK;
90
91 _fail:
92 LOG_E("%s: Put partition.%s[%u] start = %lu count = %lu error = %s",
93 to_disk_name(disk), type, partno, start, count, rt_strerror(err));
94
95 if (blk)
96 {
97 rt_free(blk);
98 }
99
100 return err;
101 }
102
rt_blk_disk_probe_partition(struct rt_blk_disk * disk)103 rt_err_t rt_blk_disk_probe_partition(struct rt_blk_disk *disk)
104 {
105 rt_err_t err = RT_EOK;
106
107 if (!disk)
108 {
109 return -RT_EINVAL;
110 }
111
112 LOG_D("%s: Probing disk partitions", to_disk_name(disk));
113
114 if (disk->partitions)
115 {
116 return err;
117 }
118
119 err = -RT_EEMPTY;
120
121 if (disk->max_partitions == RT_BLK_PARTITION_NONE)
122 {
123 LOG_D("%s: Unsupported partitions", to_disk_name(disk));
124
125 return err;
126 }
127
128 for (int i = 0; i < RT_ARRAY_SIZE(partition_list); ++i)
129 {
130 rt_err_t part_err = partition_list[i](disk);
131
132 if (part_err == -RT_ENOMEM)
133 {
134 err = part_err;
135 break;
136 }
137
138 if (!part_err)
139 {
140 err = RT_EOK;
141 break;
142 }
143 }
144
145 if ((err && err != -RT_ENOMEM) || disk->partitions == 0)
146 {
147 /* No partition found */
148 rt_size_t total_sectors = rt_blk_disk_get_capacity(disk);
149
150 err = blk_put_partition(disk, RT_NULL, 0, total_sectors, 0);
151 }
152
153 return err;
154 }
155