/src/u-boot/disk/part_mac.c
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0+ |
2 | | /* |
3 | | * (C) Copyright 2000 |
4 | | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
5 | | */ |
6 | | |
7 | | /* |
8 | | * Support for harddisk partitions. |
9 | | * |
10 | | * To be compatible with LinuxPPC and Apple we use the standard Apple |
11 | | * SCSI disk partitioning scheme. For more information see: |
12 | | * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 |
13 | | */ |
14 | | |
15 | | #include <command.h> |
16 | | #include <log.h> |
17 | | #include <memalign.h> |
18 | | #include "part_mac.h" |
19 | | #include <part.h> |
20 | | |
21 | | /* stdlib.h causes some compatibility problems; should fixe these! -- wd */ |
22 | | #ifndef __ldiv_t_defined |
23 | | typedef struct { |
24 | | long int quot; /* Quotient */ |
25 | | long int rem; /* Remainder */ |
26 | | } ldiv_t; |
27 | | extern ldiv_t ldiv (long int __numer, long int __denom); |
28 | | # define __ldiv_t_defined 1 |
29 | | #endif |
30 | | |
31 | | static int part_mac_read_ddb(struct blk_desc *desc, mac_driver_desc_t *ddb_p); |
32 | | static int part_mac_read_pdb(struct blk_desc *desc, int part, |
33 | | mac_partition_t *pdb_p); |
34 | | |
35 | | /* |
36 | | * Test for a valid MAC partition |
37 | | */ |
38 | | static int part_test_mac(struct blk_desc *desc) |
39 | 0 | { |
40 | 0 | ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); |
41 | 0 | ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); |
42 | 0 | ulong i, n; |
43 | |
|
44 | 0 | if (part_mac_read_ddb(desc, ddesc)) { |
45 | | /* |
46 | | * error reading Driver Descriptor Block, |
47 | | * or no valid Signature |
48 | | */ |
49 | 0 | return (-1); |
50 | 0 | } |
51 | | |
52 | 0 | n = 1; /* assuming at least one partition */ |
53 | 0 | for (i=1; i<=n; ++i) { |
54 | 0 | if ((blk_dread(desc, i, 1, (ulong *)mpart) != 1) || |
55 | 0 | mpart->signature != MAC_PARTITION_MAGIC) { |
56 | 0 | return (-1); |
57 | 0 | } |
58 | | /* update partition count */ |
59 | 0 | n = mpart->map_count; |
60 | 0 | } |
61 | 0 | return (0); |
62 | 0 | } |
63 | | |
64 | | static void part_print_mac(struct blk_desc *desc) |
65 | 0 | { |
66 | 0 | ulong i, n; |
67 | 0 | ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); |
68 | 0 | ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); |
69 | 0 | ldiv_t mb, gb; |
70 | |
|
71 | 0 | if (part_mac_read_ddb(desc, ddesc)) { |
72 | | /* |
73 | | * error reading Driver Descriptor Block, |
74 | | * or no valid Signature |
75 | | */ |
76 | 0 | return; |
77 | 0 | } |
78 | | |
79 | 0 | n = ddesc->blk_count; |
80 | |
|
81 | 0 | mb = ldiv(n, ((1024 * 1024) / ddesc->blk_size)); /* MB */ |
82 | | /* round to 1 digit */ |
83 | 0 | mb.rem *= 10 * ddesc->blk_size; |
84 | 0 | mb.rem += 512 * 1024; |
85 | 0 | mb.rem /= 1024 * 1024; |
86 | |
|
87 | 0 | gb = ldiv(10 * mb.quot + mb.rem, 10240); |
88 | 0 | gb.rem += 512; |
89 | 0 | gb.rem /= 1024; |
90 | |
|
91 | 0 | printf ("Block Size=%d, Number of Blocks=%d, " |
92 | 0 | "Total Capacity: %ld.%ld MB = %ld.%ld GB\n" |
93 | 0 | "DeviceType=0x%x, DeviceId=0x%x\n\n" |
94 | 0 | " #: type name" |
95 | 0 | " length base (size)\n", |
96 | 0 | ddesc->blk_size, |
97 | 0 | ddesc->blk_count, |
98 | 0 | mb.quot, mb.rem, gb.quot, gb.rem, |
99 | 0 | ddesc->dev_type, ddesc->dev_id |
100 | 0 | ); |
101 | |
|
102 | 0 | n = 1; /* assuming at least one partition */ |
103 | 0 | for (i=1; i<=n; ++i) { |
104 | 0 | ulong bytes; |
105 | 0 | char c; |
106 | |
|
107 | 0 | printf ("%4ld: ", i); |
108 | 0 | if (blk_dread(desc, i, 1, (ulong *)mpart) != 1) { |
109 | 0 | printf ("** Can't read Partition Map on %d:%ld **\n", |
110 | 0 | desc->devnum, i); |
111 | 0 | return; |
112 | 0 | } |
113 | | |
114 | 0 | if (mpart->signature != MAC_PARTITION_MAGIC) { |
115 | 0 | printf("** Bad Signature on %d:%ld - expected 0x%04x, got 0x%04x\n", |
116 | 0 | desc->devnum, i, MAC_PARTITION_MAGIC, |
117 | 0 | mpart->signature); |
118 | 0 | return; |
119 | 0 | } |
120 | | |
121 | | /* update partition count */ |
122 | 0 | n = mpart->map_count; |
123 | |
|
124 | 0 | c = 'k'; |
125 | 0 | bytes = mpart->block_count; |
126 | 0 | bytes /= (1024 / ddesc->blk_size); /* kB; assumes blk_size == 512 */ |
127 | 0 | if (bytes >= 1024) { |
128 | 0 | bytes >>= 10; |
129 | 0 | c = 'M'; |
130 | 0 | } |
131 | 0 | if (bytes >= 1024) { |
132 | 0 | bytes >>= 10; |
133 | 0 | c = 'G'; |
134 | 0 | } |
135 | |
|
136 | 0 | printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n", |
137 | 0 | mpart->type, |
138 | 0 | mpart->name, |
139 | 0 | mpart->block_count, |
140 | 0 | mpart->start_block, |
141 | 0 | bytes, c |
142 | 0 | ); |
143 | 0 | } |
144 | | |
145 | 0 | return; |
146 | 0 | } |
147 | | |
148 | | /* |
149 | | * Read Device Descriptor Block |
150 | | */ |
151 | | static int part_mac_read_ddb(struct blk_desc *desc, mac_driver_desc_t *ddb_p) |
152 | 0 | { |
153 | 0 | if (blk_dread(desc, 0, 1, (ulong *)ddb_p) != 1) { |
154 | 0 | debug("** Can't read Driver Descriptor Block **\n"); |
155 | 0 | return (-1); |
156 | 0 | } |
157 | | |
158 | 0 | if (ddb_p->signature != MAC_DRIVER_MAGIC) { |
159 | 0 | return (-1); |
160 | 0 | } |
161 | 0 | return (0); |
162 | 0 | } |
163 | | |
164 | | /* |
165 | | * Read Partition Descriptor Block |
166 | | */ |
167 | | static int part_mac_read_pdb(struct blk_desc *desc, int part, |
168 | | mac_partition_t *pdb_p) |
169 | 0 | { |
170 | 0 | int n = 1; |
171 | |
|
172 | 0 | for (;;) { |
173 | | /* |
174 | | * We must always read the descritpor block for |
175 | | * partition 1 first since this is the only way to |
176 | | * know how many partitions we have. |
177 | | */ |
178 | 0 | if (blk_dread(desc, n, 1, (ulong *)pdb_p) != 1) { |
179 | 0 | printf("** Can't read Partition Map on %d:%d **\n", |
180 | 0 | desc->devnum, n); |
181 | 0 | return (-1); |
182 | 0 | } |
183 | | |
184 | 0 | if (pdb_p->signature != MAC_PARTITION_MAGIC) { |
185 | 0 | printf("** Bad Signature on %d:%d: expected 0x%04x, got 0x%04x\n", |
186 | 0 | desc->devnum, n, MAC_PARTITION_MAGIC, |
187 | 0 | pdb_p->signature); |
188 | 0 | return (-1); |
189 | 0 | } |
190 | | |
191 | 0 | if (n == part) |
192 | 0 | return (0); |
193 | | |
194 | 0 | if ((part < 1) || (part > pdb_p->map_count)) { |
195 | 0 | printf("** Invalid partition %d:%d [%d:1...%d:%d only]\n", |
196 | 0 | desc->devnum, part, desc->devnum, desc->devnum, |
197 | 0 | pdb_p->map_count); |
198 | 0 | return (-1); |
199 | 0 | } |
200 | | |
201 | | /* update partition count */ |
202 | 0 | n = part; |
203 | 0 | } |
204 | | |
205 | | /* NOTREACHED */ |
206 | 0 | } |
207 | | |
208 | | static int part_get_info_mac(struct blk_desc *desc, int part, |
209 | | struct disk_partition *info) |
210 | 0 | { |
211 | 0 | ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); |
212 | 0 | ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); |
213 | |
|
214 | 0 | if (part_mac_read_ddb(desc, ddesc)) |
215 | 0 | return -1; |
216 | | |
217 | 0 | info->blksz = ddesc->blk_size; |
218 | |
|
219 | 0 | if (part_mac_read_pdb(desc, part, mpart)) |
220 | 0 | return -1; |
221 | | |
222 | 0 | info->start = mpart->start_block; |
223 | 0 | info->size = mpart->block_count; |
224 | 0 | memcpy (info->type, mpart->type, sizeof(info->type)); |
225 | 0 | memcpy (info->name, mpart->name, sizeof(info->name)); |
226 | |
|
227 | 0 | return (0); |
228 | 0 | } |
229 | | |
230 | | U_BOOT_PART_TYPE(mac) = { |
231 | | .name = "MAC", |
232 | | .part_type = PART_TYPE_MAC, |
233 | | .max_entries = MAC_ENTRY_NUMBERS, |
234 | | .get_info = part_get_info_mac, |
235 | | .print = part_print_mac, |
236 | | .test = part_test_mac, |
237 | | }; |