fat.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (c) Copyright 2011 by Tigris Elektronik GmbH
  4. *
  5. * Author:
  6. * Maximilian Schwerin <mvs@tigris.de>
  7. */
  8. #include <common.h>
  9. #include <command.h>
  10. #include <env.h>
  11. #include <env_internal.h>
  12. #include <part.h>
  13. #include <malloc.h>
  14. #include <memalign.h>
  15. #include <search.h>
  16. #include <errno.h>
  17. #include <fat.h>
  18. #include <mmc.h>
  19. #include <asm/cache.h>
  20. #include <asm/global_data.h>
  21. #include <linux/stddef.h>
  22. #ifdef CONFIG_SPL_BUILD
  23. /* TODO(sjg@chromium.org): Figure out why this is needed */
  24. # if !defined(CONFIG_TARGET_AM335X_EVM) || defined(CONFIG_SPL_OS_BOOT)
  25. # define LOADENV
  26. # endif
  27. #else
  28. # define LOADENV
  29. #endif
  30. DECLARE_GLOBAL_DATA_PTR;
  31. static char *env_fat_device_and_part(void)
  32. {
  33. #ifdef CONFIG_MMC
  34. static char *part_str;
  35. if (!part_str) {
  36. part_str = CONFIG_ENV_FAT_DEVICE_AND_PART;
  37. if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc") && part_str[0] == ':') {
  38. part_str = "0" CONFIG_ENV_FAT_DEVICE_AND_PART;
  39. part_str[0] += mmc_get_env_dev();
  40. }
  41. }
  42. return part_str;
  43. #else
  44. return CONFIG_ENV_FAT_DEVICE_AND_PART;
  45. #endif
  46. }
  47. static int env_fat_save(void)
  48. {
  49. env_t __aligned(ARCH_DMA_MINALIGN) env_new;
  50. struct blk_desc *dev_desc = NULL;
  51. struct disk_partition info;
  52. const char *file = CONFIG_ENV_FAT_FILE;
  53. int dev, part;
  54. int err;
  55. loff_t size;
  56. err = env_export(&env_new);
  57. if (err)
  58. return err;
  59. part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
  60. env_fat_device_and_part(),
  61. &dev_desc, &info, 1);
  62. if (part < 0)
  63. return 1;
  64. dev = dev_desc->devnum;
  65. if (fat_set_blk_dev(dev_desc, &info) != 0) {
  66. /*
  67. * This printf is embedded in the messages from env_save that
  68. * will calling it. The missing \n is intentional.
  69. */
  70. printf("Unable to use %s %d:%d... ",
  71. CONFIG_ENV_FAT_INTERFACE, dev, part);
  72. return 1;
  73. }
  74. #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  75. if (gd->env_valid == ENV_VALID)
  76. file = CONFIG_ENV_FAT_FILE_REDUND;
  77. #endif
  78. err = file_fat_write(file, (void *)&env_new, 0, sizeof(env_t), &size);
  79. if (err == -1) {
  80. /*
  81. * This printf is embedded in the messages from env_save that
  82. * will calling it. The missing \n is intentional.
  83. */
  84. printf("Unable to write \"%s\" from %s%d:%d... ",
  85. file, CONFIG_ENV_FAT_INTERFACE, dev, part);
  86. return 1;
  87. }
  88. #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  89. gd->env_valid = (gd->env_valid == ENV_REDUND) ? ENV_VALID : ENV_REDUND;
  90. #endif
  91. return 0;
  92. }
  93. #ifdef LOADENV
  94. static int env_fat_load(void)
  95. {
  96. ALLOC_CACHE_ALIGN_BUFFER(char, buf1, CONFIG_ENV_SIZE);
  97. #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  98. ALLOC_CACHE_ALIGN_BUFFER(char, buf2, CONFIG_ENV_SIZE);
  99. int err2;
  100. #endif
  101. struct blk_desc *dev_desc = NULL;
  102. struct disk_partition info;
  103. int dev, part;
  104. int err1;
  105. #ifdef CONFIG_MMC
  106. if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc"))
  107. mmc_initialize(NULL);
  108. #endif
  109. part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
  110. env_fat_device_and_part(),
  111. &dev_desc, &info, 1);
  112. if (part < 0)
  113. goto err_env_relocate;
  114. dev = dev_desc->devnum;
  115. if (fat_set_blk_dev(dev_desc, &info) != 0) {
  116. /*
  117. * This printf is embedded in the messages from env_save that
  118. * will calling it. The missing \n is intentional.
  119. */
  120. printf("Unable to use %s %d:%d... ",
  121. CONFIG_ENV_FAT_INTERFACE, dev, part);
  122. goto err_env_relocate;
  123. }
  124. err1 = file_fat_read(CONFIG_ENV_FAT_FILE, buf1, CONFIG_ENV_SIZE);
  125. #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  126. err2 = file_fat_read(CONFIG_ENV_FAT_FILE_REDUND, buf2, CONFIG_ENV_SIZE);
  127. err1 = (err1 >= 0) ? 0 : -1;
  128. err2 = (err2 >= 0) ? 0 : -1;
  129. return env_import_redund(buf1, err1, buf2, err2, H_EXTERNAL);
  130. #else
  131. if (err1 < 0) {
  132. /*
  133. * This printf is embedded in the messages from env_save that
  134. * will calling it. The missing \n is intentional.
  135. */
  136. printf("Unable to read \"%s\" from %s%d:%d... ",
  137. CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part);
  138. goto err_env_relocate;
  139. }
  140. return env_import(buf1, 1, H_EXTERNAL);
  141. #endif
  142. err_env_relocate:
  143. env_set_default(NULL, 0);
  144. return -EIO;
  145. }
  146. #endif /* LOADENV */
  147. U_BOOT_ENV_LOCATION(fat) = {
  148. .location = ENVL_FAT,
  149. ENV_NAME("FAT")
  150. #ifdef LOADENV
  151. .load = env_fat_load,
  152. #endif
  153. .save = ENV_SAVE_PTR(env_fat_save),
  154. };