Commit 96e5b03c8ab749b6547f6a3ceb4d4b9f274211aa

Authored by Simon Glass
1 parent 14142811f4

dm: part: Convert partition API use to linker lists

We can use linker lists instead of explicitly declaring each function.
This makes the code shorter by avoiding switch() statements and lots of
header file declarations.

While this does clean up the code it introduces a few code issues with SPL.
SPL never needs to print partition information since this all happens from
commands. SPL mostly doesn't need to obtain information about a partition
either, except in a few cases. Add these cases so that the code will be
dropped from each partition driver when not needed. This avoids code bloat.

I think this is still a win, since it is not a bad thing to be explicit
about which features are used in SPL. But others may like to weigh in.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
Tested-by: Stephen Warren <swarren@nvidia.com>

Showing 7 changed files with 162 additions and 173 deletions Side-by-side Diff

... ... @@ -7,6 +7,7 @@
7 7  
8 8 #include <common.h>
9 9 #include <command.h>
  10 +#include <errno.h>
10 11 #include <ide.h>
11 12 #include <malloc.h>
12 13 #include <part.h>
... ... @@ -58,6 +59,22 @@
58 59 DECLARE_GLOBAL_DATA_PTR;
59 60  
60 61 #ifdef HAVE_BLOCK_DEVICE
  62 +static struct part_driver *part_driver_lookup_type(int part_type)
  63 +{
  64 + struct part_driver *drv =
  65 + ll_entry_start(struct part_driver, part_driver);
  66 + const int n_ents = ll_entry_count(struct part_driver, part_driver);
  67 + struct part_driver *entry;
  68 +
  69 + for (entry = drv; entry != drv + n_ents; entry++) {
  70 + if (part_type == entry->part_type)
  71 + return entry;
  72 + }
  73 +
  74 + /* Not found */
  75 + return NULL;
  76 +}
  77 +
