qld.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * Copyright (c) 2019 The Linux Foundation. All rights reserved.
  3. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for
  6. * any purpose with or without fee is hereby granted, provided that the
  7. * above copyright notice and this permission notice appear in all
  8. * copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  14. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  15. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  16. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. * PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. /**
  20. * DOC: qld
  21. * QLD: main file of QCA Live Dump (QLD)
  22. */
  23. #include "qld_priv.h"
  24. #include "qld_api.h"
  25. #include "qdf_module.h"
  26. /* Handle for qld structure */
  27. static struct qld_list_handle *qld_handle;
  28. bool is_qld_enable(void)
  29. {
  30. if (!qld_handle)
  31. return false;
  32. return true;
  33. }
  34. qdf_export_symbol(is_qld_enable);
  35. int qld_list_init(uint32_t max_list)
  36. {
  37. if (!max_list)
  38. return -EINVAL;
  39. qld_handle = qdf_mem_malloc(sizeof(*qld_handle));
  40. if (!qld_handle)
  41. return -ENOMEM;
  42. qdf_spinlock_create(&qld_handle->qld_lock);
  43. qld_handle->qld_max_list = max_list;
  44. qdf_list_create(&qld_handle->qld_list, qld_handle->qld_max_list);
  45. qld_debug("LIST init with max size of %u", qld_handle->qld_max_list);
  46. return 0;
  47. }
  48. qdf_export_symbol(qld_list_init);
  49. int qld_list_deinit(void)
  50. {
  51. if (!qld_handle) {
  52. qld_err("Handle NULL");
  53. return -EINVAL;
  54. }
  55. /* Delete the list */
  56. qld_list_delete();
  57. qdf_list_destroy(&qld_handle->qld_list);
  58. qdf_spinlock_destroy(&qld_handle->qld_lock);
  59. qdf_mem_free(qld_handle);
  60. qld_handle = NULL;
  61. qld_debug("LIST De-initialized");
  62. return 0;
  63. }
  64. qdf_export_symbol(qld_list_deinit);
  65. int qld_list_delete(void)
  66. {
  67. struct qld_node *qld;
  68. qdf_list_node_t *node = NULL;
  69. qdf_list_t *list;
  70. if (!qld_handle) {
  71. qld_err("Handle NULL");
  72. return -EINVAL;
  73. }
  74. list = &qld_handle->qld_list;
  75. qdf_spinlock_acquire(&qld_handle->qld_lock);
  76. /* Check and remove the elements of list */
  77. while (qdf_list_remove_front(list, &node) == QDF_STATUS_SUCCESS) {
  78. qld = qdf_container_of(node, struct qld_node, node);
  79. qdf_mem_free(qld);
  80. }
  81. qdf_spinlock_release(&qld_handle->qld_lock);
  82. qld_debug("LIST Emptied");
  83. return 0;
  84. }
  85. qdf_export_symbol(qld_list_delete);
  86. int qld_register(void *addr, size_t size, char *name)
  87. {
  88. struct qld_node *qld;
  89. uint32_t list_count = 0;
  90. if (!qld_handle || !addr) {
  91. qld_err("Handle or address is NULL");
  92. return -EINVAL;
  93. }
  94. if ((qld_get_list_count(&list_count) != 0)) {
  95. qdf_err("QLD: Invalid list count");
  96. return -EINVAL;
  97. }
  98. if (list_count >= qld_handle->qld_max_list) {
  99. qld_err("List full,reg failed.Increase list size");
  100. return -EINVAL;
  101. }
  102. /* Check if data is already registered */
  103. qdf_spinlock_acquire(&qld_handle->qld_lock);
  104. qdf_list_for_each(&qld_handle->qld_list, qld, node) {
  105. if (qld->entry.addr == (uintptr_t)addr) {
  106. qld_err("%s already registered", qld->entry.name);
  107. qdf_spinlock_release(&qld_handle->qld_lock);
  108. return -EINVAL;
  109. }
  110. }
  111. qdf_spinlock_release(&qld_handle->qld_lock);
  112. qld = qdf_mem_malloc(sizeof(*qld));
  113. if (!qld)
  114. return -ENOMEM;
  115. qld_debug("Insert addr=%pK size=%zu name=%s", (void *)addr, size, name);
  116. qdf_spinlock_acquire(&qld_handle->qld_lock);
  117. qld->entry.addr = (uintptr_t)addr;
  118. qld->entry.size = size;
  119. qdf_snprintf(qld->entry.name, sizeof(qld->entry.name), "%s", name);
  120. qdf_list_insert_front(&qld_handle->qld_list, &qld->node);
  121. qdf_spinlock_release(&qld_handle->qld_lock);
  122. return 0;
  123. }
  124. qdf_export_symbol(qld_register);
  125. int qld_unregister(void *addr)
  126. {
  127. struct qld_node *qld = NULL;
  128. struct qld_node *cur_entry;
  129. if (!qld_handle || !addr) {
  130. qld_err("Handle or address is NULL");
  131. return -EINVAL;
  132. }
  133. qdf_spinlock_acquire(&qld_handle->qld_lock);
  134. qdf_list_for_each(&qld_handle->qld_list, cur_entry, node) {
  135. if (cur_entry->entry.addr == (uintptr_t)addr) {
  136. qld = cur_entry;
  137. break;
  138. }
  139. }
  140. if (qld) {
  141. qdf_list_remove_node(&qld_handle->qld_list, &qld->node);
  142. qld_debug("Delete name=%s, size=%zu", qld->entry.name,
  143. qld->entry.size);
  144. qdf_mem_free(qld);
  145. }
  146. qdf_spinlock_release(&qld_handle->qld_lock);
  147. return 0;
  148. }
  149. qdf_export_symbol(qld_unregister);
  150. int qld_iterate_list(qld_iter_func gen_table, void *qld_req)
  151. {
  152. struct qld_node *qld = NULL;
  153. if (!qld_handle)
  154. return -EINVAL;
  155. if (!qld_req || !gen_table) {
  156. qld_err("req buffer or func is NULL %s", __func__);
  157. return -EINVAL;
  158. }
  159. qdf_spinlock_acquire(&qld_handle->qld_lock);
  160. qdf_list_for_each(&qld_handle->qld_list, qld, node) {
  161. (gen_table)(qld_req, &qld->entry);
  162. }
  163. qdf_spinlock_release(&qld_handle->qld_lock);
  164. return 0;
  165. }
  166. qdf_export_symbol(qld_iterate_list);
  167. int qld_get_list_count(uint32_t *list_count)
  168. {
  169. if (!qld_handle) {
  170. qld_err("Handle NULL");
  171. return -EINVAL;
  172. }
  173. *list_count = qld_handle->qld_list.count;
  174. return 0;
  175. }
  176. qdf_export_symbol(qld_get_list_count);