OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.swp.api/] [openmcapi/] [1.0/] [libmcapi/] [mcapi/] [create_endpoint.c] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
/*
2
 * Copyright (c) 2010, Mentor Graphics Corporation
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 * POSSIBILITY OF SUCH DAMAGE.
28
 */
29
 
30
 
31
 
32
#include <openmcapi.h>
33
 
34
extern mcapi_uint16_t   MCAPI_Next_Port;
35
 
36
/*************************************************************************
37
*
38
*   FUNCTION
39
*
40
*       create_endpoint
41
*
42
*   DESCRIPTION
43
*
44
*       Routine to create an endpoint on the local node.  If the port
45
*       ID field is set to MCAPI_PORT_ANY, an endpoint will be created using
46
*       the next available port in the system.
47
*
48
*   INPUTS
49
*
50
*       port_id                 The port ID of the endpoint, or MCAPI_PORT_ANY
51
*                               to create an endpoint with the next available
52
*                               port ID.
53
*       *mcapi_status           A pointer to memory that will be filled in
54
*                               with the status of the call.
55
*
56
*   OUTPUTS
57
*
58
*       The newly created endpoint.
59
*
60
*************************************************************************/
61
mcapi_endpoint_t create_endpoint(MCAPI_NODE *node_ptr,
62
                                 mcapi_port_t port_id,
63
                                 mcapi_status_t *mcapi_status)
64
{
65
    mcapi_endpoint_t    endpoint = 0;
66
    MCAPI_ENDPOINT      *endp_ptr = MCAPI_NULL;
67
    int                 i, endp_idx;
68
 
69
#if (MCAPI_MAX_ENDPOINTS != 0)
70
 
71
    /* If there is an available endpoint entry. */
72
    if (node_ptr->mcapi_endpoint_count < MCAPI_MAX_ENDPOINTS)
73
    {
74
        /* Initialize mcapi_status to success. */
75
        *mcapi_status = MCAPI_SUCCESS;
76
 
77
        /* If a specific port was specified for the new endpoint, check
78
         * that an endpoint does not already exist that uses that port.
79
         */
80
        if (port_id != MCAPI_PORT_ANY)
81
        {
82
            /* If a matching endpoint already exists. */
83
            if (mcapi_find_endpoint(port_id, node_ptr) != -1)
84
            {
85
                *mcapi_status = MCAPI_ERR_ENDP_EXISTS;
86
            }
87
        }
88
 
89
        /* If a port was not passed in, find a unique port. */
90
        else
91
        {
92
            /* Find a unique port to assign to the endpoint. */
93
            do
94
            {
95
                port_id = MCAPI_Next_Port ++;
96
 
97
                /* Ensure the application has not used this port for
98
                 * another endpoint.
99
                 */
100
                i = mcapi_find_endpoint(port_id, node_ptr);
101
 
102
            } while ( (i != -1) && (port_id != MCAPI_PORT_ANY) );
103
 
104
            /* If an unused port could not be found. */
105
            if (port_id == MCAPI_PORT_ANY)
106
            {
107
                *mcapi_status = MCAPI_ERR_PORT_INVALID;
108
            }
109
        }
110
 
111
        /* If the status is still success. */
112
        if (*mcapi_status == MCAPI_SUCCESS)
113
        {
114
            /* Create a hash index. */
115
            endp_idx = (port_id % MCAPI_MAX_ENDPOINTS);
116
 
117
            /* If this slot is available. */
118
            if (node_ptr->mcapi_endpoint_list[endp_idx].mcapi_state ==
119
                MCAPI_ENDP_CLOSED)
120
            {
121
                endp_ptr = &node_ptr->mcapi_endpoint_list[endp_idx];
122
            }
123
 
124
            /* Otherwise, find the next available slot. */
125
            else
126
            {
127
                /* Set the counter variable to zero. */
128
                i = 0;
129
 
130
                /* Find an empty slot. */
131
                do
132
                {
133
                    /* Move to the next slot. */
134
                    endp_idx ++;
135
 
136
                    /* If the index has rolled over. */
137
                    if ( (endp_idx < 0) ||
138
                         (endp_idx >= MCAPI_MAX_ENDPOINTS) )
139
                    {
140
                        endp_idx = 0;
141
                    }
142
 
143
                    /* If the endpoint entry is unused. */
144
                    if (node_ptr->mcapi_endpoint_list[endp_idx].
145
                        mcapi_state == MCAPI_ENDP_CLOSED)
146
                    {
147
                        /* Use this entry. */
148
                        endp_ptr = &node_ptr->mcapi_endpoint_list[endp_idx];
149
                        break;
150
                    }
151
 
152
                    i ++;
153
 
154
                } while (i < MCAPI_MAX_ENDPOINTS);
155
            }
156
 
157
            /* If an available entry was found. */
158
            if (endp_ptr)
159
            {
160
                /* Increment the number of used endpoints on the
161
                 * node.
162
                 */
163
                node_ptr->mcapi_endpoint_count ++;
164
 
165
                /* Clear the endpoint structure. */
166
                memset(endp_ptr, 0, sizeof(MCAPI_ENDPOINT));
167
 
168
                /* Set the state of the entry to open. */
169
                endp_ptr->mcapi_state = MCAPI_ENDP_OPEN;
170
 
171
                /* Set the port ID of the entry. */
172
                endp_ptr->mcapi_port_id = port_id;
173
 
174
                /* Set the node ID of the entry. */
175
                endp_ptr->mcapi_node_id = node_ptr->mcapi_node_id;
176
 
177
                /* Encode the endpoint. */
178
                endpoint = mcapi_encode_endpoint(endp_ptr->mcapi_node_id,
179
                                                 port_id);
180
 
181
                /* Store the handle for future use. */
182
                endp_ptr->mcapi_endp_handle = endpoint;
183
 
184
                /* Set the priority to the default. */
185
                endp_ptr->mcapi_priority = MCAPI_DEFAULT_PRIO;
186
 
187
                /* Check if any foreign nodes are waiting for this
188
                 * endpoint to be created.
189
                 */
190
                mcapi_check_foreign_resume(MCAPI_REQ_CREATED, endpoint,
191
                                           MCAPI_SUCCESS);
192
 
193
                /* Check if any local threads are waiting for this endpoint
194
                 * to be created.
195
                 */
196
                mcapi_check_resume(MCAPI_REQ_CREATED, endpoint,
197
                                   MCAPI_NULL, 0, MCAPI_SUCCESS);
198
            }
199
        }
200
    }
201
 
202
    /* There are no available endpoint entries in the system. */
203
    else
204
    {
205
        *mcapi_status = MCAPI_ERR_GENERAL; /* XXX document me */
206
    }
207
 
208
#else
209
 
210
    *mcapi_status = MCAPI_EEP_NOTALLOWED;
211
 
212
#endif
213
 
214
    return (endpoint);
215
 
216
}
217
 
