[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/tty/src/dcl_tty.c b/mcu/driver/tty/src/dcl_tty.c
new file mode 100644
index 0000000..5a67ccc
--- /dev/null
+++ b/mcu/driver/tty/src/dcl_tty.c
@@ -0,0 +1,2922 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * dcl_tty.c
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * Define how to access COM Port. Provide API for upper-layer applications to access COM Port
+ * It works with enabling compile flag __TTY_UT__.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 11 03 2021 li-cheng.tsai
+ * [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
+ *
+ * [MD700.MP][MPD] patch back from VMOLYM, avoid race condition caused null callback function issue.
+ *
+ * 08 27 2021 li-cheng.tsai
+ * [MOLY00711608] [WIN] MiniDump is observed during ICT S4(Hibernate) stress.
+ *
+ * [MD700.MP][MPD] Solved race condition in assign rx ior
+ *
+ * 09 18 2020 li-cheng.tsai
+ * [MOLY00569647] [MP7.PRECHECKIN.DEV][Code sync] sync code from T700
+ * [R3.MP][MPD][CCCIDEV]code sync from T700
+ *
+ * 09 15 2020 li-cheng.tsai
+ * [MOLY00569647] [MP7.PRECHECKIN.DEV][Code sync] sync code from T700
+ * [MP7.PRECHECKIN.DEV][MPD][CCCIDEV]code sync from T700
+ *
+ * 09 14 2020 i-wei.tsai
+ * [MOLY00548843] [TITAN CRASH][Wingtech][TITAN][MT6765][N21][TFN][P200722-00292 ]S215DL-11 Device crashes into CP Crash upload mode
+ * .
+ *
+ * 08 10 2020 i-wei.tsai
+ * [MOLY00548843] [TITAN CRASH][Wingtech][TITAN][MT6765][N21][TFN][P200722-00292 ]S215DL-11 Device crashes into CP Crash upload mode
+ *
+ * . skip clear tx handling for ccci port
+ *
+ * 06 01 2020 li-cheng.tsai
+ * [MOLY00526500] [MODEM][ASSERT ][ASSERT] file:mcu/service/qmu_bm/src/qmu_bm.c line:512 p1:0x00000000 p2:0x00000000 p3:0x00000000
+ * CCCI TTY change to fix error handling
+ *
+ * 12 05 2019 i-wei.tsai
+ * [MOLY00463962] [Gen97] TTY DEV
+ *
+ * .
+ *
+ * 12 04 2019 amit.singh
+ * [MOLY00463020] [IPCORE] [TTY] VMOLY Patchback memory reduction by re-arranging member fields of structures
+ *
+ * TTY memory reduction by structure rearrange.
+ *
+ * 12 02 2019 amit.singh
+ * [MOLY00454015] [TTY] LG patchabck of MOLY00394195 to VMOLY.1001.DEV
+ *
+ * 1001.DEV to VMOLY TRUNK patchback TTY.
+ *
+ * 06 18 2019 i-wei.tsai
+ * [MOLY00413678] [MT6297][Apollo][Ericsson][IODT][NSA FullStack][Kista][5G][1][core0,vpe0,tc0(vpe0)] Assert fail dcl_tty.c 1063 - DR
+ *
+ * .remove un-used assertion
+ *
+ * 09 11 2018 i-wei.tsai
+ * [MOLY00349664] [ASSERT] file:mcu/common/driver/tty/src/dcl_tty.c line:1789
+ *
+ * .fix race condition issue in rx callback
+ *
+ * 07 24 2018 i-wei.tsai
+ * [MOLY00341790] [MT6295] UDC feature patch back
+ *
+ * .change spinlock to HWITC
+ *
+ * 06 04 2018 i-wei.tsai
+ * [MOLY00331344] [Gen95] TTYCore fix
+ *
+ * .
+ *
+ * 09 18 2017 i-wei.tsai
+ * [MOLY00278689] Performance improvement of INT_QueryExceptionStatus
+ *
+ * .
+ *
+ * 07 06 2017 i-wei.tsai
+ * [MOLY00262251] [Coverity defect fix] tty coverity fix
+ * .
+ *
+ * 05 09 2017 i-wei.tsai
+ * [MOLY00248066] [Gen93] [TTY] Log format refine
+ * .
+ * fix modis build error
+ *
+ * 05 09 2017 i-wei.tsai
+ * [MOLY00248066] [Gen93] [TTY] Log format refine
+ * .
+ * fix modis warning
+ *
+ * 05 09 2017 i-wei.tsai
+ * [MOLY00248066] [Gen93] [TTY] Log format refine
+ * .
+ * remove dummy character
+ *
+ * 05 09 2017 i-wei.tsai
+ * [MOLY00248066] [Gen93] [TTY] Log format refine
+ * .
+ * TTY log refine
+ *
+ * 06 22 2016 mt.tsai
+ * [MOLY00154662] Fix the tty build warning
+ * .delete unused variable in TTY
+ *
+ * 06 22 2016 mt.tsai
+ * [MOLY00177032] [Coverity Scanned Code Defect]CID:116560 code defect happened in /mcu/common/driver/tty/src/dcl_tty.c
+ * .
+ * [Coverity] add spinlock to full fill the protection of some variables
+ *
+ * 02 26 2016 mt.tsai
+ * [MOLY00166612] Remove violation include kal_debug.h
+ * The APIs in kal_debug.h is legacy and don't be provided for user
+ *
+ * 09 30 2015 mt.tsai
+ * [MOLY00143135] [UMOLY][LR11] TTYCore Unit Test
+ * .modified files for ttycore unit test
+ *
+ * 09 15 2015 i-wei.tsai
+ * [MOLY00141929] [UMOLY][ELBRUS][TTY] Add SMP support
+ * .
+ *
+ * 03 02 2015 i-wei.tsai
+ * [MOLY00097392] [UMOLY] [TTY] Timer tick macro modification
+ * .
+ *
+ * 12 10 2014 i-wei.tsai
+ * [MOLY00086663] [TK6291] [TTY] Add new uart port for MTAD
+ * .
+ *
+ * 11 14 2014 i-wei.tsai
+ * [MOLY00084437] [UMOLY] [TTY] rollback changes
+ * .
+ *
+ * 06 16 2014 i-wei.tsai
+ * [MOLY00068713] [MT6752] MD2 uart config setting (Buffer mode)
+ * .
+ *
+ * 04 25 2014 i-wei.tsai
+ * [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.
+ * .
+ *
+ * 03 12 2014 i-wei.tsai
+ * [MOLY00059311] [TTY] New Feature for configurable indication mechanism
+ *
+ * 10 29 2013 i-wei.tsai
+ * [MOLY00044179] [TTY] Fixed 82LTE VT issue
+ * .
+ *
+ * 09 13 2013 shenghui.shi
+ * [MOLY00035078] [MT6290][PDN] Enable GDMA & HDMA related module PDN support
+ * move uart pdn_clr from dcl_tty.c to uart.c
+ *
+ * 08 26 2013 shenghui.shi
+ * [MOLY00035212] fix uart build modis error
+ * .
+ *
+ * 08 26 2013 shenghui.shi
+ * [MOLY00035078] [MT6290][PDN] Enable GDMA & HDMA related module PDN support
+ * add uart PDN feature
+ *
+ * 06 26 2013 i-wei.tsai
+ * [MOLY00027496] [TTYCore] Features check-in
+ * 1. add new TTY_CMD_MTU_SIZE support
+ * 2. add plug-in/plug-out indication
+ * 3. fix issue of flushing rx internal gpd
+ *
+ * 06 19 2013 i-wei.tsai
+ * [MOLY00026667] [TTYCore] Revise ttycore trace log in exception mode
+ *
+ * 05 29 2013 haoren.kao
+ * [MOLY00024108] Support New USB Core
+ * Replace with New USB Core.
+ * We sync with the following codes from HaoRen MOLY CBr w1322:
+ * 1. USB Core
+ * 2. USB Class - acm/rndis/mbim
+ * 3. ipcore
+ * 4. ttycore
+ * 5. ethercore
+ *
+ * 05 15 2013 i-wei.tsai
+ * [MOLY00021838] [MT6290 Bring-up] TTY DEV.
+ * Turn off aggressive log trace
+ *
+ * 05 10 2013 i-wei.tsai
+ * [MOLY00021838] [MT6290 Bring-up] TTY DEV
+ * sync from MT6290E1 First Call Branch
+ *
+ * 05 10 2013 i-wei.tsai
+ * [MOLY00021376] [MT6290 Bring-up] Basic load
+ * Check-in support
+ *
+ * 05 09 2013 i-wei.tsai
+ * [MOLY00021838] [MT6290 Bring-up] TTY DEV
+ * fix error for setting tx not rdy flag
+ *
+ * 05 09 2013 i-wei.tsai
+ * [MOLY00021838] [MT6290 Bring-up] TTY DEV
+ * add sending Ready2Write message when dirver attach
+ *
+ * 05 08 2013 i-wei.tsai
+ * [MOLY00021838] [MT6290 Bring-up] Revise ttycore trace log
+ * .
+ *
+ * 05 03 2013 i-wei.tsai
+ * [MOLY00021396] [MT6290 Bring-up] [Basic Load Support] [TTYCore] add option __MAUI_BASIC__
+ * basic load support
+ *
+ * 03 08 2013 i-wei.tsai
+ * [MOLY00011358] [TTYCore] TTYCore support
+ * Add CCIF UART device type and modify comments
+ *
+ * 03 01 2013 i-wei.tsai
+ * [MOLY00010632] add TTYCore new features
+ * fixed typo
+ *
+ * 02 21 2013 i-wei.tsai
+ * [MOLY00010632] add TTYCore new features
+ * checkin supporting buffer port features
+ *
+ * 11 08 2012 haoren.kao
+ * [MOLY00005322] TATAKA merge to MOLY
+ *
+ * MOLY Migration from TATAKA
+ ****************************************************************************/
+
+#include <stdio.h>
+#include "dcl.h"
+
+#include "qbm_config_num.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+#include "kal_public_api.h"
+#include "kal_general_types.h"
+#include "stack_ltlcom.h"
+#include "hif_ior.h"
+#include "kal_internal_api.h"
+#include "devdrv_ls.h"
+#include "drv_msgid.h"
+#include "md_drv_sap.h"
+#include "drvpdn.h"
+#include "drv_gdma.h"
+#include <ex_public.h>
+#include "kal_hrt_api.h"
+
+#include "cccidev_qbm.h" /* macros for QBM_TYPE_CCCI_COMM */
+
+//for reference the vp number
+#include "cmux_vp_num.h"
+
+#define TTY_CONSOLE_TRACE_ENABLED 0
+
+#define TTY_AGGRESSIVE_TRACE 0
+
+/*20120724 Ian Modify CCCI_COMM for TTYCore*/
+// #if __HIF_CCCI_SUPPORT__
+// /* using CCCI_COMM type to replace QBM_TYPE_TTY_INT/QBM_TYPE_TTY_TYPE1/QBM_TYPE_TTY_TYPE2 */
+// #define TTY_QBM_DATA_LEN QBM_CCCI_COMM_DATA_LEN
+// #define TTY_QBM_DATA_TYPE QBM_TYPE_CCCI_COMM
+// #define TTY_QBM_DES_GET_DATAPTR CCCIDEV_GET_QBM_DATAPTR
+// #define TTY_QBM_DES_GET_DATALEN CCCIDEV_GET_QBM_DATALEN
+// #define TTY_QBM_DES_SET_DATALEN CCCICOMM_SET_QBM_DATALEN
+// #else
+// #define TTY_QBM_DATA_LEN QBM_TTY_XXX_DATA_LEN
+// #define TTY_QBM_DATA_TYPE QBM_TYPE_TTY_INT
+// #define TTY_QBM_DES_GET_DATAPTR QBM_DES_GET_DATAPTR
+// #define TTY_QBM_DES_GET_DATALEN QBM_DES_GET_DATALEN
+// #define TTY_QBM_DES_SET_DATALEN QBM_DES_SET_DATALEN
+// #endif
+
+extern void dbg_print(char *fmt,...);
+
+#if TTY_CONSOLE_TRACE_ENABLED==1
+ /*
+ * Print indexed trace to console.
+ */
+ #if defined(__MTK_TARGET__)
+ //#define tty_console_trace dbg_print
+ #define tty_console_trace dbg_print
+ #define TTY_NEW_LINE "\r\n"
+ #else
+ #define tty_console_trace dbg_print
+ #define TTY_NEW_LINE "\n"
+ #endif
+
+/* #define tty_trace_error(...) tty_console_trace(__VA_ARGS__)*/
+/* #define tty_trace_info(...) tty_console_trace(__VA_ARGS__)*/
+
+ #define BEGIN_TRACE_MAP(_mod)
+ #define TRC_MSG(_msg_index, _fmt) static const char _msg_index [] = _fmt TTY_NEW_LINE;
+ #define END_TRACE_MAP(_mod)
+#else
+ /*
+ * Use DHL logging.
+ */
+ #ifndef __MAUI_BASIC__
+/* #define tty_trace_error(...) \
+ do{ \
+ if(INT_QueryExceptionStatus() == KAL_FALSE) \
+ { \
+ dhl_trace(TRACE_ERROR, DHL_USER_FLAG_NONE, __VA_ARGS__); \
+ } \
+ }while(0)*/
+
+/* #define tty_trace_info(...) \
+ do{ \
+ if(INT_QueryExceptionStatus() == KAL_FALSE) \
+ { \
+ dhl_trace(TRACE_INFO, DHL_USER_FLAG_NONE, __VA_ARGS__); \
+ } \
+ }while(0)*/
+
+/* #define tty_trace_func(...) \
+ do{ \
+ if(INT_QueryExceptionStatus() == KAL_FALSE) \
+ { \
+ dhl_trace(TRACE_FUNC, DHL_USER_FLAG_NONE, __VA_ARGS__); \
+ } \
+ }while(0)*/
+ #else
+/* #define tty_trace_error(...)*/
+/* #define tty_trace_info(...)*/
+/* #define tty_trace_func(...)*/
+ #endif
+#endif /* TTY_CONSOLE_TRACE_ENABLED */
+
+#ifndef __MAUI_BASIC__
+#include "tty_trace.h"
+#endif
+
+/* Macros */
+/* ==================================================================================================== */
+#ifdef ATEST_SYS_TTYCORE
+ extern kal_bool ut_assert_flag;
+
+ #ifdef ASSERT
+ #undef ASSERT
+ #endif
+ //#define ASSERT(x) do{ if (x) ut_assert_flag = KAL_TRUE; }while(0)
+ void ASSERT(int x) {
+ if (!x) {
+ ut_assert_flag = KAL_TRUE;
+ }
+ }
+#endif
+#define VAR_MSG_ASSERT(var_msg) do{int var_msg=0; ASSERT(var_msg);} while(0)
+
+#ifdef __TTY_DBG_MODE__
+#define DBG_ASSERT(expr) ASSERT(expr)
+#define TTY_CHECK_CONTEXT_ENABLED 1
+#else
+#define DBG_ASSERT(expr)
+#define TTY_CHECK_CONTEXT_ENABLED 0
+#endif
+
+#define TTY_HWITC_ENABLE (1)
+#if defined(TTY_HWITC_ENABLE)
+ #define TTY_SPIN_LOCK(_s) kal_hrt_take_itc_lock(KAL_ITC_TTY, KAL_INFINITE_WAIT)
+ #define TTY_SPIN_UNLOCK(_s) kal_hrt_give_itc_lock(KAL_ITC_TTY)
+#else
+ #define TTY_SPIN_LOCK(_s) kal_take_spinlock(_s, KAL_INFINITE_WAIT)
+ #define TTY_SPIN_UNLOCK(_s) kal_give_spinlock(_s)
+#endif
+
+#define TTY_CHECK_HANDLE(handle) \
+ do{ \
+ if (handle == STATUS_INVALID_DEVICE) {return STATUS_FAIL;} \
+ if (!DCL_UART_IS_HANDLE_MAGIC(handle)) {if(INT_QueryExceptionStatus() == KAL_FALSE) \
+MD_TRC(TTY_TR_INVALID_HANDLE,__LINE__, handle, kal_get_active_module_id());return STATUS_INVALID_DCL_HANDLE;} \
+ }while(0)
+
+#define TTY_CHECK_DEV_IS_READY(dev) \
+ do{ \
+ /* Check if the driver callback is registered */ \
+ if (dev >= UART_DEV_CNT || dev < 0 || !tty_mgmt_info[dev].active) \
+ { \
+ if(INT_QueryExceptionStatus() == KAL_FALSE) \
+MD_TRC(TTY_TR_DEV_DRV_NOT_RDY,__LINE__, dev, kal_get_active_module_id()); \
+ return STATUS_DEVICE_NOT_EXIST; \
+ } \
+ }while(0)
+
+#define TTY_CHECK_DEV_VALID(dev) \
+ do{ \
+ if (dev >= UART_DEV_CNT || dev < 0) {if(INT_QueryExceptionStatus() == KAL_FALSE) \
+MD_TRC(TTY_TR_DEV_NOT_VALID,__LINE__, dev, kal_get_active_module_id());return STATUS_INVALID_DEVICE;} \
+ }while(0)
+
+#if TTY_CHECK_CONTEXT_ENABLED==1
+#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)
+#define TTY_CHECK_ACTIVE_MOD(dev) \
+ do{ \
+ if (tty_mgmt_info[dev].owner_id != MOD_DRV_DBG/*dbg_print is exception*/ \
+ && tty_mgmt_info[dev].owner_id != MOD_DHL \
+ && tty_mgmt_info[dev].owner_id != MOD_DHL_READER \
+ && tty_mgmt_info[dev].opened \
+ && tty_mgmt_info[dev].owner_id != kal_get_active_module_id()) { \
+ VAR_MSG_ASSERT(TTY_Active_module_id_not_match); \
+ } \
+ }while(0)
+#else
+#define TTY_CHECK_RUN_IN_HISR(dev)
+#define TTY_CHECK_ACTIVE_MOD(dev)
+#endif
+
+#define TTY_CONV_FLUSH_TX(cnt_thre) \
+ count = 0; \
+ if (TTY_IS_CONVENTIONAL_TX(device)) { \
+ while (1) { \
+ if (tty_mgmt_info[device].tx_gpd_num_used == 0) { \
+ break; \
+ } \
+ kal_sleep_task(KAL_TICKS_10_MSEC/2); \
+ if (++count > cnt_thre) { \
+ VAR_MSG_ASSERT(flush_tx_cmd_too_long); \
+ } \
+ } \
+ }
+
+#define TTY_CONV_FLUSH_RX(cnt_thre) \
+ count = 0; \
+ if (TTY_IS_CONVENTIONAL_RX(device)) { \
+ while (1) { \
+ if (tty_mgmt_info[device].rx_gpd_num_assigned == 0) { \
+ break; \
+ } \
+ kal_sleep_task(KAL_TICKS_10_MSEC/2); \
+ if (++count > cnt_thre) { \
+ VAR_MSG_ASSERT(flush_rx_cmd_too_long); \
+ } \
+ } \
+ }
+
+
+
+#define TTY_IS_CONVENTIONAL_TX(dev) (!(tty_mgmt_info[dev].flag & TTY_FLAG_NEW_TX))
+#define TTY_IS_CONVENTIONAL_RX(dev) (!(tty_mgmt_info[dev].flag & TTY_FLAG_NEW_RX))
+#define TTY_DRV_IS_ATTACHED(dev) (tty_mgmt_info[dev].drv_state == DRV_ST_ATTACHED)
+
+#define DCL_UART_MAGIC_NUM 0x40000000
+#define DCL_UART_IS_HANDLE_MAGIC(handl_) ((handl_)& DCL_UART_MAGIC_NUM)
+#define DCL_UART_GET_DEV(handle_) ((DCL_DEV)((handle_) & (~DCL_UART_MAGIC_NUM)))
+
+#define UART_DEV_CNT (uart_max_port - uart_port1 + 1) //subtract uart1, in case uart1 != 0 in future.
+
+#define TTY_BC_TX_GPD_MAX_NUM 2 /* Tx Max GPD number for backward-compatible */
+#define GPD_NUM_FOR_TTY 100
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#define TTY_IS_BUFF_PORT(dev) ((tty_mgmt_info[dev].drv_type == BUFF_DRV_TYPE))
+#define TTY_MIN(_a, _b) (((_a) <= (_b)) ? (_a) : (_b))
+
+#define TTY_CHK_DEV_OPEN(dev) (DCL_TRUE == tty_mgmt_info[dev].opened)
+
+/* Structure define & Global variable */
+/* ==================================================================================================== */
+typedef struct _tty_port_mgmt
+{
+ /* for buffer type driver*/
+ DCL_UINT32 drv_type;
+ kal_spinlockid spinLock; // each device has its own lock
+ DCL_UINT32 rx_allow_len; //Indicates downlink mtu size of HIF
+ qbm_gpd *rx_gpd;
+ DCL_UINT32 rx_gpd_num_assigned;
+ DCL_UINT32 tx_gpd_num_used;
+ /* for backward-compatible */
+ DCL_UART_TX_FUNC conv_tx_cb;
+ DCL_UART_RX_FUNC conv_rx_cb;
+ DCL_UINT32 dev_type; //record device type
+ DCL_UINT32 qbm_data_len; //supported GPD type length
+ DCL_UINT32 flag;
+ tty_drv_state_change_cb drv_state_change_cb;
+ DCL_UINT32 qbm_data_type; //supported GPD type
+ tty_rx_cb rx_cb;
+ tty_txdone_cb tx_done_cb;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ module_type pending_owner;
+ DCL_UINT16 rx_buf_offset; // it indicates the buffer offset of rx_gpd (data in rx_gpd before offset has been received)
+ DCL_UINT16 chunk_size;
+ module_type owner_id;
+
+ tty_drv_state_e drv_state; // 1: driver attach; 0: driver detach
+ /* For legacy USBcore solution: driver attach event may be later than user traffic*/
+ DCL_BOOL tx_not_rdy;
+ DCL_BOOL opened; // opened by upper module
+ DCL_BOOL init_by_new_mod;
+ DCL_BOOL rx_up_mod_wait; //add for buffer device
+ DCL_BOOL tx_up_mod_wait;
+ DCL_BOOL flush_rx;
+ DCL_BOOL flush_tx;
+ DCL_BOOL no_indication; //User can set attribute to disable receiving ILM through SIO_SET_INDICATION
+ DCL_BOOL active; // registered uart handler callback by driver
+ /*store flag if user send SIO_CMD_OPEN or register callback before driver register CB*/
+ DCL_BOOL early_tx_done_cb_req;
+ DCL_BOOL early_open_req;
+} tty_port_mgmt;
+
+typedef enum
+{
+ GPD_DRV_TYPE,
+ BUFF_DRV_TYPE,
+}tty_driver_type;
+
+typedef struct _tty_dev_info
+{
+ SIO_TYPE_T dev_type;
+ DCL_UINT32 buff_type;
+ DCL_UINT32 buff_data_len;
+ tty_driver_type drv_type;
+}tty_dev_info;
+
+#define NOT_DEFINED_TYPE 0xFFFFFFFF
+#define NOT_DEFINED_LENGTH 0xFFFFFFFF
+
+static tty_dev_info tty_dev_info_tbl[DCL_UART_DEV_TYPE_MAX] = {
+#if defined(MT6752) && defined(__MD2__)
+ {DCL_UART_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //6752 MD2 uart only support buffer mode
+#else
+ {DCL_UART_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , GPD_DRV_TYPE},
+#endif
+ {DCL_UART_USB_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , GPD_DRV_TYPE},
+ {DCL_UART_BLUETOOTH_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
+ {DCL_UART_SPPA_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
+ {DCL_UART_CMUX_TYPE, NOT_DEFINED_TYPE , NOT_DEFINED_LENGTH , BUFF_DRV_TYPE},
+ {DCL_UART_CCCI_TYPE, QBM_TYPE_CCCI_COMM, QBM_CCCI_COMM_DATA_LEN , GPD_DRV_TYPE},
+ {DCL_UART_CCIF_TYPE, NOT_DEFINED_TYPE, NOT_DEFINED_LENGTH , BUFF_DRV_TYPE},
+ {DCL_UART_DCC_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
+ {DCL_UART_LOGACC_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
+ {DCL_UART_LMU_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
+ {DCL_UART_SP_USB_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
+ {DCL_UART_MINI_LOG_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , BUFF_DRV_TYPE}, //not checked
+ {DCL_UART_MTAD_TYPE, QBM_TYPE_TTY_INT , QBM_TTY_XXX_DATA_LEN , GPD_DRV_TYPE},
+};
+
+
+static tty_port_mgmt tty_mgmt_info[UART_DEV_CNT];
+
+/* Internal used API declaration */
+/* ==================================================================================================== */
+static DCL_STATUS _DclSerialPort_UpModuleReinit(DCL_DEV device, module_type module_id, int flag);
+static 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);
+
+
+/* Internal used API */
+/* ==================================================================================================== */
+static void DEVDRV_LS_DRAM_EX_ROCODE
+TTY_QBM_DES_SET_DATALEN(void* gpd, kal_uint32 data_len)
+{
+ void* bd = NULL;
+
+ ASSERT(NULL != gpd);
+ if(0 != QBM_DES_GET_BDP(gpd))
+ {
+ //4 <case> GPD->BD->BUFF
+ bd = QBM_DES_GET_DATAPTR(gpd);
+ ASSERT(NULL!=bd);
+ QBM_DES_SET_DATALEN(bd, data_len);
+ qbm_cal_set_checksum((kal_uint8 *)bd);
+ }
+
+ QBM_DES_SET_DATALEN(gpd, data_len);
+ qbm_cal_set_checksum((kal_uint8 *)gpd);
+}
+
+static DCL_UINT32 DEVDRV_LS_DRAM_EX_ROCODE
+TTY_QBM_DES_GET_DATALEN(void* gpd)
+{
+ void* bd = NULL;
+ DCL_UINT32 data_len = 0;
+
+ ASSERT(NULL!=gpd);
+ if(0 != QBM_DES_GET_BDP(gpd)){
+ //4 <case 1> GPD->BD->BUFF
+ bd = QBM_DES_GET_DATAPTR(gpd);
+ ASSERT(NULL!=bd);
+ data_len = QBM_DES_GET_DATALEN(bd);
+ }else{
+ //4 <case 2> GPD->BUFF
+ data_len = QBM_DES_GET_DATALEN(gpd);
+ }
+ return data_len;
+}
+
+static void* DEVDRV_LS_DRAM_EX_ROCODE
+TTY_QBM_DES_GET_DATAPTR(void* gpd)
+{
+ void* bd = NULL;
+ void* data_ptr = NULL;
+
+ ASSERT(NULL!=gpd);
+ if(0 != QBM_DES_GET_BDP(gpd)){
+ //4 <case 1> GPD->BD->BUFF
+ bd = QBM_DES_GET_DATAPTR(gpd);
+ ASSERT(NULL!=bd);
+ data_ptr = QBM_DES_GET_DATAPTR(bd);
+ }else{
+ //4 <case 2> GPD->BUFF
+ data_ptr = QBM_DES_GET_DATAPTR(gpd);
+ }
+
+ ASSERT(NULL!=data_ptr);
+ return data_ptr;
+}
+
+static void DEVDRV_LS_DRAM_EX_ROCODE
+_tty_update_buff_info_from_port(DCL_DEV device, SIO_TYPE_T dev_type)
+{
+ DCL_UINT8 i;
+
+ for( i = 0; i < DCL_UART_DEV_TYPE_MAX; i++)
+ {
+ if(tty_dev_info_tbl[i].dev_type == dev_type)
+ {
+ tty_mgmt_info[device].qbm_data_type = tty_dev_info_tbl[i].buff_type;
+ tty_mgmt_info[device].qbm_data_len = tty_dev_info_tbl[i].buff_data_len;
+ tty_mgmt_info[device].drv_type = tty_dev_info_tbl[i].drv_type;
+ return;
+ }
+ }
+ ASSERT(i < DCL_UART_DEV_TYPE_MAX);
+ return;
+}
+
+void DEVDRV_LS_DRAM_EX_ROCODE
+_tty_send_ilm(
+ DCL_DEV device,
+ module_type source_id,
+ msg_type msg_id)
+{
+ void *port_ptr = 0;
+
+ /*New feature: some ports may not need ilm indication*/
+ if(tty_mgmt_info[device].no_indication == 1)
+ {
+ return;
+ }
+
+ switch(msg_id)
+ {
+ case MSG_ID_UART_READY_TO_READ_IND:
+ {
+ uart_ready_to_read_ind_struct *tmp;
+ tmp = (uart_ready_to_read_ind_struct *)
+ construct_local_para(sizeof(uart_ready_to_read_ind_struct),TD_UL);
+ tmp->port = device;
+ port_ptr = tmp;
+ }
+ break;
+ case MSG_ID_UART_READY_TO_WRITE_IND:
+ {
+ uart_ready_to_write_ind_struct *tmp;
+ tmp = (uart_ready_to_write_ind_struct *)
+ construct_local_para(sizeof(uart_ready_to_write_ind_struct),TD_UL);
+ tmp->port = device;
+ port_ptr = tmp;
+ }
+ break;
+ case MSG_ID_UART_DSR_CHANGE_IND:
+ {
+ uart_dsr_change_ind_struct *tmp;
+ tmp = (uart_dsr_change_ind_struct *)
+ construct_local_para(sizeof(uart_dsr_change_ind_struct),TD_UL);
+ tmp->port = device;
+ port_ptr = tmp;
+ }
+ break;
+ case MSG_ID_UART_ESCAPE_DETECTED_IND:
+ {
+ uart_escape_detected_ind_struct *tmp;
+ tmp = (uart_escape_detected_ind_struct *)
+ construct_local_para(sizeof(uart_escape_detected_ind_struct),TD_UL);
+ tmp->port = device;
+ port_ptr = tmp;
+ }
+ break;
+ case MSG_ID_UART_PLUGOUT_IND:
+ {
+ uart_plugout_ind_struct *tmp;
+ tmp = (uart_plugout_ind_struct *)
+ construct_local_para(sizeof(uart_plugout_ind_struct),TD_RESET);
+ tmp->port = device;
+ port_ptr = tmp;
+ }
+ break;
+ case MSG_ID_UART_PLUGIN_IND:
+ {
+ uart_plugin_ind_struct *tmp;
+ tmp = (uart_plugin_ind_struct *)
+ construct_local_para(sizeof(uart_plugin_ind_struct),TD_RESET);
+ tmp->port = device;
+ port_ptr = tmp;
+ }
+ break;
+ default:
+ {
+ /* Print error log */
+ return;
+ }
+ }
+
+ msg_send5(source_id, // source module ID
+ tty_mgmt_info[device].owner_id, // destination module ID
+ DRIVER_PS_SAP, // sap ID
+ msg_id, // msg ID
+ port_ptr // local_para_struct *
+ );
+
+}
+
+#ifdef __TTY_DBG_MODE__
+/**
+ * @brief Check if any gpd length is zero
+ * @result none
+ */
+static void DEVDRV_LS_DRAM_EX_ROCODE
+_tty_gpd_zero_len_check(
+ tty_io_request_t *ior)
+{
+ tty_io_request_t *ior_tmp = ior;
+
+ do {
+ void *gpd = ior_tmp->first_gpd;
+
+ while (gpd != ior_tmp->last_gpd) {
+ ASSERT(TTY_QBM_DES_GET_DATALEN(gpd));
+ gpd = QBM_DES_GET_NEXT(gpd);
+ }
+ ASSERT(TTY_QBM_DES_GET_DATALEN(gpd));
+ } while ((ior_tmp = ior_tmp->next_request) != NULL);
+}
+#endif
+
+/**
+ * @brief Free all gpds of ior
+ * @result total number of free gpd
+ */
+static DCL_UINT32 DEVDRV_LS_DRAM_EX_ROCODE
+_tty_free_ior(
+ tty_io_request_t *ior)
+{
+ DCL_UINT32 number = 0;
+
+ if (ior) {
+ do {
+ number += qbmt_dest_q(ior->first_gpd, ior->last_gpd);
+ } while ((ior = ior->next_request) != NULL);
+ }
+
+ return number;
+}
+
+/*
+ _tty_rx_cb is used for backward-compatible.
+ In TTY Core design, only one rx ior is prepared for Rx receiving in conventional Rx mode.
+ 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
+ one rx_gpd is re-assigned to driver.
+ Thus rx_gpd don't need mutex protection.
+*/
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+_tty_rx_cb(
+ DCL_HANDLE handle,
+ module_type source_id,
+ tty_io_request_t *rx_ior)
+{
+ DCL_DEV device;
+ void *gpd_tmp;
+ tty_io_request_t *ior_tmp;
+
+ device = DCL_UART_GET_DEV(handle);
+
+ if (!tty_mgmt_info[device].flush_rx) {
+ /* global rx gpd must be NULL when rx callback of non-flush command is called */
+ ASSERT(!tty_mgmt_info[device].rx_gpd);
+ }
+
+ /*
+ The rx callback is called by flush done :
+ <1> there is a next request of rx_ior
+ <2> there are 2 gpd of rx_ior
+ */
+ if (rx_ior->next_request)
+ {
+ ASSERT(tty_mgmt_info[device].flush_rx);
+ ASSERT(rx_ior->first_gpd == rx_ior->last_gpd);
+ ASSERT(rx_ior->next_request->first_gpd == rx_ior->next_request->last_gpd);
+ ior_tmp = rx_ior->next_request;
+ rx_ior->next_request = NULL;
+ QBM_FREE_ONE(ior_tmp->first_gpd);
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ ASSERT(tty_mgmt_info[device].rx_gpd_num_assigned >= 1);
+ tty_mgmt_info[device].rx_gpd_num_assigned --;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ } else if (rx_ior->first_gpd != rx_ior->last_gpd)
+ {
+ ASSERT(tty_mgmt_info[device].flush_rx);
+
+ // tj.chang, 2011/12/27: We should not promise the length of last_gpd is 0.
+// ASSERT(TTY_QBM_DES_GET_DATALEN(rx_ior->last_gpd) == 0);
+ ASSERT(QBM_DES_GET_NEXT(rx_ior->first_gpd) == rx_ior->last_gpd);
+ gpd_tmp = rx_ior->last_gpd;
+ rx_ior->last_gpd = rx_ior->first_gpd;
+ QBM_FREE_ONE(gpd_tmp);
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ ASSERT(tty_mgmt_info[device].rx_gpd_num_assigned >= 1);
+ tty_mgmt_info[device].rx_gpd_num_assigned --;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ if (!tty_mgmt_info[device].flush_rx && TTY_QBM_DES_GET_DATALEN(rx_ior->first_gpd) > 0)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_gpd = rx_ior->first_gpd;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ //change start for ALPS04065656
+ //handling race condition between UL data gpd and clr rx buff.
+ if(tty_mgmt_info[device].flush_rx) {
+ void *rx_gpd;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if(tty_mgmt_info[device].rx_gpd) {
+ rx_gpd = tty_mgmt_info[device].rx_gpd;
+ tty_mgmt_info[device].rx_gpd = NULL;
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ tty_mgmt_info[device].rx_gpd_num_assigned--;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ QBM_FREE_ONE(rx_gpd);
+ } else {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ } else {
+ //change end for ALPS04065656
+ /* Inform upper layer module readyToRead */
+ if (tty_mgmt_info[device].conv_rx_cb) {
+ tty_mgmt_info[device].conv_rx_cb(device);
+ } else {
+ _tty_send_ilm(device, source_id, MSG_ID_UART_READY_TO_READ_IND);
+ }
+ }
+ } else
+ { /* The rx callback is called by clear tx/rx buffer (flush) command */
+ QBM_FREE_ONE(rx_ior->first_gpd);
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ ASSERT(tty_mgmt_info[device].rx_gpd_num_assigned >= 1);
+ tty_mgmt_info[device].rx_gpd_num_assigned --;
+ if (tty_mgmt_info[device].rx_gpd_num_assigned == 0) {
+ /* clear flush_rx flag if all rx_gpd are free */
+ tty_mgmt_info[device].flush_rx = 0;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ return STATUS_OK;
+}
+
+/*
+ _tty_rx_buff_cb is used for backward-compatible buffer mode driver.
+ This callback is only used for conventional user on buffer mode port.
+ The main task of this callback is sending ILM to tty user.
+ (Flush RX shall not go there.)
+*/
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+_tty_rx_buff_cb(
+ DCL_HANDLE handle,
+ module_type source_id,
+ tty_io_request_t *rx_ior)
+{
+ DCL_DEV device;
+
+ device = DCL_UART_GET_DEV(handle);
+
+ /*Current design does not return data through callback*/
+ ASSERT(rx_ior == NULL);
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].rx_up_mod_wait)
+ {
+ tty_mgmt_info[device].rx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].conv_rx_cb) {
+ tty_mgmt_info[device].conv_rx_cb(device);
+ } else {
+ _tty_send_ilm(device, source_id, MSG_ID_UART_READY_TO_READ_IND);
+ }
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ return STATUS_OK;
+}
+
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+_tty_tx_done_cb(
+ DCL_HANDLE handle,
+ module_type source_id,
+ tty_io_request_t *tx_ior)
+{
+ DCL_DEV device;
+ DCL_UINT32 number;
+
+ device = DCL_UART_GET_DEV(handle);
+
+ if (tx_ior) {
+ number = _tty_free_ior(tx_ior);
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ ASSERT(tty_mgmt_info[device].tx_gpd_num_used >= number);
+ tty_mgmt_info[device].tx_gpd_num_used -= number;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ if (!tty_mgmt_info[device].flush_tx)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].tx_up_mod_wait)
+ {
+ tty_mgmt_info[device].tx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].conv_tx_cb) {
+ tty_mgmt_info[device].conv_tx_cb(device);
+ } else {
+ _tty_send_ilm(device, source_id, MSG_ID_UART_READY_TO_WRITE_IND);
+ }
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ } else {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].tx_gpd_num_used == 0) {
+ /* clear flush_tx flag if all tx_gpd are free */
+ tty_mgmt_info[device].flush_tx = 0;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ } else {
+ /* print error log - tx_ior can't be null */
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_TX_IOR_IS_NULL,device, source_id);
+ ASSERT(tx_ior);
+ return STATUS_FAIL;
+ }
+
+ return STATUS_OK;
+}
+
+/*
+ _tty_tx_buff_done_cb is used for backward-compatible buffer mode driver.
+ This callback is only used for conventional user on buffer mode port.
+ The main task of this callback is sending ILM to tty user.
+ (Flush TX shall not go there.)
+*/
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+_tty_tx_buff_done_cb(
+ DCL_HANDLE handle,
+ module_type source_id,
+ tty_io_request_t *tx_ior)
+{
+ DCL_DEV device;
+
+ device = DCL_UART_GET_DEV(handle);
+
+ /*Current design does not return data through callback*/
+ ASSERT(tx_ior == NULL);
+
+ /*
+ * This function is invoked when lower driver finish the TX.
+ * check up_mod_wait to send the indication message
+ */
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].tx_up_mod_wait)
+ {
+ tty_mgmt_info[device].tx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].conv_tx_cb) {
+ tty_mgmt_info[device].conv_tx_cb(device);
+ } else {
+ _tty_send_ilm(device, source_id, MSG_ID_UART_READY_TO_WRITE_IND);
+ }
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ return STATUS_OK;
+}
+
+void DEVDRV_LS_DRAM_EX_ROCODE
+_cal_and_set_rx_allow_len(
+ DCL_DEV device,
+ DCL_UINT16 chunk_size)
+{
+ DCL_HANDLE handle;
+ UART_CTRL_GET_MTU_SIZE_T ur_ctrl_get_mtu_size;
+
+ handle = DclSerialPort_Open(device, 0);
+
+ if(chunk_size == 1) //no chunk size restriction
+ {
+ DclSerialPort_Control(handle, TTY_CMD_GET_MTU_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_mtu_size);
+ tty_mgmt_info[device].rx_allow_len = TTY_MIN(ur_ctrl_get_mtu_size.ulmtu_sz, tty_mgmt_info[device].qbm_data_len);
+ }
+ else
+ {
+ tty_mgmt_info[device].rx_allow_len = chunk_size;
+ }
+
+ ASSERT(tty_mgmt_info[device].rx_allow_len >= chunk_size);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DRV_RX_ALLOW_LEN,device, tty_mgmt_info[device].rx_allow_len);
+ return;
+}
+
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+_tty_conv_assign_rx_gpd_to_drv(
+ DCL_DEV device)
+{
+ DCL_STATUS result;
+ UART_CTRL_ASSIGN_RX_IOR_T ur_ctrl_assign_rxior;
+ tty_io_request_t *rx_ior;
+ void *rx_gpd_first, *rx_gpd_last;
+ DCL_UINT32 remain_rx_gpd_num;
+ DCL_UINT32 alloc_num;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ 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*/)
+ {
+ remain_rx_gpd_num = 2 - tty_mgmt_info[device].rx_gpd_num_assigned;
+ /** 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*/
+ tty_mgmt_info[device].rx_gpd_num_assigned += remain_rx_gpd_num;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ //alloc_num = qbmt_alloc_q_no_tail(TTY_QBM_DATA_TYPE, remain_rx_gpd_num, &rx_gpd_first, &rx_gpd_last);
+ alloc_num = qbmt_alloc_q_no_tail(tty_mgmt_info[device].qbm_data_type, remain_rx_gpd_num, &rx_gpd_first, &rx_gpd_last);
+ if (alloc_num != remain_rx_gpd_num)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ /** Minus assigned gpd when cannot get gpds */
+ tty_mgmt_info[device].rx_gpd_num_assigned -= remain_rx_gpd_num;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_GPD_EXHAUST,device, kal_get_active_module_id());
+ VAR_MSG_ASSERT(tty_internal_qbm_exhaust);
+ return STATUS_FAIL;
+ }
+
+ //ASSERT(TTY_QBM_DATA_LEN >= tty_mgmt_info[device].chunk_size);
+ ASSERT(tty_mgmt_info[device].qbm_data_len >= tty_mgmt_info[device].chunk_size);
+
+ /* First gpd */
+ QBM_DES_SET_HWO(rx_gpd_first);
+ QBM_DES_SET_ALLOW_LEN(rx_gpd_first, tty_mgmt_info[device].rx_allow_len);
+ qbm_cal_set_checksum(rx_gpd_first);
+ QBM_CACHE_FLUSH(rx_gpd_first, sizeof(qbm_gpd));
+
+ /* Last gpd */
+ if (alloc_num == 2) {
+ QBM_DES_SET_HWO(rx_gpd_last);
+ QBM_DES_SET_ALLOW_LEN(rx_gpd_last, tty_mgmt_info[device].rx_allow_len);
+ qbm_cal_set_checksum(rx_gpd_last);
+ QBM_CACHE_FLUSH(rx_gpd_last, sizeof(qbm_gpd));
+ }
+
+ rx_ior = (tty_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(rx_gpd_first);
+ rx_ior->first_gpd = rx_gpd_first;
+ rx_ior->last_gpd = rx_gpd_last;
+ rx_ior->next_request = NULL;
+
+ ur_ctrl_assign_rxior.u4OwnerId = tty_mgmt_info[device].owner_id;
+ ur_ctrl_assign_rxior.ior = rx_ior;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ _tty_free_ior(rx_ior);
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, TTY_CMD_ASSIGN_RX_IOR, (DCL_CTRL_DATA_T *)&ur_ctrl_assign_rxior);
+ if (result != STATUS_OK) {
+ /* command failed */
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ /** Minus assigned gpd when driver return fail */
+ tty_mgmt_info[device].rx_gpd_num_assigned -= remain_rx_gpd_num;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ _tty_free_ior(rx_ior);
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ERR_ASSIGN_RX_IOR,device, result, kal_get_active_module_id());
+ return result;
+ }
+ } else {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+_tty_conv_drv_state_change_cb(
+ DCL_HANDLE handle,
+ tty_drv_state_e state)
+{
+ DCL_DEV device;
+
+ device = DCL_UART_GET_DEV(handle);
+
+ switch(state)
+ {
+ case DRV_ST_DETACHED:
+ {
+ _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_PLUGOUT_IND);
+ break;
+ }
+ case DRV_ST_ATTACHED:
+ {
+ _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_PLUGIN_IND);
+ break;
+ }
+ default:
+ {
+ ASSERT(0);
+ break;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+/* External used API */
+/* ==================================================================================================== */
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_Initialize(void)
+{
+#if !defined(TTY_HWITC_ENABLE)
+ kal_uint32 i;
+ kal_char tty_lock_name[50];
+#endif
+ /* QBM number for TTY internal used must be larger than or equal to max possible gpd number for rx data path use */
+ /* we dont need to reserve GPD buffer for virtual port, because the driver mode of virtual port is buffer mode*/
+ //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*/));
+ ASSERT(QBM_NUM_TTY_INT >= ((UART_DEV_CNT-CMUX_VP_NUM-CCCI_TTY_DEV_NUM)*2/*2 buffer for Rx*/));
+#if defined(__HIF_CCCI_SUPPORT__)
+ ASSERT(QBM_NUM_CCCI_COMM >= (CCCI_TTY_DEV_NUM*2/*2 buffer for Rx*/));
+#endif
+
+ /*Init tty_mgmt_info instance*/
+ kal_mem_set(tty_mgmt_info, 0, sizeof(tty_port_mgmt)*UART_DEV_CNT);
+
+ /* Init lock resource */
+#if !defined(TTY_HWITC_ENABLE)
+ /* HW ITC don't need create process, but spinlock needs */
+ for(i = 0; i < UART_DEV_CNT; i++)
+ {
+ sprintf(tty_lock_name, "TTYSPINLOCK_%d", i);
+ tty_mgmt_info[i].spinLock = kal_create_spinlock(tty_lock_name);
+ if(tty_mgmt_info[i].spinLock == NULL) ASSERT(0);
+ }
+#endif
+ return STATUS_OK;
+}
+
+DCL_HANDLE DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_Open(
+ DCL_DEV dev,
+ DCL_FLAGS flags)
+{
+
+ if ((dev<uart_port1) ||(dev>uart_max_port)) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_OPEN_ERR,dev, kal_get_active_module_id());
+ return STATUS_INVALID_DEVICE;
+ }
+
+ if (uart_port_null == dev) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_OPEN_ERR,dev, kal_get_active_module_id());
+ return STATUS_INVALID_DEVICE;
+ }
+
+ return (DCL_UART_MAGIC_NUM | dev);
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_Close(
+ DCL_HANDLE handle)
+{
+ return STATUS_OK;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_Configure(
+ DCL_HANDLE handle,
+ DCL_CONFIGURE_T *configure)
+{
+ return STATUS_OK;
+}
+
+
+/*!
+ * @brief If upper layer module execute DclSerialPort_UpModuleInit
+ * ---> New Module Init
+ * ---> In DclSerialPort_UpModuleInit, it will help send SIO_CMD_OPEN command
+ * If upper layer module execute DclSerialPort_Control with SIO_CMD_OPEN command without calling DclSerialPort_UpModuleInit
+ * ---> Old module init (for backward compatible)
+ */
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_Control(
+ DCL_HANDLE handle,
+ DCL_CTRL_CMD cmd,
+ DCL_CTRL_DATA_T *data)
+{
+ DCL_STATUS result;
+ DCL_DEV device;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+
+
+ /*20130313:SIO_CMD_OPEN will not check device exist*/
+ if (cmd == SIO_CMD_OPEN)
+ {
+ TTY_CHECK_DEV_VALID(device);
+
+ /*If driver has not register yet, store the request*/
+ if(!tty_mgmt_info[device].active)
+ {
+ UART_CTRL_OPEN_T *ur_ctrl_open = &(data->rUARTCtrlOPEN);
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].early_open_req) {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_OPEN_ALREADY_OPENED,device, kal_get_active_module_id());
+ return STATUS_ALREADY_OPENED;
+ }
+ tty_mgmt_info[device].early_open_req = 1;
+ tty_mgmt_info[device].pending_owner = (module_type) ur_ctrl_open->u4OwenrId;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_OK;
+ }
+ }
+ else if(cmd == SIO_CMD_CLOSE)
+ {
+ TTY_CHECK_DEV_VALID(device);
+ /*If driver has not register yet, store the request*/
+ if(!tty_mgmt_info[device].active)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].early_open_req) {
+ tty_mgmt_info[device].early_open_req = 0;
+ tty_mgmt_info[device].pending_owner = MOD_NIL;
+ if (tty_mgmt_info[device].early_tx_done_cb_req)
+ {
+ tty_mgmt_info[device].early_tx_done_cb_req = 0;
+ }
+ //clean info set by UpmoduleInit
+ if(tty_mgmt_info[device].init_by_new_mod)
+ {
+ tty_mgmt_info[device].init_by_new_mod = 0;
+ tty_mgmt_info[device].owner_id = MOD_NIL;
+ tty_mgmt_info[device].flag = 0;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DEV_IS_NOT_OPENED,device, kal_get_active_module_id());
+ return STATUS_NOT_OPENED;
+ }
+
+ return STATUS_OK;
+ }
+ }
+ else
+ {
+ TTY_CHECK_DEV_IS_READY(device);
+ }
+#if TTY_AGGRESSIVE_TRACE
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_DCL_CONTROL,device, cmd, kal_get_active_module_id());
+#endif
+
+ /* Pre-command Process */
+ switch (cmd)
+ {
+ case SIO_CMD_OPEN:
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].opened) {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_OPEN_ALREADY_OPENED,device, kal_get_active_module_id());
+ return STATUS_ALREADY_OPENED;
+ }
+ tty_mgmt_info[device].opened = 1;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ break;
+
+ case SIO_CMD_GET_BYTES:
+ case SIO_CMD_GET_UART_BYTE:
+ {
+ UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
+ UART_CTRL_GET_BYTES_T *p_ur_ctrl_getbytes;
+ DCL_UINT16 real_data_len;
+ DCL_UINT8 *real_data;
+ void *rx_gpd;
+
+ if (!TTY_IS_CONVENTIONAL_RX(device)) {
+ return STATUS_INVALID_OPERATION;
+ }
+
+ /* If device is buffer port, bypass cmd to driver*/
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ // TODO:add support for SIO_CMD_GET_UART_BYTE, which is blocking read.
+ ASSERT(cmd == SIO_CMD_GET_BYTES);
+ break;
+ }
+
+ /*
+ This area is for conventional RX - backward compatible
+ */
+ if (cmd == SIO_CMD_GET_UART_BYTE) {
+ UART_CTRL_GET_UART_BYTE_T *p_ur_ctrl_get_uart_byte;
+ p_ur_ctrl_get_uart_byte = &(data->rUARTCtrlGETUARTBYTE);
+ ur_ctrl_getbytes.puBuffaddr = &p_ur_ctrl_get_uart_byte->uByte;
+ ur_ctrl_getbytes.u2Length = 1;
+ p_ur_ctrl_getbytes = &ur_ctrl_getbytes;
+ } else {
+ p_ur_ctrl_getbytes = &(data->rUARTCtrlGETBYTES);
+ }
+
+ if (TTY_DRV_IS_ATTACHED(device) && ! tty_mgmt_info[device].flush_rx) {
+ _tty_conv_assign_rx_gpd_to_drv(device);
+ } else {
+ p_ur_ctrl_getbytes->u2RetSize = 0;
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_WRONG_STATE,device, kal_get_active_module_id());
+ return STATUS_ERROR_WRONG_STATE;
+ }
+
+ rx_gpd = tty_mgmt_info[device].rx_gpd;
+ if (!rx_gpd) {
+ p_ur_ctrl_getbytes->u2RetSize = 0;
+#if TTY_AGGRESSIVE_TRACE
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_CONV_RX_NOT_RDY,device, kal_get_active_module_id());
+#endif
+ } else {
+ real_data = (DCL_UINT8*)TTY_QBM_DES_GET_DATAPTR(rx_gpd) + tty_mgmt_info[device].rx_buf_offset;
+ real_data_len = TTY_QBM_DES_GET_DATALEN(rx_gpd) - tty_mgmt_info[device].rx_buf_offset;
+
+ if (real_data_len > p_ur_ctrl_getbytes->u2Length) {
+ kal_mem_cpy(p_ur_ctrl_getbytes->puBuffaddr, real_data, p_ur_ctrl_getbytes->u2Length);
+ p_ur_ctrl_getbytes->u2RetSize = p_ur_ctrl_getbytes->u2Length;
+ tty_mgmt_info[device].rx_buf_offset += p_ur_ctrl_getbytes->u2Length;
+ } else {
+ kal_mem_cpy(p_ur_ctrl_getbytes->puBuffaddr, real_data, real_data_len);
+ p_ur_ctrl_getbytes->u2RetSize = real_data_len;
+
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_gpd = NULL;
+ ASSERT(tty_mgmt_info[device].rx_gpd_num_assigned >= 1);
+ tty_mgmt_info[device].rx_gpd_num_assigned --;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ QBM_FREE_ONE(rx_gpd);
+
+ /* Re-aasign rx gpd to driver for data receiveing */
+ _tty_conv_assign_rx_gpd_to_drv(device);
+ }
+ }
+#if TTY_AGGRESSIVE_TRACE
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_CONV_RX,device, p_ur_ctrl_getbytes->u2RetSize);
+#endif
+ return STATUS_OK;
+ }
+ break;
+
+ case SIO_CMD_PUT_UART_BYTE:
+ case SIO_CMD_PUT_UART_BYTES:
+ case SIO_CMD_PUT_BYTES:
+ case SIO_CMD_PUT_ISR_BYTES:
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ UART_CTRL_PUT_BYTES_T *p_ur_ctrl_putbytes;
+ DCL_UINT8 *buf_ptr;
+ void *tx_gpd;
+ hif_io_request_t *tx_ior;
+ UART_CTRL_PUT_BYTES_IOR_T ur_ctrl_putbytes_ior;
+
+ if (!TTY_IS_CONVENTIONAL_TX(device)) {
+ return STATUS_INVALID_OPERATION;
+ }
+
+ /* If device is buffer port, bypass cmd to driver*/
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ // TODO:add support for SIO_CMD_PUT_UART_BYTE(S), which are blocking write.
+ ASSERT(cmd == SIO_CMD_PUT_BYTES);
+ break;
+ }
+
+ /*
+ This area is for conventional TX
+ */
+ if (cmd == SIO_CMD_PUT_UART_BYTE) {
+ UART_CTRL_PUT_UART_BYTE_T *p_ur_ctrl_put_uart_byte;
+ p_ur_ctrl_put_uart_byte = &(data->rUARTCtrlPUTUARTBYTE);
+ ur_ctrl_putbytes.puBuffaddr = &p_ur_ctrl_put_uart_byte->uData;
+ ur_ctrl_putbytes.u2Length = 1;
+ p_ur_ctrl_putbytes = &ur_ctrl_putbytes;
+ } else if (cmd == SIO_CMD_PUT_UART_BYTES) {
+ UART_CTRL_PUT_UART_BYTES_T *p_ur_ctrl_put_uart_bytes;
+ p_ur_ctrl_put_uart_bytes = &(data->rUARTCtrlPUTUARTBYTES);
+ ur_ctrl_putbytes.puBuffaddr = p_ur_ctrl_put_uart_bytes->puBuffaddr;
+ ur_ctrl_putbytes.u2Length = p_ur_ctrl_put_uart_bytes->u2Length;
+ p_ur_ctrl_putbytes = &ur_ctrl_putbytes;
+ } else {
+ p_ur_ctrl_putbytes = &(data->rUARTCtrlPUTBYTES);
+ }
+
+ ASSERT(p_ur_ctrl_putbytes->u2Length);
+
+ if (!TTY_DRV_IS_ATTACHED(device) || tty_mgmt_info[device].flush_tx) {
+ p_ur_ctrl_putbytes->u2RetSize = 0;
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_WRONG_STATE,device, kal_get_active_module_id());
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_not_rdy = 1;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_ERROR_WRONG_STATE;
+ }
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if(!TTY_CHK_DEV_OPEN(device)){
+ p_ur_ctrl_putbytes->u2RetSize = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_NOT_OPENED;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].tx_gpd_num_used >= TTY_BC_TX_GPD_MAX_NUM) {
+ /* tx ior is not yet retrieved, still in driver */
+ p_ur_ctrl_putbytes->u2RetSize = 0;
+ if (cmd != SIO_CMD_PUT_ISR_BYTES) {
+ tty_mgmt_info[device].tx_up_mod_wait = 1;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+#if TTY_AGGRESSIVE_TRACE
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_CONV_TX_NOT_RDY,device, tty_mgmt_info[device].tx_gpd_num_used, kal_get_active_module_id());
+#endif
+ } else {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ //tx_gpd = QBM_ALLOC_ONE(TTY_QBM_DATA_TYPE);
+ tx_gpd = QBM_ALLOC_ONE(tty_mgmt_info[device].qbm_data_type);
+
+ if (tx_gpd)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_gpd_num_used ++;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ tx_ior = (hif_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(tx_gpd);
+ tx_ior->next_request = NULL;
+ tx_ior->first_gpd = tx_gpd;
+ tx_ior->last_gpd = tx_gpd;
+
+ ur_ctrl_putbytes_ior.u4OwnerId = tty_mgmt_info[device].owner_id;
+ ur_ctrl_putbytes_ior.putIor = (void*)tx_ior;
+
+ buf_ptr = TTY_QBM_DES_GET_DATAPTR(tx_gpd);
+
+ //if (TTY_QBM_DATA_LEN >= p_ur_ctrl_putbytes->u2Length) {
+ if (tty_mgmt_info[device].qbm_data_len >= p_ur_ctrl_putbytes->u2Length) {
+ kal_mem_cpy(buf_ptr, p_ur_ctrl_putbytes->puBuffaddr, p_ur_ctrl_putbytes->u2Length);
+ p_ur_ctrl_putbytes->u2RetSize = p_ur_ctrl_putbytes->u2Length;
+ if (cmd != SIO_CMD_PUT_ISR_BYTES) {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ } else {
+ //kal_mem_cpy(buf_ptr, p_ur_ctrl_putbytes->puBuffaddr, TTY_QBM_DATA_LEN);
+ //p_ur_ctrl_putbytes->u2RetSize = TTY_QBM_DATA_LEN;
+ kal_mem_cpy(buf_ptr, p_ur_ctrl_putbytes->puBuffaddr, tty_mgmt_info[device].qbm_data_len);
+ p_ur_ctrl_putbytes->u2RetSize = tty_mgmt_info[device].qbm_data_len;
+ if (cmd != SIO_CMD_PUT_ISR_BYTES) {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_up_mod_wait = 1;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+
+ TTY_QBM_DES_SET_DATALEN(tx_gpd, p_ur_ctrl_putbytes->u2RetSize); // Set data length
+
+ //QBM_CACHE_FLUSH(buf_ptr, p_ur_ctrl_putbytes->u2RetSize); // khr debug, flush data
+#if TTY_AGGRESSIVE_TRACE
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_CONV_TX,device, p_ur_ctrl_putbytes->u2RetSize);
+#endif
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ tty_mgmt_info[device].tx_gpd_num_used --;
+ if (cmd != SIO_CMD_PUT_ISR_BYTES) {
+ tty_mgmt_info[device].tx_up_mod_wait = 1;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ QBM_FREE_ONE(tx_gpd);
+ p_ur_ctrl_putbytes->u2RetSize = 0;
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, TTY_CMD_PUT_BYTES_IOR, (DCL_CTRL_DATA_T *)&ur_ctrl_putbytes_ior);
+ if (result != STATUS_OK) {
+ /* command failed */
+ QBM_FREE_ONE(tx_gpd);
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_gpd_num_used --;
+ if (cmd != SIO_CMD_PUT_ISR_BYTES) {
+ tty_mgmt_info[device].tx_up_mod_wait = 1;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ p_ur_ctrl_putbytes->u2RetSize = 0;
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ERR_PUT_BYTES_IOR,device, result, kal_get_active_module_id());
+ return result;
+ }
+ } else {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_GPD_EXHAUST,device, kal_get_active_module_id());
+ //This case has error handling, so remove assert check here.
+ //VAR_MSG_ASSERT(tty_internal_gpd_exhaust);
+ p_ur_ctrl_putbytes->u2RetSize = 0;
+ if (cmd != SIO_CMD_PUT_ISR_BYTES) {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_up_mod_wait = 1;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+ }
+
+ return STATUS_OK;
+ }
+ break;
+
+ case SIO_CMD_GET_RX_AVAIL:
+ {
+ UART_CTRL_RX_AVAIL_T *ur_ctrl_rx_avail;
+ ur_ctrl_rx_avail = &(data->rUARTCtrlRXAVAIL);
+
+ /* If device is buffer port, bypass cmd to driver*/
+ if(TTY_IS_BUFF_PORT(device) && TTY_IS_CONVENTIONAL_RX(device))
+ {
+ break;
+ }
+
+ if (TTY_IS_CONVENTIONAL_RX(device))
+ {
+ if (tty_mgmt_info[device].rx_gpd) {
+ ur_ctrl_rx_avail->u2RetSize = TTY_QBM_DES_GET_DATALEN(tty_mgmt_info[device].rx_gpd) - tty_mgmt_info[device].rx_buf_offset;
+ } else {
+ ur_ctrl_rx_avail->u2RetSize = 0;
+ }
+ return STATUS_OK;
+ } else
+ {
+ return STATUS_FAIL; // This command doesn't be suported in NEW TTY Rx path
+ }
+ }
+ break;
+
+ case SIO_CMD_GET_TX_AVAIL:
+ case SIO_CMD_GET_ISR_TX_AVAIL:
+ {
+ UART_CTRL_TX_AVAIL_T *ur_ctrl_tx_avail;
+ ur_ctrl_tx_avail = &(data->rUARTCtrlTXAVAIL);
+
+ /* If device is buffer port, bypass cmd to driver*/
+ if(TTY_IS_BUFF_PORT(device) && TTY_IS_CONVENTIONAL_TX(device))
+ {
+ break;
+ }
+
+ if (TTY_IS_CONVENTIONAL_TX(device))
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].tx_gpd_num_used >= TTY_BC_TX_GPD_MAX_NUM) {
+ /* If Tx ior is in driver, return Tx available room = 0 byte */
+ ur_ctrl_tx_avail->u2RetSize = 0;
+ } else {
+ /* If Tx ior is retrieved and available, return Tx available room = TTY_QBM_DATA_LEN byte */
+ //ur_ctrl_tx_avail->u2RetSize = TTY_QBM_DATA_LEN;
+ ur_ctrl_tx_avail->u2RetSize = tty_mgmt_info[device].qbm_data_len;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ return STATUS_OK;
+ } else
+ {
+ return STATUS_FAIL; // This command doesn't be suported in NEW TTY Tx path
+ }
+ }
+ break;
+
+ case TTY_CMD_GET_DRV_STATE:
+ {
+ UART_CTRL_GET_DRV_STATE_T *ur_ctrl_get_drv_st;
+ ur_ctrl_get_drv_st = &(data->rUARTCtrlGetDrvState);
+
+ ur_ctrl_get_drv_st->drv_state = tty_mgmt_info[device].drv_state;
+
+ return STATUS_OK;
+ }
+ break;
+
+ case SIO_CMD_REG_TX_CB:
+ {
+ UART_CTRL_REG_TX_CB_T *ur_ctrl_reg_tx_cb;
+ ur_ctrl_reg_tx_cb = &(data->rUARTCtrlREGTXCB);
+
+ if (!TTY_IS_CONVENTIONAL_TX(device)) {
+ return STATUS_INVALID_OPERATION;
+ }
+
+ tty_mgmt_info[device].conv_tx_cb = ur_ctrl_reg_tx_cb->func;
+
+ return STATUS_OK;
+ }
+ break;
+
+ case SIO_CMD_REG_RX_CB:
+ {
+ UART_CTRL_REG_RX_CB_T *ur_ctrl_reg_rx_cb;
+ ur_ctrl_reg_rx_cb = &(data->rUARTCtrlREGRXCB);
+
+ if (!TTY_IS_CONVENTIONAL_RX(device)) {
+ return STATUS_INVALID_OPERATION;
+ }
+
+ tty_mgmt_info[device].conv_rx_cb = ur_ctrl_reg_rx_cb->func;
+
+ return STATUS_OK;
+ }
+ break;
+
+ case SIO_CMD_SET_OWNER:
+ case SIO_CMD_CLOSE:
+ {
+ /* Only GPD port will reference this flag*/
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ tty_mgmt_info[device].flush_tx = 1;
+ tty_mgmt_info[device].flush_rx = 1;
+
+ }
+ /* Check if there is any rx buff store in tty*/
+ if(TTY_IS_CONVENTIONAL_RX(device))
+ {
+ void *rx_gpd;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].rx_gpd) {
+ rx_gpd = tty_mgmt_info[device].rx_gpd;
+ tty_mgmt_info[device].rx_gpd = NULL;
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ tty_mgmt_info[device].rx_gpd_num_assigned--;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ QBM_FREE_ONE(rx_gpd);
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+ }
+ break;
+ case SIO_CMD_CLR_TX_BUF:
+ {
+ /* CCCI driver doesn't support TX flush command
+ * beacause some port share the same HW queue.
+ */
+ if(DCL_UART_CCCI_TYPE != tty_mgmt_info[device].dev_type){
+ /*Buffer port need to clear tx_up_mod_wait_flag*/
+ if(TTY_IS_BUFF_PORT(device)){
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_up_mod_wait = 1;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ else {
+ /* Only GPD port will reference this flag*/
+ tty_mgmt_info[device].flush_tx = 1;
+ }
+ }
+ }
+ break;
+ case SIO_CMD_CLR_RX_BUF:
+ {
+ void *rx_gpd;
+ /* Only GPD port will reference this flag*/
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ tty_mgmt_info[device].flush_rx = 1;
+ }
+ /* Check if there is any rx buff store in tty*/
+ if (TTY_IS_CONVENTIONAL_RX(device))
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].rx_gpd) {
+ rx_gpd = tty_mgmt_info[device].rx_gpd;
+ tty_mgmt_info[device].rx_gpd = NULL;
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ tty_mgmt_info[device].rx_gpd_num_assigned--;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ QBM_FREE_ONE(rx_gpd);
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+ /*Buffer port need to clear rx_up_mod_wait_flag*/
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_up_mod_wait = 1;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+ break;
+ case SIO_CMD_SEND_ISR_DATA:
+ case SIO_CMD_SEND_DATA:
+ {
+ VAR_MSG_ASSERT(not_support_sio_command);
+ }
+ break;
+ case TTY_CMD_SET_INDICATION:
+ {
+ UART_CTRL_SET_INDICATION_T *ur_ctrl_set_indication;
+ ur_ctrl_set_indication = &(data->rUARTCtrlSETINDICATION);
+
+ if(ur_ctrl_set_indication->need_indication == 0)
+ {
+ tty_mgmt_info[device].no_indication = 1;
+ }
+
+ }
+ break;
+ default:
+ break;
+ }
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ if (cmd == SIO_CMD_OPEN) {
+ tty_mgmt_info[device].opened = 0;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, cmd, data);
+
+ if (result != STATUS_OK) {
+ if (cmd == SIO_CMD_OPEN) {
+ /* open failed */
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].opened = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DCL_CMD_NG,device, cmd, result);
+ return result;
+ }
+
+ /* Post-command Process */
+ switch (cmd)
+ {
+ case SIO_CMD_OPEN:
+ {
+ if (!tty_mgmt_info[device].init_by_new_mod)
+ { /* Conventional Module Init */
+ UART_CTRL_OPEN_T *ur_ctrl_open;
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CONV_INIT,device, kal_get_active_module_id());
+
+ tty_mgmt_info[device].rx_gpd = NULL;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_gpd_num_assigned = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ tty_mgmt_info[device].flag = 0;
+ tty_mgmt_info[device].no_indication = 0;
+
+ ur_ctrl_open = &(data->rUARTCtrlOPEN);
+ tty_mgmt_info[device].owner_id = (module_type)ur_ctrl_open->u4OwenrId;
+
+ /* buffer port shall register different callback*/
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ _DclSerialPort_UpModuleRegisterCb(device, _tty_rx_buff_cb, _tty_tx_buff_done_cb, NULL);
+ }
+ else
+ {
+ /* 20130617: Add drv_state_change callback for supporting plug-in/plug-out indication*/
+ _DclSerialPort_UpModuleRegisterCb(device, _tty_rx_cb, _tty_tx_done_cb, _tty_conv_drv_state_change_cb);
+ }
+ }
+
+ /* Init rx_up_mod_wait for buffer port*/
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_up_mod_wait = 1;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ /* 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 */
+ /* Only takes when GPD ports*/
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ if (TTY_IS_CONVENTIONAL_RX(device) && TTY_DRV_IS_ATTACHED(device))
+ {
+ _tty_conv_assign_rx_gpd_to_drv(device);
+ }
+ }
+ }
+ break;
+ case SIO_CMD_SET_OWNER:
+ {
+ UART_CTRL_OWNER_T *ur_ctrl_owner;
+ DCL_UINT32 count;
+
+ ur_ctrl_owner = &(data->rUARTCtrlOWNER);
+
+ /* Only GPD port needs to check if all GPDs of previous user are returned*/
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ TTY_CONV_FLUSH_TX(10);
+ TTY_CONV_FLUSH_RX(10);
+ }
+
+ /* Reset parameters */
+ tty_mgmt_info[device].flag = 0;
+ tty_mgmt_info[device].rx_gpd = NULL;
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].conv_tx_cb = NULL;
+ tty_mgmt_info[device].conv_rx_cb = NULL;
+ tty_mgmt_info[device].flush_tx = 0;
+ tty_mgmt_info[device].flush_rx = 0;
+ tty_mgmt_info[device].owner_id = (module_type)ur_ctrl_owner->u4OwenrId;
+ tty_mgmt_info[device].no_indication= 0;
+
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ /* Pre-assign Rx gpd if conventional Rx path is used */
+ if (TTY_DRV_IS_ATTACHED(device) && TTY_IS_CONVENTIONAL_RX(device))
+ {
+ _tty_conv_assign_rx_gpd_to_drv(device);
+ }
+
+ /* By default set all callback functions with tty internal handler */
+ _DclSerialPort_UpModuleRegisterCb(device, _tty_rx_cb, _tty_tx_done_cb, NULL);
+ }
+ else
+ {
+ /* buffer port, just register buff port callback*/
+ _DclSerialPort_UpModuleRegisterCb(device, _tty_rx_buff_cb, _tty_tx_buff_done_cb, NULL);
+ }
+ }
+ break;
+ case SIO_CMD_CLR_TX_BUF:
+ {
+ DCL_UINT32 count;
+
+ if(DCL_UART_CCCI_TYPE != tty_mgmt_info[device].dev_type){
+ /* Only GPD port needs to check if all GPDs of previous user are returned*/
+ if(!TTY_IS_BUFF_PORT(device)){
+ TTY_CONV_FLUSH_TX(10);
+ tty_mgmt_info[device].flush_tx = 0;
+ }
+ }
+ }
+ break;
+ case SIO_CMD_CLR_RX_BUF:
+ {
+ DCL_UINT32 count;
+
+ /* Only GPD port needs to check if all GPDs of previous user are returned*/
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ TTY_CONV_FLUSH_RX(10);
+
+ tty_mgmt_info[device].flush_rx = 0;
+
+ if (TTY_DRV_IS_ATTACHED(device) && TTY_IS_CONVENTIONAL_RX(device))
+ {
+ _tty_conv_assign_rx_gpd_to_drv(device);
+ }
+ }
+ }
+ break;
+ case SIO_CMD_CLOSE:
+ {
+ DCL_UINT32 count;
+
+ /* Only GPD port needs to check if all GPDs of previous user are returned*/
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ TTY_CONV_FLUSH_TX(10);
+ TTY_CONV_FLUSH_RX(10);
+ }
+
+ tty_mgmt_info[device].flush_tx = 0;
+ tty_mgmt_info[device].flush_rx = 0;
+ tty_mgmt_info[device].flag = 0;
+ tty_mgmt_info[device].init_by_new_mod = 0;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].opened = 0;
+ tty_mgmt_info[device].rx_gpd_num_assigned = 0;
+ tty_mgmt_info[device].tx_gpd_num_used = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ tty_mgmt_info[device].conv_tx_cb = NULL;
+ tty_mgmt_info[device].conv_rx_cb = NULL;
+ tty_mgmt_info[device].no_indication= 0;
+ }
+ break;
+ //case SIO_CMD_PUT_UART_BYTE: //not support in buffer port currently
+ //case SIO_CMD_PUT_UART_BYTES: //not support in buffer port currently
+ //case SIO_CMD_PUT_ISR_BYTES: //not support in buffer port currently
+ case SIO_CMD_PUT_BYTES:
+ {
+ UART_CTRL_PUT_BYTES_T *p_ur_ctrl_putbytes;
+ UART_CTRL_TX_AVAIL_T ur_ctrl_tx_avail;
+
+ //GPD port shall not go here.
+ ASSERT(TTY_IS_BUFF_PORT(device));
+
+ /*
+ Only SIO_CMD_PUT_BYTES will return length of transmitted data
+ */
+ if(cmd == SIO_CMD_PUT_BYTES)
+ {
+ p_ur_ctrl_putbytes = &(data->rUARTCtrlPUTBYTES);
+ if(p_ur_ctrl_putbytes->u2Length != p_ur_ctrl_putbytes->u2RetSize)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_up_mod_wait = 1;
+
+ /*
+ Ready to write message may lost before setting tx_up_mod_wait as 1.
+ (Due to user task priority may be lower than HIF task priority)
+ so we need to double confirmed with HIF driver if it is really no space to write
+ */
+ ur_ctrl_tx_avail.u2RetSize = 0;
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ sp_handler_cb(device, SIO_CMD_GET_TX_AVAIL, (DCL_CTRL_DATA_T *)&ur_ctrl_tx_avail);
+ if(ur_ctrl_tx_avail.u2RetSize > 0)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if( tty_mgmt_info[device].tx_up_mod_wait == 1)
+ {
+ tty_mgmt_info[device].tx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_READY_TO_WRITE_IND);
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+ }
+ }
+ }
+ break;
+ case SIO_CMD_GET_BYTES:
+ //case SIO_CMD_GET_UART_BYTE: //not support in buffer port currently
+ {
+ UART_CTRL_GET_BYTES_T *p_ur_ctrl_getbytes;
+ UART_CTRL_RX_AVAIL_T ur_ctrl_rx_avail;
+
+ //GPD port shall not go here.
+ ASSERT(TTY_IS_BUFF_PORT(device));
+
+ if(cmd == SIO_CMD_GET_BYTES)
+ {
+ p_ur_ctrl_getbytes = &(data->rUARTCtrlGETBYTES);
+ //Last read
+ if(p_ur_ctrl_getbytes->u2Length > p_ur_ctrl_getbytes->u2RetSize)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_up_mod_wait = 1;
+
+
+ /*
+ Ready to read message may lost before setting rx_up_mod_wait as 1.
+ (Due to user task priority may be lower than HIF task priority)
+ so we need to double confirmed with HIF driver if it is really no data ready to read
+ */
+ ur_ctrl_rx_avail.u2RetSize = 0;
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ sp_handler_cb(device, SIO_CMD_GET_RX_AVAIL, (DCL_CTRL_DATA_T *)&ur_ctrl_rx_avail);
+ if(ur_ctrl_rx_avail.u2RetSize > 0)
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if( tty_mgmt_info[device].rx_up_mod_wait == 1)
+ {
+ tty_mgmt_info[device].rx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_READY_TO_READ_IND);
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_UpModuleInit(
+ DCL_HANDLE handle,
+ module_type module_id,
+ int flag)
+{
+ DCL_STATUS status = STATUS_FAIL;
+ DCL_DEV device;
+ UART_CTRL_OPEN_T uCtlOpen;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+
+ /*20130313:remove driver active check, because user may do initial flow before driver in active state*/
+ TTY_CHECK_DEV_VALID(device);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_NEW_INIT,device,module_id);
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (tty_mgmt_info[device].opened || tty_mgmt_info[device].early_open_req) {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_OPEN_ALREADY_OPENED,device, module_id);
+ return STATUS_ALREADY_OPENED;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ tty_mgmt_info[device].owner_id = module_id;
+ tty_mgmt_info[device].flag = flag;
+ tty_mgmt_info[device].init_by_new_mod = 1;
+ tty_mgmt_info[device].rx_gpd = NULL;
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].rx_gpd_num_assigned = 0;
+ tty_mgmt_info[device].tx_gpd_num_used = 0;
+ tty_mgmt_info[device].tx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].conv_tx_cb = NULL;
+ tty_mgmt_info[device].conv_rx_cb = NULL;
+ tty_mgmt_info[device].flush_tx = 0;
+ tty_mgmt_info[device].flush_rx = 0;
+ tty_mgmt_info[device].no_indication = 0;
+
+ if (TTY_IS_CONVENTIONAL_TX(device) && TTY_IS_CONVENTIONAL_RX(device)) {
+ tty_mgmt_info[device].init_by_new_mod = 0;
+ }
+
+ /* Send SIO_CMD_OPEN command */
+ /* 20130313: If driver is not active, store SIO_CMD_OPEN and then return */
+ if(tty_mgmt_info[device].active)
+ {
+ uCtlOpen.u4OwenrId = module_id;
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*)&uCtlOpen);
+ if (STATUS_OK != status) {
+ return status;
+ }
+ }
+ else
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].early_open_req = 1;
+ tty_mgmt_info[device].pending_owner = module_id;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_OK;
+ }
+
+ return STATUS_OK;
+}
+
+static DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+_DclSerialPort_UpModuleReinit(
+ DCL_DEV device,
+ module_type module_id,
+ int flag)
+{
+ DCL_STATUS result;
+ UART_CTRL_CLR_BUFFER_T ur_ctrl_clr_buf;
+ DCL_UINT32 count;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ /*
+ * Notes: if device is buffer port, just reset the ttycore internal flag,
+ * because it is impossible to use gpd buffer on buffer port
+ */
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ goto _RESET_FLAG;
+ }
+
+ /* If primary module uses conventional Rx and new module uses new rx path, flush Rx data path */
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (TTY_IS_CONVENTIONAL_RX(device) &&
+ tty_mgmt_info[device].rx_gpd_num_assigned > 0 &&
+ (flag & TTY_FLAG_NEW_RX)
+ )
+ {
+
+
+ /* -- 1. Send clear rx buffer command -- */
+ ur_ctrl_clr_buf.u4OwenrId = tty_mgmt_info[device].owner_id;
+ tty_mgmt_info[device].flush_rx = 1;
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, SIO_CMD_CLR_RX_BUF, (DCL_CTRL_DATA_T*)&ur_ctrl_clr_buf);
+ if (result != STATUS_OK) {
+ /* command failed */
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ERR_CLR_RX_BUF,device, result, kal_get_active_module_id());
+ return result;
+ }
+
+ /* -- 2. Wait until all rx gpds are returned back -- */
+ TTY_CONV_FLUSH_RX(10);
+ } else {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+_RESET_FLAG:
+ tty_mgmt_info[device].owner_id = module_id;
+ tty_mgmt_info[device].flag = flag;
+ tty_mgmt_info[device].rx_gpd = NULL;
+ tty_mgmt_info[device].rx_buf_offset = 0;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].tx_gpd_num_used = 0;
+ tty_mgmt_info[device].tx_up_mod_wait = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].conv_tx_cb = NULL;
+ tty_mgmt_info[device].conv_rx_cb = NULL;
+ tty_mgmt_info[device].flush_tx = 0;
+ tty_mgmt_info[device].flush_rx = 0;
+ tty_mgmt_info[device].no_indication = 0;
+
+ if (TTY_IS_CONVENTIONAL_TX(device) && TTY_IS_CONVENTIONAL_RX(device)) {
+ tty_mgmt_info[device].init_by_new_mod = 0;
+ } else {
+ tty_mgmt_info[device].init_by_new_mod = 1;
+ }
+
+ return STATUS_OK;
+}
+
+/* Re-init API is invoked when New upper module change owner -> it need re-set flag and re-register related callback function */
+/* This API must be called after SIO_CMD_SET_OWNER command */
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_UpModuleReinit(
+ DCL_HANDLE handle,
+ module_type module_id,
+ int flag)
+{
+ DCL_DEV device;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+ TTY_CHECK_DEV_IS_READY(device);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_REINIT,device, module_id);
+
+ if (!tty_mgmt_info[device].opened) {
+ return STATUS_NOT_OPENED;
+ }
+
+ return _DclSerialPort_UpModuleReinit(device, module_id, flag);
+}
+
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_UpModuleDeinit(
+ DCL_HANDLE handle)
+{
+ DCL_STATUS status = STATUS_FAIL;
+ DCL_DEV device;
+ UART_CTRL_CLOSE_T data;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+
+ /*20130313:remove driver active check, because user may do initial flow before driver in active state*/
+ TTY_CHECK_DEV_VALID(device);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DEINIT,device, kal_get_active_module_id());
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].opened && !tty_mgmt_info[device].early_open_req) {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DEV_IS_NOT_OPENED,device, kal_get_active_module_id());
+ return STATUS_NOT_OPENED;
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ /* Send SIO_CMD_CLOSE command */
+ data.u4OwenrId = tty_mgmt_info[device].owner_id;
+ status = DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*)&data);
+
+ return status;
+}
+
+static DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+_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)
+{
+ DCL_STATUS result;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ tty_mgmt_info[device].rx_cb = rx_cb;
+ tty_mgmt_info[device].tx_done_cb = tx_done_cb;
+ tty_mgmt_info[device].drv_state_change_cb = drv_state_change_cb;
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if(!tty_mgmt_info[device].active && tx_done_cb)
+ {
+ tty_mgmt_info[device].early_tx_done_cb_req = 1;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_OK;
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ /* Send TTY_CMD_TX_INFO command */
+ if (tx_done_cb)
+ {
+ UART_CTRL_NEED_TX_DONE_CB_T ur_ctrl_need_tx_done_cb;
+
+ ur_ctrl_need_tx_done_cb.u4OwnerId = tty_mgmt_info[device].owner_id;
+ ur_ctrl_need_tx_done_cb.needTxDoneCb = 1;
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, TTY_CMD_NEED_TX_DONE_CB, (DCL_CTRL_DATA_T*)&ur_ctrl_need_tx_done_cb);
+ if (result != STATUS_OK) {
+ /* command failed */
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ERR_NEED_TX_DONE_CB,device, result, kal_get_active_module_id());
+ return result;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_UpModuleRegisterCb(
+ DCL_HANDLE handle,
+ tty_rx_cb rx_cb,
+ tty_txdone_cb tx_done_cb,
+ tty_drv_state_change_cb drv_state_change_cb)
+{
+ DCL_DEV device;
+ DCL_STATUS result;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+
+ /*20130313:remove driver active check, because user may do initial flow before driver in active state*/
+ TTY_CHECK_DEV_VALID(device);
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_REG_CB,device, kal_get_active_module_id());
+
+ /* Check flag & callback correctness */
+ if (!TTY_IS_CONVENTIONAL_RX(device) && !rx_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_NEW_RX_CB_IS_NULL,device, kal_get_active_module_id());
+ VAR_MSG_ASSERT(use_new_rx_but_not_register_cb);
+ }
+ if (TTY_IS_CONVENTIONAL_RX(device)) {
+ ASSERT(!rx_cb);
+
+ /* Buffer port use different internal callback*/
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ rx_cb = _tty_rx_buff_cb;
+ }
+ else
+ {
+ rx_cb = _tty_rx_cb;
+ }
+ }
+ if (TTY_IS_CONVENTIONAL_TX(device)) {
+ ASSERT(!tx_done_cb);
+
+ /* Buffer port use different internal callback*/
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ tx_done_cb = _tty_tx_buff_done_cb;
+ }
+ else
+ {
+ tx_done_cb = _tty_tx_done_cb;
+ }
+ }
+
+ if (TTY_IS_CONVENTIONAL_RX(device) && TTY_IS_CONVENTIONAL_TX(device)) {
+ ASSERT(!drv_state_change_cb);
+ } else {
+ ASSERT(drv_state_change_cb);
+ }
+
+ result = _DclSerialPort_UpModuleRegisterCb(device, rx_cb, tx_done_cb, drv_state_change_cb);
+ if (result != STATUS_OK) {
+ /* command failed */
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_REG_CB_FAIL,device, result, kal_get_active_module_id());
+ return result;
+ }
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_UpModuleTransmit(
+ DCL_HANDLE handle,
+ tty_io_request_t *ior)
+{
+ DCL_DEV device;
+ UART_CTRL_PUT_BYTES_IOR_T ur_ctrl_putbytes_ior;
+ DCL_STATUS result;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+ DBG_ASSERT(ior);
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+
+
+
+ if (!TTY_CHK_DEV_OPEN(device)){
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_NOT_OPENED;
+ }
+
+ ur_ctrl_putbytes_ior.u4OwnerId = tty_mgmt_info[device].owner_id;
+ ur_ctrl_putbytes_ior.putIor = (void*)ior;
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, TTY_CMD_PUT_BYTES_IOR, (DCL_CTRL_DATA_T*)&ur_ctrl_putbytes_ior);
+
+#ifdef __TTY_DBG_MODE__
+ _tty_gpd_zero_len_check(ior);
+#endif
+
+ return result;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_UpModuleTransmitLight(
+ DCL_HANDLE handle,
+ tty_io_request_t *ior)
+{
+ DCL_DEV device;
+ UART_CTRL_PUT_BYTES_IOR_T ur_ctrl_putbytes_ior;
+ DCL_STATUS result;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+ DBG_ASSERT(ior);
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+
+ ur_ctrl_putbytes_ior.u4OwnerId = tty_mgmt_info[device].owner_id;
+ ur_ctrl_putbytes_ior.putIor = (void*)ior;
+
+#ifdef __TTY_DBG_MODE__
+ _tty_gpd_zero_len_check(ior);
+#endif
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, TTY_CMD_PUT_BYTES_IOR_LIGHT, (DCL_CTRL_DATA_T*)&ur_ctrl_putbytes_ior);
+ return result;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_UpModuleAssignRxIor(
+ DCL_HANDLE handle,
+ tty_io_request_t *rx_ior)
+{
+ DCL_DEV device;
+ UART_CTRL_ASSIGN_RX_IOR_T uartCtlAsnRxIor;
+ DCL_STATUS result;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+ DBG_ASSERT(rx_ior);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ASSIGN_RX_IOR,device, kal_get_active_module_id());
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+
+ uartCtlAsnRxIor.u4OwnerId = tty_mgmt_info[device].owner_id;
+ uartCtlAsnRxIor.ior = (void*)rx_ior;
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, TTY_CMD_ASSIGN_RX_IOR, (DCL_CTRL_DATA_T*)&uartCtlAsnRxIor);
+
+ return result;
+}
+
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_DrvRegisterCb(
+ DCL_HANDLE handle,
+ Seriport_HANDLER_T* seriport_handler)
+{
+ DCL_DEV device;
+ UART_CTRL_OPEN_T uCtlOpen;
+ UART_CTRL_NEED_TX_DONE_CB_T ur_ctrl_need_tx_done_cb;
+ DCL_STATUS status;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DRV_REGISTER_CB,device, seriport_handler, kal_get_active_module_id());
+
+ if (!seriport_handler->SeriportHandlerCb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ ASSERT(seriport_handler->SeriportHandlerCb);
+ return STATUS_INVALID_ARGUMENT;
+ }
+
+ if (tty_mgmt_info[device].active) {
+ return STATUS_ALREADY_OPENED;
+ }
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ tty_mgmt_info[device].sp_handler_cb = seriport_handler->SeriportHandlerCb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ tty_mgmt_info[device].dev_type = seriport_handler->DevType;
+ _tty_update_buff_info_from_port(device, seriport_handler->DevType);
+
+ //Must to put at the end of function.
+ tty_mgmt_info[device].active = 1;
+
+ //------------------------------------------------------------------//
+ //check if user has opened the port before driver register callback //
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if(tty_mgmt_info[device].early_open_req)
+ {
+ tty_mgmt_info[device].early_open_req = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ uCtlOpen.u4OwenrId = tty_mgmt_info[device].pending_owner;
+ //temp for uart
+ //DclSerialPort_Control(handle,SIO_CMD_INIT,(DCL_CTRL_DATA_T*)&uCtlOpen);
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*)&uCtlOpen);
+ if (STATUS_OK != status) {
+ //ASSERT(0);
+ return status;
+ }
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if(tty_mgmt_info[device].early_tx_done_cb_req)
+ {
+ tty_mgmt_info[device].early_tx_done_cb_req = 0;
+ ur_ctrl_need_tx_done_cb.u4OwnerId = tty_mgmt_info[device].owner_id;
+ ur_ctrl_need_tx_done_cb.needTxDoneCb = 1;
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ status = sp_handler_cb(device, TTY_CMD_NEED_TX_DONE_CB, (DCL_CTRL_DATA_T*)&ur_ctrl_need_tx_done_cb);
+ if (status != STATUS_OK) {
+ /* command failed */
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ERR_NEED_TX_DONE_CB,device, status, kal_get_active_module_id());
+ return status;
+ }
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ return STATUS_OK;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_DrvDeRegisterCb(
+ DCL_HANDLE handle)
+{
+ DCL_DEV device;
+ //TTY_THREAD_DECLARE(thread_lock);
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DRV_DEREGISTER_CB,device, kal_get_active_module_id());
+
+ if(tty_mgmt_info[device].drv_state == DRV_ST_ATTACHED)
+ {
+ return STATUS_INVALID_OPERATION;
+ }
+
+ if (!tty_mgmt_info[device].active) {
+ return STATUS_INVALID_OPERATION;
+ }
+
+ /*Enlarge spinlock in order to protect the handler pointer */
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ /* Clear flags */
+ tty_mgmt_info[device].active = 0;
+ tty_mgmt_info[device].sp_handler_cb = NULL;
+
+ /***** Add for USB CV test *****/
+ /* Check device state */
+ /* Here we slient clear opened flag if the device is opened
+ After driver registered the device, tty will re-open the device
+ */
+ if(tty_mgmt_info[device].opened)
+ {
+
+ tty_mgmt_info[device].opened = 0;
+ tty_mgmt_info[device].early_open_req = 1;
+ tty_mgmt_info[device].pending_owner = tty_mgmt_info[device].owner_id;
+ if(tty_mgmt_info[device].tx_done_cb)
+ {
+ tty_mgmt_info[device].early_tx_done_cb_req = 1;
+ }
+ }
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ /***** Add for USB CV test *****/
+
+ return STATUS_OK;
+}
+
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_DrvAttach(
+ DCL_HANDLE handle)
+{
+ DCL_DEV device;
+ DCL_STATUS result;
+ UART_CTRL_GET_CHUNK_SIZE_T ur_ctrl_get_chunk_size;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+ TTY_CHECK_DEV_IS_READY(device);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DRV_ATTACH,device, kal_get_active_module_id());
+
+ tty_mgmt_info[device].drv_state = DRV_ST_ATTACHED;
+
+ if(TTY_IS_BUFF_PORT(device))
+ {
+ /* Set default value align with USB, although buffer port does not reference this value*/
+ tty_mgmt_info[device].chunk_size = 512;
+ goto _RETURN;
+ }
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_chunk_size);
+
+ if (result != STATUS_OK) {
+ /* command failed */
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ERR_GET_CHUNK_SIZE,device, result, kal_get_active_module_id());
+ ASSERT(0);
+ return result;
+ }
+
+ tty_mgmt_info[device].chunk_size = (DCL_UINT16)ur_ctrl_get_chunk_size.chunkSize;
+ //set rx allow len
+ _cal_and_set_rx_allow_len(device, tty_mgmt_info[device].chunk_size);
+
+ if (tty_mgmt_info[device].opened)
+ {
+ /* Notify upper layer the driver status is attached */
+ if (tty_mgmt_info[device].drv_state_change_cb) {
+ tty_mgmt_info[device].drv_state_change_cb(handle, DRV_ST_ATTACHED);
+ }
+
+ if (TTY_IS_CONVENTIONAL_RX(device)) {
+ _tty_conv_assign_rx_gpd_to_drv(device);
+ }
+
+ if (TTY_IS_CONVENTIONAL_TX(device))
+ {
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if(tty_mgmt_info[device].tx_not_rdy == 1)
+ {
+ tty_mgmt_info[device].tx_not_rdy = 0;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ _tty_send_ilm(device, MOD_TTY, MSG_ID_UART_READY_TO_WRITE_IND);
+ }
+ else
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+ }
+
+_RETURN:
+ return STATUS_OK;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_DrvDetach(
+ DCL_HANDLE handle)
+{
+ DCL_DEV device;
+ DCL_STATUS result;
+ UART_CTRL_CLR_BUFFER_T ur_ctrl_clr_buf;
+ SeriPort_HANLDER_CB sp_handler_cb;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+ TTY_CHECK_DEV_IS_READY(device);
+
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DRV_DETACH,device, kal_get_active_module_id());
+
+ tty_mgmt_info[device].drv_state = DRV_ST_DETACHED;
+
+ /* Notify upper layer the driver status is detached */
+ if (tty_mgmt_info[device].opened)
+ {
+ if (tty_mgmt_info[device].drv_state_change_cb) {
+ tty_mgmt_info[device].drv_state_change_cb(handle, DRV_ST_DETACHED);
+ }
+
+ /* Send clear tx/rx buffer command */
+ ur_ctrl_clr_buf.u4OwenrId = tty_mgmt_info[device].owner_id;
+
+ /* Buffer port also needs to do flush when detached */
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if ((tty_mgmt_info[device].tx_gpd_num_used != 0 && TTY_IS_CONVENTIONAL_TX(device))
+ || TTY_IS_BUFF_PORT(device) )
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ /* Only GPD driver needs to toggle this flag*/
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ tty_mgmt_info[device].flush_tx = 1;
+ }
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, SIO_CMD_CLR_TX_BUF, (DCL_CTRL_DATA_T*)&ur_ctrl_clr_buf);
+ if (result != STATUS_OK) {
+ /* command failed */
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ERR_CLR_TX_BUF,device, result, kal_get_active_module_id());
+ return result;
+ }
+ } else {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+
+ /* Buffer port also needs to do flush when detached */
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if ((tty_mgmt_info[device].rx_gpd_num_assigned != 0 && TTY_IS_CONVENTIONAL_RX(device))
+ || TTY_IS_BUFF_PORT(device) )
+ {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+
+ /* Only GPD driver needs to toggle this flag*/
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ tty_mgmt_info[device].flush_rx = 1;
+ }
+ TTY_SPIN_LOCK(tty_mgmt_info[device].spinLock);
+ if (!tty_mgmt_info[device].sp_handler_cb) {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+ MD_TRC(TTY_TR_DRV_CB_IS_NULL,device, kal_get_active_module_id());
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ return STATUS_FAIL;
+ }
+ sp_handler_cb = tty_mgmt_info[device].sp_handler_cb;
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ result = sp_handler_cb(device, SIO_CMD_CLR_RX_BUF, (DCL_CTRL_DATA_T*)&ur_ctrl_clr_buf);
+ if (result != STATUS_OK) {
+ /* command failed */
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_CMD_ERR_CLR_RX_BUF,device, result, kal_get_active_module_id());
+ return result;
+ }
+ } else {
+ TTY_SPIN_UNLOCK(tty_mgmt_info[device].spinLock);
+ }
+ }
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_DrvRx(
+ DCL_HANDLE handle,
+ module_type source_id,
+ void *rx_ior)
+{
+ DCL_DEV device;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+
+ if (tty_mgmt_info[device].opened && tty_mgmt_info[device].rx_cb) {
+ tty_mgmt_info[device].rx_cb(handle, source_id, (tty_io_request_t*)rx_ior);
+ } else {
+ if(INT_QueryExceptionStatus() == KAL_FALSE)
+MD_TRC(TTY_TR_DRV_RX_NG,device, tty_mgmt_info[device].opened, tty_mgmt_info[device].rx_cb);
+ /* Free ior when the device is closed */
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ _tty_free_ior(rx_ior);
+ }
+ }
+ return STATUS_OK;
+}
+
+DCL_STATUS DEVDRV_LS_DRAM_EX_ROCODE
+DclSerialPort_DrvTxDone(
+ DCL_HANDLE handle,
+ module_type source_id,
+ void *tx_ior)
+{
+ DCL_DEV device;
+
+ TTY_CHECK_HANDLE(handle);
+ device = DCL_UART_GET_DEV(handle);
+
+ if (tty_mgmt_info[device].opened && tty_mgmt_info[device].tx_done_cb) {
+ tty_mgmt_info[device].tx_done_cb(handle, source_id, (tty_io_request_t*)tx_ior);
+ } else {
+ /* Free ior when the device is closed */
+ if(!TTY_IS_BUFF_PORT(device))
+ {
+ _tty_free_ior(tx_ior);
+ }
+ }
+
+ return STATUS_OK;
+}
+
+