summaryrefslogtreecommitdiff
path: root/cesar/mac/sar/src/bridge_dma.c
blob: 78a023a6acb8d29d5f406cb86d73b5fece7966bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    mac/sar/src/bridge_dma.c
 * \brief   header for the bridge dma launch.
 * \ingroup mac_sar
 */

#include "common/std.h"
#include "hal/phy/bridgedma.h"
#include "mac/sar/inc/bridge_dma.h"

void
sar_bridge_dma_list_init (sar_bridge_dma_list_t *list)
{
    list->head = NULL;
    list->tail = NULL;
}

sar_job_mfs_t*
sar_bridge_dma_peek (sar_bridge_dma_list_t *list)
{
    dbg_assert (list);

    return list->head;
}

sar_job_mfs_t*
sar_bridge_dma_get_head (sar_bridge_dma_list_t *list)
{
    sar_job_mfs_t *job = NULL;

    dbg_assert (list);

    if (list->head == list->tail)
    {
        job = list->head;
        list->head = NULL;
        list->tail = NULL;
    }
    else if (list->head != NULL)
    {
        job = list->head;
        list->head = PARENT_OF (sar_job_mfs_t, job, list->head->job.next);
    }

    return job;
}

void
sar_bridge_dma_add_jobs (sar_bridge_dma_list_t *bridge_list,
                         sar_job_mfs_t *head, sar_job_mfs_t *last)
{
    dbg_assert (bridge_list);
    dbg_assert (head);
    dbg_assert (last);
    last->job.next = NULL;

    if (bridge_list->tail == NULL)
    {
        bridge_list->head = head;
        bridge_list->tail = last;
    }
    else
    {
        bridge_list->tail->job.last = false;
        bridge_list->tail->job.next = &head->job;
        bridge_list->tail = last;
    }
}

void
sar_bridge_dma_add_pending_job (sar_bridge_dma_list_t *list,
                                sar_job_mfs_t *head)
{
    dbg_assert (list);
    dbg_assert (head);

    if (list->head == NULL)
    {
        list->head = head;
        list->tail = head;
    }
    else
    {
        list->tail->job.next = &head->job;
        list->tail = head;
    }

    head->job.next = NULL;
}

bool
sar_bridge_dma_list_is_empty (sar_bridge_dma_list_t *list)
{
    dbg_assert (list);

    if (list->head == NULL)
    {
        return true;
    }

    return false;
}

void
sar_bridge_dma_uninit_list (sar_bridge_dma_list_t *list)
{
    dbg_assert (list);

    sar_job_mfs_t *job_mfs;
    pb_t *pb_curr;

    //release all pending jobs.
    while ( (job_mfs = sar_bridge_dma_get_head (list))!= NULL)
    {
        // release the PB in the job
        while (job_mfs->job.first_pb_desc)
        {
            pb_curr = (pb_t *) job_mfs->job.first_pb_desc;
            job_mfs->job.first_pb_desc = job_mfs->job.first_pb_desc->next;
            blk_release_desc ((blk_t *) pb_curr);
        }

        blk_release ((blk_t *) job_mfs->mfs);
        blk_release ((blk_t *) job_mfs);
    }

    list->head = NULL;
    list->tail = NULL;
}