Explorar el Código

qcacld-3.0: Fix the usage of struct list_head for vdev_resp_queue

Fix the usage of linux-specific structures and functions by
replacing them with OS-abstracted types for vdev_resp_queue.

Change-Id: If2d4a9a1dffd59ec1db4b4aa572dfa453bfd0167
CRs-Fixed: 931094
Krishna Kumaar Natarajan hace 9 años
padre
commit
a5c53bd6c0

+ 2 - 0
core/cdf/inc/cdf_list.h

@@ -107,4 +107,6 @@ CDF_STATUS cdf_list_peek_next(cdf_list_t *p_list, cdf_list_node_t *p_node,
 CDF_STATUS cdf_list_remove_node(cdf_list_t *p_list,
 				cdf_list_node_t *p_node_to_remove);
 
+bool cdf_list_empty(cdf_list_t *list);
+
 #endif /* __CDF_LIST_H */

+ 11 - 0
core/cdf/src/cdf_list.c

@@ -223,3 +223,14 @@ CDF_STATUS cdf_list_peek_next(cdf_list_t *pList, cdf_list_node_t *pNode,
 
 	return CDF_STATUS_SUCCESS;
 }
+
+/**
+ * cdf_list_empty() - check if the list is empty
+ * @list: pointer to the list
+ *
+ * Return: true if the list is empty and false otherwise.
+ */
+bool cdf_list_empty(cdf_list_t *list)
+{
+	return list_empty(&list->anchor);
+}

+ 1 - 1
core/wma/inc/wma.h

@@ -1239,7 +1239,7 @@ typedef struct {
 	uint32_t scan_id;
 	struct wma_txrx_node *interfaces;
 	pdev_cli_config_t pdevconfig;
-	struct list_head vdev_resp_queue;
+	cdf_list_t vdev_resp_queue;
 	cdf_spinlock_t vdev_respq_lock;
 	cdf_list_t wma_hold_req_queue;
 	cdf_spinlock_t wma_hold_req_q_lock;

+ 2 - 0
core/wma/inc/wma_internal.h

@@ -104,6 +104,8 @@
 #define LINK_RATE_VHT           0x3
 
 #define MAX_ENTRY_HOLD_REQ_QUEUE 2
+#define MAX_ENTRY_VDEV_RESP_QUEUE 10
+
 /**
  * struct index_data_rate_type - non vht data rate type
  * @beacon_rate_index: Beacon rate index

+ 39 - 11
core/wma/src/wma_dev_if.c

@@ -337,14 +337,13 @@ static struct wma_target_req *wma_find_req(tp_wma_handle wma,
 			cdf_list_peek_next(&wma->wma_hold_req_queue, node1,
 					   &node2));
 
+	cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
 	if (!found) {
-		cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
 		WMA_LOGE(FL("target request not found for vdev_id %d type %d"),
 			 vdev_id, type);
 		return NULL;
 	}
 
-	cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
 	WMA_LOGD(FL("target request found for vdev id: %d type %d"),
 		 vdev_id, type);
 
@@ -362,28 +361,48 @@ static struct wma_target_req *wma_find_req(tp_wma_handle wma,
 static struct wma_target_req *wma_find_vdev_req(tp_wma_handle wma,
 						uint8_t vdev_id, uint8_t type)
 {
-	struct wma_target_req *req_msg = NULL, *tmp;
+	struct wma_target_req *req_msg = NULL;
 	bool found = false;
+	cdf_list_node_t *node1 = NULL, *node2 = NULL;
+	CDF_STATUS status;
 
 	cdf_spin_lock_bh(&wma->vdev_respq_lock);
-	list_for_each_entry_safe(req_msg, tmp, &wma->vdev_resp_queue, node) {
+	if (CDF_STATUS_SUCCESS != cdf_list_peek_front(&wma->vdev_resp_queue,
+						      &node2)) {
+		cdf_spin_unlock_bh(&wma->vdev_respq_lock);
+		WMA_LOGE(FL("unable to get target req from vdev resp queue"));
+		return NULL;
+	}
+
+	do {
+		node1 = node2;
+		req_msg = cdf_container_of(node1, struct wma_target_req, node);
 		if (req_msg->vdev_id != vdev_id)
 			continue;
 		if (req_msg->type != type)
 			continue;
 
 		found = true;
-		list_del(&req_msg->node);
+		status = cdf_list_remove_node(&wma->vdev_resp_queue, node1);
+		if (CDF_STATUS_SUCCESS != status) {
+			cdf_spin_unlock_bh(&wma->vdev_respq_lock);
+			WMA_LOGD(FL("Failed to target req for vdev_id %d type %d"),
+				 vdev_id, type);
+			return NULL;
+		}
 		break;
-	}
+	} while (CDF_STATUS_SUCCESS  ==
+			cdf_list_peek_next(&wma->vdev_resp_queue,
+					   node1, &node2));
+
 	cdf_spin_unlock_bh(&wma->vdev_respq_lock);
 	if (!found) {
-		WMA_LOGP("%s: target request not found for vdev_id %d type %d",
-			 __func__, vdev_id, type);
+		WMA_LOGP(FL("target request not found for vdev_id %d type %d"),
+			 vdev_id, type);
 		return NULL;
 	}
-	WMA_LOGD("%s: target request found for vdev id: %d type %d msg %d",
-		 __func__, vdev_id, type, req_msg->msg_type);
+	WMA_LOGD(FL("target request found for vdev id: %d type %d msg %d"),
+		 vdev_id, type, req_msg->msg_type);
 	return req_msg;
 }
 
@@ -2619,6 +2638,7 @@ struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma,
 					 void *params, uint32_t timeout)
 {
 	struct wma_target_req *req;
+	CDF_STATUS status;
 
 	req = cdf_mem_malloc(sizeof(*req));
 	if (!req) {
@@ -2636,7 +2656,15 @@ struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma,
 			  wma_vdev_resp_timer, req);
 	cdf_mc_timer_start(&req->event_timeout, timeout);
 	cdf_spin_lock_bh(&wma->vdev_respq_lock);
-	list_add_tail(&req->node, &wma->vdev_resp_queue);
+	status = cdf_list_insert_back(&wma->vdev_resp_queue, &req->node);
+	if (CDF_STATUS_SUCCESS != status) {
+		cdf_spin_unlock_bh(&wma->vdev_respq_lock);
+		WMA_LOGE(FL("Failed add request in queue for vdev_id %d type %d"),
+			 vdev_id, type);
+		cdf_mem_free(req);
+		return NULL;
+	}
+
 	cdf_spin_unlock_bh(&wma->vdev_respq_lock);
 	return req;
 }

+ 24 - 7
core/wma/src/wma_main.c

@@ -1687,7 +1687,8 @@ CDF_STATUS wma_open(void *cds_context,
 		goto err_event_init;
 	}
 
-	INIT_LIST_HEAD(&wma_handle->vdev_resp_queue);
+	cdf_list_init(&wma_handle->vdev_resp_queue,
+		      MAX_ENTRY_VDEV_RESP_QUEUE);
 	cdf_spinlock_init(&wma_handle->vdev_respq_lock);
 	cdf_list_init(&wma_handle->wma_hold_req_queue,
 		      MAX_ENTRY_HOLD_REQ_QUEUE);
@@ -2769,7 +2770,7 @@ static void wma_cleanup_hold_req(tp_wma_handle wma)
 
 	do {
 		node1 = node2;
-		req_msg = (struct wma_target_req *)node1;
+		req_msg = cdf_container_of(node1, struct wma_target_req, node);
 		status = cdf_list_remove_node(&wma->wma_hold_req_queue, node1);
 		if (CDF_STATUS_SUCCESS != status) {
 			cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
@@ -2795,13 +2796,29 @@ static void wma_cleanup_hold_req(tp_wma_handle wma)
  */
 static void wma_cleanup_vdev_resp(tp_wma_handle wma)
 {
-	struct wma_target_req *msg, *tmp;
+	struct wma_target_req *req_msg = NULL;
+	cdf_list_node_t *node1 = NULL;
+	CDF_STATUS status;
 
 	cdf_spin_lock_bh(&wma->vdev_respq_lock);
-	list_for_each_entry_safe(msg, tmp, &wma->vdev_resp_queue, node) {
-		list_del(&msg->node);
-		cdf_mc_timer_destroy(&msg->event_timeout);
-		cdf_mem_free(msg);
+	if (cdf_list_empty(&wma->vdev_resp_queue)) {
+		cdf_spin_unlock_bh(&wma->vdev_respq_lock);
+		WMA_LOGI(FL("request queue maybe empty"));
+		return;
+	}
+
+	while (CDF_STATUS_SUCCESS != cdf_list_peek_front(&wma->vdev_resp_queue,
+						      &node1)) {
+		req_msg = cdf_container_of(node1, struct wma_target_req, node);
+		status = cdf_list_remove_node(&wma->vdev_resp_queue, node1);
+		if (CDF_STATUS_SUCCESS != status) {
+			cdf_spin_unlock_bh(&wma->vdev_respq_lock);
+			WMA_LOGE(FL("Failed to remove request for vdev_id %d type %d"),
+				 req_msg->vdev_id, req_msg->type);
+			return;
+		}
+		cdf_mc_timer_destroy(&req_msg->event_timeout);
+		cdf_mem_free(req_msg);
 	}
 	cdf_spin_unlock_bh(&wma->vdev_respq_lock);
 }