218
/*************************************************************************
219
*
220
*   FUNCTION
221
*
222
*       mcapi_check_foreign_resume
223
*
224
*   DESCRIPTION
225
*
226
*       Checks if any pending requests from foreign nodes should be resumed.
227
*
228
*   INPUTS
229
*
230
*       type                    The type of request to check.
231
*       endpoint                The endpoint for which the request is
232
*                               suspended on some action.
233
*       status                  The status to set in the request structure.
234
*
235
*   OUTPUTS
236
*
237
*       None.
238
*
239
*************************************************************************/
240
void mcapi_check_foreign_resume(int type, mcapi_endpoint_t endpoint,
241
                                mcapi_status_t status)
242
{
243
    mcapi_request_t     *request, *next_ptr;
244
    MCAPI_GLOBAL_DATA   *node_data;
245
 
246
    /* Get a pointer to the global node list. */
247
    node_data = mcapi_get_node_data();
248
 
249
    /* Get a pointer to the first entry in the request queue. */
250
    request = node_data->mcapi_foreign_req_queue.flink;
251
 
252
    /* Check each request to see if the operation has been completed. */
253
    while (request)
254
    {
255
        /* Get a pointer to the next entry. */
256
        next_ptr = request->mcapi_next;
257
 
258
        switch (type)
259
        {
260
            /* An endpoint associated with a pending request has been
261
             * created.
262
             */
263
            case MCAPI_REQ_CREATED:
264
 
265
                /* If the request structure is waiting for an endpoint to be
266
                 * created.
267
                 */
268
                if ( (request->mcapi_type == MCAPI_REQ_CREATED) &&
269
                     (mcapi_encode_endpoint(request->mcapi_target_node_id,
270
                                            request->mcapi_target_port_id) == endpoint) )
271
                {
272
                    /* Remove this item from the list. */
273
                    mcapi_remove(&node_data->mcapi_foreign_req_queue, request);
274
 
275
                    /* Set the status to success. */
276
                    request->mcapi_status = MCAPI_SUCCESS;
277
 
278
                    /* Send the response. */
279
                    mcapi_tx_response(node_data, request);
280
 
281
                    /* Set this request structure back to available. */
282
                    mcapi_release_request_struct(request);
283
                }
284
 
285
                break;
286
 
287
            default:
288
 
289
                break;
290
        }
291
 
292
        /* Get the next request entry in the list. */
293
        request = next_ptr;
294
    }
295
 
296
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.