summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/digi/pcimac/cm_chan.c
blob: b07b9a52d72c6f18eac6bc701bf66e76f257a46d (plain) (blame)
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
/*
 * CM_CHAN.C - channel allocation (for incoming) code
 */

#include	<ndis.h>
#include	<ndiswan.h>
#include	<mytypes.h>
#include	<mydefs.h>
#include	<disp.h>
#include	<util.h>
#include	<opcodes.h>
#include	<adapter.h>
#include	<idd.h>
#include    <mtl.h>
#include	<cm.h>

CM_CHAN		*chan_tbl;
BOOL		chan_used[MAX_CHAN_IN_SYSTEM];


#pragma NDIS_INIT_FUNCTION(ChannelInit)

//
// Allocate free channel pool
//
VOID
ChannelInit(VOID)
{
    NDIS_PHYSICAL_ADDRESS	pa = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);

	/* allocate memory object */
    NdisAllocateMemory((PVOID*)&chan_tbl, sizeof(CM_CHAN) * MAX_CHAN_IN_SYSTEM, 0, pa);
    if ( chan_tbl == NULL )
    {
        D_LOG(D_ALWAYS, ("ChannelInit: memory allocate failed!"));
		return;
    }
    D_LOG(D_ALWAYS, ("ChannelInit: chan_tbl: 0x%x", chan_tbl));
	NdisZeroMemory (chan_tbl, sizeof(CM_CHAN) * MAX_CHAN_IN_SYSTEM);
	NdisZeroMemory (chan_used, sizeof(chan_used));
}

VOID
ChannelTerm(VOID)
{
    /* free memory */
    NdisFreeMemory(chan_tbl, sizeof(CM_CHAN) * MAX_CHAN_IN_SYSTEM, 0);
}

/* allocate a channel */
CM_CHAN*
cm__chan_alloc(VOID)
{
    CM_CHAN     *chan = NULL;
    INT         n;

    D_LOG(D_ENTRY, ("cm__chan_alloc: entry"));

    for ( n = 0 ; n < MAX_CHAN_IN_SYSTEM ; n++ )
        if ( !chan_used[n] )
        {
            chan_used[n] = TRUE;
            chan = chan_tbl + n;
            break;
        }

    D_LOG(D_EXIT, ("cm__alloc_chan: exit, chan: 0x%lx", chan));
    return(chan);
}

/* free a channel */
VOID
cm__chan_free(CM_CHAN *chan)
{
    D_LOG(D_ENTRY, ("cm__chan_free: entry, chan: 0x%lx", chan));

    chan_used[chan - chan_tbl] = FALSE;
}

/* call a callback function for each used channel */
BOOL
cm__chan_foreach(BOOL (*func)(), VOID *a1, VOID *a2)
{
    INT     n;
    BOOL    ret = TRUE;

    D_LOG(D_ENTRY, ("cm__chan_foreach: entry, func: %lx, a1: 0x%lx, a2: 0x%lx", \
                                    func, a1, a2));

    for ( n = 0 ; n < MAX_CHAN_IN_SYSTEM ; n++ )
        if ( chan_used[n] )
        {
			CM_CHAN		*chan = chan_tbl + n;

            D_LOG(D_ALWAYS, ("cm__chan_foreach: calling for chan# %d, channel: %lx", n, chan));

            ret = (*func)(chan, a1, a2);

            D_LOG(D_ALWAYS, ("cm__chan_foreach: returned %d", ret));

            if ( !ret )
                break;
        }

    return(ret);
}