[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;
+}
+
+
diff --git a/mcu/driver/tty/src/excp_tty_ut.c b/mcu/driver/tty/src/excp_tty_ut.c
new file mode 100644
index 0000000..0dbaa4c
--- /dev/null
+++ b/mcu/driver/tty/src/excp_tty_ut.c
@@ -0,0 +1,767 @@
+/*****************************************************************************
+* 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:
+ * ---------
+ * excp_tty_ut.c
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * TTY Core unit test file in exception mode - it needs Host Test Program to run test.
+ * It works with enabling compile flag __EXCEPT_TTY_UT__.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 03 11 2015 i-wei.tsai
+ * [MOLY00097392] [UMOLY] [TTY] Timer tick macro modification
+ * .
+ *
+ * 09 13 2013 i-wei.tsai
+ * [MOLY00037205] [CCCI Exception] CCCI exception mode 1st check-in.
+ * CCCI Exception IT
+ *
+ * 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
+ *
+ * 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
+ *
+ * 11 12 2012 haoren.kao
+ * [MOLY00005322] TATAKA merge to MOLY
+ * * Shorten the busy loop time from about 5 ms to 10 us in order to avoid host test program SetCommState timeout.
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "dcl.h"
+#include "hmu.h"
+#include "kal_debug.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+#include "syscomp_config.h"
+
+#include "devdrv_ls.h"
+#include "drv_msgid.h"
+#include "md_drv_sap.h"
+#include "kal_public_defs.h"
+
+
+//#define __EXPT_CCCI_TTY_IT__
+
+#ifdef __EXPT_CCCI_TTY_IT__
+#define EXCEPTION_TEST_PORT uart_port_dhl_sp_expt
+//#define EXCEPTION_TEST_PORT uart_port_dhl_ctrl_sp_expt
+#else
+#define EXCEPTION_TEST_PORT uart_port_usb2
+#endif
+#define TX_BUF_NUM 500
+#define RX_BUF_NUM 499+1/*for tailed gpd*/
+#define TEST_LB_PKT_NUM 200
+#define EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT (QBM_TTY_XXX_DATA_LEN)
+
+#ifdef __EXPT_CCCI_TTY_IT__
+#define EXPT_TTY_TX_GPD_TYPE QBM_TYPE_CCCI_COMM
+#define EXPT_TTY_RX_GPD_TYPE QBM_TYPE_CCCI_COMM
+#else
+#define EXPT_TTY_TX_GPD_TYPE QBM_TYPE_TTY_INT
+#define EXPT_TTY_RX_GPD_TYPE QBM_TYPE_TTY_INT
+#endif
+
+#define EXCP_HALT() while(1)
+
+#ifdef __EXPT_CCCI_TTY_IT__
+static DCL_UINT8 bm_buf_excp_tx[QBM_QUEUE_GET_MEM_SIZE(QBM_TYPE_CCCI_COMM, TX_BUF_NUM)];
+static DCL_UINT8 bm_buf_excp_rx[QBM_QUEUE_GET_MEM_SIZE(QBM_TYPE_CCCI_COMM, RX_BUF_NUM)];
+#else
+static DCL_UINT8 bm_buf_excp_tx[QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TTY_INT, TX_BUF_NUM)];
+static DCL_UINT8 bm_buf_excp_rx[QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TTY_INT, RX_BUF_NUM)];
+#endif
+
+static void *excp_tgpd_head = NULL;
+static void *excp_tgpd_tail = NULL;
+static void *excp_rgpd_head = NULL;
+static void *excp_rgpd_tail = NULL;
+
+static void *excp_tgpd_free_head = NULL;
+static void *excp_tgpd_free_tail = NULL;
+static void *excp_rgpd_free_head = NULL;
+static void *excp_rgpd_free_tail = NULL;
+
+typedef enum {
+ GPD_TYPE_TX,
+ GPD_TYPE_RX,
+} GPD_TYPE;
+
+
+#define BUSY_LOOP(_n) do{volatile int i; volatile int j=0; for (i=0; i<_n; i++) {j+=i*2;}}while(0)
+
+extern void dbg_print(char *fmt,...);
+
+#define TTYUT_DBG_PRINT(...)
+
+
+/*for debug only (CCCI)*/
+static volatile kal_uint32 DBG_LOCK = 1;
+
+#define BUSY_STOP() \
+ do{ \
+ while(1){ \
+ if(DBG_LOCK == 0) break; \
+ } \
+ }while(0) \
+
+void _excp_qbm_init(void)
+{
+ bm_queue_config conf;
+ kal_uint32 size;
+ kal_uint8 *pool;
+
+ qbm_init();
+
+ /* Tx GPD queue init */
+ qbm_init_q_config(&conf);
+ size = QBM_QUEUE_GET_MEM_SIZE(EXPT_TTY_TX_GPD_TYPE, TX_BUF_NUM);
+ pool = &bm_buf_excp_tx[0];
+ conf.buff_num = TX_BUF_NUM;
+ conf.p_mem_pool_str = pool;
+ conf.p_mem_pool_end = pool + size;
+ qbm_init_queue_non_free(EXPT_TTY_TX_GPD_TYPE, &conf, &excp_tgpd_head, &excp_tgpd_tail);
+
+ excp_tgpd_free_head = excp_tgpd_head;
+ excp_tgpd_free_tail = excp_tgpd_tail;
+
+ /* Rx GPD queue init */
+ qbm_init_q_config(&conf);
+ size = QBM_QUEUE_GET_MEM_SIZE(EXPT_TTY_RX_GPD_TYPE, RX_BUF_NUM);
+ pool = &bm_buf_excp_rx[0];
+ conf.buff_num = RX_BUF_NUM;
+ conf.p_mem_pool_str = pool;
+ conf.p_mem_pool_end = pool + size;
+ qbm_init_queue_non_free(EXPT_TTY_RX_GPD_TYPE, &conf, &excp_rgpd_head, &excp_rgpd_tail);
+
+ excp_rgpd_free_head = excp_rgpd_head;
+ excp_rgpd_free_tail = excp_rgpd_tail;
+
+}
+
+/**
+ * @ return gpd number allocated successfully
+ */
+static DCL_UINT16 _excp_alloc_gpd(
+ GPD_TYPE type,
+ kal_uint32 buff_num,
+ void **pp_head,
+ void **pp_tail
+ )
+{
+ kal_uint16 alloc_num = 0;
+ void *free_head;
+ void *free_tail;
+ void *cur;
+ void *pre = NULL;
+
+ free_head = (type == GPD_TYPE_TX) ? excp_tgpd_free_head : excp_rgpd_free_head;
+ free_tail = (type == GPD_TYPE_TX) ? excp_tgpd_free_tail : excp_rgpd_free_tail;
+
+ cur = free_head;
+
+ while (cur != NULL && buff_num > 0)
+ {
+ alloc_num ++;
+ buff_num --;
+ pre = cur;
+ cur = QBM_DES_GET_NEXT(cur);
+ }
+
+ *pp_head = free_head;
+ *pp_tail = pre;
+
+ if (type == GPD_TYPE_TX) {
+ excp_tgpd_free_head = cur;
+ } else {
+ excp_rgpd_free_head = cur;
+ }
+
+ return alloc_num;
+}
+
+static void _excp_free_gpd(
+ GPD_TYPE type,
+ void *p_head,
+ void *p_tail
+ )
+{
+ void *free_head;
+ void *free_tail;
+
+ free_head = (type == GPD_TYPE_TX) ? excp_tgpd_free_head : excp_rgpd_free_head;
+ free_tail = (type == GPD_TYPE_TX) ? excp_tgpd_free_tail : excp_rgpd_free_tail;
+
+ if (free_head == NULL) {
+ free_head = p_head;
+ } else {
+ QBM_DES_SET_NEXT(free_tail, p_head);
+ }
+ free_tail = p_tail;
+
+ if (type == GPD_TYPE_TX) {
+ excp_tgpd_free_head = free_head;
+ excp_tgpd_free_tail = free_tail;
+ } else {
+ excp_rgpd_free_head = free_head;
+ excp_rgpd_free_tail = free_tail;
+ }
+}
+
+
+static kal_uint32 _excp_rst_gpd_list(kal_uint32 type,qbm_gpd* first_gpd, qbm_gpd* last_gpd)
+{
+ qbm_gpd* current_gpd = NULL;
+ qbm_gpd* next_gpd = NULL;
+ kal_uint32 num_gpd = 0;
+
+ ASSERT(first_gpd && last_gpd);
+ current_gpd = first_gpd;
+
+ do {
+ next_gpd = QBM_DES_GET_NEXT(current_gpd);
+ qbm_reset_pd(type, (void*)current_gpd);
+ qbm_cal_set_checksum((kal_uint8 *)current_gpd);
+ QBM_CACHE_FLUSH(current_gpd, sizeof(qbm_gpd));
+ num_gpd ++;
+ if ( current_gpd == last_gpd )
+ {
+ break;
+ }
+ current_gpd = next_gpd;
+ } while ( current_gpd != NULL );
+
+ return num_gpd;
+}
+
+static void* _excp_get_qbm_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 _excp_set_qbm_datalen(void* gpd, kal_uint32 data_len)
+{
+ void* bd = NULL;
+
+ ASSERT(NULL != gpd);
+ /*QBM_TYPE_CCCI_COMM specific function*/
+ ASSERT(QBM_TYPE_CCCI_COMM == QBM_GET_TYPE(gpd));
+ /*Must have BD*/
+ ASSERT(0 != QBM_DES_GET_BDP(gpd));
+
+ 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 void excp_loopback_test(DCL_HANDLE handle, kal_bool is_before_reset, kal_uint32 num)
+{
+ unsigned char *tx_buf_ptr;
+ unsigned char *rx_buf_ptr;
+ kal_char trigger_string[50] = {0};
+ kal_uint32 i;
+ kal_uint32 total_rx_num;
+ TTY_CTRL_EXCP_ASSIGN_RX_GPD_T ttyCtlAsnRxGpd;
+ TTY_CTRL_EXCP_GET_RX_GPD_T ttyCtlGetRxGpd;
+ TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd;
+ TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo;
+ TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt;
+ UART_CTRL_GET_CHUNK_SIZE_T ur_ctrl_get_chunk_size;
+
+ /*
+ Wait a period of time to let Host have enought time to open com port
+ */
+ for (i = 0; i < 500000; i ++)
+ {
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); }
+ BUSY_LOOP(100);
+ }
+
+ /*
+ Send a packet to trigger Host start loopback test
+ #format: "exception num" (ex. "exception 50")
+ */
+ _excp_alloc_gpd(GPD_TYPE_TX, 1, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(ttyCtlTxGpd.first_gpd);
+ kal_mem_set(trigger_string, 0, sizeof(trigger_string));
+ sprintf(trigger_string, "exception %d", num);
+ kal_mem_cpy(tx_buf_ptr, trigger_string, strlen(trigger_string)+1);
+
+ // Set Tx GPD
+ QBM_CACHE_FLUSH(tx_buf_ptr, strlen(trigger_string)+1);
+ QBM_DES_SET_DATALEN(ttyCtlTxGpd.first_gpd, strlen(trigger_string)+1);
+ QBM_DES_SET_HWO(ttyCtlTxGpd.first_gpd);
+ qbm_cal_set_checksum(ttyCtlTxGpd.first_gpd);
+ QBM_CACHE_FLUSH(ttyCtlTxGpd.first_gpd, sizeof(qbm_gpd));
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd);
+ // Polling Tx Done Info until all Tx GPD are sent and retrieved
+ do {
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); }
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo);
+
+ if (ttyCtlTxDoneInfo.num > 0) {
+ _excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd);
+ break;
+ }
+ } while (1);
+
+
+ /* Assign Rx GPD to driver */
+ _excp_alloc_gpd(GPD_TYPE_RX, 2/*1 for tailed GPD*/, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd);
+ DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_chunk_size);
+ // first gpd
+ if(ur_ctrl_get_chunk_size.chunkSize == 1)
+ {
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT);
+ }
+ else
+ {
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, ur_ctrl_get_chunk_size.chunkSize);
+ }
+ QBM_DES_SET_HWO(ttyCtlAsnRxGpd.first_gpd);
+ qbm_cal_set_checksum(ttyCtlAsnRxGpd.first_gpd);
+ QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.first_gpd, sizeof(qbm_gpd));
+ // last gpd
+ if(ur_ctrl_get_chunk_size.chunkSize == 1)
+ {
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT);
+ }
+ else
+ {
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.last_gpd, ur_ctrl_get_chunk_size.chunkSize);
+ }
+ QBM_DES_SET_HWO(ttyCtlAsnRxGpd.last_gpd);
+ qbm_cal_set_checksum(ttyCtlAsnRxGpd.last_gpd);
+ QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.last_gpd, sizeof(qbm_gpd));
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd);
+
+ total_rx_num = 0;
+ while (total_rx_num < num) // Polling Received Rx GPD and transmit the data to Host
+ {
+ void *cur_tx;
+ void *cur_rx;
+ kal_uint16 rx_len;
+ kal_uint16 gpd_num;
+
+ /* Get Rx GPD */
+ do {
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);}
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_GET_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlGetRxGpd);
+ } while (ttyCtlGetRxGpd.num == 0);
+ total_rx_num += ttyCtlGetRxGpd.num;
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] receive %d gpds, has received total %d gpds\r\n", ttyCtlGetRxGpd.num, total_rx_num);
+
+ /* Allocate Tx GPD and re-transmit the rx data to Host */
+ gpd_num = ttyCtlGetRxGpd.num;
+ _excp_alloc_gpd(GPD_TYPE_TX, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+
+ cur_rx = ttyCtlGetRxGpd.first_gpd;
+ cur_tx = ttyCtlTxGpd.first_gpd;
+
+ for (i = 0; i < ttyCtlGetRxGpd.num; i ++)
+ {
+ rx_buf_ptr = QBM_DES_GET_DATAPTR(cur_rx);
+ rx_len = QBM_DES_GET_DATALEN(cur_rx);
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(cur_tx);
+
+ QBM_CACHE_INVALID(rx_buf_ptr, rx_len);
+ kal_mem_cpy(tx_buf_ptr, rx_buf_ptr, rx_len);
+ QBM_CACHE_FLUSH(tx_buf_ptr, rx_len);
+
+ /* Set Tx GPD */
+ QBM_DES_SET_DATALEN(cur_tx, rx_len);
+ QBM_DES_SET_HWO(cur_tx);
+ qbm_cal_set_checksum(cur_tx);
+ QBM_CACHE_FLUSH(cur_tx, sizeof(qbm_gpd));
+
+ /* Reset Rx GPD */
+ QBM_DES_SET_ALLOW_LEN(cur_rx, ur_ctrl_get_chunk_size.chunkSize);
+ QBM_DES_SET_HWO(cur_rx);
+ qbm_cal_set_checksum(cur_rx);
+ QBM_CACHE_FLUSH(cur_rx, sizeof(qbm_gpd));
+
+ cur_tx = QBM_DES_GET_NEXT(cur_tx);
+ cur_rx = QBM_DES_GET_NEXT(cur_rx);
+ }
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd);
+
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); }
+
+ /* Re-assign Rx GPD to driver */
+ ttyCtlAsnRxGpd.first_gpd = ttyCtlGetRxGpd.first_gpd;
+ ttyCtlAsnRxGpd.last_gpd = ttyCtlGetRxGpd.last_gpd;
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd);
+
+ /* Polling Tx Done Info until all Tx GPD are sent and retrieved */
+ do {
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);}
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo);
+
+ if (ttyCtlTxDoneInfo.num > 0) {
+ _excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd);
+ gpd_num -= ttyCtlTxDoneInfo.num;
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] has sent %d gpds\r\n", ttyCtlTxDoneInfo.num);
+ }
+ } while (gpd_num > 0);
+
+ /* Check HIF state */
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt);
+ if (ttyCtlHifSt.hif_state != HIF_STATE_NORMAL) {
+ EXCP_HALT();
+ }
+
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); }
+ }
+
+}
+
+static void excp_ccci_loopback_test(DCL_HANDLE handle, kal_uint32 num)
+{
+ unsigned char *tx_buf_ptr;
+ unsigned char *rx_buf_ptr;
+ kal_char trigger_string[50] = {0};
+ kal_uint32 i;
+ kal_uint32 total_rx_num;
+ TTY_CTRL_EXCP_ASSIGN_RX_GPD_T ttyCtlAsnRxGpd;
+ TTY_CTRL_EXCP_GET_RX_GPD_T ttyCtlGetRxGpd;
+ TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd;
+ TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo;
+ TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt;
+ UART_CTRL_GET_MTU_SIZE_T ur_ctrl_get_mtu_size;
+ kal_uint32 tmp_num;
+
+ /*For debug test only*/
+ //BUSY_STOP();
+
+ /* Assign Rx GPD to driver */
+ // TODO:Need to revise APIs. Because in exception mode(espicailly in HISR), some QBM APIs shall not be used. (ex:enhance mutex)
+ //tmp_num = _excp_alloc_gpd(GPD_TYPE_RX, 2/*1 for tailed GPD*/, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd);
+ tmp_num = qbmt_alloc_q_no_tail(EXPT_TTY_RX_GPD_TYPE, 2, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd);
+ if(tmp_num!= 2) while(1);
+ DclSerialPort_Control(handle, TTY_CMD_GET_MTU_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_mtu_size);
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, ur_ctrl_get_mtu_size.ulmtu_sz);
+ QBM_DES_SET_HWO(ttyCtlAsnRxGpd.first_gpd);
+ qbm_cal_set_checksum(ttyCtlAsnRxGpd.first_gpd);
+ QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.first_gpd, sizeof(qbm_gpd));
+ // last gpd
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.last_gpd, ur_ctrl_get_mtu_size.ulmtu_sz);
+ QBM_DES_SET_HWO(ttyCtlAsnRxGpd.last_gpd);
+ qbm_cal_set_checksum(ttyCtlAsnRxGpd.last_gpd);
+ QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.last_gpd, sizeof(qbm_gpd));
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd);
+
+ total_rx_num = 0;
+ //while (total_rx_num < num) // Polling Received Rx GPD and transmit the data to Host
+ while(1)
+ {
+ void *cur_tx;
+ void *cur_rx;
+ kal_uint16 rx_len;
+ kal_uint16 gpd_num;
+
+ /* Get Rx GPD */
+ do {
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_GET_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlGetRxGpd);
+ } while (ttyCtlGetRxGpd.num == 0);
+ total_rx_num += ttyCtlGetRxGpd.num;
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] receive %d gpds, has received total %d gpds\r\n", ttyCtlGetRxGpd.num, total_rx_num);
+
+ /* Allocate Tx GPD and re-transmit the rx data to Host */
+ gpd_num = ttyCtlGetRxGpd.num;
+ //_excp_alloc_gpd(GPD_TYPE_TX, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+ tmp_num = qbmt_alloc_q_no_tail(EXPT_TTY_TX_GPD_TYPE, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+ if(tmp_num!= gpd_num) while(1);
+
+ cur_rx = ttyCtlGetRxGpd.first_gpd;
+ cur_tx = ttyCtlTxGpd.first_gpd;
+
+ for (i = 0; i < ttyCtlGetRxGpd.num; i ++)
+ {
+ rx_buf_ptr = _excp_get_qbm_dataptr(cur_rx);
+ rx_len = QBM_DES_GET_DATALEN(cur_rx);
+ tx_buf_ptr = _excp_get_qbm_dataptr(cur_tx);
+
+ QBM_CACHE_INVALID(rx_buf_ptr, rx_len);
+ kal_mem_cpy(tx_buf_ptr, rx_buf_ptr, rx_len);
+ QBM_CACHE_FLUSH(tx_buf_ptr, rx_len);
+
+ /* Set Tx GPD */
+ _excp_set_qbm_datalen(cur_tx, rx_len);
+ QBM_DES_SET_HWO(cur_tx);
+ qbm_cal_set_checksum(cur_tx);
+ QBM_CACHE_FLUSH(cur_tx, sizeof(qbm_gpd));
+
+ /* Reset Rx GPD */
+ _excp_rst_gpd_list(EXPT_TTY_RX_GPD_TYPE,cur_rx,cur_rx);
+ QBM_DES_SET_ALLOW_LEN(cur_rx, ur_ctrl_get_mtu_size.ulmtu_sz);
+ //QBM_DES_SET_HWO(cur_rx);
+ qbm_cal_set_checksum(cur_rx);
+ QBM_CACHE_FLUSH(cur_rx, sizeof(qbm_gpd));
+
+ cur_tx = QBM_DES_GET_NEXT(cur_tx);
+ cur_rx = QBM_DES_GET_NEXT(cur_rx);
+ }
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd);
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+
+ /*Re-assign Rx GPD to driver */
+ ttyCtlAsnRxGpd.first_gpd = ttyCtlGetRxGpd.first_gpd;
+ ttyCtlAsnRxGpd.last_gpd = ttyCtlGetRxGpd.last_gpd;
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd);
+
+ /* Polling Tx Done Info until all Tx GPD are sent and retrieved */
+ do {
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+
+ /*Debug only to check sdio interrupt status*/
+ //if((*SDIO_IRQ_DL_FTE0SR) & SDIO_INT_MASK) while(1);
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo);
+
+ if (ttyCtlTxDoneInfo.num > 0) {
+ //_excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd);
+ qbmt_dest_q(ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd);
+ gpd_num -= ttyCtlTxDoneInfo.num;
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] has sent %d gpds\r\n", ttyCtlTxDoneInfo.num);
+ }
+ } while (gpd_num > 0);
+
+ /* Check HIF state */
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt);
+ if (ttyCtlHifSt.hif_state != HIF_STATE_NORMAL) {
+ EXCP_HALT();
+ }
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+ }
+
+}
+
+DCL_STATUS excp_ttyut(void)
+{
+ DCL_HANDLE handle;
+
+ //for debug only
+ //BUSY_STOP();
+
+ hmu_except_init();
+
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut start\r\n");
+
+ handle = DclSerialPort_Open(EXCEPTION_TEST_PORT, 0);
+
+ /* Init QBM for exception */
+ _excp_qbm_init();
+
+ /* Test Case 1: Loopback before RESET */
+ /* HIF init and Clear channel */
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_INIT, NULL);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_CLEAR_CHANNEL, NULL);
+
+#ifdef __EXPT_CCCI_TTY_IT__
+ excp_ccci_loopback_test(handle, TEST_LB_PKT_NUM);
+#else
+ //BUSY_LOOP(60000000);
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 1\r\n");
+ {
+ excp_loopback_test(handle, KAL_TRUE, TEST_LB_PKT_NUM);
+ }
+
+ /* Test Case 2: RESET */
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 2\r\n");
+ {
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_RESET, NULL);
+ }
+
+ /* Test Case 3: Loopback after RESET */
+ /* HIF init */
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_INIT, NULL);
+ //BUSY_LOOP(60000000);
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 3\r\n");
+ {
+ excp_loopback_test(handle, KAL_FALSE, TEST_LB_PKT_NUM);
+ }
+
+ /* Test Case 4: HIF_STATE return TXERROR */
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 4\r\n");
+ {
+ TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd;
+ TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo;
+ TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt;
+ kal_uint16 gpd_num;
+ kal_uint16 count;
+
+ BUSY_LOOP(50000);
+ while (1)
+ {
+ gpd_num = _excp_alloc_gpd(GPD_TYPE_TX, 1, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] allocate %d gpd\r\n", gpd_num);
+ if (gpd_num == 0) {
+ break;
+ }
+ QBM_DES_SET_DATALEN(ttyCtlTxGpd.first_gpd, 100);
+ QBM_DES_SET_HWO(ttyCtlTxGpd.first_gpd);
+ qbm_cal_set_checksum(ttyCtlTxGpd.first_gpd);
+ QBM_CACHE_FLUSH(ttyCtlTxGpd.first_gpd, sizeof(qbm_gpd));
+
+ BUSY_LOOP(300000);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+ }
+
+ count = 10000;
+ while (count-- > 0)
+ {
+ BUSY_LOOP(30000);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo);
+ }
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt);
+ if (ttyCtlHifSt.hif_state != HIF_STATE_TXERROR) {
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] ERROR!! HIF_STATE return NORMAL\r\n");
+ EXCP_HALT();
+ } else {
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] HIF_STATE return HIF_STATE_TXERROR\r\n");
+ }
+ }
+
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut end\r\n");
+#endif
+ return STATUS_OK;
+}
+
+static kal_bool excp_ttyut_task_init(void)
+{
+ return KAL_TRUE;
+}
+
+static void excp_ttyut_task_main(task_entry_struct *task_entry_ptr)
+{
+ DCL_HANDLE handle;
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ char *dummy_string = "DUMMYdummyDummY";
+ DCL_STATUS status;
+ UART_CTRL_GET_DRV_STATE_T getDrvState;
+
+ handle = DclSerialPort_Open(EXCEPTION_TEST_PORT, 0);
+
+ DclSerialPort_UpModuleInit(handle, MOD_EXCP_TTYUT, 0); // conventional init
+
+ /*If taking CCCI exception IT test, task will be blocked here. Because, driver is attached when exception init*/
+ getDrvState.u4OwnerId = MOD_EXCP_TTYUT;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while ((getDrvState.drv_state != DRV_ST_ATTACHED) || (status != STATUS_OK));
+
+ kal_sleep_task(KAL_TICKS_5_SEC);
+
+ /* Transmit a dummy packet */
+ ur_ctrl_putbytes.u4OwenrId = MOD_EXCP_TTYUT;
+ ur_ctrl_putbytes.puBuffaddr = (DCL_UINT8*)dummy_string;
+ ur_ctrl_putbytes.u2Length = strlen(dummy_string);
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+
+ kal_sleep_task(KAL_TICKS_5_SEC);
+
+ /* Trigger an assert to enter exception mode */
+ ASSERT(0);
+}
+
+kal_bool excp_ttyut_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct excp_ttyut_handler_info =
+ {
+ excp_ttyut_task_main, /* task entry function */
+ excp_ttyut_task_init, /* task initialization function */
+ NULL /* task reset handler */
+ };
+
+ TTYUT_DBG_PRINT("=========>excp_ttyut_create\r\n");
+
+ *handle = (comptask_handler_struct *)&excp_ttyut_handler_info;
+ return KAL_TRUE;
+}
+
diff --git a/mcu/driver/tty/src/tty_unit_test.c b/mcu/driver/tty/src/tty_unit_test.c
new file mode 100644
index 0000000..099ec7c
--- /dev/null
+++ b/mcu/driver/tty/src/tty_unit_test.c
@@ -0,0 +1,3302 @@
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "task_config.h"
+#include "sys_test.h"
+#include "dcl.h"
+#include "qmu_bm_util.h"
+#include "drv_msgid.h"
+
+#if !defined ATEST_SYS_TTYCORE
+#error "This file is used for system test only."
+#endif
+
+/***************************************************************************
+ Macro Declaration
+ ***************************************************************************/
+#define ST_MOD_NAME "TTYUT"
+
+#define MOD_TTY_UT MOD_SYS_TEST
+#define DRV_TTY_UT MOD_SYS_TEST
+#define MOD_CURRENT kal_get_active_module_id()
+
+#define UART_DEV_CNT (uart_max_port - uart_port1 + 1)
+
+#define HW_BUFF_SIZE 8192
+#define UT_TEST_SIZE 8000
+#define UT_CHUNK_SIZE 512
+#define UT_DATA_MASK 0x000000CC
+
+#define DCL_UART_MAGIC_NUM 0x40000000
+
+#define DCL_UART_GET_DEV(_handle) ((DCL_DEV)((_handle) & (~DCL_UART_MAGIC_NUM)))
+
+#define FAIL_MSG(fmt, ...) do { \
+ kal_sprintf(p_ret_err_str, "%s():%s:%d " fmt, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \
+ *p_ret_err_str_sz = strlen(p_ret_err_str); \
+ } while (0)
+#define FAIL_MSG_EXT(ext, fmt, ...) do { \
+ kal_sprintf(p_ret_err_str, strcat(ext, "%s():%s:%d " fmt), __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \
+ *p_ret_err_str_sz = strlen(p_ret_err_str); \
+ } while (0)
+#define MIN(_x, _y) (((_x) > (_y)) ? (_y) : (_x))
+
+#define list_each_gpd_no_tail(_gpd, _first_gpd, _last_gpd) \
+ for ( _gpd = _first_gpd; _gpd != _last_gpd; _gpd = QBM_DES_GET_NEXT(_gpd))
+
+#define list_each_gpd(_gpd, _first_gpd, _last_gpd) QBM_DES_SET_NEXT(_last_gpd, NULL); \
+ for ( _gpd = _first_gpd; _gpd != NULL; _gpd = QBM_DES_GET_NEXT(_gpd))
+#define list_each_bd(_bd, _first_bd) for (_bd = _first_bd; _bd != NULL; _bd = QBM_DES_GET_NEXT(_bd))
+
+/***************************************************************************
+ Data Structure
+ ***************************************************************************/
+// This flag used to check event occur, and it will be "extern" in dcl_tty.c
+kal_bool ut_assert_flag = KAL_FALSE;
+
+typedef struct _UtInstance {
+/***********************
+ Upper Module
+ ***********************/
+ // For Receiving Ior From RxCb (New Rx Path)
+ tty_io_request_t *Rx_Ior;
+
+/***********************
+ Driver
+ ***********************/
+ // RxGpdQue
+ void *Rx_first_gpd;
+ void *Rx_last_gpd;
+ // TxGpdQue
+ void *Tx_first_gpd;
+ void *Tx_last_gpd;
+ // Flag
+ kal_bool Need_Tx_done_cb;
+
+/***********************
+ Hardware buffer
+ ***********************/
+ int size;
+ int start;
+ char HwBuff[HW_BUFF_SIZE];
+} UtInstance;
+
+static UtInstance Dev_Mgmt[UART_DEV_CNT];
+
+/***************************************************************************
+ Hardware Buffer Function
+ ***************************************************************************/
+/*
+ * Here is a simple hw buffer
+ * There is no check for data overflow.
+ */
+int Hw_GetRemainSpace(DCL_DEV dev)
+{
+ return HW_BUFF_SIZE - (Dev_Mgmt[dev].start + Dev_Mgmt[dev].size);
+}
+
+void Hw_PushData(DCL_DEV dev, const void *src, kal_uint32 size)
+{
+ char *hwbuff_data_end = Dev_Mgmt[dev].HwBuff + Dev_Mgmt[dev].start + Dev_Mgmt[dev].size;
+ kal_mem_cpy(hwbuff_data_end, src, size);
+ Dev_Mgmt[dev].size += size;
+}
+
+void Hw_PushDataFromTxQue(DCL_DEV dev)
+{
+ void *gpd_t;
+ void *bd_t;
+
+ list_each_gpd(gpd_t, Dev_Mgmt[dev].Tx_first_gpd, Dev_Mgmt[dev].Tx_last_gpd) {
+ // only push data of gpd with hwo equal to 1
+ if (QBM_DES_GET_HWO(gpd_t)) {
+ if (QBM_DES_GET_BDP(gpd_t)) {
+ list_each_bd(bd_t, QBM_DES_GET_DATAPTR(gpd_t)) {
+ Hw_PushData(dev, QBM_DES_GET_DATAPTR(bd_t), QBM_DES_GET_DATALEN(bd_t));
+ }
+ } else {
+ Hw_PushData(dev, QBM_DES_GET_DATAPTR(gpd_t), QBM_DES_GET_DATALEN(gpd_t));
+ }
+ }
+
+ // set hwo to 0
+ QBM_DES_CLR_HWO(gpd_t);
+ }
+}
+
+void Hw_PopData(DCL_DEV dev, void *dest, kal_uint32 size)
+{
+ char *hwbuff_data_start = Dev_Mgmt[dev].HwBuff + Dev_Mgmt[dev].start;
+ kal_mem_cpy(dest, hwbuff_data_start, size);
+ Dev_Mgmt[dev].start += size;
+ Dev_Mgmt[dev].size -= size;
+}
+
+void Hw_PopDataToRxQue(DCL_DEV dev)
+{
+ void *gpd_t;
+ void *bd_t;
+
+ list_each_gpd_no_tail(gpd_t, Dev_Mgmt[dev].Rx_first_gpd, Dev_Mgmt[dev].Rx_last_gpd) {
+ // check hardware buffer still have data
+ if (Dev_Mgmt[dev].size == 0)
+ break;
+
+ if (QBM_DES_GET_BDP(gpd_t)) {
+ list_each_bd(bd_t, QBM_DES_GET_DATAPTR(gpd_t)) {
+ kal_uint32 len = MIN(QBM_DES_GET_ALLOW_LEN(bd_t), Dev_Mgmt[dev].size);
+ if (len) {
+ Hw_PopData(dev, QBM_DES_GET_DATAPTR(bd_t), len);
+ }
+ QBM_DES_SET_DATALEN(bd_t, len);
+ }
+ } else {
+ kal_uint32 len = MIN(QBM_DES_GET_ALLOW_LEN(gpd_t), Dev_Mgmt[dev].size);
+ if (len) {
+ Hw_PopData(dev, QBM_DES_GET_DATAPTR(gpd_t), len);
+ }
+ QBM_DES_SET_DATALEN(gpd_t, len);
+ }
+
+ // set hwo to 0
+ QBM_DES_CLR_HWO(gpd_t);
+ }
+}
+
+void Hw_ClearBuff(DCL_DEV dev)
+{
+ kal_mem_set(Dev_Mgmt[dev].HwBuff, 0, HW_BUFF_SIZE);
+
+ Dev_Mgmt[dev].start = 0;
+ Dev_Mgmt[dev].size = 0;
+}
+
+/***************************************************************************
+ Tx/Rx Operator Function
+ ***************************************************************************/
+void Rx_EnQue(DCL_DEV dev, void *_ior)
+{
+ void *gpd_t;
+ tty_io_request_t *ior = (tty_io_request_t *)_ior;
+
+ // Set gpd HWO to 1,only tail gpd HWO to 0. And then En-Q
+ list_each_gpd(gpd_t, ior->first_gpd, ior->last_gpd) {
+ QBM_DES_SET_HWO(gpd_t);
+ }
+ QBM_DES_CLR_HWO(ior->last_gpd);
+
+ if (!Dev_Mgmt[dev].Rx_first_gpd) {
+ Dev_Mgmt[dev].Rx_first_gpd = ior->first_gpd;
+ Dev_Mgmt[dev].Rx_last_gpd = ior->last_gpd;
+ } else {
+ qbmt_common_en_q_rx(
+ ior->first_gpd,
+ ior->last_gpd,
+ &Dev_Mgmt[dev].Rx_first_gpd,
+ &Dev_Mgmt[dev].Rx_last_gpd);
+ }
+}
+
+void Tx_EnQue(DCL_DEV dev, void *_ior)
+{
+ void *gpd_t;
+ tty_io_request_t *ior = (tty_io_request_t *)_ior;
+
+ // Set gpd HWO to 1, And then En-Q
+ list_each_gpd(gpd_t, ior->first_gpd, ior->last_gpd) {
+ QBM_DES_SET_HWO(gpd_t);
+ }
+
+ if (!Dev_Mgmt[dev].Tx_first_gpd) {
+ Dev_Mgmt[dev].Tx_first_gpd = ior->first_gpd;
+ Dev_Mgmt[dev].Tx_last_gpd = ior->last_gpd;
+ } else {
+ QBM_DES_SET_NEXT(Dev_Mgmt[dev].Tx_last_gpd, ior->first_gpd);
+ }
+}
+
+void * Rx_DeQueToIor(DCL_DEV dev)
+{
+ void *ior = NULL;
+ void *new_head;
+ void *new_tail;
+
+ if (Dev_Mgmt[dev].Rx_first_gpd) {
+ qbmt_de_q(
+ &Dev_Mgmt[dev].Rx_first_gpd,
+ &Dev_Mgmt[dev].Rx_last_gpd,
+ &new_head,
+ &new_tail);
+
+ if (new_head) {
+ ior = QBM_DES_GET_SW_CTRL_FIELD(new_head);
+ ((tty_io_request_t *)ior)->first_gpd = new_head;
+ ((tty_io_request_t *)ior)->last_gpd = new_tail;
+ }
+ }
+
+ return ior;
+}
+
+void Rx_Flush_Gpd(DCL_DEV dev)
+{
+ void *Rx_Ior;
+ DCL_HANDLE handle;
+
+ handle = DclSerialPort_Open(dev, 0);
+
+ // Using RxCb to return the all GPD of Rx Queue
+ if (Dev_Mgmt[dev].Rx_first_gpd) {
+ Rx_Ior = QBM_DES_GET_SW_CTRL_FIELD(Dev_Mgmt[dev].Rx_first_gpd);
+ ((tty_io_request_t *)Rx_Ior)->first_gpd = Dev_Mgmt[dev].Rx_first_gpd;
+ ((tty_io_request_t *)Rx_Ior)->last_gpd = Dev_Mgmt[dev].Rx_last_gpd;
+
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, Rx_Ior);
+
+ Dev_Mgmt[dev].Rx_first_gpd = 0;
+ Dev_Mgmt[dev].Rx_last_gpd = 0;
+ }
+}
+
+/*
+ * This function maybe need to be called after Hw_PushDataFromTxQue() invoked.
+ * Because it will flush each gpd without care about whether hwo is set.
+ *
+ * The Hw_PushDataFromTxQue() will be invoked in driver callback with command "TTY_CMD_PUT_BYTES_IOR"
+ */
+void Tx_Flush_Gpd(DCL_DEV dev)
+{
+ void * Tx_Ior;
+ DCL_HANDLE handle;
+
+ handle = DclSerialPort_Open(dev, 0);
+
+ // Using TxDoneCb to return Tx GPD or Free gpds
+ if (Dev_Mgmt[dev].Tx_first_gpd) {
+ Tx_Ior = QBM_DES_GET_SW_CTRL_FIELD(Dev_Mgmt[dev].Tx_first_gpd);
+ ((tty_io_request_t *)Tx_Ior)->first_gpd = Dev_Mgmt[dev].Tx_first_gpd;
+ ((tty_io_request_t *)Tx_Ior)->last_gpd = Dev_Mgmt[dev].Tx_last_gpd;
+
+ if (Dev_Mgmt[dev].Need_Tx_done_cb) {
+ DclSerialPort_DrvTxDone(handle, DRV_TTY_UT, Tx_Ior);
+ } else {
+ qbmt_dest_q(Dev_Mgmt[dev].Tx_first_gpd, Dev_Mgmt[dev].Tx_last_gpd);
+ }
+
+ Dev_Mgmt[dev].Tx_first_gpd = 0;
+ Dev_Mgmt[dev].Tx_last_gpd = 0;
+ }
+}
+/***************************************************************************
+ Callback Test Function
+ ***************************************************************************/
+DCL_STATUS
+_drv_handler_cb(
+ DCL_DEV dev,
+ DCL_CTRL_CMD cmd,
+ DCL_CTRL_DATA_T *data)
+{
+ DCL_STATUS ret_status = STATUS_OK;
+
+ switch (cmd)
+ {
+ case SIO_CMD_INIT:
+ case SIO_CMD_OPEN:
+ {
+ ret_status = STATUS_OK;
+ }
+ break;
+
+ case SIO_CMD_CLOSE:
+ {
+ UART_CTRL_CLOSE_T *prCtrlClose;
+ prCtrlClose = &(data->rUARTCtrlCLOSE);
+
+ // Flush Tx/Rx GPD (In buffer mode, Flush will do nothing because queue is empty
+ Tx_Flush_Gpd(dev);
+ Rx_Flush_Gpd(dev);
+
+ // Clear Need_Tx_done_cb flag
+ Dev_Mgmt[dev].Need_Tx_done_cb = KAL_FALSE;
+ }
+ break;
+
+ case SIO_CMD_PUT_BYTES:
+ { // Only for Buffer Mode
+ int size;
+ UART_CTRL_PUT_BYTES_T *prCtrlPutBytes;
+
+ prCtrlPutBytes = &(data->rUARTCtrlPUTBYTES);
+ size = MIN(prCtrlPutBytes->u2Length, UT_CHUNK_SIZE);
+
+ Hw_PushData(dev, prCtrlPutBytes->puBuffaddr, size);
+ prCtrlPutBytes->u2RetSize = size;
+ }
+ break;
+
+ case SIO_CMD_GET_BYTES:
+ { // Only for Buffer Mode
+ int size;
+ UART_CTRL_GET_BYTES_T *prCtrlGetBytes;
+
+ prCtrlGetBytes = &(data->rUARTCtrlGETBYTES);
+ size = MIN(prCtrlGetBytes->u2Length, UT_CHUNK_SIZE);
+
+ Hw_PopData(dev, prCtrlGetBytes->puBuffaddr, size);
+ prCtrlGetBytes->u2RetSize = size;
+ }
+ break;
+
+ case TTY_CMD_NEED_TX_DONE_CB:
+ {
+ UART_CTRL_NEED_TX_DONE_CB_T *prCtrlNeedTxDoneCb;
+ prCtrlNeedTxDoneCb = &(data->rUARTCtrlNeedTxDoneCb);
+
+ Dev_Mgmt[dev].Need_Tx_done_cb = prCtrlNeedTxDoneCb->needTxDoneCb;
+ }
+ break;
+
+ case TTY_CMD_ASSIGN_RX_IOR:
+ {
+ UART_CTRL_ASSIGN_RX_IOR_T *prCtrlAssignRxIor;
+
+ prCtrlAssignRxIor = &(data->rUARTCtrlAssignRxIor);
+
+ // En-Q Rx_Ior
+ Rx_EnQue(dev, prCtrlAssignRxIor->ior);
+ }
+ break;
+
+ case TTY_CMD_PUT_BYTES_IOR:
+ case TTY_CMD_PUT_BYTES_IOR_LIGHT:
+ {
+ UART_CTRL_PUT_BYTES_IOR_T *prCtrlPutBytesIor;
+
+ prCtrlPutBytesIor = &(data->rUARTCtrlPUTBYTESIOR);
+
+ // En-Q Tx_Ior
+ Tx_EnQue(dev, prCtrlPutBytesIor->putIor);
+
+ // Copy GPD data to HwBuff
+ Hw_PushDataFromTxQue(dev);
+
+ }
+ break;
+
+ case TTY_CMD_GET_CHUNK_SIZE:
+ {
+ UART_CTRL_GET_CHUNK_SIZE_T *prCtrlChunkSize;
+ prCtrlChunkSize = &(data->rUARTCtrlGETCHUNKSIZE);
+ prCtrlChunkSize->chunkSize = UT_CHUNK_SIZE;
+ }
+ break;
+ case SIO_CMD_SET_OWNER:
+ {
+ // Flush Tx/Rx GPD
+ Tx_Flush_Gpd(dev);
+ Rx_Flush_Gpd(dev);
+
+ // Clear Need_Tx_done_cb flag
+ Dev_Mgmt[dev].Need_Tx_done_cb = KAL_FALSE;
+ }
+ break;
+
+ case SIO_CMD_GET_OWNER_ID:
+ break;
+
+ case SIO_CMD_CLR_RX_BUF:
+ {
+ Rx_Flush_Gpd(dev);
+ }
+ break;
+
+ case SIO_CMD_CLR_TX_BUF:
+ {
+ Tx_Flush_Gpd(dev);
+ }
+ break;
+
+ case SIO_CMD_GET_TX_AVAIL:
+ { // Only for Buffer Mode
+ UART_CTRL_TX_AVAIL_T *prCtrlTxAvail;
+
+ prCtrlTxAvail = &(data->rUARTCtrlTXAVAIL);
+
+ prCtrlTxAvail->u2RetSize = Hw_GetRemainSpace;
+ }
+ break;
+
+ case SIO_CMD_GET_RX_AVAIL:
+ { // Only for Buffer Mode
+ DCL_HANDLE handle;
+ UART_CTRL_RX_AVAIL_T *prCtrlRxAvail;
+
+ prCtrlRxAvail = &(data->rUARTCtrlRXAVAIL);
+
+ prCtrlRxAvail->u2RetSize = Dev_Mgmt[dev].size;
+
+ // Here we invoke RxCb to send ilm and clear Notify_ILM flag in Buffer Mode
+ handle = DclSerialPort_Open(dev, 0);
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, NULL);
+
+ // Get the Notify_ILM and this flag is cleared by above callback
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_READ_IND) {
+ ret_status = STATUS_FAIL;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ break;
+
+ default:
+ {
+ ret_status = STATUS_INVALID_CMD;
+ }
+ break;
+ }
+
+ return ret_status;
+}
+
+DCL_STATUS
+_tx_done_cb(
+ DCL_HANDLE handle,
+ module_type source_id,
+ tty_io_request_t *tx_ior)
+{
+ // Just Free all gpd
+ qbmt_dest_q(tx_ior->first_gpd, tx_ior->last_gpd);
+
+ return STATUS_OK;
+}
+
+DCL_STATUS
+_rx_cb(
+ DCL_HANDLE handle,
+ module_type source_id,
+ tty_io_request_t *rx_ior)
+{
+ DCL_DEV device;
+
+ device = DCL_UART_GET_DEV(handle);
+
+ Dev_Mgmt[device].Rx_Ior = rx_ior;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS
+ _drv_state_change_cb(
+ DCL_HANDLE handle,
+ tty_drv_state_e state)
+{
+ switch(state)
+ {
+ case DRV_ST_DETACHED:
+ case DRV_ST_ATTACHED:
+ default:
+ break;
+ }
+
+ return STATUS_OK;
+}
+
+/****************************************************************************
+ Test Function
+ ***************************************************************************/
+
+#define IS_SUB_CASE_FAIL(_func) (_func(p_ret_err_str, p_ret_err_str_sz) == KAL_FALSE)
+/***********************************
+ Function Verification
+ ***********************************/
+
+kal_bool FuncVeri_Common(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_HANDLE handle;
+ DCL_STATUS status;
+
+ /*
+ * DclSerialPort_Initialize Test
+ */
+ status = DclSerialPort_Initialize();
+ if (status != STATUS_OK) {
+ FAIL_MSG("Initialize Failed!");
+ return KAL_FALSE;
+ }
+
+ /*
+ * DclSerialPort_Open(device, flags) Test
+ * - parameter
+ * device - which port you want to get handle
+ * flags - no used
+ *
+ * - Description
+ * This function is used to get handle only
+ * and do nothing with initialization setting of port
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Scenario
+ * Port range(P) | Expected result
+ * ============================================================
+ * P < uart_port1 or P > uart_max_port | STATUS_INVALID_DEVICE
+ * uart_port1 <= P <= uart_max_port | DCL_UART_MAGIC_NUM | device
+ */
+
+ for (device = 0; device < uart_port1; device++) {
+ handle = DclSerialPort_Open(device, 0);
+ if (handle != STATUS_INVALID_DEVICE) {
+ FAIL_MSG("Get handle test Failed! port # = %d", device);
+ return KAL_FALSE;
+ }
+ }
+
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+ if (handle != (DCL_UART_MAGIC_NUM | device)) {
+ FAIL_MSG("Get handle test Failed! port # = %d", device);
+ return KAL_FALSE;
+ }
+ }
+
+ for (device = uart_max_port + 1; device < uart_port_null; device++) {
+ handle = DclSerialPort_Open(device, 0);
+ if (handle != STATUS_INVALID_DEVICE) {
+ FAIL_MSG("Get handle test Failed! port # = %d", device);
+ return KAL_FALSE;
+ }
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool FuncVeri_DrvRegDeRegCb(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_HANDLE handle;
+ DCL_STATUS status;
+ SIO_TYPE_T devtype;
+ Seriport_HANDLER_T drv_ut_handler;
+
+ /*
+ * DclSerialPort_DrvRegisterCb(handle, drv_cb)
+ * - Description
+ * Register driver callback function as uart handler for TTYCore.
+ * And specify device type(will affect chunkSize & others...
+ * This API will make port active.
+ *
+ * DclSerialPort_DrvDeRegisterCb(handle)
+ * - Description
+ * Clear uart handler for TTYCore.
+ * This API will make port inactive.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Scenario
+ * Conditions | Expected result
+ * ============================================================
+ * Invalid port | STATUS_FAIL
+ | STATUS_INVALID_DCL_HANDLE
+ | STATUS_INVALID_DEVICE
+ * valid port
+ * drv_cb is null | STATUS_INVALID_ARGUMENT
+ * RegCb/DeRegCb | STATUS_OK
+ * Dup RegCb | STATUS_ALREADY_OPENED
+ * Dup DeRegCb | STATUS_INVALID_OPERATION
+ *
+ * Other Situations
+ * Each port will register with each device type
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * TODO
+ * DeRegCb with DrvAttach
+ */
+
+ device = uart_port_null;
+ handle = DclSerialPort_Open(device, 0);
+ // Invalid Port Test
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG("Driver RegisterCb in Invalid port");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG("Driver De-RegisterCb in Invalid port");
+ return KAL_FALSE;
+ }
+
+ // Valid Port Test
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ for (devtype = DCL_UART_TYPE; devtype < DCL_UART_DEV_TYPE_MAX; devtype++){
+ drv_ut_handler.DevType = devtype;
+
+ // Register NULL callback (will assert)
+ drv_ut_handler.SeriportHandlerCb = NULL;
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if ((ut_assert_flag == KAL_FALSE) || (status != STATUS_INVALID_ARGUMENT)) {
+ FAIL_MSG("Driver Register NULL Test Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+ ut_assert_flag = KAL_FALSE;
+
+ drv_ut_handler.SeriportHandlerCb = _drv_handler_cb;
+
+ // First Register callback
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver Register Callback Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Duplicated Register callback
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if (status != STATUS_ALREADY_OPENED) {
+ FAIL_MSG("Driver Duplicated RegisterCb Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // First De-Register callback
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver De-RegisterCb Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Duplicated De-Register callback
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_INVALID_OPERATION) {
+ FAIL_MSG("Driver Duplicated De-RegisterCb Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ /// TODO: De-RegisterCb with DrvAttach
+ }
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool FuncVeri_DrvAtDetach(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_HANDLE handle;
+ DCL_STATUS status;
+ SIO_TYPE_T devtype;
+ Seriport_HANDLER_T drv_ut_handler;
+
+ /*
+ * DclSerialPort_DrvAttach(handle)
+ * DclSerialPort_DrvDetach(handle)
+ * - Description
+ * Change port state to attach/detach as state of driver connect/disconnect
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Scenario
+ * Conditions | Expected result
+ * ============================================================
+ * Invalid port | STATUS_FAIL
+ | STATUS_INVALID_DCL_HANDLE
+ | STATUS_DEVICE_NOT_EXIST
+ * valid port
+ * port active
+ * Attach/Detach | STATUS_OK
+ * Dup Attach/Detach | STATUS_OK
+ * port inactive
+ * Attach/Detach | STATUS_DEVICE_NOT_EXIST
+ */
+
+ device = uart_port_null;
+ handle = DclSerialPort_Open(device, 0);
+ // Invalid Port Test
+ status = DclSerialPort_DrvAttach(handle);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG("Driver Attach in Invalid port");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_DrvDetach(handle);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG("Driver Detach in Invalid port");
+ return KAL_FALSE;
+ }
+
+ // Valid Port Test
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ // Port InActive
+ status = DclSerialPort_DrvAttach(handle);
+ if (status != STATUS_DEVICE_NOT_EXIST) {
+ FAIL_MSG("Driver Attach with port inactive Failed! Device# = %d", device);
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_DrvDetach(handle);
+ if (status != STATUS_DEVICE_NOT_EXIST) {
+ FAIL_MSG("Driver Detach with port inactive Failed! Device# = %d", device);
+ return KAL_FALSE;
+ }
+
+ drv_ut_handler.SeriportHandlerCb = _drv_handler_cb;
+ // Port Active with each device type
+ for (devtype = DCL_UART_TYPE; devtype < DCL_UART_DEV_TYPE_MAX; devtype++){
+ drv_ut_handler.DevType = devtype;
+
+ // Register callback (Active)
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver Register Callback Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // First Attach
+ status = DclSerialPort_DrvAttach(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver Attach Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ //Duplicated Attach
+ status = DclSerialPort_DrvAttach(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver Duplicated Attach Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // First Detach
+ status = DclSerialPort_DrvDetach(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver Detach Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Duplicated Detach
+ status = DclSerialPort_DrvDetach(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver Duplicated Detach Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // De-Register callback (InActive port - Avoid next time RegisterCb Failed)
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver De-RegisterCb Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool FuncVeri_UpInitDeinit(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_HANDLE handle;
+ DCL_STATUS status;
+ SIO_TYPE_T devtype;
+ Seriport_HANDLER_T drv_ut_handler;
+
+ /*
+ * DclSerialPort_UpModuleInit(handle, module_id, flag)
+ * DclSerialPort_Control(handle, SIO_CMD_OPEN, data)
+ * - Description
+ * Setup owner id and Tx/Rx path in specify port.
+ * Send SIO_CMD_OPEN to let Driver know port is opened.
+ *
+ * DclSerialPort_UpModuleDeinit(handle)
+ * DclSerialPort_Control(handle, SIO_CMD_CLOSE, data)
+ * - Description
+ * Clear owner id and Tx/Rx path in specify port.
+ * Send SIO_CMD_CLOSE to let Driver know port is closed.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Scenario
+ * Conditions | Expected result
+ * ============================================================
+ * Invalid port | STATUS_FAIL
+ | STATUS_INVALID_DCL_HANDLE
+ | STATUS_INVALID_DEVICE
+ * valid port
+ * Init/Deinit | STATUS_OK
+ * Dup Init/Deinit | STATUS_ALREADY_OPENED/STATUS_NOT_OPENED
+ *
+ * Other Situations
+ * when Driver active/inactive
+ * active with each device type
+ * Kinds of Initialization
+ * New Tx, New Rx, New Tx&Rx, Conv(New API/ Conv API)
+ * Kinds of De-Initialization
+ * New API/ Conv API)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * TODO
+ * In this Test Case, we only test pair of Conv Init & Conv De-Init
+ * New Init & New De-Init
+ * Uncovering case
+ * pair of Conv Init & New De-Init
+ * New Init & Conv De-Init
+ *
+ * Add them If it is needed.
+ */
+
+ // Conv API Test
+ {
+ UART_CTRL_OPEN_T ur_ctrl_open;
+ UART_CTRL_CLOSE_T ur_ctrl_close;
+ char *Error_Tag = "[Conv API][Conv Tx & Conv Rx] ";
+
+ ur_ctrl_open.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_close.u4OwenrId = MOD_TTY_UT;
+
+ device = uart_port_null;
+ handle = DclSerialPort_Open(device, 0);
+ // Invalid Port Test
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG_EXT(Error_Tag, "Init in Invalid port");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*) &ur_ctrl_close);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG_EXT(Error_Tag, "De-Init in Invalid port");
+ return KAL_FALSE;
+ }
+
+ // Valid Port Test
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ // Port InActive
+ {
+ // First Init
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Init in InActive Valid port");
+ return KAL_FALSE;
+ }
+
+ // Duplicated Init
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status != STATUS_ALREADY_OPENED) {
+ FAIL_MSG_EXT(Error_Tag, "Duplicated Init in InActive Valid port");
+ return KAL_FALSE;
+ }
+
+ // First De-Init
+ status = DclSerialPort_Control(handle, SIO_CMD_CLOSE,(DCL_CTRL_DATA_T*) &ur_ctrl_close);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "De-Init in InActive Valid port");
+ return KAL_FALSE;
+ }
+
+ // Duplicated De-Init
+ status = DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*) &ur_ctrl_close);
+ if (status != STATUS_NOT_OPENED) {
+ FAIL_MSG_EXT(Error_Tag, "Duplicated De-Init in InActive Valid port");
+ return KAL_FALSE;
+ }
+ }
+
+ drv_ut_handler.SeriportHandlerCb = _drv_handler_cb;
+ // Port Active with each device type
+ for (devtype = DCL_UART_TYPE; devtype < DCL_UART_DEV_TYPE_MAX; devtype++){
+ drv_ut_handler.DevType = devtype;
+
+ // Register callback (Active)
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Driver Register Callback Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // First Init
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Init in Active Valid port");
+ return KAL_FALSE;
+ }
+
+ // Duplicated Init
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status != STATUS_ALREADY_OPENED) {
+ FAIL_MSG_EXT(Error_Tag, "Duplicated Init in Active Valid port");
+ return KAL_FALSE;
+ }
+
+ // First De-Init
+ status = DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*) &ur_ctrl_close);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "De-Init in Active Valid port");
+ return KAL_FALSE;
+ }
+
+ // Duplicated De-Init
+ // Here is return STATUS_OK but not STATUS_NOT_OPENED
+ ///TODO: if this result of return value is BUG, please fix it.
+ status = DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*) &ur_ctrl_close);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Duplicated De-Init in Active Valid port");
+ return KAL_FALSE;
+ }
+
+ // De-Register callback (InActive port - Avoid next time RegisterCb Failed)
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Driver De-RegisterCb Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ // New API Test
+ {
+ int i;
+ int flag;
+ int Path_Case[4] = {
+ 0,
+ TTY_FLAG_NEW_TX,
+ TTY_FLAG_NEW_RX,
+ TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX};
+ char *Error_Tag[4] = {
+ "[New API][Conv Tx & Conv Rx] ",
+ "[New API][New Tx & Conv Rx] ",
+ "[New API][Conv Tx & New Rx] ",
+ "[New API][New Tx & New Rx] "};
+
+ for (i = 0; i < 4; i++) {
+ flag = Path_Case[i];
+
+ device = uart_port_null;
+ handle = DclSerialPort_Open(device, 0);
+ // Invalid Port Test
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG_EXT(Error_Tag[i], "Init in Invalid port");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG_EXT(Error_Tag[i], "De-Init in Invalid port");
+ return KAL_FALSE;
+ }
+
+
+ drv_ut_handler.SeriportHandlerCb = _drv_handler_cb;
+ // Valid Port Test
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ // Port InActive
+ {
+ // First Init
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag[i], "Init in InActive Valid port");
+ return KAL_FALSE;
+ }
+
+ // Duplicated Init
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_ALREADY_OPENED) {
+ FAIL_MSG_EXT(Error_Tag[i], "Duplicated Init in InActive Valid port");
+ return KAL_FALSE;
+ }
+
+ // First De-Init
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag[i], "De-Init in InActive Valid port");
+ return KAL_FALSE;
+ }
+
+ // Duplicated De-Init
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_NOT_OPENED) {
+ FAIL_MSG_EXT(Error_Tag[i], "Duplicated De-Init in InActive Valid port");
+ return KAL_FALSE;
+ }
+ }
+
+ // Port Active with each device type
+ for (devtype = DCL_UART_TYPE; devtype < DCL_UART_DEV_TYPE_MAX; devtype++){
+ drv_ut_handler.DevType = devtype;
+
+ // Register callback (Active)
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag[i], "Driver Register Callback Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // First Init
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag[i], "Init in Active Valid port");
+ return KAL_FALSE;
+ }
+
+ // Duplicated Init
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_ALREADY_OPENED) {
+ FAIL_MSG_EXT(Error_Tag[i], "Duplicated Init in Active Valid port");
+ return KAL_FALSE;
+ }
+
+ // First De-Init
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag[i], "De-Init in Active Valid port");
+ return KAL_FALSE;
+ }
+
+ // Duplicated De-Init
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_NOT_OPENED) {
+ FAIL_MSG_EXT(Error_Tag[i], "Duplicated De-Init in Active Valid port");
+ return KAL_FALSE;
+ }
+
+ // De-Register callback (InActive port - Avoid next time RegisterCb Failed)
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag[i], "Driver De-RegisterCb Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool FuncVeri_UpRegCb(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_HANDLE handle;
+ DCL_STATUS status;
+
+ /*
+ * DclSerialPort_UpModuleRegisterCb(handle, rx_cb, tx_done_cb, drv_state_change)
+ * - Description
+ * Register callback in specify port.
+ *
+ * This API is independent with active/inactive.
+ *
+ * - Warning
+ * Condition 1:
+ * This API is for New Upper Module,
+ * Conv Upper Module no need to use it.
+ * There is nothing verification of it.
+ *
+ * Condition 2:
+ * This API need to be used after port initializing,
+ * but there is nothing verification of it.
+ *
+ * If you use this API before port initialized,
+ * it maybe cause some unexpected result.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Scenario
+ * Conditions | Expected result
+ * ============================================================
+ * Invalid port | STATUS_FAIL
+ | STATUS_INVALID_DCL_HANDLE
+ | STATUS_INVALID_DEVICE
+ * valid port
+ * RegCb/Dup RegCb | STATUS_OK
+ * Assert Condition | ASSERT
+ * - Conv Rx & Rx_Cb is not null
+ * - New Rx & Rx_Cb is null
+ * - Conv Tx & Tx_Done_Cb is not null
+ * - Conv Tx & Conv Rx & drv_state_change_cb is not null
+ * - (New Tx or New Rx) & drv_state_change_cb is null
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * TODO
+ * In this Test Case, we only test for New Tx/Rx case and assertion case
+ *
+ * The warning as mentioned above, if that is important, please add it in TTYCore.
+ */
+
+ device = uart_port_null;
+ handle = DclSerialPort_Open(device, 0);
+ // Invalid Port Test
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, _tx_done_cb, _drv_state_change_cb);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG("Upper Module RegisterCb in Invalid port");
+ return KAL_FALSE;
+ }
+
+ // Valid Port Test
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ // Init with New Tx & New Rx Path
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Init New Tx & New Rx in Valid port");
+ return KAL_FALSE;
+ }
+
+ // First Register callback
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, _tx_done_cb, _drv_state_change_cb);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Upper Module RegisterCb in Valid port");
+ return KAL_FALSE;
+ }
+ // Duplicated Register callback with TxDoneCb is NULL
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, NULL, _drv_state_change_cb);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Upper Module Duplicated RegisterCb in Valid port and TxDoneCb is NULL");
+ return KAL_FALSE;
+ }
+
+ // De-Init - Avoid next time Init Failed)
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("De-Init New Tx & New Rx in Valid port");
+ return KAL_FALSE;
+ }
+ }
+
+ // Assertion Case
+ // Conv Rx & Rx_Cb is not null
+ // Conv Tx & Tx_Done_Cb is not null
+ // Conv Tx & Conv Rx & drv_state_change_cb is not null
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ // Init with Conv Tx & Conv Rx Path
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, 0);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Init Conv Tx & Conv Rx in Valid port");
+ return KAL_FALSE;
+ }
+
+ // Register callback - Conv Rx & Rx_Cb is not null
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, NULL, NULL);
+ if (ut_assert_flag == KAL_FALSE) {
+ FAIL_MSG("Upper Module Register Callback");
+ return KAL_FALSE;
+ }
+ ut_assert_flag = KAL_FALSE;
+
+ // Register callback - Conv Tx & Tx_Done_Cb is not null
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_UpModuleRegisterCb(handle, NULL, _tx_done_cb, NULL);
+ if (ut_assert_flag == KAL_FALSE) {
+ FAIL_MSG("Upper Module Register Callback");
+ return KAL_FALSE;
+ }
+ ut_assert_flag = KAL_FALSE;
+
+ // Register callback - Conv Tx & Conv Rx & drv_state_change_cb is not null
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_UpModuleRegisterCb(handle, NULL, NULL, _drv_state_change_cb);
+ if (ut_assert_flag == KAL_FALSE) {
+ FAIL_MSG("Upper Module Register Callback");
+ return KAL_FALSE;
+ }
+ ut_assert_flag = KAL_FALSE;
+
+ // De-Init - Avoid next time Init Failed)
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("De-Init Conv Tx & Conv Rx in Valid port");
+ return KAL_FALSE;
+ }
+ }
+ // New Rx & Rx_Cb is null
+ // (New Tx or New Rx) & drv_state_change_cb is null
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ // Init with New Rx Path
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Init New Rx in Valid port");
+ return KAL_FALSE;
+ }
+
+ // Register callback - New Rx & Rx_Cb is null
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_UpModuleRegisterCb(handle, NULL, _tx_done_cb, _drv_state_change_cb);
+ if (ut_assert_flag == KAL_FALSE) {
+ FAIL_MSG("Upper Module Register Callback");
+ return KAL_FALSE;
+ }
+ ut_assert_flag = KAL_FALSE;
+
+ // Register callback - (New Tx or New Rx) & drv_state_change_cb is null
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, _tx_done_cb, NULL);
+ if (ut_assert_flag == KAL_FALSE) {
+ FAIL_MSG("Upper Module Register Callback");
+ return KAL_FALSE;
+ }
+ ut_assert_flag = KAL_FALSE;
+
+ // De-Init - Avoid next time Init Failed)
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("De-Init New Rx in Valid port");
+ return KAL_FALSE;
+ }
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool FuncVeri_ChangeOwner(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ UART_CTRL_OPEN_T ur_ctrl_open;
+ UART_CTRL_OWNER_T ur_ctrl_owner;
+ Seriport_HANDLER_T drv_ut_handler;
+
+ /*
+ * DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, data)
+ * - Description
+ * It will flush all Tx/Rx gpd, then change port owner.
+ *
+ * This API will be invoked by new owner but not original owner.
+ * If port will change to convention owner, you just call this API.
+ * Or change to New Path owner, you must call the following two API.
+ *
+ * DclSerialPort_UpModuleReinit(handle, module_id, flag)
+ * - Description
+ * Re-Initializing the port setting without closing port.
+ * Reset flags and Re-specify the Path of new owner.
+ * DclSerialPort_UpModuleRegisterCb(handle, rx_cb, tx_done_cb, drv_state_change_cb)
+ * - Description
+ * Register Callback function for new owner.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Scenario
+ * Conditions | Expected result
+ * ============================================================
+ * Invalid port | STATUS_FAIL
+ | STATUS_INVALID_DCL_HANDLE
+ | STATUS_INVALID_DEVICE
+ * valid port
+ * port InActive | STATUS_DEVICE_NOT_EXIST
+ * port Active with Attach/Detach | STATUS_OK
+ *
+ * Other Conditions
+ * 4 types
+ * Conv to Conv, Conv to New, New to Conv, New to New
+ */
+
+ device = uart_port_null;
+ handle = DclSerialPort_Open(device, 0);
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT;
+ // Invalid Port Test
+ status = DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+ if (status != STATUS_FAIL) {
+ FAIL_MSG("Change owner in Invalid port");
+ return KAL_FALSE;
+ }
+
+
+ drv_ut_handler.SeriportHandlerCb = _drv_handler_cb;
+ // Valid Port Test
+ // Port InActive
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ status = DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+ if (status != STATUS_DEVICE_NOT_EXIST) {
+ FAIL_MSG("Change owner with port InActive in Valid port");
+ return KAL_FALSE;
+ }
+ }
+
+ // Port Active
+ for (device = uart_port1; device <= uart_max_port; device++) {
+ handle = DclSerialPort_Open(device, 0);
+
+ // Port Active with each device type
+ for (devtype = DCL_UART_TYPE; devtype < DCL_UART_DEV_TYPE_MAX; devtype++){
+ drv_ut_handler.DevType = devtype;
+
+ // Register callback (Active)
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver Register Callback Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Conv to Conv
+ {
+ char * Error_Tag = "[Conv to Conv] ";
+
+ ur_ctrl_open.u4OwenrId = MOD_TTY_UT;
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Conventional initialization");
+ return KAL_FALSE;
+ }
+
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT;
+ status = DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Change owner to Conv owner");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "De-initialization");
+ return KAL_FALSE;
+ }
+ }
+ // Conv to New
+ {
+ int flag = TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX;
+ char * Error_Tag = "[Conv to New] ";
+
+ ur_ctrl_open.u4OwenrId = MOD_TTY_UT;
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Conventional initialization");
+ return KAL_FALSE;
+ }
+
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT;
+ status = DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Change owner to New owner");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleReinit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "New owner Re-Init");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, _tx_done_cb, _drv_state_change_cb);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "New owner Re-Register Callback");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "De-initialization");
+ return KAL_FALSE;
+ }
+ }
+ // New to Conv
+ {
+ int flag = TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX;
+ char * Error_Tag = "[New to Conv] ";
+
+
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "New Module initialization");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, _tx_done_cb, _drv_state_change_cb);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "New Module Register Callback");
+ return KAL_FALSE;
+ }
+
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT;
+ status = DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Change owner to Conv owner");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "De-initialization");
+ return KAL_FALSE;
+ }
+ }
+ // New to New
+ {
+ int flag = TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX;
+ char * Error_Tag = "[New to New] ";
+
+
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "New Module initialization");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, _tx_done_cb, _drv_state_change_cb);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "New Module Register Callback");
+ return KAL_FALSE;
+ }
+
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT;
+ status = DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "Change owner to New owner");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleReinit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "New owner Re-Init");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, _tx_done_cb, _drv_state_change_cb);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "New owner Re-Register Callback");
+ return KAL_FALSE;
+ }
+
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG_EXT(Error_Tag, "De-initialization");
+ return KAL_FALSE;
+ }
+ }
+
+ // De-Register callback (InActive port - Avoid next time RegisterCb Failed)
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_OK) {
+ FAIL_MSG("Driver De-RegisterCb Failed! Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+
+ return KAL_TRUE;
+}
+
+kal_bool FuncVeri_Misc(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_HANDLE handle;
+ /*
+ * This Test Case Just For Function Coverage.
+ * Nothing to be tested here.
+ */
+
+ handle = DclSerialPort_Open(uart_port_null, 0);
+
+ DclSerialPort_Close(handle);
+ DclSerialPort_Configure(handle, NULL);
+
+ return KAL_TRUE;
+}
+
+/***********************************
+ DataPath Verification
+ ***********************************/
+
+ /*
+ * In Data path verification,
+ * We won't Test with each port, just test one to represent all.
+ *
+ * In each sub-case,
+ * We will Test driver state change callback by initialing upper module
+ * before driver register its callback.
+ *
+ * Before the operation of data transfer, it never check driver is attach
+ * due to driver attach is expected here.
+ */
+
+/**************
+ Sub-Case
+ **************/
+kal_bool DataPath_Setup(DCL_HANDLE handle, SIO_TYPE_T devtype, int flag)
+{
+ DCL_STATUS status;
+ Seriport_HANDLER_T drv_ut_handler;
+
+ // Upper Module Initialize
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, flag);
+ if (status != STATUS_OK)
+ return KAL_FALSE;
+
+ // Only New Upper Module Need to register callback
+ if (flag) {
+ switch (flag) {
+ case TTY_FLAG_NEW_TX:
+ status = DclSerialPort_UpModuleRegisterCb(handle, NULL, _tx_done_cb, _drv_state_change_cb);
+ break;
+ case TTY_FLAG_NEW_RX:
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, NULL, _drv_state_change_cb);
+ break;
+ case TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX:
+ status = DclSerialPort_UpModuleRegisterCb(handle, _rx_cb, _tx_done_cb, _drv_state_change_cb);
+ break;
+ default:
+ status = STATUS_FAIL;
+ break;
+ }
+
+ if (status != STATUS_OK)
+ return KAL_FALSE;
+ }
+
+ // Driver Register callback & Attach
+ drv_ut_handler.DevType = devtype;
+ drv_ut_handler.SeriportHandlerCb = _drv_handler_cb;
+
+ status = DclSerialPort_DrvRegisterCb(handle, &drv_ut_handler);
+ if (status != STATUS_OK)
+ return KAL_FALSE;
+
+ status = DclSerialPort_DrvAttach(handle);
+ if (status != STATUS_OK)
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+
+kal_bool DataPath_Close(DCL_HANDLE handle)
+{
+ DCL_STATUS status;
+
+ // Upper Module DeInit
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK)
+ return KAL_FALSE;
+
+ // Driver Detatch
+ status = DclSerialPort_DrvDetach(handle);
+ if (status != STATUS_OK)
+ return KAL_FALSE;
+
+ // Driver DeRegister Callback
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_OK)
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+
+// Directly Path Sub-Case
+kal_bool ConvTxPath(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, 0);
+
+ // if Upper Module is conventional & not buffer mode, driver will using ilm to inform upper module driver attach.
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_PLUGIN_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+
+ // Conventional Tx Path
+ // Send Tx Data -> TxDoneCb -> Get "Ready to Write" ilm
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ char SendBuff[UT_TEST_SIZE];
+ int datalen;
+ int offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+ // Setup Tx Buffer Structure
+ offset = 0;
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_putbytes.puBuffaddr = SendBuff;
+ ur_ctrl_putbytes.u2Length = datalen;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ offset += ur_ctrl_putbytes.u2RetSize;
+
+ // Update Tx Buffer Structure
+ ur_ctrl_putbytes.puBuffaddr = SendBuff + offset;
+ ur_ctrl_putbytes.u2Length = datalen - offset;
+ }
+
+ // Dummy Driver
+ {
+ // Return Tx GPD to TTYCore
+ Tx_Flush_Gpd(device);
+ }
+
+ // Dummy Upper Module
+ {
+ // In conventional path, _tty_tx_done_cb will send ilm to inform upper module.
+ // when data buffer have the remaining data still haven't be sent.
+ if (offset < datalen) {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_WRITE_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ } while (offset < datalen);
+
+ // Compare data with Hardware Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ Dev_Mgmt[device].HwBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("[ConvTxPath] Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("[ConvTxPath] There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool ConvRxPath(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, 0);
+
+ // if Upper Module is conventional & not buffer mode, driver will using ilm to inform upper module driver attach.
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_PLUGIN_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+
+ // Conventional Rx Path
+ // Prepare Rx Data -> RxCb -> Get "Ready to Read" ilm -> Get Rx Data
+ {
+ UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
+ char RecvBuff[UT_TEST_SIZE];
+ int datalen;
+ int offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Rx Data
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ Dev_Mgmt[device].HwBuff[i] = i & UT_DATA_MASK;
+ }
+ Dev_Mgmt[device].size = datalen;
+
+ // Setup Rx Buffer Structure
+ offset = 0;
+ ur_ctrl_getbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff;
+ ur_ctrl_getbytes.u2Length = datalen;
+
+ // Receiving Data Until Data empty in Hardware
+ do {
+ // Dummy Hardware Operation
+ {
+ // Copy Data to Driver Rx GPD in the Rx Queue
+ Hw_PopDataToRxQue(device);
+ }
+
+ // Dummy Driver
+ {
+ // Get Rx GPDs(Contain Received Data) by De-Q
+ void * ior = Rx_DeQueToIor(device);
+ // Rx callback to send ior to tty
+ if (ior) {
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, ior);
+ }
+ }
+
+ // Dummy Upper Module
+ {
+ // In conventional path, _tty_rx_cb will send ilm to inform upper module data ready to read.
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_READ_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+
+ // Get Data
+ DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_getbytes);
+ offset += ur_ctrl_getbytes.u2RetSize;
+
+ // Update Rx Buffer Structure
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff + offset;
+ ur_ctrl_getbytes.u2Length = datalen - offset;
+ }
+ } while (Dev_Mgmt[device].size);
+
+ // Compare data with Hardware Buffer
+ for (i = 0; i < datalen; i++) {
+ if (RecvBuff[i] ^ Dev_Mgmt[device].HwBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("[ConvRxPath] Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("[ConvRxPath] There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool NewTxPath(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, TTY_FLAG_NEW_TX);
+
+ // New Tx Path
+ // Send Tx Data -> TxDoneCb(For free gpds)
+ {
+ char SendBuff[UT_TEST_SIZE];
+ int datalen;
+ int offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+ // Setup Tx Buffer Structure
+ offset = 0;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ void *gpd_t;
+ void *p_head;
+ void *p_tail;
+ tty_io_request_t *ior;
+ int gpd_num = 2;
+
+ // Create gpds for ior
+ // GPD_TYPE: QBM_TYPE_TTY_INT
+ // GPD_LEN: QBM_TTY_XXX_DATA_LEN(1024)
+ qbmt_alloc_q_no_tail(QBM_TYPE_TTY_INT, gpd_num, &p_head, &p_tail);
+ ior = (tty_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+ ior->first_gpd = p_head;
+ ior->last_gpd = p_tail;
+
+ // Copy data to gpds (the following code only suit for QBM_TYPE_TTY_INT)
+ list_each_gpd(gpd_t, ior->first_gpd, ior->last_gpd) {
+ int copylen = MIN(QBM_TTY_XXX_DATA_LEN, datalen - offset);
+
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(gpd_t), SendBuff + offset, copylen);
+ offset += copylen;
+
+ QBM_DES_SET_DATALEN(gpd_t, copylen);
+ }
+
+ DclSerialPort_UpModuleTransmit(handle, ior);
+ }
+
+ // Dummy Driver
+ {
+ // Free GPD or Return Tx GPD to Upper Module
+ Tx_Flush_Gpd(device);
+ }
+ } while (offset < datalen);
+
+ // Compare data with Hardware Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ Dev_Mgmt[device].HwBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("[NewTxPath] Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("[NewTxPath] There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool NewTxLightPath(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, TTY_FLAG_NEW_TX);
+
+ // New Tx Path
+ // Send Tx Data -> TxDoneCb(For free gpds)
+ {
+ char SendBuff[UT_TEST_SIZE];
+ int datalen;
+ int offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+ // Setup Tx Buffer Structure
+ offset = 0;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ void *gpd_t;
+ void *p_head;
+ void *p_tail;
+ tty_io_request_t *ior;
+ int gpd_num = 2;
+
+ // Create gpds for ior
+ // GPD_TYPE: QBM_TYPE_TTY_INT
+ // GPD_LEN: QBM_TTY_XXX_DATA_LEN(1024)
+ qbmt_alloc_q_no_tail(QBM_TYPE_TTY_INT, gpd_num, &p_head, &p_tail);
+ ior = (tty_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+ ior->first_gpd = p_head;
+ ior->last_gpd = p_tail;
+
+ // Copy data to gpds (the following code only suit for QBM_TYPE_TTY_INT)
+ list_each_gpd(gpd_t, ior->first_gpd, ior->last_gpd) {
+ int copylen = MIN(QBM_TTY_XXX_DATA_LEN, datalen - offset);
+
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(gpd_t), SendBuff + offset, copylen);
+ offset += copylen;
+
+ QBM_DES_SET_DATALEN(gpd_t, copylen);
+ }
+
+ DclSerialPort_UpModuleTransmitLight(handle, ior);
+ }
+
+ // Dummy Driver
+ {
+ // Free GPD or Return Tx GPD to Upper Module
+ Tx_Flush_Gpd(device);
+ }
+ } while (offset < datalen);
+
+ // Compare data with Hardware Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ Dev_Mgmt[device].HwBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("[NewTxPath] Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("[NewTxPath] There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool NewRxPath(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, TTY_FLAG_NEW_RX);
+
+ // New Rx Path
+ // Send Rx gpds -> RxCb
+ {
+ char RecvBuff[UT_TEST_SIZE];
+ int datalen;
+ int offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Rx Data
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ Dev_Mgmt[device].HwBuff[i] = i & UT_DATA_MASK;
+ }
+ Dev_Mgmt[device].size = datalen;
+
+ // Setup Rx Buffer Structure
+ offset = 0;
+
+
+
+ // Receiving Data Until Data empty in Hardware
+ do {
+ // Dummy Upper Module
+ {
+ void *p_head;
+ void *p_tail;
+ tty_io_request_t *ior;
+ int gpd_num = 2;
+
+ // Create gpds for ior
+ // GPD_TYPE: QBM_TYPE_TTY_INT
+ // GPD_LEN: QBM_TTY_XXX_DATA_LEN(1024)
+ qbmt_alloc_q(QBM_TYPE_TTY_INT, gpd_num, &p_head, &p_tail);
+ ior = (tty_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+ ior->first_gpd = p_head;
+ ior->last_gpd = p_tail;
+
+ // Send Rx_Ior to Driver
+ DclSerialPort_UpModuleAssignRxIor(handle, ior);
+ }
+
+ // Dummy Hardware Operation
+ {
+ // Copy Data to Driver Rx GPD in the Rx Queue
+ Hw_PopDataToRxQue(device);
+ }
+
+ // Dummy Driver
+ {
+ // Get Rx GPDs(Contain Received Data) by De-Q
+ void * ior = Rx_DeQueToIor(device);
+ // Rx callback to send ior to tty
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, ior);
+ }
+
+ // Dummy Upper Module
+ {
+ if (Dev_Mgmt[device].Rx_Ior) {
+ void *gpd_t;
+
+ // Copy data from gpds (the following code only suit for QBM_TYPE_TTY_INT)
+ list_each_gpd(gpd_t, Dev_Mgmt[device].Rx_Ior->first_gpd, Dev_Mgmt[device].Rx_Ior->last_gpd) {
+ int copylen = MIN(QBM_TTY_XXX_DATA_LEN, QBM_DES_GET_DATALEN(gpd_t));
+
+ kal_mem_cpy(RecvBuff + offset, QBM_DES_GET_DATAPTR(gpd_t), copylen);
+ offset += copylen;
+ }
+ // Free Rx Ior
+ qbmt_dest_q(Dev_Mgmt[device].Rx_Ior->first_gpd, Dev_Mgmt[device].Rx_Ior->last_gpd);
+ }
+ }
+ } while (offset < datalen);
+
+ // Compare data with Hardware Buffer
+ for (i = 0; i < datalen; i++) {
+ if (RecvBuff[i] ^ Dev_Mgmt[device].HwBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("[NewRxPath] Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("[NewRxPath] There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool BuffModTxPath(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_CMUX_TYPE; // Driver type is BUFF_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, 0);
+
+ // Conventional Tx Path
+ // Send Tx Data -> TxDoneCb -> Get "Ready to Write" ilm
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ char SendBuff[UT_TEST_SIZE];
+ int datalen;
+ int offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+
+ // Setup Tx Buffer Structure
+ offset = 0;
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_putbytes.puBuffaddr = SendBuff;
+ ur_ctrl_putbytes.u2Length = datalen;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ offset += ur_ctrl_putbytes.u2RetSize;
+
+ // Update Tx Buffer Structure
+ ur_ctrl_putbytes.puBuffaddr = SendBuff + offset;
+ ur_ctrl_putbytes.u2Length = datalen - offset;
+ }
+
+ // Dummy Driver
+ {
+ // Using TxDoneCb to inform TTYCore
+ DclSerialPort_DrvTxDone(handle, DRV_TTY_UT, NULL);
+ }
+
+ // Dummy Upper Module
+ {
+ // In conventional path, _tty_tx_done_cb will send ilm to inform upper module.
+ // when data buffer have the remaining data still haven't be sent.
+ if (offset < datalen) {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_WRITE_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ } while (offset < datalen);
+
+ // Compare data with Hardware Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ Dev_Mgmt[device].HwBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("[BuffModTxPath] Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("[BuffModTxPath] There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool BuffModRxPath(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_CMUX_TYPE; // Driver type is BUFF_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, 0);
+
+ // Conventional Rx Path
+ // Prepare Rx Data -> RxCb -> Get "Ready to Read" ilm -> Get Rx Data
+ {
+ UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
+ char RecvBuff[UT_TEST_SIZE];
+ int datalen;
+ int offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Rx Data
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ Dev_Mgmt[device].HwBuff[i] = i & UT_DATA_MASK;
+ }
+ Dev_Mgmt[device].size = datalen;
+
+ // Setup Rx Buffer Structure
+ offset = 0;
+ ur_ctrl_getbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff;
+ ur_ctrl_getbytes.u2Length = datalen;
+
+
+ // Dummy Driver
+ {
+ // Using RxCb to inform TTYCore
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, NULL);
+
+ // It will raise the flag rx_up_mod_wait at Rx buffer mode initial
+ // When using Rx_Cb to inform TTYCore it will send ilm at first time.
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_READ_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ do {
+ // Dummy Upper Module
+ {
+ // Get Data
+ DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_getbytes);
+ offset += ur_ctrl_getbytes.u2RetSize;
+
+ // Update Rx Buffer Structure
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff + offset;
+ ur_ctrl_getbytes.u2Length = datalen - offset;
+ }
+
+ ///TODO: check there is no ilm because there is sent in SIO_CMD_GET_RX_AVAIL
+ } while (Dev_Mgmt[device].size);
+
+ // Compare data with Hardware Buffer
+ for (i = 0; i < datalen; i++) {
+ if (RecvBuff[i] ^ Dev_Mgmt[device].HwBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("[BuffModRxPath] Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("[BuffModRxPath] There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+// Loopback Test Sub-Case
+kal_bool NewTx_NewRx(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+
+ // Send Tx Data -> TxDoneCb(For free gpds) -> Send Rx gpds -> RxCb
+ {
+ char SendBuff[UT_TEST_SIZE];
+ char RecvBuff[UT_TEST_SIZE];
+ int datalen;
+ int s_offset;
+ int r_offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+ // Setup Buffer Structure
+ s_offset = 0;
+ r_offset = 0;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ void *gpd_t;
+ void *p_head;
+ void *p_tail;
+ tty_io_request_t *ior;
+ int gpd_num = 2;
+
+ // Create gpds for ior
+ // GPD_TYPE: QBM_TYPE_TTY_INT
+ // GPD_LEN: QBM_TTY_XXX_DATA_LEN(1024)
+ qbmt_alloc_q_no_tail(QBM_TYPE_TTY_INT, gpd_num, &p_head, &p_tail);
+ ior = (tty_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+ ior->first_gpd = p_head;
+ ior->last_gpd = p_tail;
+
+ // Copy data to gpds (the following code only suit for QBM_TYPE_TTY_INT)
+ list_each_gpd(gpd_t, ior->first_gpd, ior->last_gpd) {
+ int copylen = MIN(QBM_TTY_XXX_DATA_LEN, datalen - s_offset);
+
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(gpd_t), SendBuff + s_offset, copylen);
+ s_offset += copylen;
+
+ QBM_DES_SET_DATALEN(gpd_t, copylen);
+ }
+
+ DclSerialPort_UpModuleTransmit(handle, ior);
+ }
+
+ // Dummy Driver
+ {
+ // Free GPD or Return Tx GPD to Upper Module
+ Tx_Flush_Gpd(device);
+ }
+ } while (s_offset < datalen);
+
+ // Receiving Data Until Data empty in Hardware
+ do {
+ // Dummy Upper Module
+ {
+ void *p_head;
+ void *p_tail;
+ tty_io_request_t *ior;
+ int gpd_num = 2;
+
+ // Create gpds for ior
+ // GPD_TYPE: QBM_TYPE_TTY_INT
+ // GPD_LEN: QBM_TTY_XXX_DATA_LEN(1024)
+ qbmt_alloc_q(QBM_TYPE_TTY_INT, gpd_num, &p_head, &p_tail);
+ ior = (tty_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+ ior->first_gpd = p_head;
+ ior->last_gpd = p_tail;
+
+ // Send Rx_Ior to Driver
+ DclSerialPort_UpModuleAssignRxIor(handle, ior);
+ }
+
+ // Dummy Hardware Operation
+ {
+ // Copy Data to Driver Rx GPD in the Rx Queue
+ Hw_PopDataToRxQue(device);
+ }
+
+ // Dummy Driver
+ {
+ // Get Rx GPDs(Contain Received Data) by De-Q
+ void * ior = Rx_DeQueToIor(device);
+ // Rx callback to send ior to tty
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, ior);
+ }
+
+ // Dummy Upper Module
+ {
+ if (Dev_Mgmt[device].Rx_Ior) {
+ void *gpd_t;
+
+ // Copy data from gpds (the following code only suit for QBM_TYPE_TTY_INT)
+ list_each_gpd(gpd_t, Dev_Mgmt[device].Rx_Ior->first_gpd, Dev_Mgmt[device].Rx_Ior->last_gpd) {
+ int copylen = MIN(QBM_TTY_XXX_DATA_LEN, QBM_DES_GET_DATALEN(gpd_t));
+
+ kal_mem_cpy(RecvBuff + r_offset, QBM_DES_GET_DATAPTR(gpd_t), copylen);
+ r_offset += copylen;
+ }
+ // Free Rx Ior
+ qbmt_dest_q(Dev_Mgmt[device].Rx_Ior->first_gpd, Dev_Mgmt[device].Rx_Ior->last_gpd);
+ }
+ }
+ } while (r_offset < datalen);
+
+ // Compare data between Send Buffer & Receive Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ RecvBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool NewTx_ConvRx(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, TTY_FLAG_NEW_TX);
+
+ // Send Tx Data -> TxDoneCb(For free gpds) -> RxCb -> Send Rx Buffer
+ {
+ UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
+ char SendBuff[UT_TEST_SIZE];
+ char RecvBuff[UT_TEST_SIZE];
+ int datalen;
+ int s_offset;
+ int r_offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+ // Setup Tx Buffer Structure
+ s_offset = 0;
+ r_offset = 0;
+ ur_ctrl_getbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff;
+ ur_ctrl_getbytes.u2Length = datalen;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ void *gpd_t;
+ void *p_head;
+ void *p_tail;
+ tty_io_request_t *ior;
+ int gpd_num = 2;
+
+ // Create gpds for ior
+ // GPD_TYPE: QBM_TYPE_TTY_INT
+ // GPD_LEN: QBM_TTY_XXX_DATA_LEN(1024)
+ qbmt_alloc_q_no_tail(QBM_TYPE_TTY_INT, gpd_num, &p_head, &p_tail);
+ ior = (tty_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+ ior->first_gpd = p_head;
+ ior->last_gpd = p_tail;
+
+ // Copy data to gpds (the following code only suit for QBM_TYPE_TTY_INT)
+ list_each_gpd(gpd_t, ior->first_gpd, ior->last_gpd) {
+ int copylen = MIN(QBM_TTY_XXX_DATA_LEN, datalen - s_offset);
+
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(gpd_t), SendBuff + s_offset, copylen);
+ s_offset += copylen;
+
+ QBM_DES_SET_DATALEN(gpd_t, copylen);
+ }
+
+ DclSerialPort_UpModuleTransmit(handle, ior);
+ }
+
+ // Dummy Driver
+ {
+ // Free GPD or Return Tx GPD to Upper Module
+ Tx_Flush_Gpd(device);
+ }
+ } while (s_offset < datalen);
+
+ // Receiving Data Until Data empty in Hardware
+ do {
+ // Dummy Hardware Operation
+ {
+ // Copy Data to Driver Rx GPD in the Rx Queue
+ Hw_PopDataToRxQue(device);
+ }
+
+ // Dummy Driver
+ {
+ // Get Rx GPDs(Contain Received Data) by De-Q
+ void * ior = Rx_DeQueToIor(device);
+ // Rx callback to send ior to tty
+ if (ior) {
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, ior);
+ }
+ }
+
+ // Dummy Upper Module
+ {
+ // In conventional path, _tty_rx_cb will send ilm to inform upper module data ready to read.
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_READ_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+
+ // Get Data
+ DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_getbytes);
+ r_offset += ur_ctrl_getbytes.u2RetSize;
+
+ // Update Rx Buffer Structure
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff + r_offset;
+ ur_ctrl_getbytes.u2Length = datalen - r_offset;
+ }
+ } while (Dev_Mgmt[device].size);
+
+ // Compare data between Send Buffer & Receive Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ RecvBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool ConvTx_NewRx(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, TTY_FLAG_NEW_RX);
+
+ // Send Tx Data -> TxDoneCb -> Get "Ready to Write" ilm -> Send Rx gpds -> RxCb
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ char SendBuff[UT_TEST_SIZE];
+ char RecvBuff[UT_TEST_SIZE];
+ int datalen;
+ int s_offset;
+ int r_offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+ // Setup Buffer Structure
+ s_offset = 0;
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_putbytes.puBuffaddr = SendBuff;
+ ur_ctrl_putbytes.u2Length = datalen;
+ r_offset = 0;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ s_offset += ur_ctrl_putbytes.u2RetSize;
+
+ // Update Tx Buffer Structure
+ ur_ctrl_putbytes.puBuffaddr = SendBuff + s_offset;
+ ur_ctrl_putbytes.u2Length = datalen - s_offset;
+ }
+
+ // Dummy Driver
+ {
+ // Return Tx GPD to TTYCore
+ Tx_Flush_Gpd(device);
+ }
+
+ // Dummy Upper Module
+ {
+ // In conventional path, _tty_tx_done_cb will send ilm to inform upper module.
+ // when data buffer have the remaining data still haven't be sent.
+ if (s_offset < datalen) {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_WRITE_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ } while (s_offset < datalen);
+
+ // Receiving Data Until Data empty in Hardware
+ do {
+ // Dummy Upper Module
+ {
+ void *p_head;
+ void *p_tail;
+ tty_io_request_t *ior;
+ int gpd_num = 2;
+
+ // Create gpds for ior
+ // GPD_TYPE: QBM_TYPE_TTY_INT
+ // GPD_LEN: QBM_TTY_XXX_DATA_LEN(1024)
+ qbmt_alloc_q(QBM_TYPE_TTY_INT, gpd_num, &p_head, &p_tail);
+ ior = (tty_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+ ior->first_gpd = p_head;
+ ior->last_gpd = p_tail;
+
+ // Send Rx_Ior to Driver
+ DclSerialPort_UpModuleAssignRxIor(handle, ior);
+ }
+
+ // Dummy Hardware Operation
+ {
+ // Copy Data to Driver Rx GPD in the Rx Queue
+ Hw_PopDataToRxQue(device);
+ }
+
+ // Dummy Driver
+ {
+ // Get Rx GPDs(Contain Received Data) by De-Q
+ void * ior = Rx_DeQueToIor(device);
+ // Rx callback to send ior to tty
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, ior);
+ }
+
+ // Dummy Upper Module
+ {
+ if (Dev_Mgmt[device].Rx_Ior) {
+ void *gpd_t;
+
+ // Copy data from gpds (the following code only suit for QBM_TYPE_TTY_INT)
+ list_each_gpd(gpd_t, Dev_Mgmt[device].Rx_Ior->first_gpd, Dev_Mgmt[device].Rx_Ior->last_gpd) {
+ int copylen = MIN(QBM_TTY_XXX_DATA_LEN, QBM_DES_GET_DATALEN(gpd_t));
+
+ kal_mem_cpy(RecvBuff + r_offset, QBM_DES_GET_DATAPTR(gpd_t), copylen);
+ r_offset += copylen;
+ }
+ // Free Rx Ior
+ qbmt_dest_q(Dev_Mgmt[device].Rx_Ior->first_gpd, Dev_Mgmt[device].Rx_Ior->last_gpd);
+ }
+ }
+ } while (r_offset < datalen);
+
+ // Compare data between Send Buffer & Receive Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ RecvBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool ConvTx_ConvRx(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_USB_TYPE; // Driver type is GPD_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, 0);
+
+ // if Upper Module is conventional & not buffer mode, driver will using ilm to inform upper module driver attach.
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_PLUGIN_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+
+ // Send Tx Data -> TxDoneCb -> Get "Ready to Write" ilm -> RxCb -> Send Rx gpds
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
+ char SendBuff[UT_TEST_SIZE];
+ char RecvBuff[UT_TEST_SIZE];
+ int datalen;
+ int s_offset;
+ int r_offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+ // Setup Buffer Structure
+ s_offset = 0;
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_putbytes.puBuffaddr = SendBuff;
+ ur_ctrl_putbytes.u2Length = datalen;
+ r_offset = 0;
+ ur_ctrl_getbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff;
+ ur_ctrl_getbytes.u2Length = datalen;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ s_offset += ur_ctrl_putbytes.u2RetSize;
+
+ // Update Tx Buffer Structure
+ ur_ctrl_putbytes.puBuffaddr = SendBuff + s_offset;
+ ur_ctrl_putbytes.u2Length = datalen - s_offset;
+ }
+
+ // Dummy Driver
+ {
+ // Return Tx GPD to TTYCore
+ Tx_Flush_Gpd(device);
+ }
+
+ // Dummy Upper Module
+ {
+ // In conventional path, _tty_tx_done_cb will send ilm to inform upper module.
+ // when data buffer have the remaining data still haven't be sent.
+ if (s_offset < datalen) {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_WRITE_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ } while (s_offset < datalen);
+
+ // Receiving Data Until Data empty in Hardware
+ do {
+ // Dummy Hardware Operation
+ {
+ // Copy Data to Driver Rx GPD in the Rx Queue
+ Hw_PopDataToRxQue(device);
+ }
+
+ // Dummy Driver
+ {
+ // Get Rx GPDs(Contain Received Data) by De-Q
+ void * ior = Rx_DeQueToIor(device);
+ // Rx callback to send ior to tty
+ if (ior) {
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, ior);
+ }
+ }
+
+ // Dummy Upper Module
+ {
+ // In conventional path, _tty_rx_cb will send ilm to inform upper module data ready to read.
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_READ_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+
+ // Get Data
+ DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_getbytes);
+ r_offset += ur_ctrl_getbytes.u2RetSize;
+
+ // Update Rx Buffer Structure
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff + r_offset;
+ ur_ctrl_getbytes.u2Length = datalen - r_offset;
+ }
+ } while (Dev_Mgmt[device].size);
+
+ // Compare data between Send Buffer & Receive Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ RecvBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool BuffMod_ConvTx_ConvRx(kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ DCL_DEV device;
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ SIO_TYPE_T devtype;
+ kal_bool data_corrupt;
+
+ // Setup Port & Driver Type
+ device = uart_port1;
+ devtype = DCL_UART_CMUX_TYPE; // Driver type is BUFF_DRV_TYPE
+ data_corrupt = KAL_FALSE;
+
+ // Get handle
+ handle = DclSerialPort_Open(device, 0);
+
+ // Upper Module Initialize & Driver Register callback and then Attach
+ DataPath_Setup(handle, devtype, 0);
+
+ // Send Tx Data -> TxDoneCb -> Get "Ready to Write" ilm -> RxCb -> Send Rx gpds
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
+ char SendBuff[UT_TEST_SIZE];
+ char RecvBuff[UT_TEST_SIZE];
+ int datalen;
+ int s_offset;
+ int r_offset;
+ int i;
+
+ // Clear Hardware Buffer
+ Hw_ClearBuff(device);
+
+ // Prepare Data to Send
+ datalen = UT_TEST_SIZE;
+ for (i = 0; i < datalen; i++) {
+ SendBuff[i] = i & UT_DATA_MASK;
+ }
+
+ // Setup Buffer Structure
+ s_offset = 0;
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_putbytes.puBuffaddr = SendBuff;
+ ur_ctrl_putbytes.u2Length = datalen;
+ r_offset = 0;
+ ur_ctrl_getbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff;
+ ur_ctrl_getbytes.u2Length = datalen;
+
+ // Sending Data Until Sending Complete
+ do {
+ // Dummy Upper Module
+ {
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ s_offset += ur_ctrl_putbytes.u2RetSize;
+
+ // Update Tx Buffer Structure
+ ur_ctrl_putbytes.puBuffaddr = SendBuff + s_offset;
+ ur_ctrl_putbytes.u2Length = datalen - s_offset;
+ }
+
+ // Dummy Driver
+ {
+ // Using TxDoneCb to inform TTYCore
+ DclSerialPort_DrvTxDone(handle, DRV_TTY_UT, NULL);
+ }
+
+ // Dummy Upper Module
+ {
+ // In conventional path, _tty_tx_done_cb will send ilm to inform upper module.
+ // when data buffer have the remaining data still haven't be sent.
+ if (s_offset < datalen) {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_WRITE_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ } while (s_offset < datalen);
+
+ // Dummy Driver
+ {
+ // Using RxCb to inform TTYCore
+ DclSerialPort_DrvRx(handle, DRV_TTY_UT, NULL);
+
+ // It will raise the flag rx_up_mod_wait at Rx buffer mode initial
+ // When using Rx_Cb to inform TTYCore it will send ilm at first time.
+ {
+ ilm_struct current_ilm;
+
+ msg_receive_extq(¤t_ilm);
+ if (current_ilm.msg_id != MSG_ID_UART_READY_TO_READ_IND) {
+ destroy_ilm(¤t_ilm);
+ return KAL_FALSE;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ // Receiving Data Until Data empty in Hardware
+ do {
+ // Dummy Upper Module
+ {
+ // Get Data
+ DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_getbytes);
+ r_offset += ur_ctrl_getbytes.u2RetSize;
+
+ // Update Rx Buffer Structure
+ ur_ctrl_getbytes.puBuffaddr = RecvBuff + r_offset;
+ ur_ctrl_getbytes.u2Length = datalen - r_offset;
+ }
+ } while (Dev_Mgmt[device].size);
+
+ // Compare data between Send Buffer & Receive Buffer
+ for (i = 0; i < datalen; i++) {
+ if (SendBuff[i] ^ RecvBuff[i]) {
+ data_corrupt = KAL_TRUE;
+ break;
+ }
+ }
+ }
+
+ // Upper Module DeInit & Driver Detatch & DeRegister Callback
+ DataPath_Close(handle);
+
+ // Check data no corrupt
+ if (data_corrupt) {
+ FAIL_MSG("Data Corrupt in Device# = %d, DevType = %d", device, devtype);
+ return KAL_FALSE;
+ }
+
+ // Check there is no assert
+ if (ut_assert_flag) {
+ ut_assert_flag = KAL_FALSE; // clear flag
+ FAIL_MSG("There is a assertion in exception. It's found at Test Case end");
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+/**************
+ Main-Case
+ **************/
+kal_bool DataPath_DirectlyPath(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ if (IS_SUB_CASE_FAIL(ConvTxPath))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(ConvRxPath))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(NewTxPath))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(NewTxLightPath))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(NewRxPath))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(BuffModTxPath))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(BuffModRxPath))
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+
+kal_bool DataPath_LoopbackTest(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ if (IS_SUB_CASE_FAIL(NewTx_NewRx))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(NewTx_ConvRx))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(ConvTx_NewRx))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(ConvTx_ConvRx))
+ return KAL_FALSE;
+ if (IS_SUB_CASE_FAIL(BuffMod_ConvTx_ConvRx))
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+
+/***********************************
+ UnitTest Begin End
+ ***********************************/
+kal_bool utTest_Initialize(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_mem_set(Dev_Mgmt, 0, sizeof(UtInstance) * UART_DEV_CNT);
+
+ return KAL_TRUE;
+}
+
+kal_bool utTest_End(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ return KAL_TRUE;
+}
+
+/****************************************************************************
+ TTYUT Task Init Function
+ ***************************************************************************/
+
+#define UT_TEST(_func, param) { #_func, _func, param }
+ST_TCASE_T st_tcase_g[] = {
+ UT_TEST(utTest_Initialize, NULL),
+
+ // Don't take out "FuncVeri_Common" case, DclSerialPort_Initialize will make test environment clear.
+ UT_TEST(FuncVeri_Common, NULL),
+
+ UT_TEST(FuncVeri_DrvRegDeRegCb, NULL),
+ UT_TEST(FuncVeri_DrvAtDetach, NULL),
+ UT_TEST(FuncVeri_UpInitDeinit, NULL),
+ UT_TEST(FuncVeri_UpRegCb, NULL),
+ UT_TEST(FuncVeri_ChangeOwner, NULL),
+ UT_TEST(FuncVeri_Misc, NULL),
+
+ UT_TEST(DataPath_DirectlyPath, NULL),
+ UT_TEST(DataPath_LoopbackTest, NULL),
+ /// TODO: DataPath for ChangeOwner
+
+ UT_TEST(utTest_End, NULL)
+};
+kal_uint32 st_tcase_count_g = sizeof(st_tcase_g) / sizeof(ST_TCASE_T);
+
+kal_bool tty_ut_st_create (void)
+{
+ return st_reg_test(ST_MOD_NAME, /* p_mod_name */
+ &st_tcase_g, /* p_tcase */
+ st_tcase_count_g /* tcase_num */
+ );
+}
+
diff --git a/mcu/driver/tty/src/tty_ut.c b/mcu/driver/tty/src/tty_ut.c
new file mode 100644
index 0000000..a3f16ee
--- /dev/null
+++ b/mcu/driver/tty/src/tty_ut.c
@@ -0,0 +1,1779 @@
+/*****************************************************************************
+* 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:
+ * ---------
+ * tty_ut.c
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * TTY Core unit test file - it needs Host Test Program to run test.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 09 23 2019 bo-kai.huang
+ * [MOLY00357061] 97 Code Merge
+ * [TerTer]
+ *
+ * 10 21 2015 mt.tsai
+ * [MOLY00146136] Fix TTY Core ut program for SMP and set gpd's next to NULL
+ * give a UT Task instance on each port to prevent race condition & Set gpd's next as NULL
+ *
+ * 03 11 2015 i-wei.tsai
+ * [MOLY00097392] [UMOLY] [TTY] Timer tick macro modification
+ * .
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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 <stdlib.h>
+#include <math.h>
+#include "kal_debug.h"
+//#include "kal_release.h"
+#include "syscomp_config.h"
+#include "kal_debug.h"
+#include "dcl.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+
+#include "devdrv_ls.h"
+#include "drv_msgid.h"
+#include "md_drv_sap.h"
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+
+/*for dhl trace*/
+#include "dhl_trace.h"
+
+#define TTY_UT_MISC_TEST (0) /* Set 1 to enable owner test and init/deinit test*/
+
+#define USB_TEST
+//#undef USB_TEST
+
+#if defined USB_TEST /* USB COM */
+#define TTY_UT_COM_NUM 3
+#define TTY_UT_COM1 uart_port_usb3
+#define TTY_UT_COM2 uart_port_usb4
+#define TTY_UT_COM3 uart_port_usb5
+
+#else /* UART COM */
+#define TTY_UT_COM_NUM 1
+#define TTY_UT_COM1 uart_port2
+#define TTY_UT_COM2 uart_port2
+#define TTY_UT_COM3 uart_port2
+#endif
+
+#if (TTY_UT_COM_NUM > 3)
+#error "COM number more than three does not support."
+#endif
+
+#define TTY_UT_TASK_1_PRIORITY 1
+#define TTY_UT_TASK_2_PRIORITY 2
+#define TTY_UT_TASK_3_PRIORITY 3
+
+#define IO_REQUEST_PUSH(_ori, _new) \
+{ \
+ tty_io_request_t *tmp_ior = _ori; \
+ while (tmp_ior->next_request != NULL) { \
+ tmp_ior = tmp_ior->next_request; \
+ } \
+ tmp_ior->next_request = _new; \
+}
+
+#define BUSY_WAIT(_loopCnt) do{unsigned int i,j;for(i=0;i<_loopCnt;i++){j=i;j++;}}while(0)
+
+typedef enum _tty_ut_mode {
+ TTY_UT_CONV_TX_ONLY = 0,
+ TTY_UT_NEW_TX_ONLY,
+ TTY_UT_CONV_RX_ONLY,
+ TTY_UT_NEW_RX_ONLY,
+ TTY_UT_CONV_TX_CONV_RX,
+ TTY_UT_CONV_TX_NEW_RX,
+ TTY_UT_NEW_TX_CONV_RX,
+ TTY_UT_NEW_TX_NEW_RX,
+ TTY_UT_NEW_INIT_CONV_TX_CONV_RX,
+ TTY_UT_BYPASS, //This is used to disable test procedure
+} tty_ut_mode_e;
+
+static tty_ut_mode_e tty_ut_mode_1 = TTY_UT_NEW_TX_NEW_RX; //TTY_UT_NEW_TX_NEW_RX;
+static tty_ut_mode_e tty_ut_mode_2 = /*TTY_UT_NEW_TX_NEW_RX;*/ TTY_UT_CONV_TX_CONV_RX;
+static tty_ut_mode_e tty_ut_mode_3 = TTY_UT_NEW_TX_CONV_RX;
+
+// for conventional path
+#define TTY_UT_NEW_BUF_SIZE QBM_TTY_XXX_DATA_LEN
+#define TTY_UT_CONV_BUF_SIZE QBM_TTY_XXX_DATA_LEN*2
+
+#define TTY_UT_LB_CON_TX_TX_BUF_SIZE QBM_TTY_XXX_DATA_LEN*10
+
+#define TTY_UT_CHUNK_SIZE_DEFAULT (QBM_TTY_XXX_DATA_LEN)
+
+typedef struct _ttyut_instance_t {
+ DCL_HANDLE handle;
+ DCL_UINT32 owner;
+ tty_io_request_t *ttyut_rx_ior;
+ kal_mutexid ttyut_mutex;
+
+ kal_uint8 ttyut_rx_buf[TTY_UT_CONV_BUF_SIZE];
+ kal_uint8 ttyut_tx_buf[TTY_UT_CONV_BUF_SIZE];
+ kal_uint32 ttyut_tx_offset;
+ kal_uint32 ttyut_tx_len;
+
+ kal_uint8 conv_tx_rx_buf[TTY_UT_LB_CON_TX_TX_BUF_SIZE];
+ kal_uint32 conv_tx_rx_rd_idx;
+ kal_uint32 conv_tx_rx_wt_idx;
+ kal_uint32 conv_tx_rx_wrap;
+} ttyut_instance_t;
+static ttyut_instance_t ttyut_inst_g[uart_max_port];
+
+#if defined(__MTK_TARGET__)
+extern void dbg_print(char *fmt,...);
+#define ttyut_print dbg_print
+#else
+#define ttyut_print(...) dhl_print(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_TTY, ##__VA_ARGS__)
+#endif
+
+#define DCL_UART_MAGIC_NUM 0x40000000
+#define DCL_UART_GET_DEV(handle_) ((DCL_DEV)((handle_) & (~DCL_UART_MAGIC_NUM)))
+
+// ==========================================================
+// Private Function
+// ==========================================================
+static kal_bool ttyut_create_instance(DCL_HANDLE handle, DCL_UINT32 owner)
+{
+ char mutex_name_str[64];
+ DCL_DEV uart_port = DCL_UART_GET_DEV(handle);
+
+ if (ttyut_inst_g[uart_port].handle == (DCL_HANDLE) 0x0) {
+
+ sprintf(mutex_name_str, "TTY_UT_%d", (int)handle);
+ ttyut_inst_g[uart_port].handle = handle;
+ ttyut_inst_g[uart_port].owner = owner;
+ ttyut_inst_g[uart_port].ttyut_rx_ior = NULL;
+ ttyut_inst_g[uart_port].ttyut_mutex = kal_create_mutex(mutex_name_str);
+
+ return KAL_TRUE;
+ }
+
+ // Can't create TTY_UT instance, ASSERT.
+ ASSERT(0);
+ return KAL_FALSE;
+}
+
+static ttyut_instance_t* ttyut_get_instance(DCL_HANDLE handle)
+{
+ DCL_DEV uart_port = DCL_UART_GET_DEV(handle);
+
+ if (ttyut_inst_g[uart_port].handle == handle) {
+ return &ttyut_inst_g[uart_port];
+ }
+
+ return NULL;
+}
+
+
+// ==========================================================
+// Private Function
+// ==========================================================
+DCL_STATUS _ttyut_rx_cb(DCL_HANDLE handle, module_type source_id, tty_io_request_t *rx_ior)
+{
+ ttyut_instance_t *ttyut_inst_p;
+
+ ttyut_inst_p = ttyut_get_instance(handle);
+
+ kal_take_mutex(ttyut_inst_p->ttyut_mutex);
+ if (ttyut_inst_p->ttyut_rx_ior) {
+ IO_REQUEST_PUSH(ttyut_inst_p->ttyut_rx_ior, rx_ior);
+ } else {
+ ttyut_inst_p->ttyut_rx_ior = rx_ior;
+ }
+ kal_give_mutex(ttyut_inst_p->ttyut_mutex);
+
+ ttyut_print("=========>_ttyut_rx_cb\r\n");
+ return STATUS_OK;
+}
+
+DCL_STATUS _ttyut_tx_done_cb(DCL_HANDLE handle, module_type source_id, tty_io_request_t *tx_ior)
+{
+ if (tx_ior) {
+ /* free all GPDs of all IOR */
+ do {
+ qbmt_dest_q(tx_ior->first_gpd, tx_ior->last_gpd);
+ } while ((tx_ior = tx_ior->next_request) != NULL);
+ } else {
+ ttyut_print("[TTY UT] [ERROR] =========>_ttyut_tx_done_cb : tx_ior is NULL!!!!!\r\n");
+ }
+
+ ttyut_print("=========>_ttyut_tx_done_cb\r\n");
+ return STATUS_OK;
+}
+
+DCL_STATUS _ttyut_drv_state_cb(DCL_HANDLE handle, tty_drv_state_e state)
+{
+ ttyut_print("=========>_ttyut_drv_state_cb: state - %s\r\n", (state==DRV_ST_ATTACHED)?"attached":"detached");
+ return STATUS_OK;
+}
+
+DCL_STATUS _ttyut_hdr_main(DCL_DEV dev, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ return STATUS_OK;
+}
+
+kal_bool _ttyut_upmod_init_deinit_test(kal_uint8 uart_port)
+{
+ #define TEST_ROUND 100
+ #define UART_INVALID_PORT 0xFFFF
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ int idx;
+ UART_CTRL_OPEN_T ur_ctrl_open;
+ UART_CTRL_CLOSE_T ur_ctrl_close;
+ Seriport_HANDLER_T tty_ut_uart_handler = {DCL_UART_USB_TYPE, _ttyut_hdr_main};
+
+ /*Test 1*/
+ /* Init non-existed port -> should init failed */
+ /* test invalid port 0xFFFF*/
+ handle = DclSerialPort_Open(UART_INVALID_PORT, 0);
+ if(handle != STATUS_INVALID_DEVICE)
+ {
+ ttyut_print("[ERROR][TTY UT] DCL upper module open non-existed port successfully");
+ return KAL_FALSE;
+ }
+ /* test non-exist port by invalid handle with NEW API*/
+ handle = 0xFFFF;
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module init non-existed port with NEW API successfully");
+ return KAL_FALSE;
+ }
+ /* test non-exist port by invalid handle with Conventional API*/
+ handle = 0xFFFF;
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module init non-existed port with Conv API successfully");
+ return KAL_FALSE;
+ }
+
+ /*Test 2 : Driver reg/de-reg API test*/
+ /* First register callback -> should not return failed */
+ handle = DclSerialPort_Open(uart_max_port, 0);
+ for (idx = 0; idx < TEST_ROUND; idx ++)
+ {
+ status = DclSerialPort_DrvRegisterCb(handle, &tty_ut_uart_handler);
+ if (status != STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] Driver first register callback function failed");
+ return KAL_FALSE;
+ }
+ /* Duplicated register -> should return failed */
+ status = DclSerialPort_DrvRegisterCb(handle, &tty_ut_uart_handler);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] Driver first register callback function twice successfully");
+ return KAL_FALSE;
+ }
+ /* First De-register callback -> should not return failed */
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status != STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] Driver first De-register callback function failed");
+ return KAL_FALSE;
+ }
+ /* Duplicated register -> should return failed */
+ status = DclSerialPort_DrvDeRegisterCb(handle);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] Driver De-register callback function twice successfully");
+ return KAL_FALSE;
+ }
+ }
+
+ /*Test 3 : open non-registered port with NEW API*/
+ /* Init non-register port -> should not return failed */
+ handle = DclSerialPort_Open(uart_max_port, 0);
+ for (idx = 0; idx < TEST_ROUND; idx ++)
+ {
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module first init non-registered port failed");
+ return KAL_FALSE;
+ }
+ /* Duplicated init -> should init failed */
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module init twice (non-registered port)successfully!!");
+ return KAL_FALSE;
+ }
+ /* First deinit -> should deinit successfully */
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module first deinit non-registered port failed");
+ return KAL_FALSE;
+ }
+ /* Duplicated deinit -> should deinit failed */
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module deinit twice (non-registered port)successfully!!");
+ return KAL_FALSE;
+ }
+ }
+
+ /*Test 4 : open non-registered port with Conv API*/
+ /* Init non-register port -> should not return failed */
+ handle = DclSerialPort_Open(uart_max_port, 0);
+ ur_ctrl_open.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_close.u4OwenrId = MOD_TTY_UT;
+ for (idx = 0; idx < TEST_ROUND; idx ++)
+ {
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status != STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module first init non-registered port failed");
+ return KAL_FALSE;
+ }
+ /* Duplicated init -> should init failed */
+ status = DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module init twice (non-registered port)successfully!!");
+ return KAL_FALSE;
+ }
+ /* First deinit -> should deinit successfully */
+ status = DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*) &ur_ctrl_close);
+ if (status != STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module first deinit non-registered port failed");
+ return KAL_FALSE;
+ }
+ /* Duplicated deinit -> should deinit failed */
+ status = DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*) &ur_ctrl_close);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module deinit twice (non-registered port)successfully!!");
+ return KAL_FALSE;
+ }
+ }
+
+ /*Test 5 : open registered port test*/
+ handle = DclSerialPort_Open(uart_port, 0);
+ for (idx = 0; idx < TEST_ROUND; idx ++)
+ {
+ /* First init -> should init successfully */
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module init failed");
+ return KAL_FALSE;
+ }
+ DclSerialPort_UpModuleRegisterCb(handle, _ttyut_rx_cb, NULL, _ttyut_drv_state_cb);
+
+ /* Duplicated init -> should init failed */
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module init twice successfully!!");
+ return KAL_FALSE;
+ }
+
+ /* First deinit -> should deinit successfully */
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status != STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module init failed");
+ return KAL_FALSE;
+ }
+
+ /* Duplicated deinit -> should deinit failed */
+ status = DclSerialPort_UpModuleDeinit(handle);
+ if (status == STATUS_OK) {
+ ttyut_print("[ERROR][TTY UT] DCL upper module init failed");
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool _ttyut_upmod_change_owner_test()
+{
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ UART_CTRL_OPEN_T ur_ctrl_open;
+ UART_CTRL_CLOSE_T ur_ctrl_close;
+ UART_CTRL_OWNER_T ur_ctrl_owner;
+ UART_CTRL_GET_DRV_STATE_T getDrvState;
+ UART_CTRL_GET_CHUNK_SIZE_T getChunkSize;
+
+ handle = DclSerialPort_Open(TTY_UT_COM1, 0);
+
+ kal_sleep_task(KAL_TICKS_3_SEC);
+
+
+ /* Conventional owner change to conventional owner */
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ char *test_string1 = "[Change owner test] Conventional Owner A change to ";
+ char *test_string2 = "Conventional owner B\r\n";
+
+ ur_ctrl_open.u4OwenrId = MOD_TTY_UT;
+ DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+
+ /* Send string */
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_putbytes.puBuffaddr = (DCL_UINT8*)test_string1;
+ ur_ctrl_putbytes.u2Length = strlen(test_string1);
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ /* Change owner to MOD_TTY_UT99 */
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT99;
+ DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+
+ kal_set_active_module_id(MOD_TTY_UT99);
+
+ /* Send string */
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT99;
+ ur_ctrl_putbytes.puBuffaddr = (DCL_UINT8*)test_string2;
+ ur_ctrl_putbytes.u2Length = strlen(test_string2);
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ /* Close com port */
+ ur_ctrl_close.u4OwenrId = MOD_TTY_UT99;
+ DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*) &ur_ctrl_close);
+
+ kal_set_active_module_id(MOD_TTY_UT);
+ }
+
+ BUSY_WAIT(1000);
+
+ /* Conventional owner change to new owner */
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ char *test_string1 = "[Change owner test] Conventional Owner A change to ";
+ char *test_string2 = "New owner B\r\n";
+ void *tx_gpd;
+ tty_io_request_t *tx_ior;
+ unsigned char *tx_buf_ptr;
+
+ ur_ctrl_open.u4OwenrId = MOD_TTY_UT;
+ DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &ur_ctrl_open);
+
+ /* Send string */
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT;
+ ur_ctrl_putbytes.puBuffaddr = (DCL_UINT8*)test_string1;
+ ur_ctrl_putbytes.u2Length = strlen(test_string1);
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ /* Change owner to MOD_TTY_UT99 */
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT99;
+ DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+ kal_set_active_module_id(MOD_TTY_UT99);
+ DclSerialPort_UpModuleReinit(handle, MOD_TTY_UT99, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ DclSerialPort_UpModuleRegisterCb(handle, _ttyut_rx_cb, NULL, _ttyut_drv_state_cb);
+
+ // Wait for device ready
+ getDrvState.u4OwnerId = MOD_TTY_UT;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while (getDrvState.drv_state != DRV_ST_ATTACHED);
+
+ // Get chunk size
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*) &getChunkSize);
+ } while (status != STATUS_OK);
+
+ /* Send string */
+ tx_gpd = QBM_ALLOC_ONE(QBM_TYPE_TTY_TYPE1);
+ if (tx_gpd) {
+ tx_ior = (tty_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;
+
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(tx_gpd);
+ kal_mem_cpy((void*)tx_buf_ptr, test_string2, strlen(test_string2));
+ QBM_DES_SET_DATALEN(tx_gpd, strlen(test_string2)); // Set data length
+
+ QBM_DES_SET_HWO(tx_gpd);
+ qbm_cal_set_checksum(tx_gpd);
+ //QBM_CACHE_FLUSH(tx_gpd, sizeof(qbm_gpd));
+
+ DclSerialPort_UpModuleTransmit(handle, tx_ior);
+ } else {
+ ttyut_print("[ERROR] [TTY UT] GPD allocate failed in QBM_TYPE_TTY_TYPE1 type\r\n");
+ return KAL_FALSE;
+ }
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ /* Close com port */
+ DclSerialPort_UpModuleDeinit(handle);
+
+ kal_set_active_module_id(MOD_TTY_UT);
+ }
+
+ BUSY_WAIT(1000);
+
+ /* New owner change to new owner */
+ {
+ char *test_string1 = "[Change owner test] New Owner A change to ";
+ char *test_string2 = "New owner B\r\n";
+ void *tx_gpd;
+ tty_io_request_t *tx_ior;
+ unsigned char *tx_buf_ptr;
+ UART_CTRL_CLR_BUFFER_T ur_ctrl_clr_buf;
+
+ /* Bind COM port - initialization */
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK) {
+ ttyut_print("[TTY UT] DCL upper module init failed");
+ return KAL_FALSE;
+ } else {
+ DclSerialPort_UpModuleRegisterCb(handle, _ttyut_rx_cb, NULL, _ttyut_drv_state_cb);
+ // Wait for device ready
+ getDrvState.u4OwnerId = MOD_TTY_UT;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while (getDrvState.drv_state != DRV_ST_ATTACHED);
+
+ // Get chunk size
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*) &getChunkSize);
+ } while (status != STATUS_OK);
+ }
+
+ /* Send string */
+ tx_gpd = QBM_ALLOC_ONE(QBM_TYPE_TTY_TYPE1);
+ if (tx_gpd) {
+ tx_ior = (tty_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;
+
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(tx_gpd);
+ kal_mem_cpy((void*)tx_buf_ptr, test_string1, strlen(test_string1));
+ QBM_DES_SET_DATALEN(tx_gpd, strlen(test_string1)); // Set data length
+
+ QBM_DES_SET_HWO(tx_gpd);
+ qbm_cal_set_checksum(tx_gpd);
+ QBM_CACHE_FLUSH(tx_gpd, sizeof(qbm_gpd));
+
+ DclSerialPort_UpModuleTransmit(handle, tx_ior);
+ } else {
+ ttyut_print("[ERROR] [TTY UT] GPD allocate failed in QBM_TYPE_TTY_TYPE1 type\r\n");
+ return KAL_FALSE;
+ }
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ /* Send Clear Tx/Rx buffer commands */
+ ur_ctrl_clr_buf.u4OwenrId = MOD_TTY_UT;
+ DclSerialPort_Control(handle, SIO_CMD_CLR_TX_BUF, (DCL_CTRL_DATA_T*) &ur_ctrl_clr_buf);
+ DclSerialPort_Control(handle, SIO_CMD_CLR_RX_BUF, (DCL_CTRL_DATA_T*) &ur_ctrl_clr_buf);
+
+ /* Change owner to MOD_TTY_UT99 */
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT99;
+ DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+ kal_set_active_module_id(MOD_TTY_UT99);
+ DclSerialPort_UpModuleReinit(handle, MOD_TTY_UT99, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ DclSerialPort_UpModuleRegisterCb(handle, _ttyut_rx_cb, NULL, _ttyut_drv_state_cb);
+
+ // Wait for device ready
+ getDrvState.u4OwnerId = MOD_TTY_UT;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while (getDrvState.drv_state != DRV_ST_ATTACHED);
+
+ // Get chunk size
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*) &getChunkSize);
+ } while (status != STATUS_OK);
+
+ /* Send string */
+ tx_gpd = QBM_ALLOC_ONE(QBM_TYPE_TTY_TYPE1);
+ if (tx_gpd) {
+ tx_ior = (tty_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;
+
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(tx_gpd);
+ kal_mem_cpy((void*)tx_buf_ptr, test_string2, strlen(test_string2));
+ QBM_DES_SET_DATALEN(tx_gpd, strlen(test_string2)); // Set data length
+
+ QBM_DES_SET_HWO(tx_gpd);
+ qbm_cal_set_checksum(tx_gpd);
+ //QBM_CACHE_FLUSH(tx_gpd, sizeof(qbm_gpd));
+
+ DclSerialPort_UpModuleTransmit(handle, tx_ior);
+ } else {
+ ttyut_print("[ERROR] [TTY UT] GPD allocate failed in QBM_TYPE_TTY_TYPE1 type\r\n");
+ return KAL_FALSE;
+ }
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ /* Close com port */
+ DclSerialPort_UpModuleDeinit(handle);
+
+ kal_set_active_module_id(MOD_TTY_UT);
+ }
+
+ BUSY_WAIT(1000);
+
+ /* New owner change to conventional owner */
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ char *test_string1 = "[Change owner test] New Owner A change to ";
+ char *test_string2 = "Conventional owner B\r\nPASS\r\n";
+ void *tx_gpd;
+ tty_io_request_t *tx_ior;
+ unsigned char *tx_buf_ptr;
+ UART_CTRL_CLR_BUFFER_T ur_ctrl_clr_buf;
+
+ /* Bind COM port - initialization */
+ status = DclSerialPort_UpModuleInit(handle, MOD_TTY_UT, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK) {
+ ttyut_print("[TTY UT] DCL upper module init failed");
+ return KAL_FALSE;
+ } else {
+ DclSerialPort_UpModuleRegisterCb(handle, _ttyut_rx_cb, NULL, _ttyut_drv_state_cb);
+
+ // Wait for device ready
+ getDrvState.u4OwnerId = MOD_TTY_UT;
+
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while (getDrvState.drv_state != DRV_ST_ATTACHED);
+
+ // Get chunk size
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*) &getChunkSize);
+ } while (status != STATUS_OK);
+ }
+
+ /* Send string */
+ tx_gpd = QBM_ALLOC_ONE(QBM_TYPE_TTY_TYPE1);
+ if (tx_gpd) {
+ tx_ior = (tty_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;
+
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(tx_gpd);
+ kal_mem_cpy((void*)tx_buf_ptr, test_string1, strlen(test_string1));
+ QBM_DES_SET_DATALEN(tx_gpd, strlen(test_string1)); // Set data length
+
+ QBM_DES_SET_HWO(tx_gpd);
+ qbm_cal_set_checksum(tx_gpd);
+ //QBM_CACHE_FLUSH(tx_gpd, sizeof(qbm_gpd));
+
+ DclSerialPort_UpModuleTransmit(handle, tx_ior);
+ } else {
+ ttyut_print("[ERROR] [TTY UT] GPD allocate failed in QBM_TYPE_TTY_TYPE1 type\r\n");
+ return KAL_FALSE;
+ }
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ /* Send Clear Tx/Rx buffer commands */
+ ur_ctrl_clr_buf.u4OwenrId = MOD_TTY_UT;
+ DclSerialPort_Control(handle, SIO_CMD_CLR_TX_BUF, (DCL_CTRL_DATA_T*) &ur_ctrl_clr_buf);
+ DclSerialPort_Control(handle, SIO_CMD_CLR_RX_BUF, (DCL_CTRL_DATA_T*) &ur_ctrl_clr_buf);
+
+ /* Change owner to MOD_TTY_UT99 */
+ ur_ctrl_owner.u4OwenrId = MOD_TTY_UT99;
+ DclSerialPort_Control(handle, SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*) &ur_ctrl_owner);
+
+ kal_set_active_module_id(MOD_TTY_UT99);
+
+ /* Send string */
+ ur_ctrl_putbytes.u4OwenrId = MOD_TTY_UT99;
+ ur_ctrl_putbytes.puBuffaddr = (DCL_UINT8*)test_string2;
+ ur_ctrl_putbytes.u2Length = strlen(test_string2);
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ /* Close com port */
+ ur_ctrl_close.u4OwenrId = MOD_TTY_UT99;
+ DclSerialPort_Control(handle, SIO_CMD_CLOSE, (DCL_CTRL_DATA_T*) &ur_ctrl_close);
+
+ kal_set_active_module_id(MOD_TTY_UT);
+ }
+
+ BUSY_WAIT(1000);
+
+ return KAL_TRUE;
+}
+
+static kal_bool ttyut_test_preproc(tty_ut_mode_e test_mode, kal_uint8 uart_port)
+{
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ DCL_UINT32 owner = MOD_NIL;
+
+ handle = DclSerialPort_Open(uart_port, 0);
+
+ if (TTY_UT_COM1 == uart_port) {
+ owner = MOD_TTY_UT;
+ } else if (TTY_UT_COM2 == uart_port) {
+ owner = MOD_TTY_UT2;
+ } else if (TTY_UT_COM3 == uart_port) {
+ owner = MOD_TTY_UT3;
+ } else {
+ // Unsupported mode, ASSERT.
+ ASSERT(0);
+ }
+ ttyut_create_instance(handle, owner);
+
+ switch (test_mode)
+ {
+ case TTY_UT_BYPASS:
+ {
+ //Do nothing;
+ break;
+ }
+ case TTY_UT_CONV_TX_CONV_RX:
+ case TTY_UT_CONV_TX_ONLY:
+ case TTY_UT_CONV_RX_ONLY:
+ {
+ UART_CTRL_OPEN_T data;
+ data.u4OwenrId = owner;
+ DclSerialPort_Control(handle, SIO_CMD_OPEN, (DCL_CTRL_DATA_T*) &data);
+ }
+ break;
+
+ case TTY_UT_NEW_INIT_CONV_TX_CONV_RX:
+ {
+ status = DclSerialPort_UpModuleInit(handle, owner, 0);
+ if (status != STATUS_OK) {
+ ttyut_print("[TTY UT] DCL upper module init failed");
+ }
+ }
+ break;
+ case TTY_UT_NEW_TX_NEW_RX:
+ case TTY_UT_NEW_TX_ONLY:
+ case TTY_UT_NEW_RX_ONLY:
+ {
+ void *rx_gpd_first, *rx_gpd_last;
+ tty_io_request_t *rx_ior;
+ void *rx_gpd_tmp;
+ int i;
+ UART_CTRL_GET_DRV_STATE_T getDrvState;
+ UART_CTRL_GET_CHUNK_SIZE_T getChunkSize;
+
+ /* Bind COM port - initialization */
+ status = DclSerialPort_UpModuleInit(handle, owner, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK) {
+ ttyut_print("[TTY UT] DCL upper module init failed");
+ } else {
+ DclSerialPort_UpModuleRegisterCb(handle, _ttyut_rx_cb, _ttyut_tx_done_cb, _ttyut_drv_state_cb);
+
+ // Wait for device ready
+ getDrvState.u4OwnerId = owner;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while ((getDrvState.drv_state != DRV_ST_ATTACHED) || (status != STATUS_OK));
+
+ // Get chunk size
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*) &getChunkSize);
+ } while (status != STATUS_OK);
+
+ qbmt_alloc_q_no_tail(QBM_TYPE_TTY_TYPE1, 2, &rx_gpd_first, &rx_gpd_last);
+ rx_gpd_tmp = rx_gpd_first;
+
+ if (!rx_gpd_first || !rx_gpd_last) {
+ ttyut_print("[TTY UT] DCL upper module init failed");
+ return KAL_FALSE;
+ }
+
+ // Set allow length
+ for (i=0; i<2; i++) {
+ if(getChunkSize.chunkSize == 1) //Some HIF doesn't have chunksize restrictions(ex: uart)
+ {
+ QBM_DES_SET_ALLOW_LEN(rx_gpd_tmp, TTY_UT_CHUNK_SIZE_DEFAULT);
+ }
+ else
+ {
+ QBM_DES_SET_ALLOW_LEN(rx_gpd_tmp, (kal_uint16)getChunkSize.chunkSize);
+ }
+ qbm_cal_set_checksum((kal_uint8*)rx_gpd_tmp);
+ QBM_CACHE_FLUSH(rx_gpd_tmp, sizeof(qbm_gpd));
+ rx_gpd_tmp = QBM_DES_GET_NEXT(rx_gpd_tmp);
+ }
+
+ rx_ior = (tty_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(rx_gpd_first);
+ rx_ior->next_request = NULL;
+ rx_ior->first_gpd = rx_gpd_first;
+ rx_ior->last_gpd = rx_gpd_last;
+
+ DclSerialPort_UpModuleAssignRxIor(handle, rx_ior);
+ }
+ }
+ break;
+
+ case TTY_UT_CONV_TX_NEW_RX:
+ {
+ void *rx_gpd_first, *rx_gpd_last;
+ tty_io_request_t *rx_ior;
+ void *rx_gpd_tmp;
+ int i;
+ UART_CTRL_GET_DRV_STATE_T getDrvState;
+ UART_CTRL_GET_CHUNK_SIZE_T getChunkSize;
+
+ /* Bind COM port - initialization */
+ status = DclSerialPort_UpModuleInit(handle, owner, TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK) {
+ ttyut_print("[TTY UT] DCL upper module init failed");
+ } else {
+ DclSerialPort_UpModuleRegisterCb(handle, _ttyut_rx_cb, NULL, _ttyut_drv_state_cb);
+
+ // Wait for device ready
+ getDrvState.u4OwnerId = owner;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while ((getDrvState.drv_state != DRV_ST_ATTACHED) || (status != STATUS_OK));
+
+ // Get chunk size
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*) &getChunkSize);
+ } while (status != STATUS_OK);
+
+ qbmt_alloc_q_no_tail(QBM_TYPE_TTY_TYPE1, 2, &rx_gpd_first, &rx_gpd_last);
+ rx_gpd_tmp = rx_gpd_first;
+
+ if (!rx_gpd_first || !rx_gpd_last) {
+ ttyut_print("[TTY UT] DCL upper module init failed");
+ return KAL_FALSE;
+ }
+
+ // Set allow length
+ for (i=0; i<2; i++) {
+ QBM_DES_SET_ALLOW_LEN(rx_gpd_tmp, (kal_uint16)getChunkSize.chunkSize);
+ qbm_cal_set_checksum((kal_uint8*)rx_gpd_tmp);
+ QBM_CACHE_FLUSH(rx_gpd_tmp, sizeof(qbm_gpd));
+ rx_gpd_tmp = QBM_DES_GET_NEXT(rx_gpd_tmp);
+ }
+
+ rx_ior = (tty_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(rx_gpd_first);
+ rx_ior->next_request = NULL;
+ rx_ior->first_gpd = rx_gpd_first;
+ rx_ior->last_gpd = rx_gpd_last;
+
+ DclSerialPort_UpModuleAssignRxIor(handle, rx_ior);
+ }
+ }
+ break;
+
+ case TTY_UT_NEW_TX_CONV_RX:
+ {
+ UART_CTRL_GET_DRV_STATE_T getDrvState;
+
+ /* Bind COM port - initialization */
+ status = DclSerialPort_UpModuleInit(handle, owner, TTY_FLAG_NEW_TX);
+ if (status != STATUS_OK) {
+ ttyut_print("[TTY UT] DCL upper module init failed");
+ } else {
+ DclSerialPort_UpModuleRegisterCb(handle, NULL, NULL, _ttyut_drv_state_cb);
+
+ // Wait for device ready
+ getDrvState.u4OwnerId = owner;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while ((getDrvState.drv_state != DRV_ST_ATTACHED) || (status != STATUS_OK));
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return KAL_TRUE;
+}
+
+static void _tty_ut_conv_tx_conv_rx_rd_handler(DCL_HANDLE handle)
+{
+ UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ ttyut_instance_t *ttyut_inst_p;
+
+ ttyut_inst_p = ttyut_get_instance(handle);
+ ur_ctrl_getbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_getbytes.puBuffaddr = ttyut_inst_p->conv_tx_rx_buf + ttyut_inst_p->conv_tx_rx_rd_idx;
+ ur_ctrl_getbytes.u2Length = ttyut_inst_p->conv_tx_rx_wrap
+ ? (ttyut_inst_p->conv_tx_rx_wt_idx - ttyut_inst_p->conv_tx_rx_rd_idx)
+ : (TTY_UT_LB_CON_TX_TX_BUF_SIZE - ttyut_inst_p->conv_tx_rx_rd_idx);
+ if (ur_ctrl_getbytes.u2Length == 0) {
+ return;
+ }
+
+ if (STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_getbytes)
+ && ur_ctrl_getbytes.u2RetSize > 0)
+ {
+ ttyut_inst_p->conv_tx_rx_rd_idx += ur_ctrl_getbytes.u2RetSize;
+
+ if (ttyut_inst_p->conv_tx_rx_rd_idx == TTY_UT_LB_CON_TX_TX_BUF_SIZE ) {
+ /* reach the end of buffer, wrap to head */
+ ASSERT(ttyut_inst_p->conv_tx_rx_wrap == 0);
+ ttyut_inst_p->conv_tx_rx_rd_idx = 0;
+ ttyut_inst_p->conv_tx_rx_wrap = 1;
+ }
+
+ ur_ctrl_putbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_putbytes.puBuffaddr = ttyut_inst_p->conv_tx_rx_buf + ttyut_inst_p->conv_tx_rx_wt_idx;
+ ur_ctrl_putbytes.u2Length = ttyut_inst_p->conv_tx_rx_wrap
+ ? (TTY_UT_LB_CON_TX_TX_BUF_SIZE - ttyut_inst_p->conv_tx_rx_wt_idx)
+ : (ttyut_inst_p->conv_tx_rx_rd_idx - ttyut_inst_p->conv_tx_rx_wt_idx);
+ ASSERT(ur_ctrl_putbytes.u2Length > 0);
+
+ if (STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes)
+ && ur_ctrl_putbytes.u2RetSize > 0)
+ {
+ ttyut_inst_p->conv_tx_rx_wt_idx += ur_ctrl_putbytes.u2RetSize;
+
+ if (ttyut_inst_p->conv_tx_rx_wt_idx == TTY_UT_LB_CON_TX_TX_BUF_SIZE ) {
+ /* reach the end of buffer, de-wrap to head */
+ ASSERT(ttyut_inst_p->conv_tx_rx_wrap == 1);
+ ttyut_inst_p->conv_tx_rx_wt_idx = 0;
+ ttyut_inst_p->conv_tx_rx_wrap = 0;
+
+ if (ttyut_inst_p->conv_tx_rx_rd_idx > 0) {
+ ur_ctrl_putbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_putbytes.puBuffaddr = ttyut_inst_p->conv_tx_rx_buf;
+ ur_ctrl_putbytes.u2Length = ttyut_inst_p->conv_tx_rx_rd_idx - ttyut_inst_p->conv_tx_rx_wt_idx;
+ if (STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes)
+ && ur_ctrl_putbytes.u2RetSize > 0)
+ {
+ ttyut_inst_p->conv_tx_rx_wt_idx += ur_ctrl_putbytes.u2RetSize;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void _ttyut_process_ilm(DCL_HANDLE handle, ilm_struct *ilm_ptr, tty_ut_mode_e test_mode)
+{
+ ttyut_instance_t *ttyut_inst_p;
+
+ ASSERT(ilm_ptr != NULL);
+
+ ttyut_inst_p = ttyut_get_instance(handle);
+
+ if (ilm_ptr != NULL)
+ {
+ switch (ilm_ptr->msg_id)
+ {
+ case MSG_ID_UART_READY_TO_WRITE_IND:
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+
+ if (test_mode == TTY_UT_CONV_TX_CONV_RX || test_mode == TTY_UT_NEW_INIT_CONV_TX_CONV_RX)
+ {
+ ur_ctrl_putbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_putbytes.puBuffaddr = ttyut_inst_p->conv_tx_rx_buf + ttyut_inst_p->conv_tx_rx_wt_idx;
+ ur_ctrl_putbytes.u2Length = ttyut_inst_p->conv_tx_rx_wrap
+ ? (TTY_UT_LB_CON_TX_TX_BUF_SIZE - ttyut_inst_p->conv_tx_rx_wt_idx)
+ : (ttyut_inst_p->conv_tx_rx_rd_idx - ttyut_inst_p->conv_tx_rx_wt_idx);
+
+ if (ur_ctrl_putbytes.u2Length > 0
+ && STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes)
+ && ur_ctrl_putbytes.u2RetSize > 0)
+ {
+ ttyut_inst_p->conv_tx_rx_wt_idx += ur_ctrl_putbytes.u2RetSize;
+
+ if (ttyut_inst_p->conv_tx_rx_wt_idx == TTY_UT_LB_CON_TX_TX_BUF_SIZE ) {
+ /* reach the end of buffer, de-wrap to head */
+ ASSERT(ttyut_inst_p->conv_tx_rx_wrap == 1);
+ ttyut_inst_p->conv_tx_rx_wt_idx = 0;
+ ttyut_inst_p->conv_tx_rx_wrap = 0;
+
+ if (ttyut_inst_p->conv_tx_rx_rd_idx > 0) {
+ ur_ctrl_putbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_putbytes.puBuffaddr = ttyut_inst_p->conv_tx_rx_buf;
+ ur_ctrl_putbytes.u2Length = ttyut_inst_p->conv_tx_rx_rd_idx - ttyut_inst_p->conv_tx_rx_wt_idx;
+ if (STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes)
+ && ur_ctrl_putbytes.u2RetSize > 0)
+ {
+ ttyut_inst_p->conv_tx_rx_wt_idx += ur_ctrl_putbytes.u2RetSize;
+ }
+ }
+ }
+ }
+ } else if (test_mode == TTY_UT_CONV_TX_ONLY || test_mode == TTY_UT_CONV_TX_NEW_RX) {
+ if (ttyut_inst_p->ttyut_tx_len > 0)
+ {
+ ur_ctrl_putbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_putbytes.puBuffaddr = ttyut_inst_p->ttyut_tx_buf + ttyut_inst_p->ttyut_tx_offset;
+ ur_ctrl_putbytes.u2Length = ttyut_inst_p->ttyut_tx_len;
+ if (STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes))
+ {
+ ttyut_print("[TTY UT] send %d bytes data\r\n", ur_ctrl_putbytes.u2RetSize);
+ ttyut_inst_p->ttyut_tx_len -= ur_ctrl_putbytes.u2RetSize;
+ ttyut_inst_p->ttyut_tx_offset += ur_ctrl_putbytes.u2RetSize;
+ }
+ }
+ }
+ }
+ break;
+ case MSG_ID_UART_READY_TO_READ_IND:
+ {
+ UART_CTRL_GET_BYTES_T ur_ctrl_getbytes;
+ int idx;
+
+ switch (test_mode)
+ {
+ case TTY_UT_CONV_TX_CONV_RX:
+ case TTY_UT_NEW_INIT_CONV_TX_CONV_RX:
+ {
+ _tty_ut_conv_tx_conv_rx_rd_handler(handle);
+ }
+ break;
+ case TTY_UT_NEW_TX_CONV_RX:
+ {
+ ur_ctrl_getbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_getbytes.puBuffaddr = ttyut_inst_p->ttyut_rx_buf;
+ ur_ctrl_getbytes.u2Length = QBM_TTY_XXX_DATA_LEN;
+
+ if (STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_getbytes)
+ && ur_ctrl_getbytes.u2RetSize > 0)
+ {
+ void *tx_gpd;
+ tty_io_request_t *tx_ior;
+ unsigned char *tx_buf_ptr;
+
+ tx_gpd = QBM_ALLOC_ONE(QBM_TYPE_TTY_TYPE1);
+ if (tx_gpd) {
+ tx_ior = (tty_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;
+
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(tx_gpd);
+ kal_mem_cpy((void*)tx_buf_ptr, ur_ctrl_getbytes.puBuffaddr, ur_ctrl_getbytes.u2RetSize);
+ QBM_DES_SET_DATALEN(tx_gpd, ur_ctrl_getbytes.u2RetSize); // Set data length
+ QBM_DES_SET_HWO(tx_gpd);
+ qbm_cal_set_checksum(tx_gpd);
+ //QBM_CACHE_FLUSH(tx_gpd, sizeof(qbm_gpd));
+
+ ttyut_print("[TTY UT] Receive data and re-send to Host, len=%d\r\n", ur_ctrl_getbytes.u2RetSize);
+ DclSerialPort_UpModuleTransmit(handle, tx_ior);
+ } else {
+ ttyut_print("[ERROR] [TTY UT] GPD allocate failed in QBM_TYPE_TTY_TYPE1 type\r\n");
+ ASSERT(tx_gpd);
+ }
+ }
+ }
+ break;
+ case TTY_UT_CONV_RX_ONLY:
+ {
+ ur_ctrl_getbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_getbytes.puBuffaddr = ttyut_inst_p->ttyut_rx_buf;
+ ur_ctrl_getbytes.u2Length = TTY_UT_CONV_BUF_SIZE;
+
+ if (STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_getbytes)
+ && ur_ctrl_getbytes.u2RetSize > 0)
+ {
+ ttyut_print("[TTY UT] Rx Only Test, len=%d, data: ", ur_ctrl_getbytes.u2RetSize);
+ for (idx = 0; idx < ur_ctrl_getbytes.u2RetSize; idx ++) {
+ ttyut_print("%c", ur_ctrl_getbytes.puBuffaddr[idx]);
+ }
+ ttyut_print("\r\n");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void ttyut_test(tty_ut_mode_e test_mode, kal_uint8 uart_port)
+{
+ ilm_struct current_ilm = {0};
+ DCL_HANDLE handle;
+ ttyut_instance_t *ttyut_inst_p;
+ UART_CTRL_GET_DRV_STATE_T getDrvState;
+ DCL_UINT32 owner = MOD_NIL;
+ DCL_STATUS status;
+
+ handle = DclSerialPort_Open(uart_port, 0);
+ ttyut_inst_p = ttyut_get_instance(handle);
+ ASSERT(ttyut_inst_p);
+
+ // Wait for device ready
+ if (TTY_UT_COM1 == uart_port) {
+ owner = MOD_TTY_UT;
+ } else if (TTY_UT_COM2 == uart_port) {
+ owner = MOD_TTY_UT2;
+ } else if (TTY_UT_COM3 == uart_port) {
+ owner = MOD_TTY_UT3;
+ } else {
+ // Unsupported mode, ASSERT.
+ ASSERT(0);
+ }
+ getDrvState.u4OwnerId = owner;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while ((getDrvState.drv_state != DRV_ST_ATTACHED) || (status != STATUS_OK));
+
+
+ switch (test_mode)
+ {
+ case TTY_UT_BYPASS:
+ {
+ while(1)
+ {
+ //do nothing;
+ kal_sleep_task(KAL_TICKS_1_MIN);
+ }
+ }
+ case TTY_UT_CONV_TX_CONV_RX:
+ ttyut_print("[TTY UT] loopback Test of conventional Tx and conventional Rx - in Old init procedure\r\n");
+ {
+ while (1)
+ {
+ while (msg_get_extq_messages() > 0)
+ {
+ if (msg_receive_extq(¤t_ilm) == KAL_TRUE)
+ {
+ _ttyut_process_ilm(handle, ¤t_ilm, test_mode);
+ destroy_ilm(¤t_ilm);
+ }
+ }
+
+ /* Polling Read */
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+ _tty_ut_conv_tx_conv_rx_rd_handler(handle);
+ }
+ }
+ break;
+
+ case TTY_UT_NEW_INIT_CONV_TX_CONV_RX:
+ ttyut_print("[TTY UT] loopback Test of conventional Tx and conventional Rx - in New init procedure\r\n");
+ {
+ while (1)
+ {
+ while (msg_get_extq_messages() > 0)
+ {
+ if (msg_receive_extq(¤t_ilm) == KAL_TRUE)
+ {
+ _ttyut_process_ilm(handle, ¤t_ilm, test_mode);
+ destroy_ilm(¤t_ilm);
+ }
+ }
+
+ /* Polling Read */
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+ _tty_ut_conv_tx_conv_rx_rd_handler(handle);
+ }
+ }
+ break;
+
+ case TTY_UT_NEW_TX_CONV_RX:
+ ttyut_print("[TTY UT] loopback Test of new Tx and conventional Rx\r\n");
+ {
+ while (1)
+ {
+ if (msg_receive_extq(¤t_ilm) == KAL_TRUE)
+ {
+ _ttyut_process_ilm(handle, ¤t_ilm, test_mode);
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ }
+ break;
+
+ case TTY_UT_CONV_RX_ONLY:
+ ttyut_print("[TTY UT] conventional Rx Only Test\r\n");
+ {
+ while (1)
+ {
+ if (msg_receive_extq(¤t_ilm) == KAL_TRUE)
+ {
+ _ttyut_process_ilm(handle, ¤t_ilm, test_mode);
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ }
+ break;
+
+ case TTY_UT_NEW_RX_ONLY:
+ ttyut_print("[TTY UT] new Rx Only Test\r\n");
+ {
+ while (1)
+ {
+ tty_io_request_t *rx_ior;
+ unsigned char *rx_buf_ptr;
+ int rx_buf_len;
+ int idx;
+
+ kal_take_mutex(ttyut_inst_p->ttyut_mutex);
+
+ if (ttyut_inst_p->ttyut_rx_ior) {
+ rx_ior = ttyut_inst_p->ttyut_rx_ior;
+ ttyut_inst_p->ttyut_rx_ior = ttyut_inst_p->ttyut_rx_ior->next_request;
+ kal_give_mutex(ttyut_inst_p->ttyut_mutex);
+ rx_ior->next_request = NULL;
+
+ /* Assert if first gpd is not equal to last gpd, unless Clear Rx/Set owner/Close command is requested */
+ ASSERT(rx_ior->first_gpd == rx_ior->last_gpd);
+
+ rx_buf_ptr = QBM_DES_GET_DATAPTR(rx_ior->first_gpd);
+ rx_buf_len = QBM_DES_GET_DATALEN(rx_ior->first_gpd);
+ QBM_CACHE_INVALID(rx_buf_ptr, rx_buf_len);
+
+ ttyut_print("[TTY UT] Rx Only Test, len=%d, data: ", rx_buf_len);
+ for (idx = 0; idx < rx_buf_len; idx ++) {
+ ttyut_print("%c", rx_buf_ptr[idx]);
+ }
+ ttyut_print("\r\n");
+
+ QBM_DES_SET_HWO(rx_ior->first_gpd);
+ qbm_cal_set_checksum(rx_ior->first_gpd);
+ QBM_CACHE_FLUSH(rx_ior->first_gpd, sizeof(qbm_gpd));
+
+ /* Re-assign this rx ior to driver for the following receiving */
+ DclSerialPort_UpModuleAssignRxIor(handle, rx_ior);
+ } else {
+ kal_give_mutex(ttyut_inst_p->ttyut_mutex);
+ }
+
+ /* TODO: check scheduling/priority issue */
+ kal_sleep_task(KAL_TICKS_10_MSEC);
+
+ /* msg_receive_extq will block, therefore we poll if any message first */
+ while (msg_get_extq_messages() > 0)
+ {
+ if (msg_receive_extq(¤t_ilm) != KAL_TRUE)
+ {
+ break;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ }
+ break;
+ case TTY_UT_CONV_TX_ONLY:
+ kal_sleep_task(KAL_TICKS_3_SEC);
+ ttyut_print("[TTY UT] conventional Tx Only Test\r\n");
+ {
+ int idx, len;
+ DCL_STATUS ret_st;
+
+ for (idx = 0; idx < TTY_UT_CONV_BUF_SIZE; idx ++) {
+ ttyut_inst_p->ttyut_tx_buf[idx] = 'a' + idx % ('z'-'a'+1);
+ }
+ /* 1st round - 1~2048 bytes in order */
+ for (len = 1; len <= 2048; len ++) {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+
+ ttyut_print("[TTY UT] expect send %d bytes data\r\n", len);
+
+ ttyut_inst_p->ttyut_tx_offset = 0;
+ ttyut_inst_p->ttyut_tx_len = len;
+ ur_ctrl_putbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_putbytes.puBuffaddr = ttyut_inst_p->ttyut_tx_buf;
+ ur_ctrl_putbytes.u2Length = len;
+ ret_st = DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+
+ if (STATUS_OK == ret_st && ur_ctrl_putbytes.u2RetSize > 0) {
+
+ ttyut_print("[TTY UT] send %d bytes data\r\n", ur_ctrl_putbytes.u2RetSize);
+
+ ttyut_inst_p->ttyut_tx_offset = ur_ctrl_putbytes.u2RetSize;
+ ttyut_inst_p->ttyut_tx_len -= ur_ctrl_putbytes.u2RetSize;
+ }
+
+ kal_sleep_task(KAL_TICKS_10_MSEC);
+
+ /* Polling ttyut_tx_len until all tx buffer are sent */
+ while (ttyut_inst_p->ttyut_tx_len != 0)
+ {
+ kal_sleep_task(KAL_TICKS_10_MSEC/10);
+
+ while (msg_get_extq_messages() > 0)
+ {
+ if (msg_receive_extq(¤t_ilm) != KAL_TRUE) {
+ break;
+ } else {
+ _ttyut_process_ilm(handle, ¤t_ilm, test_mode);
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+
+ }
+
+ /* 2nd round - 1~2048 bytes in random size */
+ while (1)
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+
+ len = rand()%TTY_UT_CONV_BUF_SIZE + 1;
+ ur_ctrl_putbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_putbytes.puBuffaddr = ttyut_inst_p->ttyut_tx_buf;
+ ur_ctrl_putbytes.u2Length = len;
+ ttyut_inst_p->ttyut_tx_offset = 0;
+ ttyut_inst_p->ttyut_tx_len = len;
+ ret_st = DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+
+ if (STATUS_OK == ret_st && ur_ctrl_putbytes.u2RetSize > 0)
+ {
+ ttyut_print("[TTY UT] send %d bytes data\r\n", ur_ctrl_putbytes.u2RetSize);
+
+ ttyut_inst_p->ttyut_tx_offset = ur_ctrl_putbytes.u2RetSize;
+ ttyut_inst_p->ttyut_tx_len -= ur_ctrl_putbytes.u2RetSize;
+ }
+
+ /* Polling ttyut_tx_len until all tx buffer are sent */
+ while (ttyut_inst_p->ttyut_tx_len != 0)
+ {
+ kal_sleep_task(KAL_TICKS_10_MSEC);
+
+ while (msg_get_extq_messages() > 0)
+ {
+ if (msg_receive_extq(¤t_ilm) != KAL_TRUE) {
+ break;
+ } else {
+ _ttyut_process_ilm(handle, ¤t_ilm, test_mode);
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ } /* while */
+ }
+
+ break;
+ case TTY_UT_NEW_TX_ONLY:
+ kal_sleep_task(KAL_TICKS_3_SEC);
+ ttyut_print("[TTY UT] new Tx Only Test\r\n");
+ {
+ int idx;
+ for (idx = 0; idx < TTY_UT_NEW_BUF_SIZE; idx ++) {
+ ttyut_inst_p->ttyut_tx_buf[idx] = 'a' + idx % ('z'-'a'+1);
+ }
+ while (1)
+ {
+ void *tx_gpd;
+ tty_io_request_t *tx_ior;
+ unsigned char *tx_buf_ptr;
+
+ tx_gpd = QBM_ALLOC_ONE(QBM_TYPE_TTY_TYPE1);
+ if (tx_gpd) {
+ tx_ior = (tty_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;
+ ttyut_inst_p->ttyut_tx_len = rand()%TTY_UT_NEW_BUF_SIZE + 1;
+
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(tx_gpd);
+ kal_mem_cpy((void*)tx_buf_ptr, ttyut_inst_p->ttyut_tx_buf, ttyut_inst_p->ttyut_tx_len);
+ QBM_DES_SET_DATALEN(tx_gpd, ttyut_inst_p->ttyut_tx_len); // Set data length
+ QBM_DES_SET_HWO(tx_gpd);
+ qbm_cal_set_checksum(tx_gpd);
+ //QBM_CACHE_FLUSH(tx_gpd, sizeof(qbm_gpd));
+
+ ttyut_print("[TTY UT] send %d bytes data\r\n", ttyut_inst_p->ttyut_tx_len);
+ DclSerialPort_UpModuleTransmit(handle, tx_ior);
+ } else {
+ ttyut_print("[ERROR] [TTY UT] GPD allocate failed in QBM_TYPE_TTY_TYPE1 type\r\n");
+ }
+
+ /* TODO: check scheduling/priority issue */
+ kal_sleep_task(KAL_TICKS_10_MSEC);
+
+ /* msg_receive_extq will block, therefore we poll if any message first */
+ while (msg_get_extq_messages() > 0)
+ {
+ if (msg_receive_extq(¤t_ilm) != KAL_TRUE)
+ {
+ break;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ }
+ break;
+ case TTY_UT_NEW_TX_NEW_RX:
+ ttyut_print("[TTY UT] loopback Test of new Tx and new Rx\r\n");
+ {
+ while (1)
+ {
+ void *tx_gpd;
+ tty_io_request_t *tx_ior;
+ tty_io_request_t *rx_ior;
+ unsigned char *tx_buf_ptr;
+ unsigned char *rx_buf_ptr;
+ kal_uint16 rx_len;
+
+ kal_take_mutex(ttyut_inst_p->ttyut_mutex);
+
+ if (ttyut_inst_p->ttyut_rx_ior)
+ {
+ rx_ior = ttyut_inst_p->ttyut_rx_ior;
+ ttyut_inst_p->ttyut_rx_ior = ttyut_inst_p->ttyut_rx_ior->next_request;
+ kal_give_mutex(ttyut_inst_p->ttyut_mutex);
+ rx_ior->next_request = NULL;
+
+ /* Assert if first gpd is not equal to last gpd, unless Clear Rx/Set owner/Close command is requested */
+ ASSERT(rx_ior->first_gpd == rx_ior->last_gpd);
+
+ tx_gpd = QBM_ALLOC_ONE(QBM_TYPE_TTY_TYPE1);
+ if (tx_gpd) {
+ tx_ior = (tty_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;
+
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(tx_gpd);
+ rx_buf_ptr = QBM_DES_GET_DATAPTR(rx_ior->first_gpd);
+ rx_len = QBM_DES_GET_DATALEN(rx_ior->first_gpd);
+
+ QBM_CACHE_INVALID(rx_buf_ptr, rx_len);
+ kal_mem_cpy((void*)tx_buf_ptr, (void*)rx_buf_ptr, rx_len);
+ QBM_CACHE_FLUSH(tx_buf_ptr, rx_len); // flush tx data
+
+ QBM_DES_SET_DATALEN(tx_gpd, rx_len); // Set data length
+ QBM_DES_SET_HWO(tx_gpd);
+ qbm_cal_set_checksum(tx_gpd);
+ QBM_CACHE_FLUSH(tx_gpd, sizeof(qbm_gpd));
+
+ ttyut_print("[TTY UT] Receive data and re-send to Host, len=%d\r\n", rx_len);
+ DclSerialPort_UpModuleTransmitLight(handle, tx_ior);
+ } else {
+ ttyut_print("[ERROR] [TTY UT] GPD allocate failed in QBM_TYPE_TTY_TYPE1 type\r\n");
+ }
+
+ QBM_DES_SET_HWO(rx_ior->first_gpd);
+ qbm_cal_set_checksum(rx_ior->first_gpd);
+ QBM_CACHE_FLUSH(rx_ior->first_gpd, sizeof(qbm_gpd));
+
+ /* Re-assign this rx ior to driver for the following receiving */
+ DclSerialPort_UpModuleAssignRxIor(handle, rx_ior);
+ } else {
+ kal_give_mutex(ttyut_inst_p->ttyut_mutex);
+ }
+
+ /* TODO: check scheduling/priority issue */
+ kal_sleep_task(KAL_TICKS_10_MSEC);
+
+ /* msg_receive_extq will block, therefore we poll if any message first */
+ while (msg_get_extq_messages() > 0)
+ {
+ if (msg_receive_extq(¤t_ilm) != KAL_TRUE)
+ {
+ break;
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ }
+ break;
+ case TTY_UT_CONV_TX_NEW_RX:
+ ttyut_print("[TTY UT] loopback Test of conventional Tx and new Rx\r\n");
+ {
+ while (1)
+ {
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ tty_io_request_t *rx_ior;
+ void *rx_data;
+ kal_uint16 rx_len;
+
+ kal_take_mutex(ttyut_inst_p->ttyut_mutex);
+
+ if (ttyut_inst_p->ttyut_rx_ior)
+ {
+ rx_ior = ttyut_inst_p->ttyut_rx_ior;
+ ttyut_inst_p->ttyut_rx_ior = ttyut_inst_p->ttyut_rx_ior->next_request;
+ kal_give_mutex(ttyut_inst_p->ttyut_mutex);
+ rx_ior->next_request = NULL;
+
+ /* Assert if first gpd is not equal to last gpd, unless Clear Rx/Set owner/Close command is requested */
+ ASSERT(rx_ior->first_gpd == rx_ior->last_gpd);
+
+ rx_data = QBM_DES_GET_DATAPTR(rx_ior->first_gpd);
+ rx_len = QBM_DES_GET_DATALEN(rx_ior->first_gpd);
+
+ if (rx_len > 0)
+ { /* in the test case, only one gpd is used in one ior since we only send 2 gpds to driver and one is for tailing */
+ QBM_CACHE_INVALID(rx_data, rx_len);
+ ASSERT(rx_len <= QBM_TTY_XXX_DATA_LEN);
+ kal_mem_cpy(ttyut_inst_p->ttyut_tx_buf, rx_data, rx_len);
+ ttyut_inst_p->ttyut_tx_len = rx_len;
+
+ ur_ctrl_putbytes.u4OwenrId = ttyut_inst_p->owner;
+ ur_ctrl_putbytes.puBuffaddr = ttyut_inst_p->ttyut_tx_buf;
+ ur_ctrl_putbytes.u2Length = ttyut_inst_p->ttyut_tx_len;
+
+ if (STATUS_OK == DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes)
+ && ur_ctrl_putbytes.u2RetSize < ttyut_inst_p->ttyut_tx_len)
+ {
+ ttyut_inst_p->ttyut_tx_offset = ur_ctrl_putbytes.u2RetSize;
+ ttyut_inst_p->ttyut_tx_len -= ur_ctrl_putbytes.u2RetSize;
+ }
+ }
+
+ QBM_DES_SET_HWO(rx_ior->first_gpd);
+ QBM_DES_SET_NEXT(rx_ior->first_gpd, NULL);
+ qbm_cal_set_checksum(rx_ior->first_gpd);
+ QBM_CACHE_FLUSH(rx_ior->first_gpd, sizeof(qbm_gpd));
+
+ /* Re-assign this rx ior to driver for the following receiving */
+ DclSerialPort_UpModuleAssignRxIor(handle, rx_ior);
+ } else {
+ kal_give_mutex(ttyut_inst_p->ttyut_mutex);
+ }
+
+ /* TODO: check scheduling/priority issue */
+ kal_sleep_task(KAL_TICKS_10_MSEC);
+
+ /* msg_receive_extq will block, therefore we poll if any message first */
+ while (msg_get_extq_messages() > 0)
+ {
+ if (msg_receive_extq(¤t_ilm) != KAL_TRUE) {
+ break;
+ } else {
+ _ttyut_process_ilm(handle, ¤t_ilm, test_mode);
+ }
+ destroy_ilm(¤t_ilm);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+// ==========================================================
+// TTY_UT Task Function
+// ==========================================================
+kal_uint32 ttyut_tsk_num=0;
+kal_spinlockid ttyut_tsk_pri_spl;
+kal_taskid tty_tsk_pri[TTY_UT_COM_NUM];
+kal_uint32 ttyut_get_current_task_priority()
+{
+ kal_uint32 tty_pri, tty_ist=ttyut_tsk_num;
+ kal_taskid tskp=kal_get_current_task();
+ ASSERT(tskp);
+ kal_take_spinlock(ttyut_tsk_pri_spl, KAL_INFINITE_WAIT);
+ for(tty_pri=0;tty_pri<ttyut_tsk_num&&tty_tsk_pri[tty_pri]!=tskp;tty_pri++) tty_ist=tty_ist==ttyut_tsk_num&&!tty_tsk_pri[tty_pri]?tty_pri:tty_ist;
+ if(tty_pri==ttyut_tsk_num&&tty_ist<ttyut_tsk_num) tty_tsk_pri[tty_pri=tty_ist]=tskp;
+ kal_give_spinlock(ttyut_tsk_pri_spl);
+ return tty_pri==ttyut_tsk_num?0:tty_pri+1;
+}
+
+kal_bool ttyut_task_init(void)
+{
+ if(ttyut_tsk_num==0) ttyut_tsk_pri_spl=kal_create_spinlock("TTYUT_TSK_SPL");
+ tty_tsk_pri[ttyut_tsk_num++]=NULL;
+
+ // Init ttyut instance struct.
+ kal_mem_set(&ttyut_inst_g, 0, sizeof(ttyut_inst_g));
+
+ return KAL_TRUE;
+}
+
+static void ttyut_task_main(task_entry_struct *task_entry_ptr)
+{
+ kal_uint32 tsk_pri;
+ kal_bool ret = KAL_TRUE;
+
+ tsk_pri = ttyut_get_current_task_priority();
+
+#if TTY_UT_MISC_TEST
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ UART_CTRL_GET_DRV_STATE_T getDrvState;
+ /*Init test and change owner test*/
+ if (TTY_UT_TASK_1_PRIORITY == tsk_pri) {
+ // Init_deinit test
+ kal_set_active_module_id(MOD_TTY_UT);
+
+ /*Make sure driver is already attached*/
+ handle = DclSerialPort_Open(TTY_UT_COM1, 0);
+ getDrvState.u4OwnerId = MOD_TTY_UT;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while ((getDrvState.drv_state != DRV_ST_ATTACHED) || (status != STATUS_OK));
+
+ if (_ttyut_upmod_init_deinit_test(TTY_UT_COM1)) {
+ ttyut_print("[TTY UT] init-deinit test OK\r\n");
+ } else {
+ ttyut_print("[TTY UT] init-deinit test failed\r\n");
+ //return;
+ ASSERT(0);
+ }
+
+ // Change_owner test
+ if (_ttyut_upmod_change_owner_test()) {
+ ttyut_print("[TTY UT] change owner test OK\r\n");
+ } else {
+ ttyut_print("[TTY UT] change owner test failed\r\n");
+ //return;
+ ASSERT(0);
+ }
+ }
+#endif
+
+ /*
+ * S1.TTYUT_PREPROC.
+ */
+ switch (tsk_pri)
+ {
+ case TTY_UT_TASK_1_PRIORITY:
+ kal_set_active_module_id(MOD_TTY_UT);
+ ret = ttyut_test_preproc(tty_ut_mode_1, TTY_UT_COM1);
+ break;
+
+ case TTY_UT_TASK_2_PRIORITY:
+ if (TTY_UT_COM_NUM > 1) {
+ kal_set_active_module_id(MOD_TTY_UT2);
+ ret = ttyut_test_preproc(tty_ut_mode_2, TTY_UT_COM2);
+ }
+ break;
+
+ case TTY_UT_TASK_3_PRIORITY:
+ if (TTY_UT_COM_NUM > 2) {
+ kal_set_active_module_id(MOD_TTY_UT3);
+ ret = ttyut_test_preproc(tty_ut_mode_3, TTY_UT_COM3);
+ }
+ break;
+
+ default:
+ // Unsupported mode, ASSERT.
+ ASSERT(0);
+ break;
+ }
+
+ if (KAL_TRUE == ret) {
+
+ } else {
+ // Failed to ttyut_test_preproc(), ASSERT.
+ ASSERT(0);
+ }
+
+ /*
+ * S2. TTYUT_MAIN.
+ */
+ switch (tsk_pri)
+ {
+ case TTY_UT_TASK_1_PRIORITY:
+
+ ttyut_test(tty_ut_mode_1, TTY_UT_COM1);
+ break;
+
+ case TTY_UT_TASK_2_PRIORITY:
+ if (TTY_UT_COM_NUM > 1) {
+ ttyut_test(tty_ut_mode_2, TTY_UT_COM2);
+ }
+ break;
+
+ case TTY_UT_TASK_3_PRIORITY:
+ if (TTY_UT_COM_NUM > 2) {
+ ttyut_test(tty_ut_mode_3, TTY_UT_COM3);
+ }
+ break;
+
+ default:
+ // Unsupport mode, ASSERT.
+ ASSERT(0);
+ break;
+ }
+
+ while (1) {
+ kal_sleep_task(KAL_TICKS_30_SEC);
+ }
+}
+
+kal_bool ttyut_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct ttyut_handler_info =
+ {
+ ttyut_task_main, /* task entry function */
+ ttyut_task_init, /* task initialization function */
+ NULL /* task reset handler */
+ };
+
+ ttyut_print("=========>ttyut_create\r\n");
+
+ *handle = (comptask_handler_struct *)&ttyut_handler_info;
+ return KAL_TRUE;
+}
+