blob: 5a67cccef21554a3be88045fe4c396aed3285217 [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2012
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*******************************************************************************
37 * Filename:
38 * ---------
39 * dcl_tty.c
40 *
41 * Project:
42 * --------
43 * MOLY
44 *
45 * Description:
46 * ------------
47 * Define how to access COM Port. Provide API for upper-layer applications to access COM Port
48 * It works with enabling compile flag __TTY_UT__.
49 *
50 * Author:
51 * -------
52 * -------
53 *
54 * ==========================================================================
55 * $Log$
56 *
57 * 11 03 2021 li-cheng.tsai
58 * [MOLY00629269] [FOCUS][VMOLYM][MT6298][Mercury][Pre-MP1][SQC][Dongle][MTBF][HQ][Lab][Ericsson][ErrorTimes:3][1][core0,vpe1,tc2(vpe1)] Fatal Error (0x1d, 0x0, 0x900072a8) - DHLHD
59 *
60 * [MD700.MP][MPD] patch back from VMOLYM, avoid race condition caused null callback function issue.
61 *
62 * 08 27 2021 li-cheng.tsai
63 * [MOLY00711608] [WIN] MiniDump is observed during ICT S4(Hibernate) stress.
64 *
65 * [MD700.MP][MPD] Solved race condition in assign rx ior
66 *
67 * 09 18 2020 li-cheng.tsai
68 * [MOLY00569647] [MP7.PRECHECKIN.DEV][Code sync] sync code from T700
69 * [R3.MP][MPD][CCCIDEV]code sync from T700
70 *
71 * 09 15 2020 li-cheng.tsai
72 * [MOLY00569647] [MP7.PRECHECKIN.DEV][Code sync] sync code from T700
73 * [MP7.PRECHECKIN.DEV][MPD][CCCIDEV]code sync from T700
74 *
75 * 09 14 2020 i-wei.tsai
76 * [MOLY00548843] [TITAN CRASH][Wingtech][TITAN][MT6765][N21][TFN][P200722-00292 ]S215DL-11 Device crashes into CP Crash upload mode
77 * .
78 *
79 * 08 10 2020 i-wei.tsai
80 * [MOLY00548843] [TITAN CRASH][Wingtech][TITAN][MT6765][N21][TFN][P200722-00292 ]S215DL-11 Device crashes into CP Crash upload mode
81 *
82 * . skip clear tx handling for ccci port
83 *
84 * 06 01 2020 li-cheng.tsai
85 * [MOLY00526500] [MODEM][ASSERT ][ASSERT] file:mcu/service/qmu_bm/src/qmu_bm.c line:512 p1:0x00000000 p2:0x00000000 p3:0x00000000
86 * CCCI TTY change to fix error handling
87 *
88 * 12 05 2019 i-wei.tsai
89 * [MOLY00463962] [Gen97] TTY DEV
90 *
91 * .
92 *
93 * 12 04 2019 amit.singh
94 * [MOLY00463020] [IPCORE] [TTY] VMOLY Patchback memory reduction by re-arranging member fields of structures
95 *
96 * TTY memory reduction by structure rearrange.
97 *
98 * 12 02 2019 amit.singh
99 * [MOLY00454015] [TTY] LG patchabck of MOLY00394195 to VMOLY.1001.DEV
100 *
101 * 1001.DEV to VMOLY TRUNK patchback TTY.
102 *
103 * 06 18 2019 i-wei.tsai
104 * [MOLY00413678] [MT6297][Apollo][Ericsson][IODT][NSA FullStack][Kista][5G][1][core0,vpe0,tc0(vpe0)] Assert fail dcl_tty.c 1063 - DR
105 *
106 * .remove un-used assertion
107 *
108 * 09 11 2018 i-wei.tsai
109 * [MOLY00349664] [ASSERT] file:mcu/common/driver/tty/src/dcl_tty.c line:1789
110 *
111 * .fix race condition issue in rx callback
112 *
113 * 07 24 2018 i-wei.tsai
114 * [MOLY00341790] [MT6295] UDC feature patch back
115 *
116 * .change spinlock to HWITC
117 *
118 * 06 04 2018 i-wei.tsai
119 * [MOLY00331344] [Gen95] TTYCore fix
120 *
121 * .
122 *
123 * 09 18 2017 i-wei.tsai
124 * [MOLY00278689] Performance improvement of INT_QueryExceptionStatus
125 *
126 * .
127 *
128 * 07 06 2017 i-wei.tsai
129 * [MOLY00262251] [Coverity defect fix] tty coverity fix
130 * .
131 *
132 * 05 09 2017 i-wei.tsai
133 * [MOLY00248066] [Gen93] [TTY] Log format refine
134 * .
135 * fix modis build error
136 *
137 * 05 09 2017 i-wei.tsai
138 * [MOLY00248066] [Gen93] [TTY] Log format refine
139 * .
140 * fix modis warning
141 *
142 * 05 09 2017 i-wei.tsai
143 * [MOLY00248066] [Gen93] [TTY] Log format refine
144 * .
145 * remove dummy character
146 *
147 * 05 09 2017 i-wei.tsai
148 * [MOLY00248066] [Gen93] [TTY] Log format refine
149 * .
150 * TTY log refine
151 *
152 * 06 22 2016 mt.tsai
153 * [MOLY00154662] Fix the tty build warning
154 * .delete unused variable in TTY
155 *
156 * 06 22 2016 mt.tsai
157 * [MOLY00177032] [Coverity Scanned Code Defect]CID:116560 code defect happened in /mcu/common/driver/tty/src/dcl_tty.c
158 * .
159 * [Coverity] add spinlock to full fill the protection of some variables
160 *
161 * 02 26 2016 mt.tsai
162 * [MOLY00166612] Remove violation include kal_debug.h
163 * The APIs in kal_debug.h is legacy and don't be provided for user
164 *
165 * 09 30 2015 mt.tsai
166 * [MOLY00143135] [UMOLY][LR11] TTYCore Unit Test
167 * .modified files for ttycore unit test
168 *
169 * 09 15 2015 i-wei.tsai
170 * [MOLY00141929] [UMOLY][ELBRUS][TTY] Add SMP support
171 * .
172 *
173 * 03 02 2015 i-wei.tsai
174 * [MOLY00097392] [UMOLY] [TTY] Timer tick macro modification
175 * .
176 *
177 * 12 10 2014 i-wei.tsai
178 * [MOLY00086663] [TK6291] [TTY] Add new uart port for MTAD
179 * .
180 *
181 * 11 14 2014 i-wei.tsai
182 * [MOLY00084437] [UMOLY] [TTY] rollback changes
183 * .
184 *
185 * 06 16 2014 i-wei.tsai
186 * [MOLY00068713] [MT6752] MD2 uart config setting (Buffer mode)
187 * .
188 *
189 * 04 25 2014 i-wei.tsai
190 * [MOLY00063770] [Rose][KK][Free Test][EE][VT Call]EE about [ASSERT] file:dcl_tty.c line:1367 will pop up after tap "Use touch tone keypad" to enter VT call screen.
191 * .
192 *
193 * 03 12 2014 i-wei.tsai
194 * [MOLY00059311] [TTY] New Feature for configurable indication mechanism
195 *
196 * 10 29 2013 i-wei.tsai
197 * [MOLY00044179] [TTY] Fixed 82LTE VT issue
198 * .
199 *
200 * 09 13 2013 shenghui.shi
201 * [MOLY00035078] [MT6290][PDN] Enable GDMA & HDMA related module PDN support
202 * move uart pdn_clr from dcl_tty.c to uart.c
203 *
204 * 08 26 2013 shenghui.shi
205 * [MOLY00035212] fix uart build modis error
206 * .
207 *
208 * 08 26 2013 shenghui.shi
209 * [MOLY00035078] [MT6290][PDN] Enable GDMA & HDMA related module PDN support
210 * add uart PDN feature
211 *
212 * 06 26 2013 i-wei.tsai
213 * [MOLY00027496] [TTYCore] Features check-in
214 * 1. add new TTY_CMD_MTU_SIZE support
215 * 2. add plug-in/plug-out indication
216 * 3. fix issue of flushing rx internal gpd
217 *
218 * 06 19 2013 i-wei.tsai
219 * [MOLY00026667] [TTYCore] Revise ttycore trace log in exception mode
220 *
221 * 05 29 2013 haoren.kao
222 * [MOLY00024108] Support New USB Core
223 * Replace with New USB Core.
224 * We sync with the following codes from HaoRen MOLY CBr w1322:
225 * 1. USB Core
226 * 2. USB Class - acm/rndis/mbim
227 * 3. ipcore
228 * 4. ttycore
229 * 5. ethercore
230 *
231 * 05 15 2013 i-wei.tsai
232 * [MOLY00021838] [MT6290 Bring-up] TTY DEV.
233 * Turn off aggressive log trace
234 *
235 * 05 10 2013 i-wei.tsai
236 * [MOLY00021838] [MT6290 Bring-up] TTY DEV
237 * sync from MT6290E1 First Call Branch
238 *
239 * 05 10 2013 i-wei.tsai
240 * [MOLY00021376] [MT6290 Bring-up] Basic load
241 * Check-in support
242 *
243 * 05 09 2013 i-wei.tsai
244 * [MOLY00021838] [MT6290 Bring-up] TTY DEV
245 * fix error for setting tx not rdy flag
246 *
247 * 05 09 2013 i-wei.tsai
248 * [MOLY00021838] [MT6290 Bring-up] TTY DEV
249 * add sending Ready2Write message when dirver attach
250 *
251 * 05 08 2013 i-wei.tsai
252 * [MOLY00021838] [MT6290 Bring-up] Revise ttycore trace log
253 * .
254 *
255 * 05 03 2013 i-wei.tsai
256 * [MOLY00021396] [MT6290 Bring-up] [Basic Load Support] [TTYCore] add option __MAUI_BASIC__
257 * basic load support
258 *
259 * 03 08 2013 i-wei.tsai
260 * [MOLY00011358] [TTYCore] TTYCore support
261 * Add CCIF UART device type and modify comments
262 *
263 * 03 01 2013 i-wei.tsai
264 * [MOLY00010632] add TTYCore new features
265 * fixed typo
266 *
267 * 02 21 2013 i-wei.tsai
268 * [MOLY00010632] add TTYCore new features
269 * checkin supporting buffer port features
270 *
271 * 11 08 2012 haoren.kao
272 * [MOLY00005322] TATAKA merge to MOLY
273 *
274 * MOLY Migration from TATAKA
275 ****************************************************************************/
276
277#include <stdio.h>
278#include "dcl.h"
279
280#include "qbm_config_num.h"
281#include "qmu_bm.h"
282#include "qmu_bm_util.h"
283#include "kal_public_api.h"
284#include "kal_general_types.h"
285#include "stack_ltlcom.h"
286#include "hif_ior.h"
287#include "kal_internal_api.h"
288#include "devdrv_ls.h"
289#include "drv_msgid.h"
290#include "md_drv_sap.h"
291#include "drvpdn.h"
292#include "drv_gdma.h"
293#include <ex_public.h>
294#include "kal_hrt_api.h"
295
296#include "cccidev_qbm.h" /* macros for QBM_TYPE_CCCI_COMM */
297
298//for reference the vp number
299#include "cmux_vp_num.h"
300
301#define TTY_CONSOLE_TRACE_ENABLED 0
302
303#define TTY_AGGRESSIVE_TRACE 0
304
305/*20120724 Ian Modify CCCI_COMM for TTYCore*/
306// #if __HIF_CCCI_SUPPORT__
307// /* using CCCI_COMM type to replace QBM_TYPE_TTY_INT/QBM_TYPE_TTY_TYPE1/QBM_TYPE_TTY_TYPE2 */
308// #define TTY_QBM_DATA_LEN QBM_CCCI_COMM_DATA_LEN
309// #define TTY_QBM_DATA_TYPE QBM_TYPE_CCCI_COMM
310// #define TTY_QBM_DES_GET_DATAPTR CCCIDEV_GET_QBM_DATAPTR
311// #define TTY_QBM_DES_GET_DATALEN CCCIDEV_GET_QBM_DATALEN
312// #define TTY_QBM_DES_SET_DATALEN CCCICOMM_SET_QBM_DATALEN
313// #else
314// #define TTY_QBM_DATA_LEN QBM_TTY_XXX_DATA_LEN
315// #define TTY_QBM_DATA_TYPE QBM_TYPE_TTY_INT
316// #define TTY_QBM_DES_GET_DATAPTR QBM_DES_GET_DATAPTR
317// #define TTY_QBM_DES_GET_DATALEN QBM_DES_GET_DATALEN
318// #define TTY_QBM_DES_SET_DATALEN QBM_DES_SET_DATALEN
319// #endif
320
321extern void dbg_print(char *fmt,...);
322
323#if TTY_CONSOLE_TRACE_ENABLED==1
324 /*
325 * Print indexed trace to console.
326 */
327 #if defined(__MTK_TARGET__)
328 //#define tty_console_trace dbg_print
329 #define tty_console_trace dbg_print
330 #define TTY_NEW_LINE "\r\n"
331 #else
332 #define tty_console_trace dbg_print
333 #define TTY_NEW_LINE "\n"
334 #endif
335
336/* #define tty_trace_error(...) tty_console_trace(__VA_ARGS__)*/
337/* #define tty_trace_info(...) tty_console_trace(__VA_ARGS__)*/
338
339 #define BEGIN_TRACE_MAP(_mod)
340 #define TRC_MSG(_msg_index, _fmt) static const char _msg_index [] = _fmt TTY_NEW_LINE;
341 #define END_TRACE_MAP(_mod)
342#else
343 /*
344 * Use DHL logging.
345 */
346 #ifndef __MAUI_BASIC__
347/* #define tty_trace_error(...) \
348 do{ \
349 if(INT_QueryExceptionStatus() == KAL_FALSE) \
350 { \
351 dhl_trace(TRACE_ERROR, DHL_USER_FLAG_NONE, __VA_ARGS__); \
352 } \
353 }while(0)*/
354
355/* #define tty_trace_info(...) \
356 do{ \
357 if(INT_QueryExceptionStatus() == KAL_FALSE) \
358 { \
359 dhl_trace(TRACE_INFO, DHL_USER_FLAG_NONE, __VA_ARGS__); \
360 } \
361 }while(0)*/
362
363/* #define tty_trace_func(...) \
364 do{ \
365 if(INT_QueryExceptionStatus() == KAL_FALSE) \
366 { \
367 dhl_trace(TRACE_FUNC, DHL_USER_FLAG_NONE, __VA_ARGS__); \
368 } \
369 }while(0)*/
370 #else
371/* #define tty_trace_error(...)*/
372/* #define tty_trace_info(...)*/
373/* #define tty_trace_func(...)*/
374 #endif
375#endif /* TTY_CONSOLE_TRACE_ENABLED */
376
377#ifndef __MAUI_BASIC__
378#include "tty_trace.h"
379#endif
380
381/* Macros */
382/* ==================================================================================================== */
383#ifdef ATEST_SYS_TTYCORE
384 extern kal_bool ut_assert_flag;
385
386 #ifdef ASSERT
387 #undef ASSERT
388 #endif
389 //#define ASSERT(x) do{ if (x) ut_assert_flag = KAL_TRUE; }while(0)
390 void ASSERT(int x) {
391 if (!x) {
392 ut_assert_flag = KAL_TRUE;
393 }
394 }
395#endif
396#define VAR_MSG_ASSERT(var_msg) do{int var_msg=0; ASSERT(var_msg);} while(0)
397
398#ifdef __TTY_DBG_MODE__
399#define DBG_ASSERT(expr) ASSERT(expr)
400#define TTY_CHECK_CONTEXT_ENABLED 1
401#else
402#define DBG_ASSERT(expr)
403#define TTY_CHECK_CONTEXT_ENABLED 0
404#endif
405
406#define TTY_HWITC_ENABLE (1)
407#if defined(TTY_HWITC_ENABLE)
408 #define TTY_SPIN_LOCK(_s) kal_hrt_take_itc_lock(KAL_ITC_TTY, KAL_INFINITE_WAIT)
409 #define TTY_SPIN_UNLOCK(_s) kal_hrt_give_itc_lock(KAL_ITC_TTY)
410#else
411 #define TTY_SPIN_LOCK(_s) kal_take_spinlock(_s, KAL_INFINITE_WAIT)
412 #define TTY_SPIN_UNLOCK(_s) kal_give_spinlock(_s)
413#endif
414
415#define TTY_CHECK_HANDLE(handle) \
416 do{ \
417 if (handle == STATUS_INVALID_DEVICE) {return STATUS_FAIL;} \
418 if (!DCL_UART_IS_HANDLE_MAGIC(handle)) {if(INT_QueryExceptionStatus() == KAL_FALSE) \
419MD_TRC(TTY_TR_INVALID_HANDLE,__LINE__, handle, kal_get_active_module_id());return STATUS_INVALID_DCL_HANDLE;} \
420 }while(0)
421
422#define TTY_CHECK_DEV_IS_READY(dev) \
423 do{ \
424 /* Check if the driver callback is registered */ \
425 if (dev >= UART_DEV_CNT || dev < 0 || !tty_mgmt_info[dev].active) \
426 { \
427 if(INT_QueryExceptionStatus() == KAL_FALSE) \
428MD_TRC(TTY_TR_DEV_DRV_NOT_RDY,__LINE__, dev, kal_get_active_module_id()); \
429 return STATUS_DEVICE_NOT_EXIST; \
430 } \
431 }while(0)
432
433#define TTY_CHECK_DEV_VALID(dev) \
434 do{ \
435 if (dev >= UART_DEV_CNT || dev < 0) {if(INT_QueryExceptionStatus() == KAL_FALSE) \
436MD_TRC(TTY_TR_DEV_NOT_VALID,__LINE__, dev, kal_get_active_module_id());return STATUS_INVALID_DEVICE;} \
437 }while(0)
438
439#if TTY_CHECK_CONTEXT_ENABLED==1
440#define TTY_CHECK_RUN_IN_HISR(dev) do{if (tty_mgmt_info[dev].owner_id != MOD_DRV_DBG/*dbg_print is exception*/ && kal_if_hisr()){VAR_MSG_ASSERT(TTY_it_runs_in_hisr);}} while(0)
441#define TTY_CHECK_ACTIVE_MOD(dev) \
442 do{ \
443 if (tty_mgmt_info[dev].owner_id != MOD_DRV_DBG/*dbg_print is exception*/ \
444 && tty_mgmt_info[dev].owner_id != MOD_DHL \
445 && tty_mgmt_info[dev].owner_id != MOD_DHL_READER \
446 && tty_mgmt_info[dev].opened \
447 && tty_mgmt_info[dev].owner_id != kal_get_active_module_id()) { \
448 VAR_MSG_ASSERT(TTY_Active_module_id_not_match); \
449 } \
450 }while(0)
451#else
452#define TTY_CHECK_RUN_IN_HISR(dev)
453#define TTY_CHECK_ACTIVE_MOD(dev)
454#endif
455
456#define TTY_CONV_FLUSH_TX(cnt_thre) \
457 count = 0; \
458 if (TTY_IS_CONVENTIONAL_TX(device)) { \
459 while (1) { \
460 if (tty_mgmt_info[device].tx_gpd_num_used == 0) { \
461 break; \
462 } \
463 kal_sleep_task(KAL_TICKS_10_MSEC/2); \
464 if (++count > cnt_thre) { \
465 VAR_MSG_ASSERT(flush_tx_cmd_too_long); \
466 } \
467 } \
468 }
469
470#define TTY_CONV_FLUSH_RX(cnt_thre) \
471 count = 0; \
472 if (TTY_IS_CONVENTIONAL_RX(device)) { \
473 while (1) { \
474 if (tty_mgmt_info[device].rx_gpd_num_assigned == 0) { \
475 break; \
476 } \
477 kal_sleep_task(KAL_TICKS_10_MSEC/2); \
478 if (++count > cnt_thre) { \
479 VAR_MSG_ASSERT(flush_rx_cmd_too_long); \
480 } \
481 } \
482 }
483
484
485
486#define TTY_IS_CONVENTIONAL_TX(dev) (!(tty_mgmt_info[dev].flag & TTY_FLAG_NEW_TX))
487#define TTY_IS_CONVENTIONAL_RX(dev) (!(tty_mgmt_info[dev].flag & TTY_FLAG_NEW_RX))
488#define TTY_DRV_IS_ATTACHED(dev) (tty_mgmt_info[dev].drv_state == DRV_ST_ATTACHED)
489
490#define DCL_UART_MAGIC_NUM 0x40000000
491#define DCL_UART_IS_HANDLE_MAGIC(handl_) ((handl_)& DCL_UART_MAGIC_NUM)
492#define DCL_UART_GET_DEV(handle_) ((DCL_DEV)((handle_) & (~DCL_UART_MAGIC_NUM)))
493
494#define UART_DEV_CNT (uart_max_port - uart_port1 + 1) //subtract uart1, in case uart1 != 0 in future.
495
496#define TTY_BC_TX_GPD_MAX_NUM 2 /* Tx Max GPD number for backward-compatible */
497#define GPD_NUM_FOR_TTY 100
498
499#if 0
500/* under construction !*/
501/* under construction !*/
502/* under construction !*/
503/* under construction !*/
504#endif
505
506#define TTY_IS_BUFF_PORT(dev) ((tty_mgmt_info[dev].drv_type == BUFF_DRV_TYPE))
507#define TTY_MIN(_a, _b) (((_a) <= (_b)) ? (_a) : (_b))
508
509#define TTY_CHK_DEV_OPEN(dev) (DCL_TRUE == tty_mgmt_info[dev].opened)
510
511/* Structure define & Global variable */
512/* ==================================================================================================== */
513typedef struct _tty_port_mgmt
514{
515 /* for buffer type driver*/
516 DCL_UINT32 drv_type;
517 kal_spinlockid spinLock; // each device has its own lock
518 DCL_UINT32 rx_allow_len; //Indicates downlink mtu size of HIF
519 qbm_gpd *rx_gpd;
520 DCL_UINT32 rx_gpd_num_assigned;
521 DCL_UINT32 tx_gpd_num_used;
522 /* for backward-compatible */
523 DCL_UART_TX_FUNC conv_tx_cb;
524 DCL_UART_RX_FUNC conv_rx_cb;
525 DCL_UINT32 dev_type; //record device type
526 DCL_UINT32 qbm_data_len; //supported GPD type length
527 DCL_UINT32 flag;
528 tty_drv_state_change_cb drv_state_change_cb;
529 DCL_UINT32 qbm_data_type; //supported GPD type
530 tty_rx_cb rx_cb;
531 tty_txdone_cb tx_done_cb;
532 SeriPort_HANLDER_CB sp_handler_cb;
533
534 module_type pending_owner;
535 DCL_UINT16 rx_buf_offset; // it indicates the buffer offset of rx_gpd (data in rx_gpd before offset has been received)
536 DCL_UINT16 chunk_size;
537 module_type owner_id;
538
539 tty_drv_state_e drv_state; // 1: driver attach; 0: driver detach
540 /* For legacy USBcore solution: driver attach event may be later than user traffic*/
541 DCL_BOOL tx_not_rdy;
542 DCL_BOOL opened; // opened by upper module
543 DCL_BOOL init_by_new_mod;
544 DCL_BOOL rx_up_mod_wait; //add for buffer device
545 DCL_BOOL tx_up_mod_wait;
546 DCL_BOOL flush_rx;
547 DCL_BOOL flush_tx;
548 DCL_BOOL no_indication; //User can set attribute to disable receiving ILM through SIO_SET_INDICATION
549 DCL_BOOL active; // registered uart handler callback by driver
550 /*store flag if user send SIO_CMD_OPEN or register callback before driver register CB*/
551 DCL_BOOL early_tx_done_cb_req;
552 DCL_BOOL early_open_req;
553} tty_port_mgmt;
554
555typedef enum
556{
557 GPD_DRV_TYPE,
558 BUFF_DRV_TYPE,
559}tty_driver_type;
560
561typedef struct _tty_dev_info
562{
563 SIO_TYPE_T dev_type;
564 DCL_UINT32 buff_type;
565 DCL_UINT32 buff_data_len;
566 tty_driver_type drv_type;
567}tty_dev_info;
568
569#define NOT_DEFINED_TYPE 0xFFFFFFFF
570#define NOT_DEFINED_LENGTH 0xFFFFFFFF
571
572static tty_dev_info tty_dev_info_tbl[DCL_UART_DEV_TYPE_MAX] = {
573#if defined(MT6752) && defined(__MD2__)
574 {DCL_UART_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //6752 MD2 uart only support buffer mode
575#else
576 {DCL_UART_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , GPD_DRV_TYPE},
577#endif
578 {DCL_UART_USB_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , GPD_DRV_TYPE},
579 {DCL_UART_BLUETOOTH_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
580 {DCL_UART_SPPA_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
581 {DCL_UART_CMUX_TYPE, NOT_DEFINED_TYPE , NOT_DEFINED_LENGTH , BUFF_DRV_TYPE},
582 {DCL_UART_CCCI_TYPE, QBM_TYPE_CCCI_COMM, QBM_CCCI_COMM_DATA_LEN , GPD_DRV_TYPE},
583 {DCL_UART_CCIF_TYPE, NOT_DEFINED_TYPE, NOT_DEFINED_LENGTH , BUFF_DRV_TYPE},
584 {DCL_UART_DCC_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
585 {DCL_UART_LOGACC_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
586 {DCL_UART_LMU_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
587 {DCL_UART_SP_USB_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
588 {DCL_UART_MINI_LOG_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
589 {DCL_UART_MTAD_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , GPD_DRV_TYPE},
590};
591
592
593static tty_port_mgmt tty_mgmt_info[UART_DEV_CNT];
594
595/* Internal used API declaration */
596/* ==================================================================================================== */
597static DCL_STATUS _DclSerialPort_UpModuleReinit(DCL_DEV device, module_type module_id, int flag);
598static DCL_STATUS _DclSerialPort_UpModuleRegisterCb(DCL_DEV device, tty_rx_cb rx_cb, tty_txdone_cb tx_done_cb, tty_drv_state_change_cb drv_state_change_cb);
599
600
601/* Internal used API */
602/* ==================================================================================================== */
603static void DEVDRV_LS_DRAM_EX_ROCODE
604TTY_QBM_DES_SET_DATALEN(void* gpd, kal_uint32 data_len)
605{
606 void* bd = NULL;
607
608 ASSERT(NULL != gpd);
609 if(0 != QBM_DES_GET_BDP(gpd))
610 {
611 //4 <case> GPD->BD->BUFF
612 bd = QBM_DES_GET_DATAPTR(gpd);
613 ASSERT(NULL!=bd);
614 QBM_DES_SET_DATALEN(bd, data_len);
615 qbm_cal_set_checksum((kal_uint8 *)bd);
616 }
617
618 QBM_DES_SET_DATALEN(gpd, data_len);
619 qbm_cal_set_checksum((kal_uint8 *)gpd);
620}
621
622static DCL_UINT32 DEVDRV_LS_DRAM_EX_ROCODE
623TTY_QBM_DES_GET_DATALEN(void* gpd)
624{
625 void* bd = NULL;
626 DCL_UINT32 data_len = 0;
627
628 ASSERT(NULL!=gpd);
629 if(0 != QBM_DES_GET_BDP(gpd)){
630 //4 <case 1> GPD->BD->BUFF
631 bd = QBM_DES_GET_DATAPTR(gpd);
632 ASSERT(NULL!=bd);
633 data_len = QBM_DES_GET_DATALEN(bd);
634 }else{
635 //4 <case 2> GPD->BUFF
636 data_len = QBM_DES_GET_DATALEN(gpd);
637 }
638 return data_len;
639}
640
641static void* DEVDRV_LS_DRAM_EX_ROCODE
642TTY_QBM_DES_GET_DATAPTR(void* gpd)
643{
644 void* bd = NULL;
645 void* data_ptr = NULL;
646
647 ASSERT(NULL!=gpd);
648 if(0 != QBM_DES_GET_BDP(gpd)){
649 //4 <case 1> GPD->BD->BUFF
650 bd = QBM_DES_GET_DATAPTR(gpd);
651 ASSERT(NULL!=bd);
652 data_ptr = QBM_DES_GET_DATAPTR(bd);
653 }else{
654 //4 <case 2> GPD->BUFF
655 data_ptr = QBM_DES_GET_DATAPTR(gpd);
656 }
657
658 ASSERT(NULL!=data_ptr);
659 return data_ptr;
660}
661
662static void DEVDRV_LS_DRAM_EX_ROCODE
663_tty_update_buff_info_from_port(DCL_DEV device, SIO_TYPE_T dev_type)
664{
665 DCL_UINT8 i;
666
667 for( i = 0; i < DCL_UART_DEV_TYPE_MAX; i++)
668 {
669 if(tty_dev_info_tbl[i].dev_type == dev_type)
670 {
671 tty_mgmt_info[device].qbm_data_type = tty_dev_info_tbl[i].buff_type;
672 tty_mgmt_info[device].qbm_data_len = tty_dev_info_tbl[i].buff_data_len;
673 tty_mgmt_info[device].drv_type = tty_dev_info_tbl[i].drv_type;
674 return;
675 }
676 }
677 ASSERT(i < DCL_UART_DEV_TYPE_MAX);
678 return;
679}
680
681void DEVDRV_LS_DRAM_EX_ROCODE
682_tty_send_ilm(
683 DCL_DEV device,
684 module_type source_id,
685 msg_type msg_id)
686{
687 void *port_ptr = 0;
688
689 /*New feature: some ports may not need ilm indication*/
690 if(tty_mgmt_info[device].no_indication == 1)
691 {
692 return;
693 }
694
695 switch(msg_id)
696 {
697 case MSG_ID_UART_READY_TO_READ_IND:
698 {
699 uart_ready_to_read_ind_struct *tmp;
700 tmp = (uart_ready_to_read_ind_struct *)
701 construct_local_para(sizeof(uart_ready_to_read_ind_struct),TD_UL);
702 tmp->port = device;
703 port_ptr = tmp;
704 }
705 break;
706 case MSG_ID_UART_READY_TO_WRITE_IND:
707 {
708 uart_ready_to_write_ind_struct *tmp;
709 tmp = (uart_ready_to_write_ind_struct *)
710 construct_local_para(sizeof(uart_ready_to_write_ind_struct),TD_UL);
711 tmp->port = device;
712 port_ptr = tmp;
713 }
714 break;
715 case MSG_ID_UART_DSR_CHANGE_IND:
716 {
717 uart_dsr_change_ind_struct *tmp;
718 tmp = (uart_dsr_change_ind_struct *)
719 construct_local_para(sizeof(uart_dsr_change_ind_struct),TD_UL);
720 tmp->port = device;
721 port_ptr = tmp;
722 }
723 break;
724 case MSG_ID_UART_ESCAPE_DETECTED_IND:
725 {
726 uart_escape_detected_ind_struct *tmp;
727 tmp = (uart_escape_detected_ind_struct *)
728 construct_local_para(sizeof(uart_escape_detected_ind_struct),TD_UL);
729 tmp->port = device;
730 port_ptr = tmp;
731 }
732 break;
733 case MSG_ID_UART_PLUGOUT_IND:
734 {
735 uart_plugout_ind_struct *tmp;
736 tmp = (uart_plugout_ind_struct *)
737 construct_local_para(sizeof(uart_plugout_ind_struct),TD_RESET);
738 tmp->port = device;
739 port_ptr = tmp;
740 }
741 break;
742 case MSG_ID_UART_PLUGIN_IND:
743 {
744 uart_plugin_ind_struct *tmp;
745 tmp = (uart_plugin_ind_struct *)
746 construct_local_para(sizeof(uart_plugin_ind_struct),TD_RESET);
747 tmp->port = device;
748 port_ptr = tmp;
749 }
750 break;
751 default:
752 {
753 /* Print error log */
754 return;
755 }
756 }
757
758 msg_send5(source_id, // source module ID
759 tty_mgmt_info[device].owner_id, // destination module ID
760 DRIVER_PS_SAP, // sap ID
761 msg_id, // msg ID
762 port_ptr // local_para_struct *
763 );
764
765}
766
767#ifdef __TTY_DBG_MODE__
768/**
769 * @brief Check if any gpd length is zero
770 * @result none
771 */
772static void DEVDRV_LS_DRAM_EX_ROCODE
773_tty_gpd_zero_len_check(
774 tty_io_request_t *ior)
775{
776 tty_io_request_t *ior_tmp = ior;
777
778 do {
779 void *gpd = ior_tmp->first_gpd;
780
781 while (gpd != ior_tmp->last_gpd) {
782 ASSERT(TTY_QBM_DES_GET_DATALEN(gpd));
783 gpd = QBM_DES_GET_NEXT(gpd);
784 }
785 ASSERT(TTY_QBM_DES_GET_DATALEN(gpd));
786 } while ((ior_tmp = ior_tmp->next_request) != NULL);
787}
788#endif
789
790/**
791 * @brief Free all gpds of ior
792 * @result total number of free gpd
793 */
794static DCL_UINT32 DEVDRV_LS_DRAM_EX_ROCODE
795_tty_free_ior(
796 tty_io_request_t *ior)
797{
798 DCL_UINT32 number = 0;
799
800 if (ior) {
801 do {
802 number += qbmt_dest_q(ior->first_gpd, ior->last_gpd);
803 } while ((ior = ior->next_request) != NULL);
804 }
805
806 return number;
807}
808
809/*
810 _tty_rx_cb is used for backward-compatible.
811 In TTY Core design, only one rx ior is prepared for Rx receiving in conventional Rx mode.
812 If rx_gpd is callbacked and when conventional upper module send SIO_CMD_GET_BYTES command to receive data, _tty_rx_cb won't be called until the only
813 one rx_gpd is re-assigned to driver.
814 Thus rx_gpd don't need mutex protection.
815*/
816DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
817_tty_rx_cb(
818 DCL_HANDLE handle,
819 module_type source_id,
820 tty_io_request_t *rx_ior)
821{
822 DCL_DEV device;
823 void *gpd_tmp;
824 tty_io_request_t *ior_tmp;
825
826 device = DCL_UART_GET_DEV(handle);
827
828 if (!tty_mgmt_info[device].flush_rx) {
829 /* global rx gpd must be NULL when rx callback of non-flush command is called */
830 ASSERT(!tty_mgmt_info[device].rx_gpd);
831 }
832
833 /*
834 The rx callback is called by flush done :
835 <1> there is a next request of rx_ior
836 <2> there are 2 gpd of rx_ior
837 */
838 if (rx_ior->next_request)
839 {
840 ASSERT(tty_mgmt_info[device].flush_rx);
841 ASSERT(rx_ior->first_gpd == rx_ior->last_gpd);
842 ASSERT(rx_ior->next_request->first_gpd == rx_ior->next_request->last_gpd);
843 ior_tmp = rx_ior->next_request;
844 rx_ior->next_request = NULL;
845 QBM_FREE_ONE(ior_tmp->first_gpd);
846 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
847 ASSERT(tty_mgmt_info[device].rx_gpd_num_assigned >= 1);
848 tty_mgmt_info[device].rx_gpd_num_assigned --;
849 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
850 } else if (rx_ior->first_gpd != rx_ior->last_gpd)
851 {
852 ASSERT(tty_mgmt_info[device].flush_rx);
853
854 // tj.chang, 2011/12/27: We should not promise the length of last_gpd is 0.
855// ASSERT(TTY_QBM_DES_GET_DATALEN(rx_ior->last_gpd) == 0);
856 ASSERT(QBM_DES_GET_NEXT(rx_ior->first_gpd) == rx_ior->last_gpd);
857 gpd_tmp = rx_ior->last_gpd;
858 rx_ior->last_gpd = rx_ior->first_gpd;
859 QBM_FREE_ONE(gpd_tmp);
860 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
861 ASSERT(tty_mgmt_info[device].rx_gpd_num_assigned >= 1);
862 tty_mgmt_info[device].rx_gpd_num_assigned --;
863 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
864 }
865
866 if (!tty_mgmt_info[device].flush_rx && TTY_QBM_DES_GET_DATALEN(rx_ior->first_gpd) > 0)
867 {
868 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
869 tty_mgmt_info[device].rx_gpd = rx_ior->first_gpd;
870 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
871
872 //change start for ALPS04065656
873 //handling race condition between UL data gpd and clr rx buff.
874 if(tty_mgmt_info[device].flush_rx) {
875 void *rx_gpd;
876 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
877 if(tty_mgmt_info[device].rx_gpd) {
878 rx_gpd = tty_mgmt_info[device].rx_gpd;
879 tty_mgmt_info[device].rx_gpd = NULL;
880 tty_mgmt_info[device].rx_buf_offset = 0;
881 tty_mgmt_info[device].rx_gpd_num_assigned--;
882 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
883 QBM_FREE_ONE(rx_gpd);
884 } else {
885 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
886 }
887
888 } else {
889 //change end for ALPS04065656
890 /* Inform upper layer module readyToRead */
891 if (tty_mgmt_info[device].conv_rx_cb) {
892 tty_mgmt_info[device].conv_rx_cb(device);
893 } else {
894 _tty_send_ilm(device, source_id, MSG_ID_UART_READY_TO_READ_IND);
895 }
896 }
897 } else
898 { /* The rx callback is called by clear tx/rx buffer (flush) command */
899 QBM_FREE_ONE(rx_ior->first_gpd);
900 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
901 ASSERT(tty_mgmt_info[device].rx_gpd_num_assigned >= 1);
902 tty_mgmt_info[device].rx_gpd_num_assigned --;
903 if (tty_mgmt_info[device].rx_gpd_num_assigned == 0) {
904 /* clear flush_rx flag if all rx_gpd are free */
905 tty_mgmt_info[device].flush_rx = 0;
906 }
907 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
908 }
909
910 return STATUS_OK;
911}
912
913/*
914 _tty_rx_buff_cb is used for backward-compatible buffer mode driver.
915 This callback is only used for conventional user on buffer mode port.
916 The main task of this callback is sending ILM to tty user.
917 (Flush RX shall not go there.)
918*/
919DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
920_tty_rx_buff_cb(
921 DCL_HANDLE handle,
922 module_type source_id,
923 tty_io_request_t *rx_ior)
924{
925 DCL_DEV device;
926
927 device = DCL_UART_GET_DEV(handle);
928
929 /*Current design does not return data through callback*/
930 ASSERT(rx_ior == NULL);
931
932 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
933 if (tty_mgmt_info[device].rx_up_mod_wait)
934 {
935 tty_mgmt_info[device].rx_up_mod_wait = 0;
936 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
937 if (tty_mgmt_info[device].conv_rx_cb) {
938 tty_mgmt_info[device].conv_rx_cb(device);
939 } else {
940 _tty_send_ilm(device, source_id, MSG_ID_UART_READY_TO_READ_IND);
941 }
942 }
943 else
944 {
945 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
946 }
947 return STATUS_OK;
948}
949
950
951DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
952_tty_tx_done_cb(
953 DCL_HANDLE handle,
954 module_type source_id,
955 tty_io_request_t *tx_ior)
956{
957 DCL_DEV device;
958 DCL_UINT32 number;
959
960 device = DCL_UART_GET_DEV(handle);
961
962 if (tx_ior) {
963 number = _tty_free_ior(tx_ior);
964
965 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
966 ASSERT(tty_mgmt_info[device].tx_gpd_num_used >= number);
967 tty_mgmt_info[device].tx_gpd_num_used -= number;
968 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
969
970 if (!tty_mgmt_info[device].flush_tx)
971 {
972 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
973 if (tty_mgmt_info[device].tx_up_mod_wait)
974 {
975 tty_mgmt_info[device].tx_up_mod_wait = 0;
976 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
977 if (tty_mgmt_info[device].conv_tx_cb) {
978 tty_mgmt_info[device].conv_tx_cb(device);
979 } else {
980 _tty_send_ilm(device, source_id, MSG_ID_UART_READY_TO_WRITE_IND);
981 }
982 }
983 else
984 {
985 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
986 }
987
988 } else {
989 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
990 if (tty_mgmt_info[device].tx_gpd_num_used == 0) {
991 /* clear flush_tx flag if all tx_gpd are free */
992 tty_mgmt_info[device].flush_tx = 0;
993 }
994 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
995 }
996 } else {
997 /* print error log - tx_ior can't be null */
998 if(INT_QueryExceptionStatus() == KAL_FALSE)
999MD_TRC(TTY_TR_TX_IOR_IS_NULL,device, source_id);
1000 ASSERT(tx_ior);
1001 return STATUS_FAIL;
1002 }
1003
1004 return STATUS_OK;
1005}
1006
1007/*
1008 _tty_tx_buff_done_cb is used for backward-compatible buffer mode driver.
1009 This callback is only used for conventional user on buffer mode port.
1010 The main task of this callback is sending ILM to tty user.
1011 (Flush TX shall not go there.)
1012*/
1013DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
1014_tty_tx_buff_done_cb(
1015 DCL_HANDLE handle,
1016 module_type source_id,
1017 tty_io_request_t *tx_ior)
1018{
1019 DCL_DEV device;
1020
1021 device = DCL_UART_GET_DEV(handle);
1022
1023 /*Current design does not return data through callback*/
1024 ASSERT(tx_ior == NULL);
1025
1026 /*
1027 * This function is invoked when lower driver finish the TX.
1028 * check up_mod_wait to send the indication message
1029 */
1030 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1031 if (tty_mgmt_info[device].tx_up_mod_wait)
1032 {
1033 tty_mgmt_info[device].tx_up_mod_wait = 0;
1034 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1035 if (tty_mgmt_info[device].conv_tx_cb) {
1036 tty_mgmt_info[device].conv_tx_cb(device);
1037 } else {
1038 _tty_send_ilm(device, source_id, MSG_ID_UART_READY_TO_WRITE_IND);
1039 }
1040 }
1041 else
1042 {
1043 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1044 }
1045
1046 return STATUS_OK;
1047}
1048
1049void DEVDRV_LS_DRAM_EX_ROCODE
1050_cal_and_set_rx_allow_len(
1051 DCL_DEV device,
1052 DCL_UINT16 chunk_size)
1053{
1054 DCL_HANDLE handle;
1055 UART_CTRL_GET_MTU_SIZE_T ur_ctrl_get_mtu_size;
1056
1057 handle = DclSerialPort_Open(device, 0);
1058
1059 if(chunk_size == 1) //no chunk size restriction
1060 {
1061 DclSerialPort_Control(handle, TTY_CMD_GET_MTU_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_mtu_size);
1062 tty_mgmt_info[device].rx_allow_len = TTY_MIN(ur_ctrl_get_mtu_size.ulmtu_sz, tty_mgmt_info[device].qbm_data_len);
1063 }
1064 else
1065 {
1066 tty_mgmt_info[device].rx_allow_len = chunk_size;
1067 }
1068
1069 ASSERT(tty_mgmt_info[device].rx_allow_len >= chunk_size);
1070
1071 if(INT_QueryExceptionStatus() == KAL_FALSE)
1072MD_TRC(TTY_TR_DRV_RX_ALLOW_LEN,device, tty_mgmt_info[device].rx_allow_len);
1073 return;
1074}
1075
1076
1077DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
1078_tty_conv_assign_rx_gpd_to_drv(
1079 DCL_DEV device)
1080{
1081 DCL_STATUS result;
1082 UART_CTRL_ASSIGN_RX_IOR_T ur_ctrl_assign_rxior;
1083 tty_io_request_t *rx_ior;
1084 void *rx_gpd_first, *rx_gpd_last;
1085 DCL_UINT32 remain_rx_gpd_num;
1086 DCL_UINT32 alloc_num;
1087 SeriPort_HANLDER_CB sp_handler_cb;
1088
1089 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1090 if (!tty_mgmt_info[device].flush_rx && tty_mgmt_info[device].rx_gpd_num_assigned < 2 /*one for tailed gpd, another for real data receiving*/)
1091 {
1092 remain_rx_gpd_num = 2 - tty_mgmt_info[device].rx_gpd_num_assigned;
1093 /** Add assigned gpd first to avoid conventional assign_rx_ior race condition , one is triggered in DclSerialPort_DrvAttach, the other is SIO_CMD_OPEN post-command*/
1094 tty_mgmt_info[device].rx_gpd_num_assigned += remain_rx_gpd_num;
1095 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1096
1097 //alloc_num = qbmt_alloc_q_no_tail(TTY_QBM_DATA_TYPE, remain_rx_gpd_num, &rx_gpd_first, &rx_gpd_last);
1098 alloc_num = qbmt_alloc_q_no_tail(tty_mgmt_info[device].qbm_data_type, remain_rx_gpd_num, &rx_gpd_first, &rx_gpd_last);
1099 if (alloc_num != remain_rx_gpd_num)
1100 {
1101 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1102 /** Minus assigned gpd when cannot get gpds */
1103 tty_mgmt_info[device].rx_gpd_num_assigned -= remain_rx_gpd_num;
1104 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1105 if(INT_QueryExceptionStatus() == KAL_FALSE)
1106MD_TRC(TTY_TR_GPD_EXHAUST,device, kal_get_active_module_id());
1107 VAR_MSG_ASSERT(tty_internal_qbm_exhaust);
1108 return STATUS_FAIL;
1109 }
1110
1111 //ASSERT(TTY_QBM_DATA_LEN >= tty_mgmt_info[device].chunk_size);
1112 ASSERT(tty_mgmt_info[device].qbm_data_len >= tty_mgmt_info[device].chunk_size);
1113
1114 /* First gpd */
1115 QBM_DES_SET_HWO(rx_gpd_first);
1116 QBM_DES_SET_ALLOW_LEN(rx_gpd_first, tty_mgmt_info[device].rx_allow_len);
1117 qbm_cal_set_checksum(rx_gpd_first);
1118 QBM_CACHE_FLUSH(rx_gpd_first, sizeof(qbm_gpd));
1119
1120 /* Last gpd */
1121 if (alloc_num == 2) {
1122 QBM_DES_SET_HWO(rx_gpd_last);
1123 QBM_DES_SET_ALLOW_LEN(rx_gpd_last, tty_mgmt_info[device].rx_allow_len);
1124 qbm_cal_set_checksum(rx_gpd_last);
1125 QBM_CACHE_FLUSH(rx_gpd_last, sizeof(qbm_gpd));
1126 }
1127
1128 rx_ior = (tty_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(rx_gpd_first);
1129 rx_ior->first_gpd = rx_gpd_first;
1130 rx_ior->last_gpd = rx_gpd_last;
1131 rx_ior->next_request = NULL;
1132
1133 ur_ctrl_assign_rxior.u4OwnerId = tty_mgmt_info[device].owner_id;
1134 ur_ctrl_assign_rxior.ior = rx_ior;
1135 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1136 if (!tty_mgmt_info[device].sp_handler_cb) {
1137 if(INT_QueryExceptionStatus() == KAL_FALSE)
1138 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
1139 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1140 _tty_free_ior(rx_ior);
1141 return STATUS_FAIL;
1142 }
1143 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
1144 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1145 result = sp_handler_cb(device, TTY_CMD_ASSIGN_RX_IOR, (DCL_CTRL_DATA_T *)&ur_ctrl_assign_rxior);
1146 if (result != STATUS_OK) {
1147 /* command failed */
1148 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1149 /** Minus assigned gpd when driver return fail */
1150 tty_mgmt_info[device].rx_gpd_num_assigned -= remain_rx_gpd_num;
1151 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1152 _tty_free_ior(rx_ior);
1153 if(INT_QueryExceptionStatus() == KAL_FALSE)
1154MD_TRC(TTY_TR_CMD_ERR_ASSIGN_RX_IOR,device, result, kal_get_active_module_id());
1155 return result;
1156 }
1157 } else {
1158 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1159 }
1160
1161 return STATUS_OK;
1162}
1163
1164DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
1165_tty_conv_drv_state_change_cb(
1166 DCL_HANDLE handle,
1167 tty_drv_state_e state)
1168{
1169 DCL_DEV device;
1170
1171 device = DCL_UART_GET_DEV(handle);
1172
1173 switch(state)
1174 {
1175 case DRV_ST_DETACHED:
1176 {
1177 _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_PLUGOUT_IND);
1178 break;
1179 }
1180 case DRV_ST_ATTACHED:
1181 {
1182 _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_PLUGIN_IND);
1183 break;
1184 }
1185 default:
1186 {
1187 ASSERT(0);
1188 break;
1189 }
1190 }
1191
1192 return STATUS_OK;
1193}
1194
1195
1196/* External used API */
1197/* ==================================================================================================== */
1198
1199DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
1200DclSerialPort_Initialize(void)
1201{
1202#if !defined(TTY_HWITC_ENABLE)
1203 kal_uint32 i;
1204 kal_char tty_lock_name[50];
1205#endif
1206 /* QBM number for TTY internal used must be larger than or equal to max possible gpd number for rx data path use */
1207 /* we dont need to reserve GPD buffer for virtual port, because the driver mode of virtual port is buffer mode*/
1208 //ASSERT(QBM_NUM_TTY_INT >= ((UART_DEV_CNT-CMUX_VP_NUM)*2/*2 buffer for Rx*/+(UART_DEV_CNT-CMUX_VP_NUM)*TTY_BC_TX_GPD_MAX_NUM/*Tx*/));
1209 ASSERT(QBM_NUM_TTY_INT >= ((UART_DEV_CNT-CMUX_VP_NUM-CCCI_TTY_DEV_NUM)*2/*2 buffer for Rx*/));
1210#if defined(__HIF_CCCI_SUPPORT__)
1211 ASSERT(QBM_NUM_CCCI_COMM >= (CCCI_TTY_DEV_NUM*2/*2 buffer for Rx*/));
1212#endif
1213
1214 /*Init tty_mgmt_info instance*/
1215 kal_mem_set(tty_mgmt_info, 0, sizeof(tty_port_mgmt)*UART_DEV_CNT);
1216
1217 /* Init lock resource */
1218#if !defined(TTY_HWITC_ENABLE)
1219 /* HW ITC don't need create process, but spinlock needs */
1220 for(i = 0; i < UART_DEV_CNT; i++)
1221 {
1222 sprintf(tty_lock_name, "TTYSPINLOCK_%d", i);
1223 tty_mgmt_info[i].spinLock = kal_create_spinlock(tty_lock_name);
1224 if(tty_mgmt_info[i].spinLock == NULL) ASSERT(0);
1225 }
1226#endif
1227 return STATUS_OK;
1228}
1229
1230DCL_HANDLE DEVDRV_LS_DRAM_EX_ROCODE
1231DclSerialPort_Open(
1232 DCL_DEV dev,
1233 DCL_FLAGS flags)
1234{
1235
1236 if ((dev<uart_port1) ||(dev>uart_max_port)) {
1237 if(INT_QueryExceptionStatus() == KAL_FALSE)
1238MD_TRC(TTY_TR_OPEN_ERR,dev, kal_get_active_module_id());
1239 return STATUS_INVALID_DEVICE;
1240 }
1241
1242 if (uart_port_null == dev) {
1243 if(INT_QueryExceptionStatus() == KAL_FALSE)
1244MD_TRC(TTY_TR_OPEN_ERR,dev, kal_get_active_module_id());
1245 return STATUS_INVALID_DEVICE;
1246 }
1247
1248 return (DCL_UART_MAGIC_NUM | dev);
1249}
1250
1251DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
1252DclSerialPort_Close(
1253 DCL_HANDLE handle)
1254{
1255 return STATUS_OK;
1256}
1257
1258DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
1259DclSerialPort_Configure(
1260 DCL_HANDLE handle,
1261 DCL_CONFIGURE_T *configure)
1262{
1263 return STATUS_OK;
1264}
1265
1266
1267/*!
1268 * @brief If upper layer module execute DclSerialPort_UpModuleInit
1269 * ---> New Module Init
1270 * ---> In DclSerialPort_UpModuleInit, it will help send SIO_CMD_OPEN command
1271 * If upper layer module execute DclSerialPort_Control with SIO_CMD_OPEN command without calling DclSerialPort_UpModuleInit
1272 * ---> Old module init (for backward compatible)
1273 */
1274DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
1275DclSerialPort_Control(
1276 DCL_HANDLE handle,
1277 DCL_CTRL_CMD cmd,
1278 DCL_CTRL_DATA_T *data)
1279{
1280 DCL_STATUS result;
1281 DCL_DEV device;
1282 SeriPort_HANLDER_CB sp_handler_cb;
1283
1284 TTY_CHECK_HANDLE(handle);
1285 device = DCL_UART_GET_DEV(handle);
1286
1287
1288 /*20130313:SIO_CMD_OPEN will not check device exist*/
1289 if (cmd == SIO_CMD_OPEN)
1290 {
1291 TTY_CHECK_DEV_VALID(device);
1292
1293 /*If driver has not register yet, store the request*/
1294 if(!tty_mgmt_info[device].active)
1295 {
1296 UART_CTRL_OPEN_T *ur_ctrl_open = &(data->rUARTCtrlOPEN);
1297
1298 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1299 if (tty_mgmt_info[device].early_open_req) {
1300 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1301 if(INT_QueryExceptionStatus() == KAL_FALSE)
1302MD_TRC(TTY_TR_CMD_OPEN_ALREADY_OPENED,device, kal_get_active_module_id());
1303 return STATUS_ALREADY_OPENED;
1304 }
1305 tty_mgmt_info[device].early_open_req = 1;
1306 tty_mgmt_info[device].pending_owner = (module_type) ur_ctrl_open->u4OwenrId;
1307 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1308 return STATUS_OK;
1309 }
1310 }
1311 else if(cmd == SIO_CMD_CLOSE)
1312 {
1313 TTY_CHECK_DEV_VALID(device);
1314 /*If driver has not register yet, store the request*/
1315 if(!tty_mgmt_info[device].active)
1316 {
1317 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1318 if (tty_mgmt_info[device].early_open_req) {
1319 tty_mgmt_info[device].early_open_req = 0;
1320 tty_mgmt_info[device].pending_owner = MOD_NIL;
1321 if (tty_mgmt_info[device].early_tx_done_cb_req)
1322 {
1323 tty_mgmt_info[device].early_tx_done_cb_req = 0;
1324 }
1325 //clean info set by UpmoduleInit
1326 if(tty_mgmt_info[device].init_by_new_mod)
1327 {
1328 tty_mgmt_info[device].init_by_new_mod = 0;
1329 tty_mgmt_info[device].owner_id = MOD_NIL;
1330 tty_mgmt_info[device].flag = 0;
1331 }
1332 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1333 }
1334 else
1335 {
1336 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1337 if(INT_QueryExceptionStatus() == KAL_FALSE)
1338MD_TRC(TTY_TR_DEV_IS_NOT_OPENED,device, kal_get_active_module_id());
1339 return STATUS_NOT_OPENED;
1340 }
1341
1342 return STATUS_OK;
1343 }
1344 }
1345 else
1346 {
1347 TTY_CHECK_DEV_IS_READY(device);
1348 }
1349#if TTY_AGGRESSIVE_TRACE
1350 if(INT_QueryExceptionStatus() == KAL_FALSE)
1351MD_TRC(TTY_TR_CMD_DCL_CONTROL,device, cmd, kal_get_active_module_id());
1352#endif
1353
1354 /* Pre-command Process */
1355 switch (cmd)
1356 {
1357 case SIO_CMD_OPEN:
1358 {
1359 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1360 if (tty_mgmt_info[device].opened) {
1361 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1362 if(INT_QueryExceptionStatus() == KAL_FALSE)
1363MD_TRC(TTY_TR_CMD_OPEN_ALREADY_OPENED,device, kal_get_active_module_id());
1364 return STATUS_ALREADY_OPENED;
1365 }
1366 tty_mgmt_info[device].opened = 1;
1367 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1368 }
1369 break;
1370
1371 case SIO_CMD_GET_BYTES:
1372 case SIO_CMD_GET_UART_BYTE:
1373 {
1374 UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
1375 UART_CTRL_GET_BYTES_T *p_ur_ctrl_getbytes;
1376 DCL_UINT16 real_data_len;
1377 DCL_UINT8 *real_data;
1378 void *rx_gpd;
1379
1380 if (!TTY_IS_CONVENTIONAL_RX(device)) {
1381 return STATUS_INVALID_OPERATION;
1382 }
1383
1384 /* If device is buffer port, bypass cmd to driver*/
1385 if(TTY_IS_BUFF_PORT(device))
1386 {
1387 // TODO:add support for SIO_CMD_GET_UART_BYTE, which is blocking read.
1388 ASSERT(cmd == SIO_CMD_GET_BYTES);
1389 break;
1390 }
1391
1392 /*
1393 This area is for conventional RX - backward compatible
1394 */
1395 if (cmd == SIO_CMD_GET_UART_BYTE) {
1396 UART_CTRL_GET_UART_BYTE_T *p_ur_ctrl_get_uart_byte;
1397 p_ur_ctrl_get_uart_byte = &(data->rUARTCtrlGETUARTBYTE);
1398 ur_ctrl_getbytes.puBuffaddr = &p_ur_ctrl_get_uart_byte->uByte;
1399 ur_ctrl_getbytes.u2Length = 1;
1400 p_ur_ctrl_getbytes = &ur_ctrl_getbytes;
1401 } else {
1402 p_ur_ctrl_getbytes = &(data->rUARTCtrlGETBYTES);
1403 }
1404
1405 if (TTY_DRV_IS_ATTACHED(device) && ! tty_mgmt_info[device].flush_rx) {
1406 _tty_conv_assign_rx_gpd_to_drv(device);
1407 } else {
1408 p_ur_ctrl_getbytes->u2RetSize = 0;
1409 if(INT_QueryExceptionStatus() == KAL_FALSE)
1410MD_TRC(TTY_TR_WRONG_STATE,device, kal_get_active_module_id());
1411 return STATUS_ERROR_WRONG_STATE;
1412 }
1413
1414 rx_gpd = tty_mgmt_info[device].rx_gpd;
1415 if (!rx_gpd) {
1416 p_ur_ctrl_getbytes->u2RetSize = 0;
1417#if TTY_AGGRESSIVE_TRACE
1418 if(INT_QueryExceptionStatus() == KAL_FALSE)
1419MD_TRC(TTY_TR_CMD_CONV_RX_NOT_RDY,device, kal_get_active_module_id());
1420#endif
1421 } else {
1422 real_data = (DCL_UINT8*)TTY_QBM_DES_GET_DATAPTR(rx_gpd) + tty_mgmt_info[device].rx_buf_offset;
1423 real_data_len = TTY_QBM_DES_GET_DATALEN(rx_gpd) - tty_mgmt_info[device].rx_buf_offset;
1424
1425 if (real_data_len > p_ur_ctrl_getbytes->u2Length) {
1426 kal_mem_cpy(p_ur_ctrl_getbytes->puBuffaddr, real_data, p_ur_ctrl_getbytes->u2Length);
1427 p_ur_ctrl_getbytes->u2RetSize = p_ur_ctrl_getbytes->u2Length;
1428 tty_mgmt_info[device].rx_buf_offset += p_ur_ctrl_getbytes->u2Length;
1429 } else {
1430 kal_mem_cpy(p_ur_ctrl_getbytes->puBuffaddr, real_data, real_data_len);
1431 p_ur_ctrl_getbytes->u2RetSize = real_data_len;
1432
1433 tty_mgmt_info[device].rx_buf_offset = 0;
1434 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1435 tty_mgmt_info[device].rx_gpd = NULL;
1436 ASSERT(tty_mgmt_info[device].rx_gpd_num_assigned >= 1);
1437 tty_mgmt_info[device].rx_gpd_num_assigned --;
1438 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1439 QBM_FREE_ONE(rx_gpd);
1440
1441 /* Re-aasign rx gpd to driver for data receiveing */
1442 _tty_conv_assign_rx_gpd_to_drv(device);
1443 }
1444 }
1445#if TTY_AGGRESSIVE_TRACE
1446 if(INT_QueryExceptionStatus() == KAL_FALSE)
1447MD_TRC(TTY_TR_CMD_CONV_RX,device, p_ur_ctrl_getbytes->u2RetSize);
1448#endif
1449 return STATUS_OK;
1450 }
1451 break;
1452
1453 case SIO_CMD_PUT_UART_BYTE:
1454 case SIO_CMD_PUT_UART_BYTES:
1455 case SIO_CMD_PUT_BYTES:
1456 case SIO_CMD_PUT_ISR_BYTES:
1457 {
1458 UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
1459 UART_CTRL_PUT_BYTES_T *p_ur_ctrl_putbytes;
1460 DCL_UINT8 *buf_ptr;
1461 void *tx_gpd;
1462 hif_io_request_t *tx_ior;
1463 UART_CTRL_PUT_BYTES_IOR_T ur_ctrl_putbytes_ior;
1464
1465 if (!TTY_IS_CONVENTIONAL_TX(device)) {
1466 return STATUS_INVALID_OPERATION;
1467 }
1468
1469 /* If device is buffer port, bypass cmd to driver*/
1470 if(TTY_IS_BUFF_PORT(device))
1471 {
1472 // TODO:add support for SIO_CMD_PUT_UART_BYTE(S), which are blocking write.
1473 ASSERT(cmd == SIO_CMD_PUT_BYTES);
1474 break;
1475 }
1476
1477 /*
1478 This area is for conventional TX
1479 */
1480 if (cmd == SIO_CMD_PUT_UART_BYTE) {
1481 UART_CTRL_PUT_UART_BYTE_T *p_ur_ctrl_put_uart_byte;
1482 p_ur_ctrl_put_uart_byte = &(data->rUARTCtrlPUTUARTBYTE);
1483 ur_ctrl_putbytes.puBuffaddr = &p_ur_ctrl_put_uart_byte->uData;
1484 ur_ctrl_putbytes.u2Length = 1;
1485 p_ur_ctrl_putbytes = &ur_ctrl_putbytes;
1486 } else if (cmd == SIO_CMD_PUT_UART_BYTES) {
1487 UART_CTRL_PUT_UART_BYTES_T *p_ur_ctrl_put_uart_bytes;
1488 p_ur_ctrl_put_uart_bytes = &(data->rUARTCtrlPUTUARTBYTES);
1489 ur_ctrl_putbytes.puBuffaddr = p_ur_ctrl_put_uart_bytes->puBuffaddr;
1490 ur_ctrl_putbytes.u2Length = p_ur_ctrl_put_uart_bytes->u2Length;
1491 p_ur_ctrl_putbytes = &ur_ctrl_putbytes;
1492 } else {
1493 p_ur_ctrl_putbytes = &(data->rUARTCtrlPUTBYTES);
1494 }
1495
1496 ASSERT(p_ur_ctrl_putbytes->u2Length);
1497
1498 if (!TTY_DRV_IS_ATTACHED(device) || tty_mgmt_info[device].flush_tx) {
1499 p_ur_ctrl_putbytes->u2RetSize = 0;
1500 if(INT_QueryExceptionStatus() == KAL_FALSE)
1501MD_TRC(TTY_TR_WRONG_STATE,device, kal_get_active_module_id());
1502 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1503 tty_mgmt_info[device].tx_not_rdy = 1;
1504 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1505 return STATUS_ERROR_WRONG_STATE;
1506 }
1507
1508 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1509 if(!TTY_CHK_DEV_OPEN(device)){
1510 p_ur_ctrl_putbytes->u2RetSize = 0;
1511 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1512 return STATUS_NOT_OPENED;
1513 }
1514 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1515
1516 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1517 if (tty_mgmt_info[device].tx_gpd_num_used >= TTY_BC_TX_GPD_MAX_NUM) {
1518 /* tx ior is not yet retrieved, still in driver */
1519 p_ur_ctrl_putbytes->u2RetSize = 0;
1520 if (cmd != SIO_CMD_PUT_ISR_BYTES) {
1521 tty_mgmt_info[device].tx_up_mod_wait = 1;
1522 }
1523 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1524#if TTY_AGGRESSIVE_TRACE
1525 if(INT_QueryExceptionStatus() == KAL_FALSE)
1526MD_TRC(TTY_TR_CMD_CONV_TX_NOT_RDY,device, tty_mgmt_info[device].tx_gpd_num_used, kal_get_active_module_id());
1527#endif
1528 } else {
1529 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1530 //tx_gpd = QBM_ALLOC_ONE(TTY_QBM_DATA_TYPE);
1531 tx_gpd = QBM_ALLOC_ONE(tty_mgmt_info[device].qbm_data_type);
1532
1533 if (tx_gpd)
1534 {
1535 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1536 tty_mgmt_info[device].tx_gpd_num_used ++;
1537 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1538
1539 tx_ior = (hif_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(tx_gpd);
1540 tx_ior->next_request = NULL;
1541 tx_ior->first_gpd = tx_gpd;
1542 tx_ior->last_gpd = tx_gpd;
1543
1544 ur_ctrl_putbytes_ior.u4OwnerId = tty_mgmt_info[device].owner_id;
1545 ur_ctrl_putbytes_ior.putIor = (void*)tx_ior;
1546
1547 buf_ptr = TTY_QBM_DES_GET_DATAPTR(tx_gpd);
1548
1549 //if (TTY_QBM_DATA_LEN >= p_ur_ctrl_putbytes->u2Length) {
1550 if (tty_mgmt_info[device].qbm_data_len >= p_ur_ctrl_putbytes->u2Length) {
1551 kal_mem_cpy(buf_ptr, p_ur_ctrl_putbytes->puBuffaddr, p_ur_ctrl_putbytes->u2Length);
1552 p_ur_ctrl_putbytes->u2RetSize = p_ur_ctrl_putbytes->u2Length;
1553 if (cmd != SIO_CMD_PUT_ISR_BYTES) {
1554 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1555 tty_mgmt_info[device].tx_up_mod_wait = 0;
1556 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1557 }
1558 } else {
1559 //kal_mem_cpy(buf_ptr, p_ur_ctrl_putbytes->puBuffaddr, TTY_QBM_DATA_LEN);
1560 //p_ur_ctrl_putbytes->u2RetSize = TTY_QBM_DATA_LEN;
1561 kal_mem_cpy(buf_ptr, p_ur_ctrl_putbytes->puBuffaddr, tty_mgmt_info[device].qbm_data_len);
1562 p_ur_ctrl_putbytes->u2RetSize = tty_mgmt_info[device].qbm_data_len;
1563 if (cmd != SIO_CMD_PUT_ISR_BYTES) {
1564 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1565 tty_mgmt_info[device].tx_up_mod_wait = 1;
1566 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1567 }
1568 }
1569
1570 TTY_QBM_DES_SET_DATALEN(tx_gpd, p_ur_ctrl_putbytes->u2RetSize); // Set data length
1571
1572 //QBM_CACHE_FLUSH(buf_ptr, p_ur_ctrl_putbytes->u2RetSize); // khr debug, flush data
1573#if TTY_AGGRESSIVE_TRACE
1574 if(INT_QueryExceptionStatus() == KAL_FALSE)
1575MD_TRC(TTY_TR_CMD_CONV_TX,device, p_ur_ctrl_putbytes->u2RetSize);
1576#endif
1577 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1578 if (!tty_mgmt_info[device].sp_handler_cb) {
1579 if(INT_QueryExceptionStatus() == KAL_FALSE)
1580 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
1581 tty_mgmt_info[device].tx_gpd_num_used --;
1582 if (cmd != SIO_CMD_PUT_ISR_BYTES) {
1583 tty_mgmt_info[device].tx_up_mod_wait = 1;
1584 }
1585 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1586 QBM_FREE_ONE(tx_gpd);
1587 p_ur_ctrl_putbytes->u2RetSize = 0;
1588 return STATUS_FAIL;
1589 }
1590 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
1591 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1592 result = sp_handler_cb(device, TTY_CMD_PUT_BYTES_IOR, (DCL_CTRL_DATA_T *)&ur_ctrl_putbytes_ior);
1593 if (result != STATUS_OK) {
1594 /* command failed */
1595 QBM_FREE_ONE(tx_gpd);
1596 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1597 tty_mgmt_info[device].tx_gpd_num_used --;
1598 if (cmd != SIO_CMD_PUT_ISR_BYTES) {
1599 tty_mgmt_info[device].tx_up_mod_wait = 1;
1600 }
1601 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1602 p_ur_ctrl_putbytes->u2RetSize = 0;
1603 if(INT_QueryExceptionStatus() == KAL_FALSE)
1604MD_TRC(TTY_TR_CMD_ERR_PUT_BYTES_IOR,device, result, kal_get_active_module_id());
1605 return result;
1606 }
1607 } else {
1608 if(INT_QueryExceptionStatus() == KAL_FALSE)
1609MD_TRC(TTY_TR_GPD_EXHAUST,device, kal_get_active_module_id());
1610 //This case has error handling, so remove assert check here.
1611 //VAR_MSG_ASSERT(tty_internal_gpd_exhaust);
1612 p_ur_ctrl_putbytes->u2RetSize = 0;
1613 if (cmd != SIO_CMD_PUT_ISR_BYTES) {
1614 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1615 tty_mgmt_info[device].tx_up_mod_wait = 1;
1616 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1617 }
1618 }
1619 }
1620
1621 return STATUS_OK;
1622 }
1623 break;
1624
1625 case SIO_CMD_GET_RX_AVAIL:
1626 {
1627 UART_CTRL_RX_AVAIL_T *ur_ctrl_rx_avail;
1628 ur_ctrl_rx_avail = &(data->rUARTCtrlRXAVAIL);
1629
1630 /* If device is buffer port, bypass cmd to driver*/
1631 if(TTY_IS_BUFF_PORT(device) && TTY_IS_CONVENTIONAL_RX(device))
1632 {
1633 break;
1634 }
1635
1636 if (TTY_IS_CONVENTIONAL_RX(device))
1637 {
1638 if (tty_mgmt_info[device].rx_gpd) {
1639 ur_ctrl_rx_avail->u2RetSize = TTY_QBM_DES_GET_DATALEN(tty_mgmt_info[device].rx_gpd) - tty_mgmt_info[device].rx_buf_offset;
1640 } else {
1641 ur_ctrl_rx_avail->u2RetSize = 0;
1642 }
1643 return STATUS_OK;
1644 } else
1645 {
1646 return STATUS_FAIL; // This command doesn't be suported in NEW TTY Rx path
1647 }
1648 }
1649 break;
1650
1651 case SIO_CMD_GET_TX_AVAIL:
1652 case SIO_CMD_GET_ISR_TX_AVAIL:
1653 {
1654 UART_CTRL_TX_AVAIL_T *ur_ctrl_tx_avail;
1655 ur_ctrl_tx_avail = &(data->rUARTCtrlTXAVAIL);
1656
1657 /* If device is buffer port, bypass cmd to driver*/
1658 if(TTY_IS_BUFF_PORT(device) && TTY_IS_CONVENTIONAL_TX(device))
1659 {
1660 break;
1661 }
1662
1663 if (TTY_IS_CONVENTIONAL_TX(device))
1664 {
1665 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1666 if (tty_mgmt_info[device].tx_gpd_num_used >= TTY_BC_TX_GPD_MAX_NUM) {
1667 /* If Tx ior is in driver, return Tx available room = 0 byte */
1668 ur_ctrl_tx_avail->u2RetSize = 0;
1669 } else {
1670 /* If Tx ior is retrieved and available, return Tx available room = TTY_QBM_DATA_LEN byte */
1671 //ur_ctrl_tx_avail->u2RetSize = TTY_QBM_DATA_LEN;
1672 ur_ctrl_tx_avail->u2RetSize = tty_mgmt_info[device].qbm_data_len;
1673 }
1674 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1675
1676 return STATUS_OK;
1677 } else
1678 {
1679 return STATUS_FAIL; // This command doesn't be suported in NEW TTY Tx path
1680 }
1681 }
1682 break;
1683
1684 case TTY_CMD_GET_DRV_STATE:
1685 {
1686 UART_CTRL_GET_DRV_STATE_T *ur_ctrl_get_drv_st;
1687 ur_ctrl_get_drv_st = &(data->rUARTCtrlGetDrvState);
1688
1689 ur_ctrl_get_drv_st->drv_state = tty_mgmt_info[device].drv_state;
1690
1691 return STATUS_OK;
1692 }
1693 break;
1694
1695 case SIO_CMD_REG_TX_CB:
1696 {
1697 UART_CTRL_REG_TX_CB_T *ur_ctrl_reg_tx_cb;
1698 ur_ctrl_reg_tx_cb = &(data->rUARTCtrlREGTXCB);
1699
1700 if (!TTY_IS_CONVENTIONAL_TX(device)) {
1701 return STATUS_INVALID_OPERATION;
1702 }
1703
1704 tty_mgmt_info[device].conv_tx_cb = ur_ctrl_reg_tx_cb->func;
1705
1706 return STATUS_OK;
1707 }
1708 break;
1709
1710 case SIO_CMD_REG_RX_CB:
1711 {
1712 UART_CTRL_REG_RX_CB_T *ur_ctrl_reg_rx_cb;
1713 ur_ctrl_reg_rx_cb = &(data->rUARTCtrlREGRXCB);
1714
1715 if (!TTY_IS_CONVENTIONAL_RX(device)) {
1716 return STATUS_INVALID_OPERATION;
1717 }
1718
1719 tty_mgmt_info[device].conv_rx_cb = ur_ctrl_reg_rx_cb->func;
1720
1721 return STATUS_OK;
1722 }
1723 break;
1724
1725 case SIO_CMD_SET_OWNER:
1726 case SIO_CMD_CLOSE:
1727 {
1728 /* Only GPD port will reference this flag*/
1729 if(!TTY_IS_BUFF_PORT(device))
1730 {
1731 tty_mgmt_info[device].flush_tx = 1;
1732 tty_mgmt_info[device].flush_rx = 1;
1733
1734 }
1735 /* Check if there is any rx buff store in tty*/
1736 if(TTY_IS_CONVENTIONAL_RX(device))
1737 {
1738 void *rx_gpd;
1739 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1740 if (tty_mgmt_info[device].rx_gpd) {
1741 rx_gpd = tty_mgmt_info[device].rx_gpd;
1742 tty_mgmt_info[device].rx_gpd = NULL;
1743 tty_mgmt_info[device].rx_buf_offset = 0;
1744 tty_mgmt_info[device].rx_gpd_num_assigned--;
1745 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1746 QBM_FREE_ONE(rx_gpd);
1747 }
1748 else
1749 {
1750 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1751 }
1752 }
1753 }
1754 break;
1755 case SIO_CMD_CLR_TX_BUF:
1756 {
1757 /* CCCI driver doesn't support TX flush command
1758 * beacause some port share the same HW queue.
1759 */
1760 if(DCL_UART_CCCI_TYPE != tty_mgmt_info[device].dev_type){
1761 /*Buffer port need to clear tx_up_mod_wait_flag*/
1762 if(TTY_IS_BUFF_PORT(device)){
1763 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1764 tty_mgmt_info[device].tx_up_mod_wait = 1;
1765 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1766 }
1767 else {
1768 /* Only GPD port will reference this flag*/
1769 tty_mgmt_info[device].flush_tx = 1;
1770 }
1771 }
1772 }
1773 break;
1774 case SIO_CMD_CLR_RX_BUF:
1775 {
1776 void *rx_gpd;
1777 /* Only GPD port will reference this flag*/
1778 if(!TTY_IS_BUFF_PORT(device))
1779 {
1780 tty_mgmt_info[device].flush_rx = 1;
1781 }
1782 /* Check if there is any rx buff store in tty*/
1783 if (TTY_IS_CONVENTIONAL_RX(device))
1784 {
1785 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1786 if (tty_mgmt_info[device].rx_gpd) {
1787 rx_gpd = tty_mgmt_info[device].rx_gpd;
1788 tty_mgmt_info[device].rx_gpd = NULL;
1789 tty_mgmt_info[device].rx_buf_offset = 0;
1790 tty_mgmt_info[device].rx_gpd_num_assigned--;
1791 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1792 QBM_FREE_ONE(rx_gpd);
1793 }
1794 else
1795 {
1796 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1797 }
1798 }
1799 /*Buffer port need to clear rx_up_mod_wait_flag*/
1800 if(TTY_IS_BUFF_PORT(device))
1801 {
1802 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1803 tty_mgmt_info[device].rx_up_mod_wait = 1;
1804 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1805 }
1806 }
1807 break;
1808 case SIO_CMD_SEND_ISR_DATA:
1809 case SIO_CMD_SEND_DATA:
1810 {
1811 VAR_MSG_ASSERT(not_support_sio_command);
1812 }
1813 break;
1814 case TTY_CMD_SET_INDICATION:
1815 {
1816 UART_CTRL_SET_INDICATION_T *ur_ctrl_set_indication;
1817 ur_ctrl_set_indication = &(data->rUARTCtrlSETINDICATION);
1818
1819 if(ur_ctrl_set_indication->need_indication == 0)
1820 {
1821 tty_mgmt_info[device].no_indication = 1;
1822 }
1823
1824 }
1825 break;
1826 default:
1827 break;
1828 }
1829 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1830 if (!tty_mgmt_info[device].sp_handler_cb) {
1831 if(INT_QueryExceptionStatus() == KAL_FALSE)
1832 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
1833 if (cmd == SIO_CMD_OPEN) {
1834 tty_mgmt_info[device].opened = 0;
1835 }
1836 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1837 return STATUS_FAIL;
1838 }
1839 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
1840 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1841 result = sp_handler_cb(device, cmd, data);
1842
1843 if (result != STATUS_OK) {
1844 if (cmd == SIO_CMD_OPEN) {
1845 /* open failed */
1846 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1847 tty_mgmt_info[device].opened = 0;
1848 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1849 }
1850 if(INT_QueryExceptionStatus() == KAL_FALSE)
1851MD_TRC(TTY_TR_DCL_CMD_NG,device, cmd, result);
1852 return result;
1853 }
1854
1855 /* Post-command Process */
1856 switch (cmd)
1857 {
1858 case SIO_CMD_OPEN:
1859 {
1860 if (!tty_mgmt_info[device].init_by_new_mod)
1861 { /* Conventional Module Init */
1862 UART_CTRL_OPEN_T *ur_ctrl_open;
1863
1864 if(INT_QueryExceptionStatus() == KAL_FALSE)
1865MD_TRC(TTY_TR_CONV_INIT,device, kal_get_active_module_id());
1866
1867 tty_mgmt_info[device].rx_gpd = NULL;
1868 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1869 tty_mgmt_info[device].rx_gpd_num_assigned = 0;
1870 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1871 tty_mgmt_info[device].rx_buf_offset = 0;
1872 tty_mgmt_info[device].flag = 0;
1873 tty_mgmt_info[device].no_indication = 0;
1874
1875 ur_ctrl_open = &(data->rUARTCtrlOPEN);
1876 tty_mgmt_info[device].owner_id = (module_type)ur_ctrl_open->u4OwenrId;
1877
1878 /* buffer port shall register different callback*/
1879 if(TTY_IS_BUFF_PORT(device))
1880 {
1881 _DclSerialPort_UpModuleRegisterCb(device, _tty_rx_buff_cb, _tty_tx_buff_done_cb, NULL);
1882 }
1883 else
1884 {
1885 /* 20130617: Add drv_state_change callback for supporting plug-in/plug-out indication*/
1886 _DclSerialPort_UpModuleRegisterCb(device, _tty_rx_cb, _tty_tx_done_cb, _tty_conv_drv_state_change_cb);
1887 }
1888 }
1889
1890 /* Init rx_up_mod_wait for buffer port*/
1891 if(TTY_IS_BUFF_PORT(device))
1892 {
1893 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1894 tty_mgmt_info[device].rx_up_mod_wait = 1;
1895 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1896 }
1897
1898 /* If upper module firstly send SIO_CMD_OPEN command & use conventional Rx path, tty will help send TTY_CMD_ASSIGN_RX_IOR to assign RX IOR to driver */
1899 /* Only takes when GPD ports*/
1900 if(!TTY_IS_BUFF_PORT(device))
1901 {
1902 if (TTY_IS_CONVENTIONAL_RX(device) && TTY_DRV_IS_ATTACHED(device))
1903 {
1904 _tty_conv_assign_rx_gpd_to_drv(device);
1905 }
1906 }
1907 }
1908 break;
1909 case SIO_CMD_SET_OWNER:
1910 {
1911 UART_CTRL_OWNER_T *ur_ctrl_owner;
1912 DCL_UINT32 count;
1913
1914 ur_ctrl_owner = &(data->rUARTCtrlOWNER);
1915
1916 /* Only GPD port needs to check if all GPDs of previous user are returned*/
1917 if(!TTY_IS_BUFF_PORT(device))
1918 {
1919 TTY_CONV_FLUSH_TX(10);
1920 TTY_CONV_FLUSH_RX(10);
1921 }
1922
1923 /* Reset parameters */
1924 tty_mgmt_info[device].flag = 0;
1925 tty_mgmt_info[device].rx_gpd = NULL;
1926 tty_mgmt_info[device].rx_buf_offset = 0;
1927 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
1928 tty_mgmt_info[device].tx_up_mod_wait = 0;
1929 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
1930 tty_mgmt_info[device].conv_tx_cb = NULL;
1931 tty_mgmt_info[device].conv_rx_cb = NULL;
1932 tty_mgmt_info[device].flush_tx = 0;
1933 tty_mgmt_info[device].flush_rx = 0;
1934 tty_mgmt_info[device].owner_id = (module_type)ur_ctrl_owner->u4OwenrId;
1935 tty_mgmt_info[device].no_indication= 0;
1936
1937 if(!TTY_IS_BUFF_PORT(device))
1938 {
1939 /* Pre-assign Rx gpd if conventional Rx path is used */
1940 if (TTY_DRV_IS_ATTACHED(device) && TTY_IS_CONVENTIONAL_RX(device))
1941 {
1942 _tty_conv_assign_rx_gpd_to_drv(device);
1943 }
1944
1945 /* By default set all callback functions with tty internal handler */
1946 _DclSerialPort_UpModuleRegisterCb(device, _tty_rx_cb, _tty_tx_done_cb, NULL);
1947 }
1948 else
1949 {
1950 /* buffer port, just register buff port callback*/
1951 _DclSerialPort_UpModuleRegisterCb(device, _tty_rx_buff_cb, _tty_tx_buff_done_cb, NULL);
1952 }
1953 }
1954 break;
1955 case SIO_CMD_CLR_TX_BUF:
1956 {
1957 DCL_UINT32 count;
1958
1959 if(DCL_UART_CCCI_TYPE != tty_mgmt_info[device].dev_type){
1960 /* Only GPD port needs to check if all GPDs of previous user are returned*/
1961 if(!TTY_IS_BUFF_PORT(device)){
1962 TTY_CONV_FLUSH_TX(10);
1963 tty_mgmt_info[device].flush_tx = 0;
1964 }
1965 }
1966 }
1967 break;
1968 case SIO_CMD_CLR_RX_BUF:
1969 {
1970 DCL_UINT32 count;
1971
1972 /* Only GPD port needs to check if all GPDs of previous user are returned*/
1973 if(!TTY_IS_BUFF_PORT(device))
1974 {
1975 TTY_CONV_FLUSH_RX(10);
1976
1977 tty_mgmt_info[device].flush_rx = 0;
1978
1979 if (TTY_DRV_IS_ATTACHED(device) && TTY_IS_CONVENTIONAL_RX(device))
1980 {
1981 _tty_conv_assign_rx_gpd_to_drv(device);
1982 }
1983 }
1984 }
1985 break;
1986 case SIO_CMD_CLOSE:
1987 {
1988 DCL_UINT32 count;
1989
1990 /* Only GPD port needs to check if all GPDs of previous user are returned*/
1991 if(!TTY_IS_BUFF_PORT(device))
1992 {
1993 TTY_CONV_FLUSH_TX(10);
1994 TTY_CONV_FLUSH_RX(10);
1995 }
1996
1997 tty_mgmt_info[device].flush_tx = 0;
1998 tty_mgmt_info[device].flush_rx = 0;
1999 tty_mgmt_info[device].flag = 0;
2000 tty_mgmt_info[device].init_by_new_mod = 0;
2001 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2002 tty_mgmt_info[device].opened = 0;
2003 tty_mgmt_info[device].rx_gpd_num_assigned = 0;
2004 tty_mgmt_info[device].tx_gpd_num_used = 0;
2005 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2006 tty_mgmt_info[device].rx_buf_offset = 0;
2007 tty_mgmt_info[device].conv_tx_cb = NULL;
2008 tty_mgmt_info[device].conv_rx_cb = NULL;
2009 tty_mgmt_info[device].no_indication= 0;
2010 }
2011 break;
2012 //case SIO_CMD_PUT_UART_BYTE: //not support in buffer port currently
2013 //case SIO_CMD_PUT_UART_BYTES: //not support in buffer port currently
2014 //case SIO_CMD_PUT_ISR_BYTES: //not support in buffer port currently
2015 case SIO_CMD_PUT_BYTES:
2016 {
2017 UART_CTRL_PUT_BYTES_T *p_ur_ctrl_putbytes;
2018 UART_CTRL_TX_AVAIL_T ur_ctrl_tx_avail;
2019
2020 //GPD port shall not go here.
2021 ASSERT(TTY_IS_BUFF_PORT(device));
2022
2023 /*
2024 Only SIO_CMD_PUT_BYTES will return length of transmitted data
2025 */
2026 if(cmd == SIO_CMD_PUT_BYTES)
2027 {
2028 p_ur_ctrl_putbytes = &(data->rUARTCtrlPUTBYTES);
2029 if(p_ur_ctrl_putbytes->u2Length != p_ur_ctrl_putbytes->u2RetSize)
2030 {
2031 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2032 tty_mgmt_info[device].tx_up_mod_wait = 1;
2033
2034 /*
2035 Ready to write message may lost before setting tx_up_mod_wait as 1.
2036 (Due to user task priority may be lower than HIF task priority)
2037 so we need to double confirmed with HIF driver if it is really no space to write
2038 */
2039 ur_ctrl_tx_avail.u2RetSize = 0;
2040 if (!tty_mgmt_info[device].sp_handler_cb) {
2041 if(INT_QueryExceptionStatus() == KAL_FALSE)
2042 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2043 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2044 return STATUS_FAIL;
2045 }
2046 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2047 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2048 sp_handler_cb(device, SIO_CMD_GET_TX_AVAIL, (DCL_CTRL_DATA_T *)&ur_ctrl_tx_avail);
2049 if(ur_ctrl_tx_avail.u2RetSize > 0)
2050 {
2051 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2052 if( tty_mgmt_info[device].tx_up_mod_wait == 1)
2053 {
2054 tty_mgmt_info[device].tx_up_mod_wait = 0;
2055 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2056 _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_READY_TO_WRITE_IND);
2057 }
2058 else
2059 {
2060 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2061 }
2062 }
2063 }
2064 }
2065 }
2066 break;
2067 case SIO_CMD_GET_BYTES:
2068 //case SIO_CMD_GET_UART_BYTE: //not support in buffer port currently
2069 {
2070 UART_CTRL_GET_BYTES_T *p_ur_ctrl_getbytes;
2071 UART_CTRL_RX_AVAIL_T ur_ctrl_rx_avail;
2072
2073 //GPD port shall not go here.
2074 ASSERT(TTY_IS_BUFF_PORT(device));
2075
2076 if(cmd == SIO_CMD_GET_BYTES)
2077 {
2078 p_ur_ctrl_getbytes = &(data->rUARTCtrlGETBYTES);
2079 //Last read
2080 if(p_ur_ctrl_getbytes->u2Length > p_ur_ctrl_getbytes->u2RetSize)
2081 {
2082 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2083 tty_mgmt_info[device].rx_up_mod_wait = 1;
2084
2085
2086 /*
2087 Ready to read message may lost before setting rx_up_mod_wait as 1.
2088 (Due to user task priority may be lower than HIF task priority)
2089 so we need to double confirmed with HIF driver if it is really no data ready to read
2090 */
2091 ur_ctrl_rx_avail.u2RetSize = 0;
2092 if (!tty_mgmt_info[device].sp_handler_cb) {
2093 if(INT_QueryExceptionStatus() == KAL_FALSE)
2094 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2095 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2096 return STATUS_FAIL;
2097 }
2098
2099 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2100 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2101 sp_handler_cb(device, SIO_CMD_GET_RX_AVAIL, (DCL_CTRL_DATA_T *)&ur_ctrl_rx_avail);
2102 if(ur_ctrl_rx_avail.u2RetSize > 0)
2103 {
2104 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2105 if( tty_mgmt_info[device].rx_up_mod_wait == 1)
2106 {
2107 tty_mgmt_info[device].rx_up_mod_wait = 0;
2108 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2109 _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_READY_TO_READ_IND);
2110 }
2111 else
2112 {
2113 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2114 }
2115 }
2116 }
2117 }
2118 }
2119 break;
2120 default:
2121 break;
2122 }
2123
2124 return result;
2125}
2126
2127DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2128DclSerialPort_UpModuleInit(
2129 DCL_HANDLE handle,
2130 module_type module_id,
2131 int flag)
2132{
2133 DCL_STATUS status = STATUS_FAIL;
2134 DCL_DEV device;
2135 UART_CTRL_OPEN_T uCtlOpen;
2136
2137 TTY_CHECK_HANDLE(handle);
2138 device = DCL_UART_GET_DEV(handle);
2139
2140 /*20130313:remove driver active check, because user may do initial flow before driver in active state*/
2141 TTY_CHECK_DEV_VALID(device);
2142
2143 if(INT_QueryExceptionStatus() == KAL_FALSE)
2144MD_TRC(TTY_TR_NEW_INIT,device,module_id);
2145
2146 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2147 if (tty_mgmt_info[device].opened || tty_mgmt_info[device].early_open_req) {
2148 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2149 if(INT_QueryExceptionStatus() == KAL_FALSE)
2150MD_TRC(TTY_TR_CMD_OPEN_ALREADY_OPENED,device, module_id);
2151 return STATUS_ALREADY_OPENED;
2152 }
2153 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2154
2155 tty_mgmt_info[device].owner_id = module_id;
2156 tty_mgmt_info[device].flag = flag;
2157 tty_mgmt_info[device].init_by_new_mod = 1;
2158 tty_mgmt_info[device].rx_gpd = NULL;
2159 tty_mgmt_info[device].rx_buf_offset = 0;
2160 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2161 tty_mgmt_info[device].rx_gpd_num_assigned = 0;
2162 tty_mgmt_info[device].tx_gpd_num_used = 0;
2163 tty_mgmt_info[device].tx_up_mod_wait = 0;
2164 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2165 tty_mgmt_info[device].conv_tx_cb = NULL;
2166 tty_mgmt_info[device].conv_rx_cb = NULL;
2167 tty_mgmt_info[device].flush_tx = 0;
2168 tty_mgmt_info[device].flush_rx = 0;
2169 tty_mgmt_info[device].no_indication = 0;
2170
2171 if (TTY_IS_CONVENTIONAL_TX(device) && TTY_IS_CONVENTIONAL_RX(device)) {
2172 tty_mgmt_info[device].init_by_new_mod = 0;
2173 }
2174
2175 /* Send SIO_CMD_OPEN command */
2176 /* 20130313: If driver is not active, store SIO_CMD_OPEN and then return */
2177 if(tty_mgmt_info[device].active)
2178 {
2179 uCtlOpen.u4OwenrId = module_id;
2180 status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*)&uCtlOpen);
2181 if (STATUS_OK != status) {
2182 return status;
2183 }
2184 }
2185 else
2186 {
2187 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2188 tty_mgmt_info[device].early_open_req = 1;
2189 tty_mgmt_info[device].pending_owner = module_id;
2190 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2191 return STATUS_OK;
2192 }
2193
2194 return STATUS_OK;
2195}
2196
2197static DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2198_DclSerialPort_UpModuleReinit(
2199 DCL_DEV device,
2200 module_type module_id,
2201 int flag)
2202{
2203 DCL_STATUS result;
2204 UART_CTRL_CLR_BUFFER_T ur_ctrl_clr_buf;
2205 DCL_UINT32 count;
2206 SeriPort_HANLDER_CB sp_handler_cb;
2207
2208 /*
2209 * Notes: if device is buffer port, just reset the ttycore internal flag,
2210 * because it is impossible to use gpd buffer on buffer port
2211 */
2212 if(TTY_IS_BUFF_PORT(device))
2213 {
2214 goto _RESET_FLAG;
2215 }
2216
2217 /* If primary module uses conventional Rx and new module uses new rx path, flush Rx data path */
2218 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2219 if (TTY_IS_CONVENTIONAL_RX(device) &&
2220 tty_mgmt_info[device].rx_gpd_num_assigned > 0 &&
2221 (flag & TTY_FLAG_NEW_RX)
2222 )
2223 {
2224
2225
2226 /* -- 1. Send clear rx buffer command -- */
2227 ur_ctrl_clr_buf.u4OwenrId = tty_mgmt_info[device].owner_id;
2228 tty_mgmt_info[device].flush_rx = 1;
2229 if (!tty_mgmt_info[device].sp_handler_cb) {
2230 if(INT_QueryExceptionStatus() == KAL_FALSE)
2231 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2232 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2233 return STATUS_FAIL;
2234 }
2235 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2236 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2237 result = sp_handler_cb(device, SIO_CMD_CLR_RX_BUF, (DCL_CTRL_DATA_T*)&ur_ctrl_clr_buf);
2238 if (result != STATUS_OK) {
2239 /* command failed */
2240 if(INT_QueryExceptionStatus() == KAL_FALSE)
2241MD_TRC(TTY_TR_CMD_ERR_CLR_RX_BUF,device, result, kal_get_active_module_id());
2242 return result;
2243 }
2244
2245 /* -- 2. Wait until all rx gpds are returned back -- */
2246 TTY_CONV_FLUSH_RX(10);
2247 } else {
2248 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2249 }
2250
2251_RESET_FLAG:
2252 tty_mgmt_info[device].owner_id = module_id;
2253 tty_mgmt_info[device].flag = flag;
2254 tty_mgmt_info[device].rx_gpd = NULL;
2255 tty_mgmt_info[device].rx_buf_offset = 0;
2256 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2257 tty_mgmt_info[device].tx_gpd_num_used = 0;
2258 tty_mgmt_info[device].tx_up_mod_wait = 0;
2259 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2260 tty_mgmt_info[device].conv_tx_cb = NULL;
2261 tty_mgmt_info[device].conv_rx_cb = NULL;
2262 tty_mgmt_info[device].flush_tx = 0;
2263 tty_mgmt_info[device].flush_rx = 0;
2264 tty_mgmt_info[device].no_indication = 0;
2265
2266 if (TTY_IS_CONVENTIONAL_TX(device) && TTY_IS_CONVENTIONAL_RX(device)) {
2267 tty_mgmt_info[device].init_by_new_mod = 0;
2268 } else {
2269 tty_mgmt_info[device].init_by_new_mod = 1;
2270 }
2271
2272 return STATUS_OK;
2273}
2274
2275/* Re-init API is invoked when New upper module change owner -> it need re-set flag and re-register related callback function */
2276/* This API must be called after SIO_CMD_SET_OWNER command */
2277DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2278DclSerialPort_UpModuleReinit(
2279 DCL_HANDLE handle,
2280 module_type module_id,
2281 int flag)
2282{
2283 DCL_DEV device;
2284
2285 TTY_CHECK_HANDLE(handle);
2286 device = DCL_UART_GET_DEV(handle);
2287 TTY_CHECK_DEV_IS_READY(device);
2288
2289 if(INT_QueryExceptionStatus() == KAL_FALSE)
2290MD_TRC(TTY_TR_REINIT,device, module_id);
2291
2292 if (!tty_mgmt_info[device].opened) {
2293 return STATUS_NOT_OPENED;
2294 }
2295
2296 return _DclSerialPort_UpModuleReinit(device, module_id, flag);
2297}
2298
2299
2300DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2301DclSerialPort_UpModuleDeinit(
2302 DCL_HANDLE handle)
2303{
2304 DCL_STATUS status = STATUS_FAIL;
2305 DCL_DEV device;
2306 UART_CTRL_CLOSE_T data;
2307
2308 TTY_CHECK_HANDLE(handle);
2309 device = DCL_UART_GET_DEV(handle);
2310
2311 /*20130313:remove driver active check, because user may do initial flow before driver in active state*/
2312 TTY_CHECK_DEV_VALID(device);
2313
2314 if(INT_QueryExceptionStatus() == KAL_FALSE)
2315MD_TRC(TTY_TR_DEINIT,device, kal_get_active_module_id());
2316
2317 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2318 if (!tty_mgmt_info[device].opened && !tty_mgmt_info[device].early_open_req) {
2319 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2320 if(INT_QueryExceptionStatus() == KAL_FALSE)
2321MD_TRC(TTY_TR_DEV_IS_NOT_OPENED,device, kal_get_active_module_id());
2322 return STATUS_NOT_OPENED;
2323 }
2324 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2325
2326 /* Send SIO_CMD_CLOSE command */
2327 data.u4OwenrId = tty_mgmt_info[device].owner_id;
2328 status = DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*)&data);
2329
2330 return status;
2331}
2332
2333static DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2334_DclSerialPort_UpModuleRegisterCb(
2335 DCL_DEV device,
2336 tty_rx_cb rx_cb,
2337 tty_txdone_cb tx_done_cb,
2338 tty_drv_state_change_cb drv_state_change_cb)
2339{
2340 DCL_STATUS result;
2341 SeriPort_HANLDER_CB sp_handler_cb;
2342
2343 tty_mgmt_info[device].rx_cb = rx_cb;
2344 tty_mgmt_info[device].tx_done_cb = tx_done_cb;
2345 tty_mgmt_info[device].drv_state_change_cb = drv_state_change_cb;
2346
2347 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2348 if(!tty_mgmt_info[device].active && tx_done_cb)
2349 {
2350 tty_mgmt_info[device].early_tx_done_cb_req = 1;
2351 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2352 return STATUS_OK;
2353 }
2354 else
2355 {
2356 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2357 }
2358
2359 /* Send TTY_CMD_TX_INFO command */
2360 if (tx_done_cb)
2361 {
2362 UART_CTRL_NEED_TX_DONE_CB_T ur_ctrl_need_tx_done_cb;
2363
2364 ur_ctrl_need_tx_done_cb.u4OwnerId = tty_mgmt_info[device].owner_id;
2365 ur_ctrl_need_tx_done_cb.needTxDoneCb = 1;
2366 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2367 if (!tty_mgmt_info[device].sp_handler_cb) {
2368 if(INT_QueryExceptionStatus() == KAL_FALSE)
2369 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2370 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2371 return STATUS_FAIL;
2372 }
2373 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2374 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2375 result = sp_handler_cb(device, TTY_CMD_NEED_TX_DONE_CB, (DCL_CTRL_DATA_T*)&ur_ctrl_need_tx_done_cb);
2376 if (result != STATUS_OK) {
2377 /* command failed */
2378 if(INT_QueryExceptionStatus() == KAL_FALSE)
2379MD_TRC(TTY_TR_CMD_ERR_NEED_TX_DONE_CB,device, result, kal_get_active_module_id());
2380 return result;
2381 }
2382 }
2383
2384 return STATUS_OK;
2385}
2386
2387DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2388DclSerialPort_UpModuleRegisterCb(
2389 DCL_HANDLE handle,
2390 tty_rx_cb rx_cb,
2391 tty_txdone_cb tx_done_cb,
2392 tty_drv_state_change_cb drv_state_change_cb)
2393{
2394 DCL_DEV device;
2395 DCL_STATUS result;
2396
2397 TTY_CHECK_HANDLE(handle);
2398 device = DCL_UART_GET_DEV(handle);
2399
2400 /*20130313:remove driver active check, because user may do initial flow before driver in active state*/
2401 TTY_CHECK_DEV_VALID(device);
2402 if(INT_QueryExceptionStatus() == KAL_FALSE)
2403MD_TRC(TTY_TR_CMD_REG_CB,device, kal_get_active_module_id());
2404
2405 /* Check flag & callback correctness */
2406 if (!TTY_IS_CONVENTIONAL_RX(device) && !rx_cb) {
2407 if(INT_QueryExceptionStatus() == KAL_FALSE)
2408MD_TRC(TTY_TR_NEW_RX_CB_IS_NULL,device, kal_get_active_module_id());
2409 VAR_MSG_ASSERT(use_new_rx_but_not_register_cb);
2410 }
2411 if (TTY_IS_CONVENTIONAL_RX(device)) {
2412 ASSERT(!rx_cb);
2413
2414 /* Buffer port use different internal callback*/
2415 if(TTY_IS_BUFF_PORT(device))
2416 {
2417 rx_cb = _tty_rx_buff_cb;
2418 }
2419 else
2420 {
2421 rx_cb = _tty_rx_cb;
2422 }
2423 }
2424 if (TTY_IS_CONVENTIONAL_TX(device)) {
2425 ASSERT(!tx_done_cb);
2426
2427 /* Buffer port use different internal callback*/
2428 if(TTY_IS_BUFF_PORT(device))
2429 {
2430 tx_done_cb = _tty_tx_buff_done_cb;
2431 }
2432 else
2433 {
2434 tx_done_cb = _tty_tx_done_cb;
2435 }
2436 }
2437
2438 if (TTY_IS_CONVENTIONAL_RX(device) && TTY_IS_CONVENTIONAL_TX(device)) {
2439 ASSERT(!drv_state_change_cb);
2440 } else {
2441 ASSERT(drv_state_change_cb);
2442 }
2443
2444 result = _DclSerialPort_UpModuleRegisterCb(device, rx_cb, tx_done_cb, drv_state_change_cb);
2445 if (result != STATUS_OK) {
2446 /* command failed */
2447 if(INT_QueryExceptionStatus() == KAL_FALSE)
2448MD_TRC(TTY_TR_CMD_REG_CB_FAIL,device, result, kal_get_active_module_id());
2449 return result;
2450 }
2451
2452 return STATUS_OK;
2453}
2454
2455DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2456DclSerialPort_UpModuleTransmit(
2457 DCL_HANDLE handle,
2458 tty_io_request_t *ior)
2459{
2460 DCL_DEV device;
2461 UART_CTRL_PUT_BYTES_IOR_T ur_ctrl_putbytes_ior;
2462 DCL_STATUS result;
2463 SeriPort_HANLDER_CB sp_handler_cb;
2464
2465 TTY_CHECK_HANDLE(handle);
2466 device = DCL_UART_GET_DEV(handle);
2467 DBG_ASSERT(ior);
2468
2469 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2470 if (!tty_mgmt_info[device].sp_handler_cb) {
2471 if(INT_QueryExceptionStatus() == KAL_FALSE)
2472 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2473 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2474 return STATUS_FAIL;
2475 }
2476
2477
2478
2479 if (!TTY_CHK_DEV_OPEN(device)){
2480 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2481 return STATUS_NOT_OPENED;
2482 }
2483
2484 ur_ctrl_putbytes_ior.u4OwnerId = tty_mgmt_info[device].owner_id;
2485 ur_ctrl_putbytes_ior.putIor = (void*)ior;
2486 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2487 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2488 result = sp_handler_cb(device, TTY_CMD_PUT_BYTES_IOR, (DCL_CTRL_DATA_T*)&ur_ctrl_putbytes_ior);
2489
2490#ifdef __TTY_DBG_MODE__
2491 _tty_gpd_zero_len_check(ior);
2492#endif
2493
2494 return result;
2495}
2496
2497DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2498DclSerialPort_UpModuleTransmitLight(
2499 DCL_HANDLE handle,
2500 tty_io_request_t *ior)
2501{
2502 DCL_DEV device;
2503 UART_CTRL_PUT_BYTES_IOR_T ur_ctrl_putbytes_ior;
2504 DCL_STATUS result;
2505 SeriPort_HANLDER_CB sp_handler_cb;
2506
2507 TTY_CHECK_HANDLE(handle);
2508 device = DCL_UART_GET_DEV(handle);
2509 DBG_ASSERT(ior);
2510
2511 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2512 if (!tty_mgmt_info[device].sp_handler_cb) {
2513 if(INT_QueryExceptionStatus() == KAL_FALSE)
2514 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2515 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2516 return STATUS_FAIL;
2517 }
2518
2519 ur_ctrl_putbytes_ior.u4OwnerId = tty_mgmt_info[device].owner_id;
2520 ur_ctrl_putbytes_ior.putIor = (void*)ior;
2521
2522#ifdef __TTY_DBG_MODE__
2523 _tty_gpd_zero_len_check(ior);
2524#endif
2525 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2526 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2527 result = sp_handler_cb(device, TTY_CMD_PUT_BYTES_IOR_LIGHT, (DCL_CTRL_DATA_T*)&ur_ctrl_putbytes_ior);
2528 return result;
2529}
2530
2531DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2532DclSerialPort_UpModuleAssignRxIor(
2533 DCL_HANDLE handle,
2534 tty_io_request_t *rx_ior)
2535{
2536 DCL_DEV device;
2537 UART_CTRL_ASSIGN_RX_IOR_T uartCtlAsnRxIor;
2538 DCL_STATUS result;
2539 SeriPort_HANLDER_CB sp_handler_cb;
2540
2541 TTY_CHECK_HANDLE(handle);
2542 device = DCL_UART_GET_DEV(handle);
2543 DBG_ASSERT(rx_ior);
2544
2545 if(INT_QueryExceptionStatus() == KAL_FALSE)
2546MD_TRC(TTY_TR_CMD_ASSIGN_RX_IOR,device, kal_get_active_module_id());
2547 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2548 if (!tty_mgmt_info[device].sp_handler_cb) {
2549 if(INT_QueryExceptionStatus() == KAL_FALSE)
2550 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2551 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2552 return STATUS_FAIL;
2553 }
2554
2555 uartCtlAsnRxIor.u4OwnerId = tty_mgmt_info[device].owner_id;
2556 uartCtlAsnRxIor.ior = (void*)rx_ior;
2557 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2558 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2559 result = sp_handler_cb(device, TTY_CMD_ASSIGN_RX_IOR, (DCL_CTRL_DATA_T*)&uartCtlAsnRxIor);
2560
2561 return result;
2562}
2563
2564
2565DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2566DclSerialPort_DrvRegisterCb(
2567 DCL_HANDLE handle,
2568 Seriport_HANDLER_T* seriport_handler)
2569{
2570 DCL_DEV device;
2571 UART_CTRL_OPEN_T uCtlOpen;
2572 UART_CTRL_NEED_TX_DONE_CB_T ur_ctrl_need_tx_done_cb;
2573 DCL_STATUS status;
2574 SeriPort_HANLDER_CB sp_handler_cb;
2575
2576 TTY_CHECK_HANDLE(handle);
2577 device = DCL_UART_GET_DEV(handle);
2578
2579 if(INT_QueryExceptionStatus() == KAL_FALSE)
2580MD_TRC(TTY_TR_DRV_REGISTER_CB,device, seriport_handler, kal_get_active_module_id());
2581
2582 if (!seriport_handler->SeriportHandlerCb) {
2583 if(INT_QueryExceptionStatus() == KAL_FALSE)
2584MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2585 ASSERT(seriport_handler->SeriportHandlerCb);
2586 return STATUS_INVALID_ARGUMENT;
2587 }
2588
2589 if (tty_mgmt_info[device].active) {
2590 return STATUS_ALREADY_OPENED;
2591 }
2592
2593 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2594 tty_mgmt_info[device].sp_handler_cb = seriport_handler->SeriportHandlerCb;
2595 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2596
2597 tty_mgmt_info[device].dev_type = seriport_handler->DevType;
2598 _tty_update_buff_info_from_port(device, seriport_handler->DevType);
2599
2600 //Must to put at the end of function.
2601 tty_mgmt_info[device].active = 1;
2602
2603 //------------------------------------------------------------------//
2604 //check if user has opened the port before driver register callback //
2605
2606 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2607 if(tty_mgmt_info[device].early_open_req)
2608 {
2609 tty_mgmt_info[device].early_open_req = 0;
2610 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2611 uCtlOpen.u4OwenrId = tty_mgmt_info[device].pending_owner;
2612 //temp for uart
2613 //DclSerialPort_Control(handle,SIO_CMD_INIT,(DCL_CTRL_DATA_T*)&uCtlOpen);
2614 status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*)&uCtlOpen);
2615 if (STATUS_OK != status) {
2616 //ASSERT(0);
2617 return status;
2618 }
2619 }
2620 else
2621 {
2622 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2623 }
2624
2625 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2626 if(tty_mgmt_info[device].early_tx_done_cb_req)
2627 {
2628 tty_mgmt_info[device].early_tx_done_cb_req = 0;
2629 ur_ctrl_need_tx_done_cb.u4OwnerId = tty_mgmt_info[device].owner_id;
2630 ur_ctrl_need_tx_done_cb.needTxDoneCb = 1;
2631 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2632 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2633 status = sp_handler_cb(device, TTY_CMD_NEED_TX_DONE_CB, (DCL_CTRL_DATA_T*)&ur_ctrl_need_tx_done_cb);
2634 if (status != STATUS_OK) {
2635 /* command failed */
2636 if(INT_QueryExceptionStatus() == KAL_FALSE)
2637MD_TRC(TTY_TR_CMD_ERR_NEED_TX_DONE_CB,device, status, kal_get_active_module_id());
2638 return status;
2639 }
2640 }
2641 else
2642 {
2643 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2644 }
2645 return STATUS_OK;
2646}
2647
2648DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2649DclSerialPort_DrvDeRegisterCb(
2650 DCL_HANDLE handle)
2651{
2652 DCL_DEV device;
2653 //TTY_THREAD_DECLARE(thread_lock);
2654
2655 TTY_CHECK_HANDLE(handle);
2656 device = DCL_UART_GET_DEV(handle);
2657
2658 if(INT_QueryExceptionStatus() == KAL_FALSE)
2659MD_TRC(TTY_TR_DRV_DEREGISTER_CB,device, kal_get_active_module_id());
2660
2661 if(tty_mgmt_info[device].drv_state == DRV_ST_ATTACHED)
2662 {
2663 return STATUS_INVALID_OPERATION;
2664 }
2665
2666 if (!tty_mgmt_info[device].active) {
2667 return STATUS_INVALID_OPERATION;
2668 }
2669
2670 /*Enlarge spinlock in order to protect the handler pointer */
2671 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2672 /* Clear flags */
2673 tty_mgmt_info[device].active = 0;
2674 tty_mgmt_info[device].sp_handler_cb = NULL;
2675
2676 /***** Add for USB CV test *****/
2677 /* Check device state */
2678 /* Here we slient clear opened flag if the device is opened
2679 After driver registered the device, tty will re-open the device
2680 */
2681 if(tty_mgmt_info[device].opened)
2682 {
2683
2684 tty_mgmt_info[device].opened = 0;
2685 tty_mgmt_info[device].early_open_req = 1;
2686 tty_mgmt_info[device].pending_owner = tty_mgmt_info[device].owner_id;
2687 if(tty_mgmt_info[device].tx_done_cb)
2688 {
2689 tty_mgmt_info[device].early_tx_done_cb_req = 1;
2690 }
2691 }
2692 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2693 /***** Add for USB CV test *****/
2694
2695 return STATUS_OK;
2696}
2697
2698
2699DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2700DclSerialPort_DrvAttach(
2701 DCL_HANDLE handle)
2702{
2703 DCL_DEV device;
2704 DCL_STATUS result;
2705 UART_CTRL_GET_CHUNK_SIZE_T ur_ctrl_get_chunk_size;
2706 SeriPort_HANLDER_CB sp_handler_cb;
2707
2708 TTY_CHECK_HANDLE(handle);
2709 device = DCL_UART_GET_DEV(handle);
2710 TTY_CHECK_DEV_IS_READY(device);
2711
2712 if(INT_QueryExceptionStatus() == KAL_FALSE)
2713MD_TRC(TTY_TR_DRV_ATTACH,device, kal_get_active_module_id());
2714
2715 tty_mgmt_info[device].drv_state = DRV_ST_ATTACHED;
2716
2717 if(TTY_IS_BUFF_PORT(device))
2718 {
2719 /* Set default value align with USB, although buffer port does not reference this value*/
2720 tty_mgmt_info[device].chunk_size = 512;
2721 goto _RETURN;
2722 }
2723 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2724 if (!tty_mgmt_info[device].sp_handler_cb) {
2725 if(INT_QueryExceptionStatus() == KAL_FALSE)
2726 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2727 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2728 return STATUS_FAIL;
2729 }
2730 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2731 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2732 result = sp_handler_cb(device, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_chunk_size);
2733
2734 if (result != STATUS_OK) {
2735 /* command failed */
2736 if(INT_QueryExceptionStatus() == KAL_FALSE)
2737MD_TRC(TTY_TR_CMD_ERR_GET_CHUNK_SIZE,device, result, kal_get_active_module_id());
2738 ASSERT(0);
2739 return result;
2740 }
2741
2742 tty_mgmt_info[device].chunk_size = (DCL_UINT16)ur_ctrl_get_chunk_size.chunkSize;
2743 //set rx allow len
2744 _cal_and_set_rx_allow_len(device, tty_mgmt_info[device].chunk_size);
2745
2746 if (tty_mgmt_info[device].opened)
2747 {
2748 /* Notify upper layer the driver status is attached */
2749 if (tty_mgmt_info[device].drv_state_change_cb) {
2750 tty_mgmt_info[device].drv_state_change_cb(handle, DRV_ST_ATTACHED);
2751 }
2752
2753 if (TTY_IS_CONVENTIONAL_RX(device)) {
2754 _tty_conv_assign_rx_gpd_to_drv(device);
2755 }
2756
2757 if (TTY_IS_CONVENTIONAL_TX(device))
2758 {
2759 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2760 if(tty_mgmt_info[device].tx_not_rdy == 1)
2761 {
2762 tty_mgmt_info[device].tx_not_rdy = 0;
2763 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2764 _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_READY_TO_WRITE_IND);
2765 }
2766 else
2767 {
2768 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2769 }
2770 }
2771 }
2772
2773_RETURN:
2774 return STATUS_OK;
2775}
2776
2777DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2778DclSerialPort_DrvDetach(
2779 DCL_HANDLE handle)
2780{
2781 DCL_DEV device;
2782 DCL_STATUS result;
2783 UART_CTRL_CLR_BUFFER_T ur_ctrl_clr_buf;
2784 SeriPort_HANLDER_CB sp_handler_cb;
2785
2786 TTY_CHECK_HANDLE(handle);
2787 device = DCL_UART_GET_DEV(handle);
2788 TTY_CHECK_DEV_IS_READY(device);
2789
2790 if(INT_QueryExceptionStatus() == KAL_FALSE)
2791MD_TRC(TTY_TR_DRV_DETACH,device, kal_get_active_module_id());
2792
2793 tty_mgmt_info[device].drv_state = DRV_ST_DETACHED;
2794
2795 /* Notify upper layer the driver status is detached */
2796 if (tty_mgmt_info[device].opened)
2797 {
2798 if (tty_mgmt_info[device].drv_state_change_cb) {
2799 tty_mgmt_info[device].drv_state_change_cb(handle, DRV_ST_DETACHED);
2800 }
2801
2802 /* Send clear tx/rx buffer command */
2803 ur_ctrl_clr_buf.u4OwenrId = tty_mgmt_info[device].owner_id;
2804
2805 /* Buffer port also needs to do flush when detached */
2806 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2807 if ((tty_mgmt_info[device].tx_gpd_num_used != 0 && TTY_IS_CONVENTIONAL_TX(device))
2808 || TTY_IS_BUFF_PORT(device) )
2809 {
2810 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2811
2812 /* Only GPD driver needs to toggle this flag*/
2813 if(!TTY_IS_BUFF_PORT(device))
2814 {
2815 tty_mgmt_info[device].flush_tx = 1;
2816 }
2817 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2818 if (!tty_mgmt_info[device].sp_handler_cb) {
2819 if(INT_QueryExceptionStatus() == KAL_FALSE)
2820 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2821 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2822 return STATUS_FAIL;
2823 }
2824 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2825 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2826 result = sp_handler_cb(device, SIO_CMD_CLR_TX_BUF, (DCL_CTRL_DATA_T*)&ur_ctrl_clr_buf);
2827 if (result != STATUS_OK) {
2828 /* command failed */
2829 if(INT_QueryExceptionStatus() == KAL_FALSE)
2830MD_TRC(TTY_TR_CMD_ERR_CLR_TX_BUF,device, result, kal_get_active_module_id());
2831 return result;
2832 }
2833 } else {
2834 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2835 }
2836
2837 /* Buffer port also needs to do flush when detached */
2838 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2839 if ((tty_mgmt_info[device].rx_gpd_num_assigned != 0 && TTY_IS_CONVENTIONAL_RX(device))
2840 || TTY_IS_BUFF_PORT(device) )
2841 {
2842 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2843
2844 /* Only GPD driver needs to toggle this flag*/
2845 if(!TTY_IS_BUFF_PORT(device))
2846 {
2847 tty_mgmt_info[device].flush_rx = 1;
2848 }
2849 TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
2850 if (!tty_mgmt_info[device].sp_handler_cb) {
2851 if(INT_QueryExceptionStatus() == KAL_FALSE)
2852 MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
2853 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2854 return STATUS_FAIL;
2855 }
2856 sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
2857 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2858 result = sp_handler_cb(device, SIO_CMD_CLR_RX_BUF, (DCL_CTRL_DATA_T*)&ur_ctrl_clr_buf);
2859 if (result != STATUS_OK) {
2860 /* command failed */
2861 if(INT_QueryExceptionStatus() == KAL_FALSE)
2862MD_TRC(TTY_TR_CMD_ERR_CLR_RX_BUF,device, result, kal_get_active_module_id());
2863 return result;
2864 }
2865 } else {
2866 TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
2867 }
2868 }
2869
2870 return STATUS_OK;
2871}
2872
2873DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2874DclSerialPort_DrvRx(
2875 DCL_HANDLE handle,
2876 module_type source_id,
2877 void *rx_ior)
2878{
2879 DCL_DEV device;
2880
2881 TTY_CHECK_HANDLE(handle);
2882 device = DCL_UART_GET_DEV(handle);
2883
2884 if (tty_mgmt_info[device].opened && tty_mgmt_info[device].rx_cb) {
2885 tty_mgmt_info[device].rx_cb(handle, source_id, (tty_io_request_t*)rx_ior);
2886 } else {
2887 if(INT_QueryExceptionStatus() == KAL_FALSE)
2888MD_TRC(TTY_TR_DRV_RX_NG,device, tty_mgmt_info[device].opened, tty_mgmt_info[device].rx_cb);
2889 /* Free ior when the device is closed */
2890 if(!TTY_IS_BUFF_PORT(device))
2891 {
2892 _tty_free_ior(rx_ior);
2893 }
2894 }
2895 return STATUS_OK;
2896}
2897
2898DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
2899DclSerialPort_DrvTxDone(
2900 DCL_HANDLE handle,
2901 module_type source_id,
2902 void *tx_ior)
2903{
2904 DCL_DEV device;
2905
2906 TTY_CHECK_HANDLE(handle);
2907 device = DCL_UART_GET_DEV(handle);
2908
2909 if (tty_mgmt_info[device].opened && tty_mgmt_info[device].tx_done_cb) {
2910 tty_mgmt_info[device].tx_done_cb(handle, source_id, (tty_io_request_t*)tx_ior);
2911 } else {
2912 /* Free ior when the device is closed */
2913 if(!TTY_IS_BUFF_PORT(device))
2914 {
2915 _tty_free_ior(tx_ior);
2916 }
2917 }
2918
2919 return STATUS_OK;
2920}
2921
2922