#ifdef __KERNEL__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #else #include #include #include #endif #include "vivdw200_irq_queue.h" #ifdef __KERNEL__ #define dw_info(...) #else #define dw_info(...) #endif //enqueue int vivdw200_enqueue(vivdw200_mis_t *data,vivdw200_mis_t* head) { #ifdef __KERNEL__ vivdw200_mis_t* new_node = (vivdw200_mis_t*)kmalloc(sizeof(vivdw200_mis_t), GFP_KERNEL); //create new node if (data == NULL || head == NULL) { //dw_info("%s: input wrong parameter\n", __func__); return -1; } new_node->val = data->val; dw_info("%s: new_node %px", __func__, new_node); INIT_LIST_HEAD(&new_node->list); list_add_tail(&new_node->list, &head->list); //append to tail #endif return 0; } //dequeue && release memory int vivdw200_dequeue(vivdw200_mis_t* data, vivdw200_mis_t* head) { #ifdef __KERNEL__ vivdw200_mis_t* entry; if (data == NULL || head == NULL) { //dw_info("%s: input wrong parameter\n", __func__); return -1; } if (list_empty(&head->list)) { //dw_info("%s: There is no node\n", __func__); return -1; } entry = list_first_entry(&head->list, vivdw200_mis_t, list); dw_info("%s: entry %px", __func__, entry); data->val = entry->val; list_del_init(&entry->list); kfree(entry); #endif return 0; } bool vivdw200_is_queue_empty( vivdw200_mis_t* head) { #ifdef __KERNEL__ return list_empty(&head->list); #else return 0; #endif } int vivdw200_create_circle_queue(vivdw200_mis_list_t* pCList, int number) { #ifdef __KERNEL__ int i; vivdw200_mis_t* pMisNode; if (pCList == NULL || number <= 0) { dw_info("%s: create circle queue failed\n", __func__); return -1; } if (pCList->pHead == NULL) { pCList->pHead = (vivdw200_mis_t*)kmalloc(sizeof(vivdw200_mis_t), GFP_KERNEL); INIT_LIST_HEAD(&pCList->pHead->list); pCList->pRead = pCList->pHead; pCList->pWrite = pCList->pHead; } dw_info("%s:pHead %px\n", __func__, pCList->pHead); for (i = 0; i < number - 1; i++) { pMisNode = (vivdw200_mis_t*)kmalloc(sizeof(vivdw200_mis_t), GFP_KERNEL); INIT_LIST_HEAD(&pMisNode->list); list_add_tail(&pMisNode->list, &pCList->pHead->list); dw_info("%s:pMisNode %px\n", __func__, pMisNode); } #endif return 0; } int vivdw200_destroy_circle_queue(vivdw200_mis_list_t* pCList) { #ifdef __KERNEL__ vivdw200_mis_t* pMisNode; if (pCList == NULL || (pCList->pHead == NULL) ) { dw_info("%s: destroy circle queue failed. pClist %px\n", __func__, pCList); return -1; } while(!list_empty(&pCList->pHead->list)) { pMisNode = list_first_entry(&pCList->pHead->list, vivdw200_mis_t, list); dw_info("%s:pMisNode %px\n", __func__, pMisNode); list_del(&pMisNode->list); kfree(pMisNode); pMisNode = NULL; } dw_info("%s:pHead %px\n", __func__, pCList->pHead); kfree(pCList->pHead); pCList->pHead = NULL; pCList->pRead = NULL; pCList->pWrite = NULL; #endif return 0; } int vivdw200_read_circle_queue(vivdw200_mis_t* data, vivdw200_mis_list_t* pCList) { #ifdef __KERNEL__ //vivdw200_mis_t* pReadEntry; if (pCList == NULL) { dw_info("%s: can not read circle queue\n", __func__); return -1; } if (pCList->pRead == pCList->pWrite) { dw_info("%s: There is no irq mis data\n", __func__); return -1; } data->val = pCList->pRead->val; dw_info("%s: entry %px, msi %08x\n", __func__, pCList->pRead, data->val); /*Get the next entry that link with read entry list*/ /*Update read pointer to next entry*/ pCList->pRead = list_first_entry(&pCList->pRead->list, vivdw200_mis_t, list); //pCList->pRead = pReadEntry; #endif return 0; } int vivdw200_write_circle_queue(vivdw200_mis_t* data, vivdw200_mis_list_t* pCList) { #ifdef __KERNEL__ vivdw200_mis_t* pWriteEntry; if (pCList == NULL) { dw_info("%s: can not read circle queue\n", __func__); return -1; } pCList->pWrite->val = data->val; dw_info("%s: entry %px, msi %08x\n", __func__, pCList->pWrite, data->val); /*get the next write entry pointer that link with the write entry list*/ pWriteEntry = list_first_entry(&pCList->pWrite->list, vivdw200_mis_t, list); /*Update write pointer to point next entry*/ pCList->pWrite = pWriteEntry; #endif return 0; }