comparison src/g23m-aci/gdd_dio/gdd_dio_con_mgr.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +0000
parents
children
comparison
equal deleted inserted replaced
0:4e78acac3d88 1:fa8dc04885d8
1 /*
2 +-----------------------------------------------------------------------------
3 | File : gdd_dio_con_mgr.c
4 +-----------------------------------------------------------------------------
5 | Copyright 2002 Texas Instruments Berlin, AG
6 | All rights reserved.
7 |
8 | This file is confidential and a trade secret of Texas
9 | Instruments Berlin, AG
10 | The receipt of or possession of this file does not convey
11 | any rights to reproduce or disclose its contents or to
12 | manufacture, use, or sell anything it may describe, in
13 | whole, or in part, without the specific written consent of
14 | Texas Instruments Berlin, AG.
15 +-----------------------------------------------------------------------------
16 | Purpose : Implements connection management functions
17 +-----------------------------------------------------------------------------
18 */
19
20
21 #define ENTITY_GDD_DIO
22
23 /*==== INCLUDES =============================================================*/
24
25 #include "typedefs.h" /* to get Condat data types */
26 #include "vsi.h" /* to get a lot of macros */
27 #include "prim.h" /* to get the definitions of used SAP and directions */
28 #include "dti.h"
29
30 #include "gdd_dio.h" /* to get the global entity definitions */
31 #include "gdd_dio_queue.h"
32 #include "gdd_dio_con_mgr.h"
33
34 #include <string.h>
35
36
37 /*==== DEFINITIONS ==========================================================*/
38
39 #define ENTER_CRITICAL_SECTION(sem) if (gdd_enter_critical_section(sem))return -1;
40 #define LEAVE_CRITICAL_SECTION(sem) if (gdd_leave_critical_section(sem))return -1;
41
42
43 /*==== CONST ================================================================*/
44
45 /*==== LOCAL VARS ===========================================================*/
46
47 static T_HANDLE sem_GDD_DIO_CON;
48
49 /*==== PRIVATE FUNCTIONS ====================================================*/
50
51 LOCAL int get_free_connection_slot(T_GDD_DIO_DATA * gdd_dio_data,
52 T_GDD_DIO_CON_DATA ** con_data /*output*/);
53 static void gdd_semaphore_err (void);
54 static int gdd_enter_critical_section (T_HANDLE sem);
55 static int gdd_leave_critical_section (T_HANDLE sem);
56
57
58 /*==== PUBLIC FUNCTIONS =====================================================*/
59
60
61 /* Initializes the connection manager */
62
63 GLOBAL void gdd_dio_con_mgr_init (T_GDD_DIO_DATA * gdd_dio_data)
64 {
65 int i;
66 T_GDD_DIO_CON_DATA * con_data = gdd_dio_data->con_arr;
67
68 TRACE_FUNCTION( "[GDD] conn_init()" );
69
70 for(i = 0; i < gdd_dio_data->max_con; ++i, ++con_data)
71 {
72 con_data->con_state = GDD_DIO_CON_DEAD;
73 }
74
75 sem_GDD_DIO_CON = vsi_s_open (VSI_CALLER "SEM_GDD_CON",1);
76 if (sem_GDD_DIO_CON EQ VSI_ERROR)
77 vsi_o_ttrace(VSI_CALLER TC_EVENT, "canīt open semaphore \"SEM_GDD_CON\"");
78 }
79
80
81 /* Setup a new DIO connection */
82
83 GLOBAL GDD_RESULT gdd_dio_con_mgr_new
84 ( T_GDD_DIO_DATA * gdd_dio_data,
85 T_GDD_CON_HANDLE * con_handle,
86 const T_GDD_CAP * cap,
87 T_GDD_RECEIVE_DATA_CB rcv_cb,
88 T_GDD_SIGNAL_CB sig_cb )
89 {
90 T_GDD_DIO_CON_DATA * con_data = 0;
91
92 TRACE_FUNCTION("[GDD] conn_new()");
93
94 if(get_free_connection_slot(gdd_dio_data, &con_data) NEQ 0)
95 {
96 TRACE_ERROR("Failed to get new connection slot");
97 return GDD_NO_CONNECTION_SLOT;
98 }
99
100 gdd_dio_queue_clear(&con_data->rx_queue);
101 gdd_dio_queue_clear(&con_data->tx_queue);
102
103 con_data->wait_send_buf = FALSE;
104
105 con_data->rcv_cb = rcv_cb;
106 con_data->sig_cb = sig_cb;
107
108 con_data->dio_cap.device_type = DIO_TYPE_PKT;
109 con_data->dio_cap.device_flags = 0;
110 con_data->dio_cap.mtu_control = 0;
111 con_data->dio_cap.mtu_data = (U16)((T_GDD_DIO_CAP *)cap)->mtu_size;
112 con_data->dio_cap.driver_name = "GDD";
113
114 (*con_handle) = con_data->dio_device;
115
116
117 gdd_dio_send_signal_to_dio(con_data, DRV_SIGTYPE_CONNECT);
118
119 return GDD_OK;
120 }
121
122
123 /* Close a connection */
124
125 GLOBAL GDD_RESULT gdd_dio_con_mgr_close
126 ( T_GDD_CON_HANDLE con_handle )
127 {
128 T_GDD_INST_ID inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle);
129 T_GDD_DIO_CON_DATA * con_data;
130
131 TRACE_FUNCTION( "[GDD] gdd_dio_con_mgr_close()" );
132
133 con_data = get_con_data(&(gdd_dio_data_base[inst]), con_handle);
134 if(con_data EQ NULL)
135 {
136 TRACE_ERROR("Failed to get connection data");
137 return GDD_INTERNAL_ERROR;
138 }
139
140 con_data->con_state = GDD_DIO_CON_CLOSE;
141
142 gdd_dio_send_signal_to_dio(con_data, DRV_SIGTYPE_DISCONNECT);
143
144 return GDD_OK;
145 }
146
147
148 /* Mark a connection as dead */
149
150 GDD_RESULT gdd_dio_con_mgr_mark_dead( T_GDD_CON_HANDLE con_handle )
151 {
152 T_GDD_INST_ID inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle);
153 T_GDD_DIO_CON_DATA * con_data;
154
155 TRACE_FUNCTION( "[GDD] gdd_dio_con_mgr_mark_dead()" );
156
157 con_data = get_con_data(&(gdd_dio_data_base[inst]), con_handle);
158 if(con_data EQ NULL)
159 {
160 TRACE_ERROR("Failed to get connection data");
161 return GDD_INTERNAL_ERROR;
162 }
163
164 /* Clear the connection slot
165 - it's sufficient to set state and nullify handle */
166 con_data->con_state = GDD_DIO_CON_DEAD;
167
168 return GDD_OK;
169 }
170
171
172 /* Check if any of the connections is (still) open or in connecting state. */
173
174 BOOL gdd_dio_con_mgr_has_open_connection
175 ( const T_GDD_DIO_DATA * gdd_dio_data )
176 {
177 int i;
178 T_GDD_DIO_CON_DATA * con_data = gdd_dio_data->con_arr;
179
180 TRACE_FUNCTION( "[GDD] gdd_dio_con_mgr_has_open_connection()" );
181
182 for(i = 0; i < gdd_dio_data->max_con; ++i, ++con_data)
183 {
184 if(con_data->con_state EQ GDD_DIO_CON_READY ||
185 con_data->con_state EQ GDD_DIO_CON_SENDING ||
186 con_data->con_state EQ GDD_DIO_CON_CONNECT)
187 {
188 return TRUE;
189 }
190 }
191 return FALSE;
192 }
193
194
195 /* Get the connection data for a given instance & handle */
196
197 GLOBAL T_GDD_DIO_CON_DATA * get_con_data(const T_GDD_DIO_DATA * gdd_dio_data,
198 T_GDD_CON_HANDLE con_handle)
199 {
200 int i;
201
202 /* Deliberately NO tracing */
203
204 for(i=0; i<gdd_dio_data->max_con; ++i)
205 {
206 if(gdd_dio_data->con_arr[i].dio_device EQ con_handle)
207 return &gdd_dio_data->con_arr[i];
208 }
209 return NULL;
210 }
211
212
213
214 /* Get the connection data for a given handle only */
215
216 GLOBAL T_GDD_DIO_CON_DATA * get_con_data_from_handle(T_GDD_CON_HANDLE con_handle)
217 {
218 T_GDD_INST_ID inst;
219
220 /* Deliberately NO tracing */
221
222 inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle);
223
224 if(inst < 0 || inst >= GDD_NUM_INSTS)
225 {
226 return 0;
227 }
228
229 return get_con_data(&(gdd_dio_data_base[inst]), con_handle);
230 }
231
232
233 /* Send a DIO signal via the specificed connection */
234
235 void gdd_dio_send_signal_to_dio
236 (T_GDD_DIO_CON_DATA * con_data, U16 sig_type)
237 {
238 T_DRV_SIGNAL drv_signal;
239 T_GDD_DIO_DATA * inst_data;
240 char * sig_type_str;
241
242 TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_dio_send_signal_to_dio()");
243
244 inst_data = &gdd_dio_data_base[inst_num_from_dev_id(con_data->dio_device)];
245
246 switch (sig_type)
247 {
248 case DRV_SIGTYPE_WRITE: sig_type_str = "DRV_SIGTYPE_WRITE"; break;
249 case DRV_SIGTYPE_READ: sig_type_str = "DRV_SIGTYPE_READ"; break;
250 case DRV_SIGTYPE_CONNECT: sig_type_str = "DRV_SIGTYPE_CONNECT"; break;
251 case DRV_SIGTYPE_DISCONNECT: sig_type_str = "DRV_SIGTYPE_DISCONNECT"; break;
252 default: sig_type_str = "ununsed signal type"; break;
253 }
254
255 TRACE_USER_CLASS_P2(TC_SIGNALS, "[GDD] Sending signal %s to DIO IL (con_handle=0x%4x)", sig_type_str, con_data->dio_device);
256
257 drv_signal.SignalType = sig_type;
258 drv_signal.DrvHandle = inst_data->drv_handle;
259 drv_signal.DataLength = sizeof(U32);
260 drv_signal.UserData = &(con_data->dio_device);
261 (*(inst_data->signal_callback))(&drv_signal);
262 }
263
264
265 /*==== PRIVATE FUNCTIONS =====================================================*/
266
267 /*
268 +------------------------------------------------------------------------------
269 | Function : get_free_connection_slot
270 +------------------------------------------------------------------------------
271 | Description : Find the next free connection slot for given instance.
272 |
273 | Parameters : gdd_dio_data - pointer to instance data
274 | con_data - pointer to pointer to connection data (output)
275 |
276 | Returns : 0 - Success (con_data has been set)
277 | -1 - Failed (no slot found)
278 +------------------------------------------------------------------------------
279 */
280 LOCAL int get_free_connection_slot(T_GDD_DIO_DATA * gdd_dio_data,
281 T_GDD_DIO_CON_DATA ** con_data /*output*/)
282 {
283 int i;
284
285 TRACE_FUNCTION( "[GDD] get_free_connection_slot()" );
286
287 ENTER_CRITICAL_SECTION(sem_GDD_DIO_CON);
288
289 for(i = 0; i < gdd_dio_data->max_con; ++i)
290 {
291 if(gdd_dio_data->device_range_start+i <= gdd_dio_data->device_range_end)
292 {
293 if(gdd_dio_data->con_arr[i].con_state EQ GDD_DIO_CON_DEAD)
294 {
295 gdd_dio_data->con_arr[i].dio_device = gdd_dio_data->device_range_start+i;
296 *con_data = &(gdd_dio_data->con_arr[i]);
297 (*con_data)->con_state = GDD_DIO_CON_CONNECT;
298
299 LEAVE_CRITICAL_SECTION(sem_GDD_DIO_CON);
300 return 0;
301 }
302 }
303 }
304
305 LEAVE_CRITICAL_SECTION(sem_GDD_DIO_CON);
306
307 return -1;
308 }
309
310
311 /*
312 +------------------------------------------------------------------------------
313 | Function : gdd_semaphore_err
314 +------------------------------------------------------------------------------
315 | Description : Handle a semaphore error
316 +------------------------------------------------------------------------------
317 */
318 static void gdd_semaphore_err (void)
319 {
320 static UCHAR out = 0;
321 if (!out)
322 {
323 out = 1;
324 vsi_o_ttrace(VSI_CALLER TC_EVENT, "semaphore error");
325 }
326 }
327
328
329 /*
330 +------------------------------------------------------------------------------
331 | Function : gdd_enter_critical_section
332 +------------------------------------------------------------------------------
333 | Description : Enters a critical section.
334 |
335 | Parameters : sem - Semaphore handle
336 |
337 | Returns : 0 - Success
338 | -1 - Failure
339 +------------------------------------------------------------------------------
340 */
341 static int gdd_enter_critical_section (T_HANDLE sem)
342 {
343 if (vsi_s_get (VSI_CALLER sem) NEQ VSI_OK)
344 {
345 gdd_semaphore_err();
346 return -1;
347 }
348 else
349 {
350 return 0;
351 }
352 }
353
354
355 /*
356 +------------------------------------------------------------------------------
357 | Function : gdd_leave_critical_section
358 +------------------------------------------------------------------------------
359 | Description : Leaves a critical section.
360 |
361 | Parameters : sem - Semaphore handle
362 |
363 | Returns : 0 - Success
364 | -1 - Failure
365 +------------------------------------------------------------------------------
366 */
367 static int gdd_leave_critical_section (T_HANDLE sem)
368 {
369 if (vsi_s_release (VSI_CALLER sem) NEQ VSI_OK)
370 {
371 gdd_semaphore_err();
372 return -1;
373 }
374 else
375 {
376 return 0;
377 }
378 }