61 78 static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
62 79 {
63 80 const struct block_drvr *drvr = block_drvr;
64 81  
65 82  
66 83  
67 84  
68 85  
... ... @@ -252,53 +269,31 @@
252 269  
253 270 void init_part(struct blk_desc *dev_desc)
254 271 {
255   -#ifdef CONFIG_ISO_PARTITION
256   - if (test_part_iso(dev_desc) == 0) {
257   - dev_desc->part_type = PART_TYPE_ISO;
258   - return;
259   - }
260   -#endif
  272 + struct part_driver *drv =
  273 + ll_entry_start(struct part_driver, part_driver);
  274 + const int n_ents = ll_entry_count(struct part_driver, part_driver);
  275 + struct part_driver *entry;
261 276  
262   -#ifdef CONFIG_MAC_PARTITION
263   - if (test_part_mac(dev_desc) == 0) {
264   - dev_desc->part_type = PART_TYPE_MAC;
265   - return;
266   - }
267   -#endif
  277 + dev_desc->part_type = PART_TYPE_UNKNOWN;
  278 + for (entry = drv; entry != drv + n_ents; entry++) {
  279 + int ret;
268 280  
269   -/* must be placed before DOS partition detection */
270   -#ifdef CONFIG_EFI_PARTITION
271   - if (test_part_efi(dev_desc) == 0) {
272   - dev_desc->part_type = PART_TYPE_EFI;
273   - return;
  281 + ret = entry->test(dev_desc);
  282 + debug("%s: try '%s': ret=%d\n", __func__, entry->name, ret);
  283 + if (!ret) {
  284 + dev_desc->part_type = entry->part_type;
  285 + break;
  286 + }
274 287 }
275   -#endif
276   -
277   -#ifdef CONFIG_DOS_PARTITION
278   - if (test_part_dos(dev_desc) == 0) {
279   - dev_desc->part_type = PART_TYPE_DOS;
280   - return;
281   - }
282   -#endif
283   -
284   -#ifdef CONFIG_AMIGA_PARTITION
285   - if (test_part_amiga(dev_desc) == 0) {
286   - dev_desc->part_type = PART_TYPE_AMIGA;
287   - return;
288   - }
289   -#endif
290   - dev_desc->part_type = PART_TYPE_UNKNOWN;
291 288 }
292 289  
293   -
  290 +static void print_part_header(const char *type, struct blk_desc *dev_desc)
  291 +{
294 292 #if defined(CONFIG_MAC_PARTITION) || \
295 293 defined(CONFIG_DOS_PARTITION) || \
296 294 defined(CONFIG_ISO_PARTITION) || \
297 295 defined(CONFIG_AMIGA_PARTITION) || \
298 296 defined(CONFIG_EFI_PARTITION)
299   -
300   -static void print_part_header(const char *type, struct blk_desc *dev_desc)
301   -{
302 297 puts ("\nPartition Map for ");
303 298 switch (dev_desc->if_type) {
304 299 case IF_TYPE_IDE:
305 300  
306 301  
307 302  
308 303  
309 304  
... ... @@ -331,54 +326,24 @@
331 326 }
332 327 printf (" device %d -- Partition Type: %s\n\n",
333 328 dev_desc->dev, type);
  329 +#endif /* any CONFIG_..._PARTITION */
334 330 }
335 331  
336   -#endif /* any CONFIG_..._PARTITION */
337   -
338 332 void print_part(struct blk_desc *dev_desc)
339 333 {
  334 + struct part_driver *drv;
340 335  
341   - switch (dev_desc->part_type) {
342   -#ifdef CONFIG_MAC_PARTITION
343   - case PART_TYPE_MAC:
344   - PRINTF ("## Testing for valid MAC partition ##\n");
345   - print_part_header ("MAC", dev_desc);
346   - print_part_mac (dev_desc);
  336 + drv = part_driver_lookup_type(dev_desc->part_type);
  337 + if (!drv) {
  338 + printf("## Unknown partition table type %x\n",
  339 + dev_desc->part_type);
347 340 return;
348   -#endif
349   -#ifdef CONFIG_DOS_PARTITION
350   - case PART_TYPE_DOS:
351   - PRINTF ("## Testing for valid DOS partition ##\n");
352   - print_part_header ("DOS", dev_desc);
353   - print_part_dos (dev_desc);
354   - return;
355   -#endif
356   -
357   -#ifdef CONFIG_ISO_PARTITION
358   - case PART_TYPE_ISO:
359   - PRINTF ("## Testing for valid ISO Boot partition ##\n");
360   - print_part_header ("ISO", dev_desc);
361   - print_part_iso (dev_desc);
362   - return;
363   -#endif
364   -
365   -#ifdef CONFIG_AMIGA_PARTITION
366   - case PART_TYPE_AMIGA:
367   - PRINTF ("## Testing for a valid Amiga partition ##\n");
368   - print_part_header ("AMIGA", dev_desc);
369   - print_part_amiga (dev_desc);
370   - return;
371   -#endif
372   -
373   -#ifdef CONFIG_EFI_PARTITION
374   - case PART_TYPE_EFI:
375   - PRINTF ("## Testing for valid EFI partition ##\n");
376   - print_part_header ("EFI", dev_desc);
377   - print_part_efi (dev_desc);
378   - return;
379   -#endif
380 341 }
381   - puts ("## Unknown partition table\n");
  342 +
  343 + PRINTF("## Testing for valid %s partition ##\n", drv->name);
  344 + print_part_header(drv->name, dev_desc);
  345 + if (drv->print)
  346 + drv->print(dev_desc);
382 347 }
383 348  
384 349 #endif /* HAVE_BLOCK_DEVICE */
... ... @@ -387,6 +352,7 @@
387 352 disk_partition_t *info)
388 353 {
389 354 #ifdef HAVE_BLOCK_DEVICE
  355 + struct part_driver *drv;
390 356  
391 357 #ifdef CONFIG_PARTITION_UUIDS
392 358 /* The common case is no UUID support */
... ... @@ -396,53 +362,19 @@
396 362 info->type_guid[0] = 0;
397 363 #endif
398 364  
399   - switch (dev_desc->part_type) {
400   -#ifdef CONFIG_MAC_PARTITION
401   - case PART_TYPE_MAC:
402   - if (get_partition_info_mac(dev_desc, part, info) == 0) {
403   - PRINTF("## Valid MAC partition found ##\n");
404   - return 0;
405   - }
406   - break;
407   -#endif
408   -
409   -#ifdef CONFIG_DOS_PARTITION
410   - case PART_TYPE_DOS:
411   - if (get_partition_info_dos(dev_desc, part, info) == 0) {
412   - PRINTF("## Valid DOS partition found ##\n");
413   - return 0;
414   - }
415   - break;
416   -#endif
417   -
418   -#ifdef CONFIG_ISO_PARTITION
419   - case PART_TYPE_ISO:
420   - if (get_partition_info_iso(dev_desc, part, info) == 0) {
421   - PRINTF("## Valid ISO boot partition found ##\n");
422   - return 0;
423   - }
424   - break;
425   -#endif
426   -
427   -#ifdef CONFIG_AMIGA_PARTITION
428   - case PART_TYPE_AMIGA:
429   - if (get_partition_info_amiga(dev_desc, part, info) == 0) {
430   - PRINTF("## Valid Amiga partition found ##\n");
431   - return 0;
432   - }
433   - break;
434   -#endif
435   -
436   -#ifdef CONFIG_EFI_PARTITION
437   - case PART_TYPE_EFI:
438   - if (get_partition_info_efi(dev_desc, part, info) == 0) {
439   - PRINTF("## Valid EFI partition found ##\n");
440   - return 0;
441   - }
442   - break;
443   -#endif
444   - default:
445   - break;
  365 + drv = part_driver_lookup_type(dev_desc->part_type);
  366 + if (!drv) {
  367 + debug("## Unknown partition table type %x\n",
  368 + dev_desc->part_type);
  369 + return -EPROTONOSUPPORT;
  370 + }
  371 + if (!drv->get_info) {
  372 + PRINTF("## Driver %s does not have the get_info() method\n");
  373 + return -ENOSYS;
  374 + }
  375 + if (drv->get_info(dev_desc, part, info) == 0) {
  376 + PRINTF("## Valid %s partition found ##\n", drv->name);
  377 + return 0;
446 378 }
447 379 #endif /* HAVE_BLOCK_DEVICE */
448 380  
... ... @@ -207,7 +207,7 @@
207 207 * Test if the given partition has an Amiga partition table/Rigid
208 208 * Disk block
209 209 */
210   -int test_part_amiga(struct blk_desc *dev_desc)
  210 +static int test_part_amiga(struct blk_desc *dev_desc)
211 211 {
212 212 struct rigid_disk_block *rdb;
213 213 struct bootcode_block *bootcode;
... ... @@ -291,8 +291,8 @@
291 291 /*
292 292 * Get info about a partition
293 293 */
294   -int get_partition_info_amiga(struct blk_desc *dev_desc, int part,
295   - disk_partition_t *info)
  294 +static int get_partition_info_amiga(struct blk_desc *dev_desc, int part,
  295 + disk_partition_t *info)
296 296 {
297 297 struct partition_block *p = find_partition(dev_desc, part-1);
298 298 struct amiga_part_geometry *g;
... ... @@ -319,7 +319,7 @@
319 319 return 0;
320 320 }
321 321  
322   -void print_part_amiga(struct blk_desc *dev_desc)
  322 +static void print_part_amiga(struct blk_desc *dev_desc)
323 323 {
324 324 struct rigid_disk_block *rdb;
325 325 struct bootcode_block *boot;
... ... @@ -378,6 +378,14 @@
378 378 printf("Disk is bootable\n");
379 379 }
380 380 }
  381 +
  382 +U_BOOT_PART_TYPE(amiga) = {
  383 + .name = "AMIGA",
  384 + .part_type = PART_TYPE_AMIGA,
  385 + .get_info = get_partition_info_amiga,
  386 + .print = print_part_amiga,
  387 + .test = test_part_amiga,
  388 +};
381 389  
382 390 #endif
... ... @@ -87,7 +87,7 @@
87 87 }
88 88  
89 89  
90   -int test_part_dos(struct blk_desc *dev_desc)
  90 +static int test_part_dos(struct blk_desc *dev_desc)
91 91 {
92 92 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
93 93  
... ... @@ -295,6 +295,13 @@
295 295 return get_partition_info_extended(dev_desc, 0, 0, 1, part, info, 0);
296 296 }
297 297  
  298 +U_BOOT_PART_TYPE(dos) = {
  299 + .name = "DOS",
  300 + .part_type = PART_TYPE_DOS,
  301 + .get_info = part_get_info_ptr(get_partition_info_dos),
  302 + .print = part_print_ptr(print_part_dos),
  303 + .test = test_part_dos,
  304 +};
298 305  
299 306 #endif
... ... @@ -319,7 +319,7 @@
319 319 return -2;
320 320 }
321 321  
322   -int test_part_efi(struct blk_desc *dev_desc)
  322 +static int test_part_efi(struct blk_desc *dev_desc)
323 323 {
324 324 ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
325 325  
... ... @@ -953,5 +953,18 @@
953 953 return 1;
954 954 }
955 955 }
  956 +
  957 +/*
  958 + * Add an 'a_' prefix so it comes before 'dos' in the linker list. We need to
  959 + * check EFI first, since a DOS partition is often used as a 'protective MBR'
  960 + * with EFI.
  961 + */
  962 +U_BOOT_PART_TYPE(a_efi) = {
  963 + .name = "EFI",
  964 + .part_type = PART_TYPE_EFI,
  965 + .get_info = part_get_info_ptr(get_partition_info_efi),
  966 + .print = part_print_ptr(print_part_efi),
  967 + .test = test_part_efi,
  968 +};
956 969 #endif
... ... @@ -217,14 +217,13 @@
217 217 return 0;
218 218 }
219 219  
220   -int get_partition_info_iso(struct blk_desc *dev_desc, int part_num,
221   - disk_partition_t *info)
  220 +static int get_partition_info_iso(struct blk_desc *dev_desc, int part_num,
  221 + disk_partition_t *info)
222 222 {
223 223 return(get_partition_info_iso_verb(dev_desc, part_num, info, 1));
224 224 }
225 225  
226   -
227   -void print_part_iso(struct blk_desc *dev_desc)
  226 +static void print_part_iso(struct blk_desc *dev_desc)
228 227 {
229 228 disk_partition_t info;
230 229 int i;
231 230  
... ... @@ -241,12 +240,19 @@
241 240 } while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);
242 241 }
243 242  
244   -int test_part_iso(struct blk_desc *dev_desc)
  243 +static int test_part_iso(struct blk_desc *dev_desc)
