io_dummy.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <string.h>
  8. #include <common/debug.h>
  9. #include <drivers/io/io_driver.h>
  10. #include <drivers/io/io_dummy.h>
  11. #include <drivers/io/io_storage.h>
  12. struct file_state {
  13. int in_use;
  14. size_t size;
  15. };
  16. static struct file_state current_file = {0};
  17. /* Identify the device type as dummy */
  18. static io_type_t device_type_dummy(void)
  19. {
  20. return IO_TYPE_DUMMY;
  21. }
  22. /* Dummy device functions */
  23. static int dummy_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
  24. static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
  25. io_entity_t *entity);
  26. static int dummy_block_len(io_entity_t *entity, size_t *length);
  27. static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
  28. size_t length, size_t *length_read);
  29. static int dummy_block_close(io_entity_t *entity);
  30. static int dummy_dev_close(io_dev_info_t *dev_info);
  31. static const io_dev_connector_t dummy_dev_connector = {
  32. .dev_open = dummy_dev_open
  33. };
  34. static const io_dev_funcs_t dummy_dev_funcs = {
  35. .type = device_type_dummy,
  36. .open = dummy_block_open,
  37. .seek = NULL,
  38. .size = dummy_block_len,
  39. .read = dummy_block_read,
  40. .write = NULL,
  41. .close = dummy_block_close,
  42. .dev_init = NULL,
  43. .dev_close = dummy_dev_close,
  44. };
  45. static const io_dev_info_t dummy_dev_info = {
  46. .funcs = &dummy_dev_funcs,
  47. .info = (uintptr_t)NULL
  48. };
  49. /* Open a connection to the dummy device */
  50. static int dummy_dev_open(const uintptr_t dev_spec __attribute__((unused)),
  51. io_dev_info_t **dev_info)
  52. {
  53. assert(dev_info != NULL);
  54. *dev_info = (io_dev_info_t *)&dummy_dev_info;
  55. return 0;
  56. }
  57. /* Close a connection to the dummy device */
  58. static int dummy_dev_close(io_dev_info_t *dev_info)
  59. {
  60. return 0;
  61. }
  62. /* Open a file on the dummy device */
  63. static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
  64. io_entity_t *entity)
  65. {
  66. int result;
  67. const io_block_spec_t *block_spec = (io_block_spec_t *)spec;
  68. if (current_file.in_use == 0) {
  69. assert(block_spec != NULL);
  70. assert(entity != NULL);
  71. current_file.in_use = 1;
  72. current_file.size = block_spec->length;
  73. entity->info = (uintptr_t)&current_file;
  74. result = 0;
  75. } else {
  76. WARN("A Dummy device is already active. Close first.\n");
  77. result = -ENOMEM;
  78. }
  79. return result;
  80. }
  81. /* Return the size of a file on the dummy device */
  82. static int dummy_block_len(io_entity_t *entity, size_t *length)
  83. {
  84. assert(entity != NULL);
  85. assert(length != NULL);
  86. *length = ((struct file_state *)entity->info)->size;
  87. return 0;
  88. }
  89. /* Read data from a file on the dummy device */
  90. static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
  91. size_t length, size_t *length_read)
  92. {
  93. assert(length_read != NULL);
  94. *length_read = length;
  95. return 0;
  96. }
  97. /* Close a file on the dummy device */
  98. static int dummy_block_close(io_entity_t *entity)
  99. {
  100. assert(entity != NULL);
  101. entity->info = 0;
  102. current_file.in_use = 0;
  103. return 0;
  104. }
  105. /* Exported functions */
  106. /* Register the dummy driver with the IO abstraction */
  107. int register_io_dev_dummy(const io_dev_connector_t **dev_con)
  108. {
  109. int result;
  110. assert(dev_con != NULL);
  111. result = io_register_device(&dummy_dev_info);
  112. if (result == 0)
  113. *dev_con = &dummy_dev_connector;
  114. return result;
  115. }