FreeCalypso > hg > fc-magnetite
comparison src/g23m-aci/gdd_dio/gdd_dio_dtxf.c @ 162:53929b40109c
src/g23m-aci: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2016 02:02:43 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
161:4557e2a9c18e | 162:53929b40109c |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | File : gdd_dio_txf.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 : This modul is part of the entity gdd_dio and implements the | |
17 | dtx service functions. | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 | |
22 #define ENTITY_GDD_DIO | |
23 | |
24 /*==== INCLUDES =============================================================*/ | |
25 | |
26 #include "typedefs.h" /* to get Condat data types */ | |
27 #include "vsi.h" /* to get a lot of macros */ | |
28 | |
29 /* GDD stuff */ | |
30 #include "gdd_dio.h" /* to get the global entity definitions */ | |
31 #include "gdd_dio_con_mgr.h" | |
32 | |
33 #include "gdd_dio_dtxf.h" | |
34 #include "gdd_dio_rxf.h" | |
35 #include "gdd_dio_drxf.h" /* Needed for allocate_gdd_desc_list() etc */ | |
36 | |
37 #include "gdd_dio_queue.h" | |
38 | |
39 /*==== CONST ================================================================*/ | |
40 | |
41 /*==== LOCAL VARS ===========================================================*/ | |
42 | |
43 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
44 | |
45 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
46 | |
47 | |
48 GLOBAL GDD_RESULT gdd_dio_dtx_get_send_buffer | |
49 ( | |
50 T_GDD_CON_HANDLE con_handle, | |
51 T_GDD_BUF ** send_buf, | |
52 U16 data_size | |
53 ) | |
54 { | |
55 T_GDD_INST_ID inst; | |
56 T_GDD_DIO_DATA * gdd_dio_data; | |
57 T_GDD_DIO_CON_DATA * con_data; | |
58 T_dio_buffer * dio_buf; | |
59 | |
60 TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_dio_dtx_get_send_buffer()"); | |
61 | |
62 inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle); | |
63 | |
64 /** | |
65 * Do the necessary checks. | |
66 */ | |
67 if(inst < 0) | |
68 { | |
69 TRACE_ERROR("[GDD] Invalid connection handle"); | |
70 return GDD_INVALID_PARAMS; | |
71 } | |
72 | |
73 if(inst >= GDD_NUM_INSTS) | |
74 { | |
75 TRACE_ERROR("[GDD] inst id out of bounds"); | |
76 return GDD_INTERNAL_ERROR; | |
77 } | |
78 gdd_dio_data = &gdd_dio_data_base[inst]; | |
79 | |
80 if(gdd_dio_init_flag[inst] EQ FALSE) | |
81 { | |
82 TRACE_ERROR("[GDD] Instance not initialized"); | |
83 return GDD_INVALID_PARAMS; | |
84 } | |
85 | |
86 if (gdd_dio_data->ker.state NEQ GDD_DIO_KER_READY) | |
87 { | |
88 TRACE_ERROR("[GDD] DIO driver not initialized"); | |
89 return GDD_INTERNAL_ERROR; | |
90 } | |
91 | |
92 con_data = get_con_data(gdd_dio_data, con_handle); | |
93 if(con_data EQ NULL) | |
94 { | |
95 TRACE_ERROR("[GDD] Invalid connection handle"); | |
96 return GDD_INVALID_PARAMS; | |
97 } | |
98 | |
99 if(data_size EQ 0 || data_size > con_data->dio_cap.mtu_data) | |
100 { | |
101 TRACE_ERROR("[GDD] requested data_size (MTU size) out of range"); | |
102 return GDD_INVALID_PARAMS; | |
103 } | |
104 | |
105 if( con_data->con_state EQ GDD_DIO_CON_CONNECT || | |
106 con_data->con_state EQ GDD_DIO_CON_SENDING || | |
107 gdd_dio_queue_peek_next_for_dequeue(&con_data->rx_queue, &dio_buf) EQ FALSE) | |
108 { | |
109 /* Set the flag indicating the somebody (the client) is waiting for a send | |
110 buffer. As a consequence, the signal GDD_SIGTYPE_SEND_BUF_AVAILABLE | |
111 will be sent as soon as we receive a new RX buffer from PSI. */ | |
112 char * reason; | |
113 if(con_data->con_state EQ GDD_DIO_CON_CONNECT) | |
114 reason = "con_state=GDD_DIO_CON_CONNECT"; | |
115 else if(con_data->con_state EQ GDD_DIO_CON_SENDING) | |
116 reason = "con_state=GDD_DIO_CON_SENDING"; | |
117 else | |
118 reason = "no buffer available in RX queue"; | |
119 | |
120 con_data->wait_send_buf = TRUE; | |
121 | |
122 TRACE_EVENT_P2("[GDD] Cannot return buffer [con_handle=0x%4x: %s]", | |
123 con_handle, reason); | |
124 | |
125 return GDD_NO_BUF_AVAILABLE; | |
126 } | |
127 else | |
128 { | |
129 /* Make sure that buffer can hold what is requested. | |
130 We must take into account that the first 2-byte segment holding | |
131 the protocol ID which is not part of the pay-load */ | |
132 if(data_size > (dio_buf->length-2)) | |
133 { | |
134 TRACE_ERROR("[GDD] Requested buffer size too large"); | |
135 return GDD_REQ_BUF_TOO_LARGE; | |
136 } | |
137 else | |
138 { | |
139 /* Setup current descriptor list and pass it back to the client */ | |
140 (*send_buf) = (T_GDD_BUF *)dio_buf; | |
141 | |
142 con_data->con_state = GDD_DIO_CON_SENDING; | |
143 | |
144 return GDD_OK; | |
145 } | |
146 } | |
147 } | |
148 | |
149 | |
150 GLOBAL GDD_RESULT gdd_dio_dtx_send_buffer(T_GDD_CON_HANDLE con_handle, T_GDD_BUF * buf) | |
151 { | |
152 #ifdef GDD_MAKE_DTX_CONTEXT_SWITCH | |
153 U32 signal = GDD_DIO_SIGNAL_SEND_DATA | (U32)con_handle; | |
154 #endif /* GDD_MAKE_DTX_CONTEXT_SWITCH */ | |
155 T_GDD_INST_ID inst; | |
156 T_GDD_DIO_DATA * gdd_dio_data; | |
157 T_GDD_DIO_CON_DATA * con_data; | |
158 T_dio_buffer * dio_buf; | |
159 | |
160 TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_dio_dtx_send_buffer()"); | |
161 | |
162 inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle); | |
163 | |
164 /** | |
165 * Do the necessary checks. | |
166 */ | |
167 if(inst < 0) | |
168 { | |
169 TRACE_ERROR("[GDD] Invalid connection handle"); | |
170 return GDD_INVALID_PARAMS; | |
171 } | |
172 else if(inst >= GDD_NUM_INSTS) | |
173 { | |
174 TRACE_ERROR("[GDD] inst id out of bounds"); | |
175 return GDD_INTERNAL_ERROR; | |
176 } | |
177 gdd_dio_data = &gdd_dio_data_base[inst]; | |
178 | |
179 if(gdd_dio_init_flag[inst] EQ FALSE) | |
180 { | |
181 TRACE_ERROR("[GDD] Instance not initialized"); | |
182 return GDD_ALREADY_INITIALIZED; | |
183 } | |
184 | |
185 if (gdd_dio_data->ker.state NEQ GDD_DIO_KER_READY) | |
186 { | |
187 TRACE_ERROR("[GDD] DIO driver not initialized"); | |
188 return GDD_INTERNAL_ERROR; | |
189 } | |
190 | |
191 con_data = get_con_data(gdd_dio_data, con_handle); | |
192 if(con_data EQ NULL) | |
193 { | |
194 TRACE_ERROR("[GDD] Invalid connection handle"); | |
195 return GDD_INVALID_PARAMS; | |
196 } | |
197 | |
198 /* The pointer which is next for dequeue must be the one which | |
199 corresponds to the buffer for sending ! */ | |
200 if(gdd_dio_queue_peek_next_for_dequeue(&con_data->rx_queue, &dio_buf) EQ FALSE) | |
201 { | |
202 return GDD_INTERNAL_ERROR; | |
203 } | |
204 #ifdef GDD_MAKE_DTX_CONTEXT_SWITCH | |
205 #ifdef MEMORY_SUPERVISION | |
206 vsi_c_ssend(hCommGDD_DIO, signal, (T_VOID_STRUCT*)dio_buf, sizeof(T_VOID_STRUCT*), __FILE__, __LINE__); | |
207 #else | |
208 vsi_c_ssend(hCommGDD_DIO, signal, (T_VOID_STRUCT*)dio_buf, sizeof(T_VOID_STRUCT*)); | |
209 #endif | |
210 return GDD_OK; | |
211 #else /* GDD_MAKE_DTX_CONTEXT_SWITCH */ | |
212 /* Call the corresponding RX function directly instead of sending signal */ | |
213 gdd_dio_rx_sig_send_data(con_handle, dio_buf); | |
214 return GDD_OK; | |
215 #endif /* GDD_MAKE_DTX_CONTEXT_SWITCH */ | |
216 | |
217 | |
218 } | |
219 |