245 244 {
246 245 disk_partition_t info;
247 246  
248 247 return(get_partition_info_iso_verb(dev_desc,0,&info,0));
249 248 }
250 249  
  250 +U_BOOT_PART_TYPE(iso) = {
  251 + .name = "ISO",
  252 + .part_type = PART_TYPE_ISO,
  253 + .get_info = get_partition_info_iso,
  254 + .print = print_part_iso,
  255 + .test = test_part_iso,
  256 +};
251 257 #endif
... ... @@ -40,7 +40,7 @@
40 40 /*
41 41 * Test for a valid MAC partition
42 42 */
43   -int test_part_mac(struct blk_desc *dev_desc)
  43 +static int test_part_mac(struct blk_desc *dev_desc)
44 44 {
45 45 ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
46 46 ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
... ... @@ -64,8 +64,7 @@
64 64 return (0);
65 65 }
66 66  
67   -
68   -void print_part_mac(struct blk_desc *dev_desc)
  67 +static void print_part_mac(struct blk_desc *dev_desc)
69 68 {
70 69 ulong i, n;
71 70 ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
... ... @@ -214,8 +213,8 @@
214 213 /* NOTREACHED */
215 214 }
216 215  
217   -int get_partition_info_mac(struct blk_desc *dev_desc, int part,
218   - disk_partition_t *info)
  216 +static int get_partition_info_mac(struct blk_desc *dev_desc, int part,
  217 + disk_partition_t *info)
