diff options
| author | Chaoqiong Xiao <[email protected]> | 2022-12-16 08:22:41 +0000 |
|---|---|---|
| committer | Chaoqiong Xiao <[email protected]> | 2022-12-16 08:22:41 +0000 |
| commit | 2c66db9568b0adbae6b06a698d9888b664d02379 (patch) | |
| tree | 3941ae8a1ee0f4dde03e7ff25247cfbcefa6248f | |
| parent | 60a6524c16c1357e14e99c8b1f72029d38cf69a1 (diff) | |
Update on 16 Dec 2022. Expand to see details.
8ff89b56 Fixed build issue with UX_MAX_DEVICES=1 in host hub standalone
e39131fc Set IPV6 Address before CDC-ECM enumerated.
0b35db7c Fixed build issue with NETX.
b4205710 Added CCID standalone support.
19 files changed, 1351 insertions, 54 deletions
diff --git a/common/usbx_device_classes/CMakeLists.txt b/common/usbx_device_classes/CMakeLists.txt index 5291d4b..6dd8859 100644 --- a/common/usbx_device_classes/CMakeLists.txt +++ b/common/usbx_device_classes/CMakeLists.txt @@ -46,9 +46,12 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_icc_insert.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_icc_remove.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_initialize.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_notify_task_run.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_notify_thread_entry.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_response.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_runner_task_run.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_runner_thread_entry.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_tasks_run.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_thread_entry.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_time_extension.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_uninitialize.c diff --git a/common/usbx_device_classes/inc/ux_device_class_ccid.h b/common/usbx_device_classes/inc/ux_device_class_ccid.h index dd4534a..a35a76a 100644 --- a/common/usbx_device_classes/inc/ux_device_class_ccid.h +++ b/common/usbx_device_classes/inc/ux_device_class_ccid.h @@ -24,7 +24,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_ccid.h PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -39,6 +39,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -52,13 +55,19 @@ /* Yes, C++ compiler is present. Use standard C. */ extern "C" { - #endif +#if !defined(UX_DEVICE_STANDALONE) /* Define CCID max number of slots, 32 for 32 bit data width. */ -#define UX_DEVICE_CLASS_CCID_MAX_N_SLOTS (sizeof(ALIGN_TYPE)*8) +#define UX_DEVICE_CLASS_CCID_MAX_N_SLOTS (4*8) +#else + +/* To optimize the max number of slots fixed to 1. */ +#define UX_DEVICE_CLASS_CCID_MAX_N_SLOTS 1 +#endif +/* Thread stack size, for RTOS mode only. */ #define UX_DEVICE_CLASS_CCID_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE #define UX_DEVICE_CLASS_CCID_NOTIFY_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE #define UX_DEVICE_CLASS_CCID_RUNNER_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE @@ -893,7 +902,9 @@ typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY_STRU /* Define CCID message command handles, if command handle is not defined device - reports command not supported to host. */ + reports command not supported to host. + In RTOS mode return normal status code (_SUCCESS/_ERROR/...). + In standalone mode return task state status code (_STATE_NEXT/_STATE_ERROR/...). */ typedef UINT (*UX_DEVICE_CLASS_CCID_HANDLE)(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*); typedef struct UX_DEVICE_CLASS_CCID_HANDLES_STRUCT { @@ -949,11 +960,18 @@ typedef struct UX_DEVICE_CLASS_CCID_RUNNER_STRUCT CHAR ux_device_class_ccid_runner_slot; CHAR ux_device_class_ccid_runner_id; CHAR ux_device_class_ccid_runner_command_index; +#if !defined(UX_DEVICE_STANDALONE) UCHAR reserved; -#if !defined(UX_DEVICE_STANDALONE) UX_THREAD ux_device_class_ccid_runner_thread; UCHAR *ux_device_class_ccid_runner_thread_stack; +#else + UCHAR ux_device_class_ccid_runner_state; + + UX_DEVICE_CLASS_CCID_HANDLE + ux_device_class_ccid_runner_handle; + UX_DEVICE_CLASS_CCID_MESSAGES + ux_device_class_ccid_runner_messages; #endif } UX_DEVICE_CLASS_CCID_RUNNER; @@ -1005,9 +1023,113 @@ typedef struct UX_DEVICE_CLASS_CCID_STRUCT UX_MUTEX ux_device_class_ccid_mutex; UX_MUTEX ux_device_class_ccid_response_mutex; UX_SEMAPHORE ux_device_class_ccid_notify_semaphore; +#else + ULONG ux_device_class_ccid_flags; + + UCHAR ux_device_class_ccid_cmd_state; + CHAR ux_device_class_ccid_cmd_index; + UCHAR ux_device_class_ccid_rsp_state; + UCHAR ux_device_class_ccid_notify_state; #endif } UX_DEVICE_CLASS_CCID; +/* Device CCID flags. */ +#define UX_DEVICE_CLASS_CCID_FLAG_LOCK 0x0001u +#define UX_DEVICE_CLASS_CCID_FLAG_CMD_RSP 0x0010u + +#if defined(UX_DEVICE_STANDALONE) +#define _ux_device_class_ccid_lock(ccid) do { \ + UX_INTERRUPT_SAVE_AREA \ + UX_DISABLE \ + if (ccid->ux_device_class_ccid_flags & UX_DEVICE_CLASS_CCID_FLAG_LOCK) \ + { \ + UX_RESTORE \ + return(UX_BUSY); \ + } \ + ccid->ux_device_class_ccid_flags |= UX_DEVICE_CLASS_CCID_FLAG_LOCK; \ + UX_RESTORE \ + } while(0) +#define _ux_device_class_ccid_unlock(ccid) do { \ + ccid->ux_device_class_ccid_flags &= ~UX_DEVICE_CLASS_CCID_FLAG_LOCK; \ + } while(0) +#else +#define _ux_device_class_ccid_lock(ccid) _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex) +#define _ux_device_class_ccid_unlock(ccid) _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex) +#endif + +/* Device CCID states. */ +#define UX_DEVICE_CLASS_CCID_CMD_IDLE (UX_STATE_STEP + 0) +#define UX_DEVICE_CLASS_CCID_CMD_START (UX_STATE_STEP + 1) +#define UX_DEVICE_CLASS_CCID_CMD_WAIT (UX_STATE_STEP + 2) +#define UX_DEVICE_CLASS_CCID_CMD_LOCK (UX_STATE_STEP + 3) +#define UX_DEVICE_CLASS_CCID_CMD_PROCESS (UX_STATE_STEP + 4) +#define UX_DEVICE_CLASS_CCID_CMD_RSP_START (UX_STATE_STEP + 5) +static inline const char *ccidCmdStateName(const UINT s) +{ + switch(s) + { + case UX_DEVICE_CLASS_CCID_CMD_IDLE: return("cmdIDLE"); + case UX_DEVICE_CLASS_CCID_CMD_START: return("cmdSTART"); + case UX_DEVICE_CLASS_CCID_CMD_WAIT: return("cmdWAIT"); + case UX_DEVICE_CLASS_CCID_CMD_LOCK: return("cmdLOCK"); + case UX_DEVICE_CLASS_CCID_CMD_PROCESS: return("cmdPROCESS"); + case UX_DEVICE_CLASS_CCID_CMD_RSP_START:return("cmdRSP_START"); + default: return("cmd?"); + } +} + +#define UX_DEVICE_CLASS_CCID_RUNNER_IDLE (UX_STATE_STEP + 0) +#define UX_DEVICE_CLASS_CCID_RUNNER_START (UX_STATE_STEP + 1) +#define UX_DEVICE_CLASS_CCID_RUNNER_HANDLE (UX_STATE_STEP + 2) +#define UX_DEVICE_CLASS_CCID_RUNNER_RSP_START (UX_STATE_STEP + 3) +static inline const char *ccidRunnerStateName(const UINT s) +{ + switch(s) + { + case UX_DEVICE_CLASS_CCID_RUNNER_IDLE: return("runnerIDLE"); + case UX_DEVICE_CLASS_CCID_RUNNER_START: return("runnerSTART"); + case UX_DEVICE_CLASS_CCID_RUNNER_HANDLE: return("runnerHANDLE"); + case UX_DEVICE_CLASS_CCID_RUNNER_RSP_START: return("runnerRSP_START"); + default: return("runner?"); + } +} + +#define UX_DEVICE_CLASS_CCID_RSP_IDLE (UX_STATE_STEP + 0) +#define UX_DEVICE_CLASS_CCID_RSP_START (UX_STATE_STEP + 1) +#define UX_DEVICE_CLASS_CCID_RSP_WAIT (UX_STATE_STEP + 2) +#define UX_DEVICE_CLASS_CCID_RSP_LOCK (UX_STATE_STEP + 3) +#define UX_DEVICE_CLASS_CCID_RSP_UPDATE (UX_STATE_STEP + 4) +#define UX_DEVICE_CLASS_CCID_RSP_DONE (UX_STATE_STEP + 5) +static inline const char *ccidRspStateName(const UINT s) +{ + switch(s) + { + case UX_DEVICE_CLASS_CCID_RSP_IDLE: return("rspIDLE"); + case UX_DEVICE_CLASS_CCID_RSP_START: return("rspSTART"); + case UX_DEVICE_CLASS_CCID_RSP_WAIT: return("rspWAIT"); + case UX_DEVICE_CLASS_CCID_RSP_LOCK: return("rspLOCK"); + case UX_DEVICE_CLASS_CCID_RSP_UPDATE: return("rspUPDATE"); + case UX_DEVICE_CLASS_CCID_RSP_DONE: return("rspDONE"); + default: return("rsp?"); + } +} + +#define UX_DEVICE_CLASS_CCID_NOTIFY_IDLE (UX_STATE_STEP + 0) +#define UX_DEVICE_CLASS_CCID_NOTIFY_LOCK (UX_STATE_STEP + 1) +#define UX_DEVICE_CLASS_CCID_NOTIFY_START (UX_STATE_STEP + 2) +#define UX_DEVICE_CLASS_CCID_NOTIFY_WAIT (UX_STATE_STEP + 3) +static inline const char *ccidNotifyStateName(const UINT s) +{ + switch(s) + { + case UX_DEVICE_CLASS_CCID_NOTIFY_IDLE: return("notifyIDLE"); + case UX_DEVICE_CLASS_CCID_NOTIFY_LOCK: return("notifyLOCK"); + case UX_DEVICE_CLASS_CCID_NOTIFY_START: return("notifySTART"); + case UX_DEVICE_CLASS_CCID_NOTIFY_WAIT: return("notifyWAIT"); + default: return("notify?"); + } +} + /* Define Device CCID command settings. */ extern const UX_DEVICE_CLASS_CCID_COMMAND_SETT _ux_device_class_ccid_command_sett[]; @@ -1022,6 +1144,10 @@ VOID _ux_device_class_ccid_thread_entry(ULONG ccid_instance); VOID _ux_device_class_ccid_notify_thread_entry(ULONG ccid_instance); VOID _ux_device_class_ccid_runner_thread_entry(ULONG runner_instance); +UINT _ux_device_class_ccid_tasks_run(VOID *instance); +UINT _ux_device_class_ccid_notify_task_run(UX_DEVICE_CLASS_CCID *ccid); +UINT _ux_device_class_ccid_runner_task_run(UX_DEVICE_CLASS_CCID *ccid); + UINT _ux_device_class_ccid_control_abort(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq); UINT _ux_device_class_ccid_response(UX_DEVICE_CLASS_CCID *ccid, UCHAR *buffer, ULONG length); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_activate.c b/common/usbx_device_classes/src/ux_device_class_ccid_activate.c index 0568a7e..ed842da 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_activate PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,9 @@ /* fixed parameter/variable */ /* names conflict C++ keyword, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -77,7 +80,9 @@ UX_SLAVE_CLASS *ccid_class; UX_DEVICE_CLASS_CCID *ccid; UX_SLAVE_ENDPOINT *endpoint; ULONG endpoint_type; +#if !defined(UX_DEVICE_STANDALONE) UINT i; +#endif /* Get the class container. */ ccid_class = command -> ux_slave_class_command_class_ptr; @@ -115,6 +120,22 @@ UINT i; endpoint = endpoint -> ux_slave_endpoint_next_endpoint; } +#if defined(UX_DEVICE_STANDALONE) + + /* Initialize slots (optimized for 1 slot). */ + ccid -> ux_device_class_ccid_slots -> ux_device_class_ccid_slot_runner = -1; + ccid -> ux_device_class_ccid_slots -> ux_device_class_ccid_slot_icc_status = + UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT; + + /* Initialize task states. */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_START; + ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_IDLE; + ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_IDLE; + + /* Initialize runner task state (optimized for 1 slot). */ + ccid -> ux_device_class_ccid_runners -> ux_device_class_ccid_runner_state = UX_DEVICE_CLASS_CCID_RUNNER_IDLE; +#else + /* Initialize slots. */ for (i = 0; i < ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_slots; @@ -139,6 +160,7 @@ UINT i; _ux_device_thread_resume(&ccid -> ux_device_class_ccid_runners[i]. ux_device_class_ccid_runner_thread); } +#endif /* If there is a activate function call it. */ if (ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_instance_activate != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_auto_seq_done.c b/common/usbx_device_classes/src/ux_device_class_ccid_auto_seq_done.c index 8874092..b3dbf49 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_auto_seq_done.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_auto_seq_done.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_auto_seq_done PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_auto_seq_done(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG icc_status) @@ -83,7 +86,7 @@ UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; ccid_slot += slot; /* Lock states. */ - _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_lock(ccid); /* Check sequencing. */ if (ccid_slot -> ux_device_class_ccid_slot_flags & UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING) @@ -93,7 +96,7 @@ UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; } /* Unlock states. */ - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Return transfer status. */ return(UX_SUCCESS); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_auto_seq_start.c b/common/usbx_device_classes/src/ux_device_class_ccid_auto_seq_start.c index 62d23a1..a2353e9 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_auto_seq_start.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_auto_seq_start.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_auto_seq_start PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -63,6 +63,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_auto_seq_start(UX_DEVICE_CLASS_CCID *ccid, ULONG slot) @@ -79,13 +82,13 @@ UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; ccid_slot += slot; /* Lock states. */ - _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_lock(ccid); /* Set state of auto sequencing. */ ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING; /* Unlock states. */ - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Return transfer status. */ return(UX_SUCCESS); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_control_abort.c b/common/usbx_device_classes/src/ux_device_class_ccid_control_abort.c index cec17e5..f2e7ae5 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_control_abort.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_control_abort.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_control_abort PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -64,6 +64,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_control_abort(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq) @@ -131,6 +134,13 @@ UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *msg; } } +#if defined(UX_DEVICE_STANDALONE) + if (ccid -> ux_device_class_ccid_cmd_state == UX_DEVICE_CLASS_CCID_CMD_WAIT) + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_START; + if (ccid -> ux_device_class_ccid_rsp_state == UX_DEVICE_CLASS_CCID_RSP_WAIT) + ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_IDLE; +#endif + /* Set aborting state. */ ccid_slot -> ux_device_class_ccid_slot_aborting = UX_TRUE; ccid_slot -> ux_device_class_ccid_slot_aborting_seq = (UCHAR)seq; diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_hardware_error.c b/common/usbx_device_classes/src/ux_device_class_ccid_hardware_error.c index 680df28..794a58e 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_hardware_error.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_hardware_error.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_hardware_error PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -64,6 +64,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_hardware_error(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG error) @@ -82,7 +85,7 @@ UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *rsp; ccid_slot += slot; /* Lock states. */ - _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_lock(ccid); /* Check error. */ if (!(ccid_slot -> ux_device_class_ccid_slot_flags & UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR)) @@ -118,15 +121,20 @@ UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *rsp; ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE; /* Unlock states. */ - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Wakeup interrupt notification. */ _ux_device_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore); + +#if defined(UX_DEVICE_STANDALONE) + if (ccid -> ux_device_class_ccid_notify_state == UX_DEVICE_CLASS_CCID_NOTIFY_IDLE) + ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_LOCK; +#endif return(UX_SUCCESS); } /* Unlock states. */ - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Return transfer status. */ return(UX_SUCCESS); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_icc_insert.c b/common/usbx_device_classes/src/ux_device_class_ccid_icc_insert.c index 4c9de6b..5eb5999 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_icc_insert.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_icc_insert.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_icc_insert PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_icc_insert(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq_start) @@ -83,12 +86,12 @@ UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; ccid_slot += slot; /* Lock states. */ - _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_lock(ccid); /* Return success if already card inserted. */ if (ccid_slot -> ux_device_class_ccid_slot_icc_status != UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT) { - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); return(UX_SUCCESS); } @@ -105,15 +108,20 @@ UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE; /* Unlock states. */ - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Wakeup interrupt notification. */ _ux_device_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore); + +#if defined(UX_DEVICE_STANDALONE) + if (ccid -> ux_device_class_ccid_notify_state == UX_DEVICE_CLASS_CCID_NOTIFY_IDLE) + ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_LOCK; +#endif return(UX_SUCCESS); } /* Unlock states. */ - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Return transfer status. */ return(UX_SUCCESS); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_icc_remove.c b/common/usbx_device_classes/src/ux_device_class_ccid_icc_remove.c index 89f9234..9c88722 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_icc_remove.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_icc_remove.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_icc_remove PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -63,6 +63,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_icc_remove(UX_DEVICE_CLASS_CCID *ccid, ULONG slot) @@ -79,12 +82,12 @@ UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; ccid_slot += slot; /* Lock states. */ - _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_lock(ccid); /* Return success if already card removed. */ if (ccid_slot -> ux_device_class_ccid_slot_icc_status == UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT) { - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); return(UX_SUCCESS); } @@ -102,11 +105,16 @@ UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; if (ccid -> ux_device_class_ccid_endpoint_notify) { ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE; - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); _ux_device_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore); + +#if defined(UX_DEVICE_STANDALONE) + if (ccid -> ux_device_class_ccid_notify_state == UX_DEVICE_CLASS_CCID_NOTIFY_IDLE) + ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_LOCK; +#endif return(UX_SUCCESS); } - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Return transfer status. */ return(UX_SUCCESS); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_initialize.c b/common/usbx_device_classes/src/ux_device_class_ccid_initialize.c index b816148..50504d0 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,14 +72,13 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_initialize(UX_SLAVE_CLASS_COMMAND *command) { -#if defined(UX_DEVICE_STANDALONE) - UX_PARAMETER_NOT_USED(command); - return(UX_FUNCTION_NOT_SUPPORTED); -#else UX_DEVICE_CLASS_CCID *ccid; UX_DEVICE_CLASS_CCID_RUNNER *runner; UX_DEVICE_CLASS_CCID_SLOT *slot; @@ -89,9 +88,11 @@ UINT status; ULONG memory_size; ULONG ccid_size, runners_size, slots_size; ULONG buffer_size, buffers_size; -ULONG stacks_size; UCHAR *memory; ULONG i; +#if !defined(UX_DEVICE_STANDALONE) +ULONG stacks_size; +#endif /* Get the class container. */ ccid_class = command -> ux_slave_class_command_class_ptr; @@ -104,10 +105,20 @@ ULONG i; - number busy <= number slots - message length < max request buffer size */ + +#if !defined(UX_DEVICE_STANDALONE) + UX_ASSERT(ccid_parameter -> ux_device_class_ccid_max_n_slots <= UX_DEVICE_CLASS_CCID_MAX_N_SLOTS); UX_ASSERT(ccid_parameter -> ux_device_class_ccid_max_n_busy_slots != 0); UX_ASSERT(ccid_parameter -> ux_device_class_ccid_max_n_busy_slots <= ccid_parameter -> ux_device_class_ccid_max_n_slots) +#else + + /* To optimize only support 1 slot. */ + ccid_parameter -> ux_device_class_ccid_max_n_slots = 1; + ccid_parameter -> ux_device_class_ccid_max_n_busy_slots = 1; +#endif + UX_ASSERT(ccid_parameter -> ux_device_class_ccid_max_transfer_length <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH); UX_ASSERT(ccid_parameter->ux_device_class_ccid_handles != UX_NULL); @@ -154,6 +165,9 @@ ULONG i; } memory_size = (memory_size + buffers_size) & 0xFFFFFFFFu; +#if !defined(UX_DEVICE_STANDALONE) + + /* Calculate memory size for stackes. */ stacks_size = ccid_parameter->ux_device_class_ccid_max_n_busy_slots; if (UX_OVERFLOW_CHECK_MULC_ULONG(stacks_size, UX_DEVICE_CLASS_CCID_RUNNER_THREAD_STACK_SIZE)) { @@ -187,6 +201,7 @@ ULONG i; return(UX_ERROR); } memory_size = (memory_size + stacks_size) & 0xFFFFFFFFu; +#endif /* Allocate memory for instance and other resources of the device ccid class. */ memory = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, memory_size); @@ -201,6 +216,8 @@ ULONG i; ccid = (UX_DEVICE_CLASS_CCID *)memory; memory += ccid_size; +#if !defined(UX_DEVICE_STANDALONE) + /* CCID thread. */ status = _ux_utility_thread_create( &ccid -> ux_device_class_ccid_thread, @@ -239,6 +256,14 @@ ULONG i; UX_THREAD_EXTENSION_PTR_SET(&(ccid -> ux_device_class_ccid_notify_thread), ccid); } } +#else + + /* Set task function. */ + ccid_class -> ux_slave_class_task_function = _ux_device_class_ccid_tasks_run; + + /* By default status is OK. */ + status = UX_SUCCESS; +#endif /* CCID runners. */ if (status == UX_SUCCESS) @@ -268,6 +293,8 @@ ULONG i; runner -> ux_device_class_ccid_runner_response = memory; memory += buffer_size; +#if !defined(UX_DEVICE_STANDALONE) + /* CCID runners threads. */ status = _ux_utility_thread_create( &runner -> ux_device_class_ccid_runner_thread, @@ -288,6 +315,7 @@ ULONG i; memory += UX_DEVICE_CLASS_CCID_RUNNER_THREAD_STACK_SIZE; UX_THREAD_EXTENSION_PTR_SET(&(runner -> ux_device_class_ccid_runner_thread), runner); } +#endif /* Next runner. */ runner ++; @@ -315,6 +343,8 @@ ULONG i; } } +#if !defined(UX_DEVICE_STANDALONE) + /* CCID mutexes, semaphore and event flags. */ if (status == UX_SUCCESS) { @@ -364,6 +394,7 @@ ULONG i; else status = UX_EVENT_ERROR; } +#endif /* Success case. */ if (status == UX_SUCCESS) @@ -384,6 +415,8 @@ ULONG i; /* In this case, mutexes and events are not created or has been handled. */ +#if !defined(UX_DEVICE_STANDALONE) + /* Check thread states and free them. */ if (ccid -> ux_device_class_ccid_thread_stack) _ux_utility_thread_delete(&ccid -> ux_device_class_ccid_thread); @@ -395,13 +428,13 @@ ULONG i; } if (ccid -> ux_device_class_ccid_notify_thread_stack) _ux_utility_thread_delete(&ccid -> ux_device_class_ccid_notify_thread); +#endif /* Free the memory. */ _ux_utility_memory_free(ccid); /* Return completion status. */ return(status); -#endif } const UX_DEVICE_CLASS_CCID_COMMAND_SETT diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_notify_task_run.c b/common/usbx_device_classes/src/ux_device_class_ccid_notify_task_run.c new file mode 100644 index 0000000..11ac29d --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_ccid_notify_task_run.c @@ -0,0 +1,229 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device CCID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_ccid.h" +#include "ux_device_stack.h" + + +#if defined(UX_DEVICE_STANDALONE) + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_ccid_notify_task_run PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is the background task of the CCID. */ +/* */ +/* It's for standalone mode. */ +/* */ +/* INPUT */ +/* */ +/* ccid Pointer to CCID class */ +/* */ +/* OUTPUT */ +/* */ +/* State machine status */ +/* UX_STATE_EXIT Device not configured */ +/* UX_STATE_IDLE No streaming transfer running */ +/* UX_STATE_WAIT Streaming transfer running */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Device Stack */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx Chaoqiong Xiao Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _ux_device_class_ccid_notify_task_run(UX_DEVICE_CLASS_CCID *ccid) +{ +UX_INTERRUPT_SAVE_AREA +UX_SLAVE_DEVICE *device; +UX_DEVICE_CLASS_CCID_SLOT *slot; +UX_SLAVE_ENDPOINT *endpoint; +UX_SLAVE_TRANSFER *transfer; +UCHAR *buffer; +ULONG length; +UCHAR icc_mask; +INT immediate_state = UX_TRUE; +UINT status; + + + /* Get the pointer to the device. */ + device = &_ux_system_slave -> ux_system_slave_device; + + /* Check if the device is configured. */ + if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) + return(UX_STATE_EXIT); + + /* Interrupt IN endpoint get (it's optional so it's OK not found). */ + endpoint = ccid -> ux_device_class_ccid_endpoint_notify; + if (endpoint == UX_NULL) + return(UX_STATE_IDLE); + transfer = &endpoint -> ux_slave_endpoint_transfer_request; + + /* Process states. */ + while(immediate_state) + { + + /* Check states. */ + switch(ccid -> ux_device_class_ccid_notify_state) + { + + case UX_DEVICE_CLASS_CCID_NOTIFY_IDLE: + return(UX_STATE_IDLE); + + case UX_DEVICE_CLASS_CCID_NOTIFY_LOCK: + + /* Wait until status locked. */ + UX_DISABLE + if (ccid -> ux_device_class_ccid_flags & UX_DEVICE_CLASS_CCID_FLAG_LOCK) + { + UX_RESTORE + return(UX_STATE_WAIT); + } + ccid -> ux_device_class_ccid_flags |= UX_DEVICE_CLASS_CCID_FLAG_LOCK; + UX_RESTORE + + /* Next: check if there is notification pending. */ + ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_START; + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_NOTIFY_START: + + /* Check slot notifications (optimized for only one slot). */ + /* Get slot. */ + slot = ccid -> ux_device_class_ccid_slots; + + /* Build slot change/hardware error message. */ + buffer = transfer -> ux_slave_transfer_request_data_pointer; + length = 0; + + /* By default no message. */ + buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] = 0; + + /* Check hardware error notification. */ + if (slot -> ux_device_class_ccid_slot_flags & + UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_HW_ERROR) + { + slot -> ux_device_class_ccid_slot_flags &= + (UCHAR)~UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_HW_ERROR; + buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] = + UX_DEVICE_CLASS_CCID_RDR_TO_PC_HARDWARE_ERROR; + buffer[UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_SLOT] = 0; + buffer[UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_SEQ] = + slot -> ux_device_class_ccid_slot_hw_error_seq; + buffer[UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_CODE] = + slot -> ux_device_class_ccid_slot_hw_error; + length = 4; + } + + /* Check slot change notification. */ + else if (slot -> ux_device_class_ccid_slot_flags & + UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE) + { + slot -> ux_device_class_ccid_slot_flags &= + (UCHAR)~UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE; + + /* Message type. */ + buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] = + UX_DEVICE_CLASS_CCID_RDR_TO_PC_NOTIFY_SLOT_CHANGE; + + /* Slot state bit. */ + icc_mask = (UCHAR)((slot -> ux_device_class_ccid_slot_icc_status == + UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_NOT_PRESENT) ? + 0u : 1u); + + /* Slot change bit. */ + icc_mask |= 0x02u; + + /* Save slot state and change. */ + buffer[UX_DEVICE_CLASS_CCID_OFFSET_SLOT_ICC_STATE] = icc_mask; + + length = 2; + } + + /* Unlock status. */ + ccid -> ux_device_class_ccid_flags &= ~UX_DEVICE_CLASS_CCID_FLAG_LOCK; + + /* Check message to see if there is message to send. */ + if (buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] == 0) + { + + /* There is no pending meesage, -> idle. */ + ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_IDLE; + return(UX_STATE_IDLE); + } + + /* There is message to send. */ + UX_SLAVE_TRANSFER_STATE_RESET(transfer); + transfer -> ux_slave_transfer_request_requested_length = length; + ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_WAIT; + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_NOTIFY_WAIT: + length = transfer -> ux_slave_transfer_request_requested_length; + status = _ux_device_stack_transfer_run(transfer, length, length); + + /* Error/success (done) case. */ + if (status <= UX_STATE_NEXT) + { + + /* Transfer done, check if there is pending message. */ + ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_LOCK; + return(UX_STATE_WAIT); + } + + /* Wait transfer. */ + return(UX_STATE_WAIT); + + default: + break; + } + + + } + + /* Unhandled state. */ + return(UX_STATE_EXIT); +} + +#endif diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_notify_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_ccid_notify_thread_entry.c index 32a740c..91350df 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_notify_thread_entry.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_notify_thread_entry.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_notify_thread_entry PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +68,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_ccid_notify_thread_entry(ULONG ccid_inst) @@ -135,7 +138,7 @@ UINT status; /* Build slot hardware error message. */ parameter = &ccid -> ux_device_class_ccid_parameter; - _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_lock(ccid); slot = ccid -> ux_device_class_ccid_slots; for (i = 0; i < parameter -> ux_device_class_ccid_max_n_slots; i ++) @@ -214,7 +217,7 @@ UINT status; length = byte_pos + 1; } - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Check message to see if there is message to send. */ if (buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] == 0) diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_response.c b/common/usbx_device_classes/src/ux_device_class_ccid_response.c index 41dafdd..3d17288 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_response.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_response.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_response PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -64,6 +64,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_response(UX_DEVICE_CLASS_CCID *ccid, UCHAR *buffer, ULONG length) @@ -90,8 +93,19 @@ UINT status; buffer, length); /* Use case of memcpy is verified. */ } +#if defined(UX_DEVICE_STANDALONE) + + /* Setup transfer struct for running. */ + UX_SLAVE_TRANSFER_STATE_RESET(transfer); + transfer -> ux_slave_transfer_request_requested_length = length; + status = UX_SUCCESS; + + ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_START; +#else + /* Transfer data. */ status = _ux_device_stack_transfer_request(transfer, length, length); +#endif /* Unlock bulk IN. */ _ux_device_mutex_off(&ccid -> ux_device_class_ccid_response_mutex); diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_runner_task_run.c b/common/usbx_device_classes/src/ux_device_class_ccid_runner_task_run.c new file mode 100644 index 0000000..0ee07d9 --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_ccid_runner_task_run.c @@ -0,0 +1,263 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device CCID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_ccid.h" +#include "ux_device_stack.h" + + +#if defined(UX_DEVICE_STANDALONE) + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_ccid_runner_task_run PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is the background task of the CCID. */ +/* */ +/* It's for standalone mode. */ +/* */ +/* INPUT */ +/* */ +/* ccid Pointer to CCID class */ +/* */ +/* OUTPUT */ +/* */ +/* State machine status */ +/* UX_STATE_EXIT Device not configured */ +/* UX_STATE_IDLE No streaming transfer running */ +/* UX_STATE_WAIT Streaming transfer running */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Device Stack */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx Chaoqiong Xiao Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _ux_device_class_ccid_runner_task_run(UX_DEVICE_CLASS_CCID *ccid) +{ + +UX_SLAVE_DEVICE *device; +UX_DEVICE_CLASS_CCID_PARAMETER *parameter; +UX_DEVICE_CLASS_CCID_HANDLE *handles; +UX_DEVICE_CLASS_CCID_HANDLE handle; +UX_DEVICE_CLASS_CCID_RUNNER *runner; +UX_DEVICE_CLASS_CCID_SLOT *slot; +UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *cmd; +UX_DEVICE_CLASS_CCID_COMMAND_SETT *cmd_sett; +UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *rsp; +UX_DEVICE_CLASS_CCID_MESSAGES *messages; +ULONG cmd_checks; +UINT status; +INT immediate_state = UX_TRUE; + + + /* Get the pointer to the device. */ + device = &_ux_system_slave -> ux_system_slave_device; + + /* Check if the device is configured. */ + if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) + return(UX_STATE_EXIT); + + /* Get CCID runner (optimized only 1 runner). */ + runner = ccid -> ux_device_class_ccid_runners; + + /* Slot to handle (optimized for only one slot). */ + slot = ccid -> ux_device_class_ccid_slots; + + /* Get CCID parameter. */ + parameter = &ccid -> ux_device_class_ccid_parameter; + + /* Get CCID messages. */ + messages = &runner -> ux_device_class_ccid_runner_messages; + + /* Get command and response buffers. */ + cmd = (UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *) + runner -> ux_device_class_ccid_runner_command; + rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *) + runner -> ux_device_class_ccid_runner_response; + + /* Process states. */ + while(immediate_state) + { + + /* Check states. */ + switch(runner -> ux_device_class_ccid_runner_state) + { + case UX_DEVICE_CLASS_CCID_RUNNER_IDLE: + return(UX_STATE_IDLE); + + case UX_DEVICE_CLASS_CCID_RUNNER_START: + + /* Command settings. */ + cmd_sett = (UX_DEVICE_CLASS_CCID_COMMAND_SETT *)_ux_device_class_ccid_command_sett; + cmd_sett += runner -> ux_device_class_ccid_runner_command_index; + + /* Message to pass to application. */ + messages -> ux_device_class_ccid_messages_pc_to_rdr = (UCHAR *)cmd; + messages -> ux_device_class_ccid_messages_rdr_to_pc = (UCHAR *)rsp; + + /* Internal checks. */ + cmd_checks = (ULONG)cmd_sett -> ux_device_class_ccid_command_sett_flags; + cmd_checks &= (ULONG)slot -> ux_device_class_ccid_slot_flags; + + /* Check hardware error! */ + if (cmd_checks & UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR) + { + + /* Response: (1,1,HW_ERROR). */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(1, 1); + rsp -> bError = UX_DEVICE_CLASS_CCID_HW_ERROR; + + /* Send response. */ + _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, + messages -> ux_device_class_ccid_messages_rdr_to_pc_length); + + /* Runner is idle (status is updated after response sent). */ + runner -> ux_device_class_ccid_runner_state = UX_DEVICE_CLASS_CCID_RUNNER_IDLE; + continue; + } + + /* Check auto sequencing! */ + if (cmd_checks & UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING) + { + + /* Response: (1,1,BUSY_WITH_AUTO_SEQUENCE). */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(1, 1); + rsp -> bError = UX_DEVICE_CLASS_CCID_BUSY_WITH_AUTO_SEQUENCE; + + /* Send response. */ + _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, + messages -> ux_device_class_ccid_messages_rdr_to_pc_length); + + /* Runner is idle (status is updated after response sent). */ + runner -> ux_device_class_ccid_runner_state = UX_DEVICE_CLASS_CCID_RUNNER_IDLE; + continue; + } + + /* Get command to process, application can fill status. */ + handles = (UX_DEVICE_CLASS_CCID_HANDLE *)parameter -> ux_device_class_ccid_handles; + handle = handles[(INT)cmd_sett -> ux_device_class_ccid_command_sett_handle_index]; + + /* Initialize response length based on type. */ + switch(rsp -> bMessageType) + { + case UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQ: + + /* Length fixed to 10+8. */ + messages -> ux_device_class_ccid_messages_rdr_to_pc_length = 18; + UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(rsp, 8); + break; + + case UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS: + + /* Length fixed to 10. */ + messages -> ux_device_class_ccid_messages_rdr_to_pc_length = + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH; + break; + + default: + + /* There is possible data, set length to max transfer length. */ + messages -> ux_device_class_ccid_messages_rdr_to_pc_length = + parameter -> ux_device_class_ccid_max_transfer_length; + break; + } + + /* Save handle that is running. */ + runner -> ux_device_class_ccid_runner_handle = handle; + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_RUNNER_HANDLE: + + /* Run handle (state machine). */ + status = runner -> ux_device_class_ccid_runner_handle(cmd -> bSlot, messages); + + /* Error cases. */ + if (status < UX_STATE_NEXT || + slot -> ux_device_class_ccid_slot_aborting) + { + + /* There is no response in this case. */ + runner -> ux_device_class_ccid_runner_state = UX_DEVICE_CLASS_CCID_RUNNER_IDLE; + return(UX_STATE_IDLE); + } + + /* Done case. */ + if (status == UX_STATE_NEXT) + { + + /* Next: response start. */ + runner -> ux_device_class_ccid_runner_state = UX_DEVICE_CLASS_CCID_RUNNER_RSP_START; + continue; + } + + /* Waiting. */ + return(UX_STATE_WAIT); + + case UX_DEVICE_CLASS_CCID_RUNNER_RSP_START: + + /* Wait response idle. */ + if (ccid -> ux_device_class_ccid_rsp_state != UX_DEVICE_CLASS_CCID_RSP_IDLE) + return(UX_STATE_WAIT); + + /* Send response. */ + _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, + messages -> ux_device_class_ccid_messages_rdr_to_pc_length); + + /* Runner is idle (status is updated after response sent). */ + runner -> ux_device_class_ccid_runner_state = UX_DEVICE_CLASS_CCID_RUNNER_IDLE; + continue; + + default: + break; + } + + /* Break the loop. */ + immediate_state = UX_FALSE; + } + + /* Unhandled state. */ + return(UX_STATE_EXIT); +} + +#endif diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_runner_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_ccid_runner_thread_entry.c index 5a7aa1c..747d08b 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_runner_thread_entry.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_runner_thread_entry.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_runner_thread_entry PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,6 +66,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_ccid_runner_thread_entry(ULONG ccid_runner) @@ -217,7 +220,7 @@ UINT status; _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, messages.ux_device_class_ccid_messages_rdr_to_pc_length); - _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_lock(ccid); /* Free runner. */ runner -> ux_device_class_ccid_runner_slot = -1; @@ -226,7 +229,7 @@ UINT status; /* Clear slot busy. */ slot -> ux_device_class_ccid_slot_runner = -1; - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); } } #endif diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_ccid_tasks_run.c new file mode 100644 index 0000000..cc56297 --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_ccid_tasks_run.c @@ -0,0 +1,546 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device CCID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_ccid.h" +#include "ux_device_stack.h" + + +#if defined(UX_DEVICE_STANDALONE) + +static inline UINT _ux_device_class_ccid_cmd_task(UX_DEVICE_CLASS_CCID *ccid); +static inline UINT _ux_device_class_ccid_rsp_task(UX_DEVICE_CLASS_CCID *ccid); + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_ccid_tasks_run PORTABLE C */ +/* 6.x */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is the background task of the CCID. */ +/* */ +/* It's for standalone mode. */ +/* */ +/* INPUT */ +/* */ +/* instance Pointer to CCID class */ +/* */ +/* OUTPUT */ +/* */ +/* State machine status */ +/* UX_STATE_EXIT Device not configured */ +/* UX_STATE_IDLE No streaming transfer running */ +/* UX_STATE_WAIT Streaming transfer running */ +/* */ +/* CALLS */ +/* */ +/* ux_device_class_ccid_notify_task_run Run interrupt notify task */ +/* ux_device_class_ccid_runner_task_run Run slot command runner task */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Device Stack */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-xxxx Chaoqiong Xiao Initial Version 6.x */ +/* */ +/**************************************************************************/ +UINT _ux_device_class_ccid_tasks_run(VOID *instance) +{ +UX_SLAVE_DEVICE *device; +UX_DEVICE_CLASS_CCID *ccid; +ULONG run_count = 0; + + + /* Get ccid instance. */ + ccid = (UX_DEVICE_CLASS_CCID *) instance; + + /* Get the pointer to the device. */ + device = &_ux_system_slave -> ux_system_slave_device; + + /* Check if the device is configured. */ + if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) + return(UX_STATE_EXIT); + + /* Bulk OUT command process. */ + if (_ux_device_class_ccid_cmd_task(ccid) != UX_STATE_IDLE) + run_count ++; + + /* Bulk IN response process. */ + if (_ux_device_class_ccid_rsp_task(ccid) != UX_STATE_IDLE) + run_count ++; + + /* Interrupt IN notification process. */ + if (_ux_device_class_ccid_notify_task_run(ccid) != UX_STATE_IDLE) + run_count ++; + + /* Runner tasks process. */ + if (_ux_device_class_ccid_runner_task_run(ccid) != UX_STATE_IDLE) + run_count ++; + + return((run_count > 0) ? UX_STATE_WAIT : UX_STATE_IDLE); +} +static inline UINT _ux_device_class_ccid_cmd_task(UX_DEVICE_CLASS_CCID *ccid) +{ +UX_INTERRUPT_SAVE_AREA +INT immediate_state = UX_TRUE; +UINT status; +UX_DEVICE_CLASS_CCID_SLOT *slot; +UX_DEVICE_CLASS_CCID_RUNNER *runner = UX_NULL; +UX_DEVICE_CLASS_CCID_PARAMETER *parameter; +UX_DEVICE_CLASS_CCID_MESSAGES messages; +UX_SLAVE_ENDPOINT *endpoint; +UX_SLAVE_TRANSFER *transfer_cmd; +UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *cmd; +UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *rsp; +UX_DEVICE_CLASS_CCID_COMMAND_SETT *cmd_sett; +CHAR cmd_index; +UX_DEVICE_CLASS_CCID_HANDLE *handles; + + + /* Check endpoint. */ + endpoint = ccid -> ux_device_class_ccid_endpoint_out; + if (endpoint == UX_NULL) + { + ccid -> ux_device_class_ccid_cmd_state = UX_STATE_RESET; + return(UX_STATE_EXIT); + } + transfer_cmd = &endpoint -> ux_slave_endpoint_transfer_request; + + /* Get running settings. */ + parameter = &ccid -> ux_device_class_ccid_parameter; + + /* Wait Bulk-OUT command. */ + while(immediate_state) + { + + /* Process state. */ + switch(ccid -> ux_device_class_ccid_cmd_state) + { + case UX_DEVICE_CLASS_CCID_CMD_START: + + /* Prepare transfer, next: wait. */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_WAIT; + UX_SLAVE_TRANSFER_STATE_RESET(transfer_cmd); + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_CMD_WAIT: + status = _ux_device_stack_transfer_run(transfer_cmd, + parameter -> ux_device_class_ccid_max_transfer_length, + parameter -> ux_device_class_ccid_max_transfer_length); + + /* Error case. */ + if (status < UX_STATE_NEXT) + { + + ccid -> ux_device_class_ccid_cmd_state = UX_STATE_RESET; + return(UX_STATE_ERROR); + } + + /* Success case. */ + if (status == UX_STATE_NEXT) + { + + /* Check transfer results. */ + if ((transfer_cmd -> ux_slave_transfer_request_completion_code != UX_SUCCESS) || + (transfer_cmd -> ux_slave_transfer_request_actual_length < + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH) || + (transfer_cmd -> ux_slave_transfer_request_actual_length > + parameter -> ux_device_class_ccid_max_transfer_length)) + { + + ccid -> ux_device_class_ccid_cmd_state = UX_STATE_RESET; + return(UX_STATE_ERROR); + } + + /* Access to CCID command message header. */ + cmd = (UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *) + transfer_cmd -> ux_slave_transfer_request_data_pointer; + + /* Get command setting index. */ + cmd_sett = (UX_DEVICE_CLASS_CCID_COMMAND_SETT *)_ux_device_class_ccid_command_sett; + for (cmd_index = 0; cmd_index < UX_DEVICE_CLASS_CCID_N_COMMANDS;) + { + if (cmd -> bMessageType == + cmd_sett -> ux_device_class_ccid_command_sett_command_type) + break; + + /* Next command setting. */ + cmd_sett ++; + cmd_index ++; + } + + /* Save command index for further actions. */ + ccid -> ux_device_class_ccid_cmd_index = cmd_index; + + /* Next: lock and update status. */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_LOCK; + continue; + } + + /* Wait. */ + return(UX_STATE_WAIT); + + case UX_DEVICE_CLASS_CCID_CMD_LOCK: + UX_DISABLE + if (ccid -> ux_device_class_ccid_flags & UX_DEVICE_CLASS_CCID_FLAG_LOCK) + { + UX_RESTORE + return(UX_STATE_WAIT); + } + ccid -> ux_device_class_ccid_flags |= UX_DEVICE_CLASS_CCID_FLAG_LOCK; + UX_RESTORE + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_CMD_PROCESS: + cmd = (UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *) + transfer_cmd -> ux_slave_transfer_request_data_pointer; + cmd_index = ccid -> ux_device_class_ccid_cmd_index; + cmd_sett = (UX_DEVICE_CLASS_CCID_COMMAND_SETT *)&_ux_device_class_ccid_command_sett[(INT)cmd_index]; + handles = (UX_DEVICE_CLASS_CCID_HANDLE *)parameter -> ux_device_class_ccid_handles; + + /* Initialize response. */ + rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *) + ccid -> ux_device_class_ccid_header; + _ux_utility_memory_set(rsp, 0, UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); /* Use case of memset is verified. */ + rsp -> bMessageType = cmd_sett -> ux_device_class_ccid_command_sett_response_type; + rsp -> bSlot = cmd -> bSlot; + rsp -> bSeq = cmd -> bSeq; + + /* Check command support (0,1,0). */ + if (rsp -> bMessageType == 0 || + handles[(INT)cmd_sett -> ux_device_class_ccid_command_sett_handle_index] == UX_NULL) + { + + /* Response: command not supported (0,1,0). */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(0, 1); + _ux_device_class_ccid_unlock(ccid); + + /* Next: response. */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_RSP_START; + return(UX_STATE_IDLE); + } + + /* check Slot exist (2,1,5). */ + if (cmd -> bSlot >= parameter -> ux_device_class_ccid_max_n_slots) + { + + /* Response: Slot not exist. */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(2, 1); + rsp -> bError = 5; + _ux_device_class_ccid_unlock(ccid); + + /* Next: response. */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_RSP_START; + return(UX_STATE_IDLE); + } + + /* Get slot instance for later usage (optimized only 1 slot). */ + slot = ccid -> ux_device_class_ccid_slots; + + /* Initialize response status from slot status. */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS( + slot -> ux_device_class_ccid_slot_icc_status, 0); + + /* Initialize response clock status. */ + if (cmd_sett -> ux_device_class_ccid_command_sett_response_type == 0x81) + rsp -> bClockStatus = slot -> ux_device_class_ccid_slot_clock_status; + + /* Abort command + - return slot status(OK) anyway + - clear aborting status + Aborting + - return slot status(ABORTED) + Other command (except SetDataRateAndClockFrequency) + - Check busy */ + + /* Abort command is handled differently. */ + if (cmd -> bMessageType != UX_DEVICE_CLASS_CCID_PC_TO_RDR_ABORT || + !slot -> ux_device_class_ccid_slot_aborting) + { + + /* Check if slot is idle (optimized one slot). */ + runner = ccid -> ux_device_class_ccid_runners; + if (ccid -> ux_device_class_ccid_n_busy == 0) + { + + /* It's not possible no runner found here, just execute runner. */ + + /* Runner is busy now. */ + runner -> ux_device_class_ccid_runner_slot = (CHAR)cmd->bSlot; + runner -> ux_device_class_ccid_runner_command_index = cmd_index; + ccid -> ux_device_class_ccid_n_busy ++; + + /* Create a copy of command and response header. */ + _ux_utility_memory_copy(runner -> ux_device_class_ccid_runner_command, + cmd, + transfer_cmd -> ux_slave_transfer_request_actual_length); /* Use case of memcpy is verified. */ + _ux_utility_memory_copy(runner -> ux_device_class_ccid_runner_response, + rsp, UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); /* Use case of memcpy is verified. */ + + /* Pre-process of command done. */ + _ux_device_class_ccid_unlock(ccid); + + /* Update runner state to start. */ + runner -> ux_device_class_ccid_runner_state = UX_DEVICE_CLASS_CCID_RUNNER_START; + + /* Command processed, command is allowed when runner is executing. */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_START; + return(UX_STATE_WAIT); + } + + /* Response: Slot Status(busy), optimized for 1 slot. */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS( + slot -> ux_device_class_ccid_slot_icc_status, 1); + rsp -> bError = UX_DEVICE_CLASS_CCID_CMD_SLOT_BUSY; + _ux_device_class_ccid_unlock(ccid); + + /* Next: response (status busy). */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_RSP_START; + continue; + } + + /* We are here when we see Abort command, or aborting. + - Abort command : slot status (ok/fail) + - Aborting : slot status (CMD_ABORTED) + */ + + /* Abort command. */ + if (cmd -> bMessageType == UX_DEVICE_CLASS_CCID_PC_TO_RDR_ABORT) + { + + /* Check sequence. */ + if (cmd -> bSeq != slot -> ux_device_class_ccid_slot_aborting_seq) + { + + /* Response: sequence error. */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS( + slot -> ux_device_class_ccid_slot_icc_status, 1); + rsp -> bError = 6; + } + else + { + + /* Aborting. */ + if (slot -> ux_device_class_ccid_slot_aborting) + { + + /* Call abort handle. */ + messages.ux_device_class_ccid_messages_pc_to_rdr = (VOID *)cmd; + messages.ux_device_class_ccid_messages_rdr_to_pc = (VOID *)rsp; + messages.ux_device_class_ccid_messages_rdr_to_pc_length = 0; + parameter -> ux_device_class_ccid_handles -> + ux_device_class_ccid_handles_abort(cmd -> bSlot, &messages); + + /* Status(OK) */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS( + slot -> ux_device_class_ccid_slot_icc_status, 0); + + /* Free runner (optimized only 1 slot). */ + runner = ccid -> ux_device_class_ccid_runners; + runner -> ux_device_class_ccid_runner_slot = -1; + ccid -> ux_device_class_ccid_n_busy --; + + /* Clear slot busy and aborting. */ + slot -> ux_device_class_ccid_slot_runner = -1; + slot -> ux_device_class_ccid_slot_aborting = UX_FALSE; + } + else + { + + /* Status(CMD_NOT_ABORTED)? */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS( + slot -> ux_device_class_ccid_slot_icc_status, 1); + rsp -> bError = UX_DEVICE_CLASS_CCID_CMD_SLOT_BUSY; + } + } + + _ux_device_class_ccid_unlock(ccid); + + /* Next: response. */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_RSP_START; + return(UX_STATE_IDLE); + } + + /* Aborting. */ + + /* Response: Slot Status(aborted). */ + rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS( + slot -> ux_device_class_ccid_slot_icc_status, 1); + rsp -> bError = UX_DEVICE_CLASS_CCID_CMD_ABORTED; + + _ux_device_class_ccid_unlock(ccid); + + /* Next: response. */ + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_RSP_START; + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_CMD_RSP_START: + + /* Wait until rsponse task is idle. */ + if (ccid -> ux_device_class_ccid_rsp_state != UX_DEVICE_CLASS_CCID_RSP_IDLE) + return(UX_STATE_WAIT); + + /* Start response. */ + _ux_device_class_ccid_response(ccid, + ccid -> ux_device_class_ccid_header, + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); + + /* Command is idle and started after response sent. */ + ccid -> ux_device_class_ccid_flags |= UX_DEVICE_CLASS_CCID_FLAG_CMD_RSP; + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_IDLE; + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_CMD_IDLE: + return(UX_STATE_IDLE); + + default: + break; + } + + /* Break the loop. */ + immediate_state = UX_FALSE; + } + + return(UX_STATE_WAIT); +} +static inline UINT _ux_device_class_ccid_rsp_task(UX_DEVICE_CLASS_CCID *ccid) +{ +UX_INTERRUPT_SAVE_AREA +INT immediate_state = UX_TRUE; +UINT status; +UX_SLAVE_ENDPOINT *endpoint; +UX_SLAVE_TRANSFER *transfer_rsp; +ULONG length; + + /* Check endpoint. */ + endpoint = ccid -> ux_device_class_ccid_endpoint_in; + if (endpoint == UX_NULL) + { + ccid -> ux_device_class_ccid_cmd_state = UX_STATE_RESET; + return(UX_STATE_EXIT); + } + transfer_rsp = &endpoint -> ux_slave_endpoint_transfer_request; + + while(immediate_state) + { + + switch(ccid -> ux_device_class_ccid_rsp_state) + { + + case UX_DEVICE_CLASS_CCID_RSP_IDLE: + return(UX_STATE_IDLE); + + case UX_DEVICE_CLASS_CCID_RSP_START: + ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_WAIT; + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_RSP_WAIT: + + /* Run bulk IN transfer. */ + length = transfer_rsp -> ux_slave_transfer_request_requested_length; + status = _ux_device_stack_transfer_run(transfer_rsp, length, length); + + /* Error/success case. */ + if (status <= UX_STATE_NEXT) + { + + /* Transfer is done. */ + + /* Check if it's command response or runner response. + After runner response status needs update (optimized 1 slot). */ + if (ccid -> ux_device_class_ccid_flags & UX_DEVICE_CLASS_CCID_FLAG_CMD_RSP) + { + ccid -> ux_device_class_ccid_flags &= ~UX_DEVICE_CLASS_CCID_FLAG_CMD_RSP; + + /* CMD -RSP: done. */ + ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_DONE; + continue; + } + + /* CMD - RUNNER - RSP : Update status. */ + ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_LOCK; + continue; + + } + + /* Wait transfer. */ + return(UX_STATE_WAIT); + + case UX_DEVICE_CLASS_CCID_RSP_LOCK: + UX_DISABLE + if (ccid -> ux_device_class_ccid_flags & UX_DEVICE_CLASS_CCID_FLAG_LOCK) + { + UX_RESTORE + return(UX_STATE_WAIT); + } + ccid -> ux_device_class_ccid_flags |= UX_DEVICE_CLASS_CCID_FLAG_LOCK; + UX_RESTORE + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_RSP_UPDATE: + + /* Free runner and clear busy slot (optimized 1 slot). */ + if (ccid -> ux_device_class_ccid_n_busy > 0) + ccid -> ux_device_class_ccid_n_busy --; + + /* Unlock. */ + ccid -> ux_device_class_ccid_flags &= ~UX_DEVICE_CLASS_CCID_FLAG_LOCK; + + /* Fall through. */ + case UX_DEVICE_CLASS_CCID_RSP_DONE: + + /* Start command. */ + if (ccid -> ux_device_class_ccid_cmd_state == UX_DEVICE_CLASS_CCID_CMD_IDLE) + ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_START; + + /* Next: idle. */ + ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_IDLE; + return(UX_STATE_IDLE); + + default: + break; + } + + /* Break the loop. */ + immediate_state = UX_FALSE; + } + + /* Unhandled state. */ + return(UX_STATE_EXIT); +} + +#endif
\ No newline at end of file diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_ccid_thread_entry.c index c30b5e8..d983672 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_thread_entry.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_thread_entry.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_thread_entry PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +68,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _ux_device_class_ccid_thread_entry(ULONG ccid_inst) @@ -163,7 +166,7 @@ UINT status; handles = (UX_DEVICE_CLASS_CCID_HANDLE *)parameter -> ux_device_class_ccid_handles; /* Lock global status resources. */ - _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_lock(ccid); /* Initialize response. */ rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *) @@ -180,7 +183,7 @@ UINT status; /* Response: command not supported (0,1,0). */ rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(0, 1); - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); continue; } @@ -192,7 +195,7 @@ UINT status; /* Response: Slot not exist. */ rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(2, 1); rsp -> bError = 5; - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); continue; } @@ -261,7 +264,7 @@ UINT status; rsp, UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); /* Use case of memcpy is verified. */ /* Pre-process of command done. */ - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Signal event to runner thread. */ _ux_utility_thread_resume(&runner -> ux_device_class_ccid_runner_thread); @@ -278,7 +281,7 @@ UINT status; rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS( slot -> ux_device_class_ccid_slot_icc_status, 1); rsp -> bError = UX_DEVICE_CLASS_CCID_CMD_SLOT_BUSY; - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); continue; } @@ -343,7 +346,7 @@ UINT status; slot -> ux_device_class_ccid_slot_aborting = UX_FALSE; } - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); /* Send response any way. */ _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); @@ -357,7 +360,7 @@ UINT status; slot -> ux_device_class_ccid_slot_icc_status, 1); rsp -> bError = UX_DEVICE_CLASS_CCID_CMD_ABORTED; - _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); + _ux_device_class_ccid_unlock(ccid); _ux_device_class_ccid_response(ccid, (UCHAR *)rsp, UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); } diff --git a/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c b/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c index 2702c39..d702e95 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c @@ -40,7 +40,7 @@ static inline VOID _ux_host_class_hub_inst_tasks_run(UX_HOST_CLASS_HUB *hub); /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_tasks_run PORTABLE C */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -90,6 +90,10 @@ static inline VOID _ux_host_class_hub_inst_tasks_run(UX_HOST_CLASS_HUB *hub); /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed reset speed handling, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */ +/* fixed compile issue if only */ +/* one device is supported, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _ux_host_class_hub_tasks_run(UX_HOST_CLASS *hub_class) @@ -262,7 +266,7 @@ UINT status; /* Check if a device is waiting on the port for reset. */ if ((device -> ux_device_flags & UX_DEVICE_FLAG_RESET) && - (device -> ux_device_parent == hub_device) && + UX_DEVICE_PARENT_MATCH(device, hub_device) && (device -> ux_device_port_location == hub -> ux_host_class_hub_run_port)) { device -> ux_device_flags &= ~UX_DEVICE_FLAG_RESET; @@ -383,7 +387,7 @@ UINT status; { /* If there is a device connected to the port, put its state to ADDR_SET. */ - if ((device -> ux_device_parent == hub -> ux_host_class_hub_device) && + if (UX_DEVICE_PARENT_MATCH(device, hub -> ux_host_class_hub_device) && (device -> ux_device_port_location == hub -> ux_host_class_hub_run_port)) { @@ -411,6 +415,8 @@ UINT status; /* Return device address to 0. */ hcd = UX_DEVICE_HCD_GET(device); + +#if UX_MAX_DEVICES > 1 if (device -> ux_device_address) { @@ -419,6 +425,7 @@ UINT status; (UCHAR)(1u << ((device -> ux_device_address-1) & 7u)); } +#endif /* Assume speed change, re-create EP0 at the HCD level. */ dev_ep0 = &device -> ux_device_control_endpoint; diff --git a/common/usbx_network/src/ux_network_driver.c b/common/usbx_network/src/ux_network_driver.c index f72ae33..c9ae9fd 100644 --- a/common/usbx_network/src/ux_network_driver.c +++ b/common/usbx_network/src/ux_network_driver.c @@ -398,7 +398,7 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device; /* FUNCTION RELEASE */ /* */ /* _ux_network_driver_entry PORTABLE C */ -/* 6.1.12 */ +/* 6.x */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -438,6 +438,9 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device; /* 07-29-2022 Yajun Xia Modified comment(s), */ /* fixed ipv6 support issue, */ /* resulting in version 6.1.12 */ +/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +/* fixed build issue with NETX,*/ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -626,12 +629,13 @@ UINT i; } else { +#ifdef FEATURE_NX_IPV6 if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) +#endif /* FEATURE_NX_IPV6 */ *(ethernet_frame_ptr+3) |= NX_ETHERNET_IP; #ifdef FEATURE_NX_IPV6 else if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) *(ethernet_frame_ptr+3) |= NX_ETHERNET_IPV6; -#endif /* FEATURE_NX_IPV6 */ else { /* Unknown IP version */ @@ -640,6 +644,7 @@ UINT i; nx_ip_driver -> nx_ip_driver_status = NX_NOT_SUCCESSFUL; break; } +#endif /* FEATURE_NX_IPV6 */ } /* Endian swapping if NX_LITTLE_ENDIAN is defined. */ |
