blk_partition.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. #define DBG_TAG "blk.part"
  11. #define DBG_LVL DBG_INFO
  12. #include <rtdbg.h>
  13. #include "blk_partition.h"
  14. static rt_err_t (*partition_list[])(struct rt_blk_disk *) =
  15. {
  16. #ifdef RT_BLK_PARTITION_EFI
  17. efi_partition,
  18. #endif
  19. #ifdef RT_BLK_PARTITION_DFS
  20. dfs_partition,
  21. #endif
  22. };
  23. rt_err_t blk_put_partition(struct rt_blk_disk *disk, const char *type,
  24. rt_size_t start, rt_size_t count, int partno)
  25. {
  26. rt_err_t err;
  27. struct rt_blk_device *blk = rt_calloc(1, sizeof(*blk));
  28. if (type && rt_strcmp(type, "dfs"))
  29. {
  30. rt_uint32_t ssz = rt_blk_disk_get_logical_block_size(disk);
  31. rt_kprintf("found part[%u], begin: %lu, size: ", partno, start * ssz);
  32. if ((count >> 11) == 0)
  33. {
  34. rt_kprintf("%u%cB\n", count >> 1, 'K'); /* KB */
  35. }
  36. else
  37. {
  38. rt_uint32_t size_mb = count >> 11; /* MB */
  39. if ((size_mb >> 10) == 0)
  40. {
  41. rt_kprintf("%u.%u%cB\n", size_mb, (count >> 1) & 0x3ff, 'M');
  42. }
  43. else
  44. {
  45. rt_kprintf("%u.%u%cB\n", size_mb >> 10, size_mb & 0x3ff, 'G');
  46. }
  47. }
  48. }
  49. if (!blk)
  50. {
  51. err = -RT_ENOMEM;
  52. goto _fail;
  53. }
  54. err = blk_dev_initialize(blk);
  55. if (err)
  56. {
  57. goto _fail;
  58. }
  59. blk->partno = partno;
  60. blk->sector_start = start;
  61. blk->sector_count = count;
  62. blk->partition.offset = start;
  63. blk->partition.size = count;
  64. blk->partition.lock = &disk->usr_lock;
  65. err = disk_add_blk_dev(disk, blk);
  66. if (err)
  67. {
  68. goto _fail;
  69. }
  70. ++disk->partitions;
  71. return RT_EOK;
  72. _fail:
  73. LOG_E("%s: Put partition.%s[%u] start = %lu count = %lu error = %s",
  74. to_disk_name(disk), type, partno, start, count, rt_strerror(err));
  75. if (blk)
  76. {
  77. rt_free(blk);
  78. }
  79. return err;
  80. }
  81. rt_err_t rt_blk_disk_probe_partition(struct rt_blk_disk *disk)
  82. {
  83. rt_err_t err = RT_EOK;
  84. if (!disk)
  85. {
  86. return -RT_EINVAL;
  87. }
  88. LOG_D("%s: Probing disk partitions", to_disk_name(disk));
  89. if (disk->partitions)
  90. {
  91. return err;
  92. }
  93. err = -RT_EEMPTY;
  94. if (disk->max_partitions == RT_BLK_PARTITION_NONE)
  95. {
  96. LOG_D("%s: Unsupported partitions", to_disk_name(disk));
  97. return err;
  98. }
  99. for (int i = 0; i < RT_ARRAY_SIZE(partition_list); ++i)
  100. {
  101. rt_err_t part_err = partition_list[i](disk);
  102. if (part_err == -RT_ENOMEM)
  103. {
  104. err = part_err;
  105. break;
  106. }
  107. if (!part_err)
  108. {
  109. err = RT_EOK;
  110. break;
  111. }
  112. }
  113. if ((err && err != -RT_ENOMEM) || disk->partitions == 0)
  114. {
  115. /* No partition found */
  116. rt_size_t total_sectors = rt_blk_disk_get_capacity(disk);
  117. err = blk_put_partition(disk, RT_NULL, 0, total_sectors, 0);
  118. }
  119. return err;
  120. }