219 218 {
220 219 ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
221 220 ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
... ... @@ -238,5 +237,12 @@
238 237 return (0);
239 238 }
240 239  
  240 +U_BOOT_PART_TYPE(mac) = {
  241 + .name = "MAC",
  242 + .part_type = PART_TYPE_MAC,
  243 + .get_info = get_partition_info_mac,
  244 + .print = print_part_mac,
  245 + .test = test_part_mac,
  246 +};
241 247 #endif
... ... @@ -195,43 +195,62 @@
195 195 { *dev_desc = NULL; return -1; }
196 196 #endif
197 197  
198   -#ifdef CONFIG_MAC_PARTITION
199   -/* disk/part_mac.c */
200   -int get_partition_info_mac(struct blk_desc *dev_desc, int part,
201   - disk_partition_t *info);
202   -void print_part_mac(struct blk_desc *dev_desc);
203   -int test_part_mac(struct blk_desc *dev_desc);
  198 +/*
  199 + * We don't support printing partition information in SPL and only support
  200 + * getting partition information in a few cases.
  201 + */
  202 +#ifdef CONFIG_SPL_BUILD
  203 +# define part_print_ptr(x) NULL
  204 +# if defined(CONFIG_SPL_EXT_SUPPORT) || \
  205 + defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION)
  206 +# define part_get_info_ptr(x) x
  207 +# else
  208 +# define part_get_info_ptr(x) NULL
  209 +# endif
  210 +#else
  211 +#define part_print_ptr(x) x
  212 +#define part_get_info_ptr(x) x
204 213 #endif
205 214  
206   -#ifdef CONFIG_DOS_PARTITION
207   -/* disk/part_dos.c */
208   -int get_partition_info_dos(struct blk_desc *dev_desc, int part,
209   - disk_partition_t *info);
210   -void print_part_dos(struct blk_desc *dev_desc);
211   -int test_part_dos(struct blk_desc *dev_desc);
212   -#endif
213 215  
214   -#ifdef CONFIG_ISO_PARTITION
215   -/* disk/part_iso.c */
216   -int get_partition_info_iso(struct blk_desc *dev_desc, int part,
217   - disk_partition_t *info);
218   -void print_part_iso(struct blk_desc *dev_desc);
219   -int test_part_iso(struct blk_desc *dev_desc);
220   -#endif
  216 +struct part_driver {
  217 + const char *name;
  218 + int part_type;
221 219  
222   -#ifdef CONFIG_AMIGA_PARTITION
223   -/* disk/part_amiga.c */
224   -int get_partition_info_amiga(struct blk_desc *dev_desc, int part,
225   - disk_partition_t *info);
226   -void print_part_amiga(struct blk_desc *dev_desc);
227   -int test_part_amiga(struct blk_desc *dev_desc);
228   -#endif
  220 + /**
  221 + * get_info() - Get information about a partition
  222 + *
  223 + * @dev_desc: Block device descriptor
  224 + * @part: Partition number (1 = first)
  225 + * @info: Returns partition information
  226 + */
  227 + int (*get_info)(struct blk_desc *dev_desc, int part,
  228 + disk_partition_t *info);
229 229  
  230 + /**
  231 + * print() - Print partition information
  232 + *
  233 + * @dev_desc: Block device descriptor
  234 + */
  235 + void (*print)(struct blk_desc *dev_desc);
  236 +
  237 + /**
  238 + * test() - Test if a device contains this partition type
  239 + *
  240 + * @dev_desc: Block device descriptor
  241 + * @return 0 if the block device appears to contain this partition
  242 + * type, -ve if not
  243 + */
  244 + int (*test)(struct blk_desc *dev_desc);
  245 +};
  246 +
  247 +/* Declare a new U-Boot partition 'driver' */
  248 +#define U_BOOT_PART_TYPE(__name) \
  249 + ll_entry_declare(struct part_driver, __name, part_driver)
  250 +
230 251 #ifdef CONFIG_EFI_PARTITION
231 252 #include <part_efi.h>
232 253 /* disk/part_efi.c */
233   -int get_partition_info_efi(struct blk_desc *dev_desc, int part,
234   - disk_partition_t *info);
235 254 /**
236 255 * get_partition_info_efi_by_name() - Find the specified GPT partition table entry
237 256 *
... ... @@ -243,8 +262,6 @@
243 262 */
244 263 int get_partition_info_efi_by_name(struct blk_desc *dev_desc,
245 264 const char *name, disk_partition_t *info);
246   -void print_part_efi(struct blk_desc *dev_desc);
247   -int test_part_efi(struct blk_desc *dev_desc);
248 265  
249 266 /**
250 267 * write_gpt_table() - Write the GUID Partition Table to disk