| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_control_abort PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function handles control request Abort of the USB CCID device. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid Pointer to ccid instance */ | ||
| /* slot Slot to abort */ | ||
| /* seq Sequence number of message */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* USBX Source Code */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_control_abort(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq) | ||
| { | ||
|
|
||
| UX_DEVICE_CLASS_CCID_PARAMETER *parameter; | ||
| UX_DEVICE_CLASS_CCID_HANDLES *handles; | ||
| UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; | ||
| UX_SLAVE_TRANSFER *transfer_in, *transfer_out; | ||
| UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *msg; | ||
|
|
||
| /* Get parameter. */ | ||
| parameter = &ccid -> ux_device_class_ccid_parameter; | ||
| handles = parameter -> ux_device_class_ccid_handles; | ||
|
|
||
| /* Check if slot is available. */ | ||
| if (slot >= parameter -> ux_device_class_ccid_max_n_slots) | ||
| return(UX_INVALID_PARAMETER); | ||
|
|
||
| /* Check if command is supported. */ | ||
| if (handles -> ux_device_class_ccid_handles_abort == UX_NULL) | ||
| return(UX_FUNCTION_NOT_SUPPORTED); | ||
|
|
||
| /* Get slot to process. */ | ||
| ccid_slot = &ccid -> ux_device_class_ccid_slots[slot]; | ||
|
|
||
| /* Check if message header received. */ | ||
| transfer_out = &ccid -> ux_device_class_ccid_endpoint_out -> | ||
| ux_slave_endpoint_transfer_request; | ||
| if (transfer_out -> ux_slave_transfer_request_actual_length < | ||
| UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH) | ||
| { | ||
|
|
||
| /* Message header not available, cancel current bulk OUT transfer. */ | ||
| _ux_device_stack_transfer_abort(transfer_out, UX_ABORTED); | ||
| } | ||
| else | ||
| { | ||
|
|
||
| /* Message header available, check message. */ | ||
| msg = (UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *) | ||
| transfer_out -> ux_slave_transfer_request_data_pointer; | ||
|
|
||
| /* Check if abort applies to the slot. */ | ||
| if (msg -> bSlot == (UCHAR)slot) | ||
| { | ||
|
|
||
| /* Yes, aborting current message, cancel current bulk OUT transfer. */ | ||
| _ux_device_stack_transfer_abort(transfer_out, UX_ABORTED); | ||
| } | ||
| else | ||
| { | ||
|
|
||
| /* Aborting another slot. */ | ||
|
|
||
| /* Check slot busy. */ | ||
| if ((signed char)ccid_slot -> ux_device_class_ccid_slot_runner >= 0) | ||
| { | ||
|
|
||
| /* Possible sending something, abort IN transfer. */ | ||
| transfer_in = &ccid -> ux_device_class_ccid_endpoint_in -> | ||
| ux_slave_endpoint_transfer_request; | ||
| _ux_device_stack_transfer_abort(transfer_in, UX_ABORTED); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /* Set aborting state. */ | ||
| ccid_slot -> ux_device_class_ccid_slot_aborting = UX_TRUE; | ||
| ccid_slot -> ux_device_class_ccid_slot_aborting_seq = (UCHAR)seq; | ||
|
|
||
| /* Invoke control abort to let application do something. */ | ||
| handles -> ux_device_class_ccid_handles_abort(slot, UX_NULL); | ||
| return(UX_SUCCESS); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_control_request PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function manages the requests sent by the host on the control */ | ||
| /* endpoints with a CLASS or VENDOR SPECIFIC type. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid Pointer to ccid class */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* None */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* _ux_device_stack_transfer_request Transfer request */ | ||
| /* _ux_device_class_ccid_request_abort Abort slot */ | ||
| /* _ux_utility_memory_copy Copy memory */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* CCID Class */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_control_request(UX_SLAVE_CLASS_COMMAND *command) | ||
| { | ||
| UX_DEVICE_CLASS_CCID *ccid; | ||
| UX_DEVICE_CLASS_CCID_PARAMETER *parameter; | ||
| UX_SLAVE_CLASS *ccid_class; | ||
| UX_SLAVE_TRANSFER *transfer_request; | ||
| UX_SLAVE_DEVICE *device; | ||
| ULONG request; | ||
| UCHAR seq, slot; | ||
| ULONG request_length; | ||
| ULONG transmit_length; | ||
| UCHAR *transmit_buffer; | ||
|
|
||
| /* Get the class container. */ | ||
| ccid_class = command -> ux_slave_class_command_class_ptr; | ||
|
|
||
| /* Get the class instance in the container. */ | ||
| ccid = (UX_DEVICE_CLASS_CCID *) ccid_class -> ux_slave_class_instance; | ||
|
|
||
| /* Get the pointer to the device. */ | ||
| device = &_ux_system_slave -> ux_system_slave_device; | ||
|
|
||
| /* Get the pointer to the transfer request associated with the control endpoint. */ | ||
| transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request; | ||
|
|
||
| /* Extract all necessary fields of the request. */ | ||
| request = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST); | ||
|
|
||
| /* Pickup the request length. */ | ||
| request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH); | ||
|
|
||
| /* Here we proceed only the standard request we know of at the device level. */ | ||
| switch (request) | ||
| { | ||
|
|
||
| case UX_DEVICE_CLASS_CCID_ABORT: | ||
| slot = transfer_request -> ux_slave_transfer_request_setup[UX_SETUP_VALUE]; | ||
| seq = transfer_request -> ux_slave_transfer_request_setup[UX_SETUP_VALUE + 1]; | ||
| return _ux_device_class_ccid_control_abort(ccid, slot, seq); | ||
|
|
||
| case UX_DEVICE_CLASS_CCID_GET_CLOCK_FREQUENCIES: | ||
| parameter = &ccid -> ux_device_class_ccid_parameter; | ||
|
|
||
| /* Check bNumClockSuppored. */ | ||
| if (parameter -> ux_device_class_ccid_clocks == UX_NULL || | ||
| parameter -> ux_device_class_ccid_n_clocks == 0) | ||
| return(UX_ERROR); | ||
|
|
||
| /* Calculate transmit length. */ | ||
| transmit_length = parameter -> ux_device_class_ccid_n_clocks; | ||
| if (UX_OVERFLOW_CHECK_MULC_ULONG(transmit_length, 4)) | ||
| return(UX_ERROR); | ||
| transmit_length <<= 2; | ||
|
|
||
| /* Update transmit buffer. */ | ||
| transmit_buffer = (UCHAR *)parameter -> ux_device_class_ccid_clocks; | ||
| break; | ||
|
|
||
| case UX_DEVICE_CLASS_CCID_GET_DATA_RATES: | ||
| parameter = &ccid -> ux_device_class_ccid_parameter; | ||
|
|
||
| /* Check bNumDataRateSuppored. */ | ||
| if (parameter -> ux_device_class_ccid_data_rates == UX_NULL || | ||
| parameter -> ux_device_class_ccid_n_data_rates == 0) | ||
| return(UX_ERROR); | ||
|
|
||
| /* Calculate transmit length. */ | ||
| transmit_length = parameter -> ux_device_class_ccid_n_data_rates; | ||
| if (UX_OVERFLOW_CHECK_MULC_ULONG(transmit_length, 4)) | ||
| return(UX_ERROR); | ||
| transmit_length <<= 2; | ||
|
|
||
| /* Update transmit buffer. */ | ||
| transmit_buffer = (UCHAR *)parameter -> ux_device_class_ccid_data_rates; | ||
| break ; | ||
|
|
||
| default: | ||
|
|
||
| /* Unknown function. It's not handled. */ | ||
| return(UX_ERROR); | ||
| } | ||
|
|
||
| /* Limit transmit length. */ | ||
| transmit_length = UX_MIN(transmit_length, UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH); | ||
| transmit_length = UX_MIN(transmit_length, request_length); | ||
|
|
||
| /* Copy data to transmit. */ | ||
| _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer, | ||
| transmit_buffer, transmit_length); /* Use case of memcpy is verified. */ | ||
|
|
||
| /* Transmit. */ | ||
| _ux_device_stack_transfer_request(transfer_request, transmit_length, request_length); | ||
|
|
||
| /* It's handled. */ | ||
| return(UX_SUCCESS); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_deactivate PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function deactivate an instance of the ccid class. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* command Pointer to a class command */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* _ux_device_stack_transfer_all_request_abort */ | ||
| /* Abort all transfers */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* CCID Class */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_deactivate(UX_SLAVE_CLASS_COMMAND *command) | ||
| { | ||
|
|
||
| UX_DEVICE_CLASS_CCID *ccid; | ||
| UX_SLAVE_CLASS *ccid_class; | ||
| UX_SLAVE_ENDPOINT *endpoint; | ||
|
|
||
| /* Get the class container. */ | ||
| ccid_class = command -> ux_slave_class_command_class_ptr; | ||
|
|
||
| /* Get the class instance in the container. */ | ||
| ccid = (UX_DEVICE_CLASS_CCID *) ccid_class -> ux_slave_class_instance; | ||
|
|
||
| /* Terminate the transactions pending on the endpoints. */ | ||
| endpoint = ccid -> ux_device_class_ccid_endpoint_out; | ||
| _ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET); | ||
|
|
||
| endpoint = ccid -> ux_device_class_ccid_endpoint_in; | ||
| _ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET); | ||
|
|
||
| endpoint = ccid -> ux_device_class_ccid_endpoint_notify; | ||
| if (endpoint) | ||
| _ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET); | ||
|
|
||
| /* If there is a deactivate function call it. */ | ||
| if (ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_instance_deactivate != UX_NULL) | ||
| { | ||
|
|
||
| /* Invoke the application. */ | ||
| ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_instance_deactivate(ccid); | ||
| } | ||
|
|
||
| /* If trace is enabled, insert this event into the trace buffer. */ | ||
| UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CCID_DEACTIVATE, ccid, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) | ||
|
|
||
| /* If trace is enabled, register this object. */ | ||
| UX_TRACE_OBJECT_UNREGISTER(ccid); | ||
|
|
||
| /* Return completion status. */ | ||
| return(UX_SUCCESS); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_entry PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function is the entry point of the device CCID class. It */ | ||
| /* will be called by the device stack enumeration module when the */ | ||
| /* host has sent a SET_CONFIGURATION command and the ccid interface */ | ||
| /* needs to be mounted. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* command Pointer to class command */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_initialize Initialize ccid class */ | ||
| /* _ux_device_class_ccid_uninitialize Uninitialize ccid class */ | ||
| /* _ux_device_class_ccid_activate Activate ccid class */ | ||
| /* _ux_device_class_ccid_deactivate Deactivate ccid class */ | ||
| /* _ux_device_class_ccid_control_request Request control */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* USBX Device Stack */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_entry(UX_SLAVE_CLASS_COMMAND *command) | ||
| { | ||
|
|
||
| UINT status; | ||
|
|
||
|
|
||
| /* The command request will tell us we need to do here, either a enumeration | ||
| query, an activation or a deactivation. */ | ||
| switch (command -> ux_slave_class_command_request) | ||
| { | ||
|
|
||
| case UX_SLAVE_CLASS_COMMAND_INITIALIZE: | ||
|
|
||
| /* Call the init function of the CCID class. */ | ||
| status = _ux_device_class_ccid_initialize(command); | ||
|
|
||
| /* Return the completion status. */ | ||
| return(status); | ||
|
|
||
| case UX_SLAVE_CLASS_COMMAND_UNINITIALIZE: | ||
|
|
||
| /* Call the init function of the CCID class. */ | ||
| status = _ux_device_class_ccid_uninitialize(command); | ||
|
|
||
| /* Return the completion status. */ | ||
| return(status); | ||
|
|
||
| case UX_SLAVE_CLASS_COMMAND_QUERY: | ||
|
|
||
| /* Check the CLASS definition in the interface descriptor. */ | ||
| if (command -> ux_slave_class_command_class == UX_DEVICE_CLASS_CCID_CLASS) | ||
| return(UX_SUCCESS); | ||
| else | ||
| return(UX_NO_CLASS_MATCH); | ||
|
|
||
| case UX_SLAVE_CLASS_COMMAND_ACTIVATE: | ||
|
|
||
| /* The activate command is used when the host has sent a SET_CONFIGURATION command | ||
| and this interface has to be mounted. Both Bulk endpoints have to be mounted | ||
| and the ccid thread needs to be activated. */ | ||
| status = _ux_device_class_ccid_activate(command); | ||
|
|
||
| /* Return the completion status. */ | ||
| return(status); | ||
|
|
||
| case UX_SLAVE_CLASS_COMMAND_DEACTIVATE: | ||
|
|
||
| /* The deactivate command is used when the device has been extracted. | ||
| The device endpoints have to be dismounted and the ccid thread canceled. */ | ||
| status = _ux_device_class_ccid_deactivate(command); | ||
|
|
||
| /* Return the completion status. */ | ||
| return(status); | ||
|
|
||
| case UX_SLAVE_CLASS_COMMAND_REQUEST: | ||
|
|
||
| /* The request command is used when the host sends a command on the control endpoint. */ | ||
| status = _ux_device_class_ccid_control_request(command); | ||
|
|
||
| /* Return the completion status. */ | ||
| return(status); | ||
|
|
||
| default: | ||
|
|
||
| /* If trace is enabled, insert this event into the trace buffer. */ | ||
| UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0) | ||
|
|
||
| /* Return an error. */ | ||
| return(UX_FUNCTION_NOT_SUPPORTED); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_hardware_error PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function indicates hardware error of the USB CCID device. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid Pointer to ccid instance */ | ||
| /* slot Slot inserted */ | ||
| /* error Error code */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* USBX Source Code */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_hardware_error(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG error) | ||
| { | ||
|
|
||
| UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; | ||
| UX_DEVICE_CLASS_CCID_RUNNER *runner; | ||
| UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *rsp; | ||
|
|
||
| /* Sanity check. */ | ||
| if (slot >= ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_slots) | ||
| return(UX_INVALID_PARAMETER); | ||
|
|
||
| /* Get slot instance. */ | ||
| ccid_slot = ccid -> ux_device_class_ccid_slots; | ||
| ccid_slot += slot; | ||
|
|
||
| /* Lock states. */ | ||
| _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); | ||
|
|
||
| /* Check error. */ | ||
| if (!(ccid_slot -> ux_device_class_ccid_slot_flags & UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR)) | ||
| { | ||
|
|
||
| /* Save error and error code. */ | ||
| ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR; | ||
| ccid_slot -> ux_device_class_ccid_slot_hw_error = (UCHAR)error; | ||
| ccid_slot -> ux_device_class_ccid_slot_hw_error_seq = 0; | ||
|
|
||
| /* Slot deactivated. */ | ||
| ccid_slot -> ux_device_class_ccid_slot_icc_status = UX_DEVICE_CLASS_CCID_ICC_INACTIVE; | ||
|
|
||
| /* Check if command is pending, update response buffer. */ | ||
| if ((signed char)ccid_slot -> ux_device_class_ccid_slot_runner >= 0) | ||
| { | ||
|
|
||
| /* Get running things. */ | ||
| runner = ccid -> ux_device_class_ccid_runners; | ||
| runner += ccid_slot -> ux_device_class_ccid_slot_runner; | ||
| rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *) | ||
| runner -> ux_device_class_ccid_runner_response; | ||
|
|
||
| /* Response: (1,1,HW_ERROR). */ | ||
| rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(1, 1); | ||
| rsp -> bError = UX_DEVICE_CLASS_CCID_HW_ERROR; | ||
| } | ||
| } | ||
|
|
||
| /* Notify if interrupt endpoint exists. */ | ||
| if (ccid -> ux_device_class_ccid_endpoint_notify) | ||
| { | ||
| 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); | ||
|
|
||
| /* Wakeup interrupt notification. */ | ||
| _ux_device_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore); | ||
| return(UX_SUCCESS); | ||
| } | ||
|
|
||
| /* Unlock states. */ | ||
| _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); | ||
|
|
||
| /* Return transfer status. */ | ||
| return(UX_SUCCESS); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_icc_insert PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function indicates card insertion of the USB CCID device. */ | ||
| /* */ | ||
| /* Note if seq_start is TRUE, application must invoke _auto_seq_done */ | ||
| /* later to indicate the sequence end, with final card status. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid Pointer to ccid instance */ | ||
| /* slot Slot inserted */ | ||
| /* seq_start Auto activation sequence on */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* USBX Source Code */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_icc_insert(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq_start) | ||
| { | ||
|
|
||
| UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; | ||
|
|
||
| /* Sanity check. */ | ||
| if (slot >= ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_slots) | ||
| return(UX_INVALID_PARAMETER); | ||
|
|
||
| /* Get slot instance. */ | ||
| ccid_slot = ccid -> ux_device_class_ccid_slots; | ||
| ccid_slot += slot; | ||
|
|
||
| /* Lock states. */ | ||
| _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); | ||
|
|
||
| /* 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); | ||
| return(UX_SUCCESS); | ||
| } | ||
|
|
||
| /* Update card status (INACTIVE). */ | ||
| ccid_slot -> ux_device_class_ccid_slot_icc_status = UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_INACTIVE; | ||
|
|
||
| /* Auto sequencing started? */ | ||
| if (seq_start) | ||
| ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING; | ||
|
|
||
| /* Notify if interrupt endpoint exists. */ | ||
| if (ccid -> ux_device_class_ccid_endpoint_notify) | ||
| { | ||
| 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); | ||
|
|
||
| /* Wakeup interrupt notification. */ | ||
| _ux_device_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore); | ||
| return(UX_SUCCESS); | ||
| } | ||
|
|
||
| /* Unlock states. */ | ||
| _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); | ||
|
|
||
| /* Return transfer status. */ | ||
| return(UX_SUCCESS); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_icc_remove PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function indicates card removal of the USB CCID device. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid Pointer to ccid instance */ | ||
| /* slot Slot removed */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* USBX Source Code */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_icc_remove(UX_DEVICE_CLASS_CCID *ccid, ULONG slot) | ||
| { | ||
|
|
||
| UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; | ||
|
|
||
| /* Sanity check. */ | ||
| if (slot >= ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_slots) | ||
| return(UX_INVALID_PARAMETER); | ||
|
|
||
| /* Get slot instance. */ | ||
| ccid_slot = ccid -> ux_device_class_ccid_slots; | ||
| ccid_slot += slot; | ||
|
|
||
| /* Lock states. */ | ||
| _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); | ||
|
|
||
| /* 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); | ||
| return(UX_SUCCESS); | ||
| } | ||
|
|
||
| /* Update card status (NOT_PRESENT). */ | ||
| ccid_slot -> ux_device_class_ccid_slot_icc_status = UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_NOT_PRESENT; | ||
|
|
||
| /* Clear sequencing. */ | ||
| ccid_slot -> ux_device_class_ccid_slot_flags &= (UCHAR)~UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING; | ||
|
|
||
| /* Clear errors. */ | ||
| ccid_slot -> ux_device_class_ccid_slot_hw_error = 0; | ||
| ccid_slot -> ux_device_class_ccid_slot_flags &= (UCHAR)~UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR; | ||
|
|
||
| /* Notify if interrupt endpoint exists. */ | ||
| 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_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore); | ||
| return(UX_SUCCESS); | ||
| } | ||
| _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); | ||
|
|
||
| /* Return transfer status. */ | ||
| return(UX_SUCCESS); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,227 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
| #if !defined(UX_DEVICE_STANDALONE) | ||
| #include "ux_device_class_ccid.h" | ||
| #include "ux_device_stack.h" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_notify_thread_entry PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function is the thread of the CCID interrupt IN endpoint. It */ | ||
| /* is waiting for the application event to start interrupt IN. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid_inst Address of ccid class */ | ||
| /* container (32-bit) */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* None */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* _ux_device_stack_transfer_request Request transfer */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* ThreadX */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| VOID _ux_device_class_ccid_notify_thread_entry(ULONG ccid_inst) | ||
| { | ||
|
|
||
| UX_SLAVE_DEVICE *device; | ||
| UX_DEVICE_CLASS_CCID *ccid; | ||
| UX_DEVICE_CLASS_CCID_SLOT *slot; | ||
| UX_DEVICE_CLASS_CCID_PARAMETER *parameter; | ||
| UX_SLAVE_ENDPOINT *endpoint; | ||
| UX_SLAVE_TRANSFER *transfer; | ||
| UCHAR *buffer; | ||
| ULONG length; | ||
| INT i; | ||
| UCHAR icc_mask; | ||
| UINT byte_pos, bits_pos; | ||
| UINT status; | ||
|
|
||
| /* Cast properly the ccid instance. */ | ||
| UX_THREAD_EXTENSION_PTR_GET(ccid, UX_DEVICE_CLASS_CCID, ccid_inst) | ||
|
|
||
| /* Get the pointer to the device. */ | ||
| device = &_ux_system_slave -> ux_system_slave_device; | ||
|
|
||
| /* This thread runs forever but can be suspended or resumed by the user application. */ | ||
| status = UX_SUCCESS; | ||
| while(1) | ||
| { | ||
|
|
||
| /* Error cases. */ | ||
| if (status != UX_SUCCESS) | ||
| { | ||
|
|
||
| /* We need to suspend ourselves. We will be resumed by the | ||
| application if needed. */ | ||
| _ux_utility_thread_suspend(&ccid -> ux_device_class_ccid_notify_thread); | ||
| status = UX_SUCCESS; | ||
| continue; | ||
| } | ||
| status = UX_ERROR; | ||
|
|
||
| /* Check device state. */ | ||
| if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) | ||
| continue; | ||
|
|
||
| /* Check endpoint. */ | ||
| endpoint = ccid -> ux_device_class_ccid_endpoint_notify; | ||
| if (endpoint == UX_NULL) | ||
| continue; | ||
| transfer = &endpoint -> ux_slave_endpoint_transfer_request; | ||
|
|
||
| /* Wait event. */ | ||
| status = _ux_utility_semaphore_get(&ccid -> ux_device_class_ccid_notify_semaphore, | ||
| UX_WAIT_FOREVER); | ||
| if (status != UX_SUCCESS) | ||
| continue; | ||
|
|
||
| /* 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; | ||
|
|
||
| /* Build slot hardware error message. */ | ||
| parameter = &ccid -> ux_device_class_ccid_parameter; | ||
|
|
||
| _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex); | ||
|
|
||
| slot = ccid -> ux_device_class_ccid_slots; | ||
| for (i = 0; i < parameter -> ux_device_class_ccid_max_n_slots; i ++) | ||
| { | ||
|
|
||
| /* Check if there is 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] = (UCHAR)i; | ||
| 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; | ||
| break; | ||
| } | ||
|
|
||
| /* Next slot. */ | ||
| slot ++; | ||
| } | ||
|
|
||
| /* Build slot changes message. */ | ||
| if (buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] == 0) | ||
| { | ||
|
|
||
| /* Scan slots. */ | ||
| slot = ccid -> ux_device_class_ccid_slots; | ||
| for (i = 0, byte_pos = 1; ; byte_pos ++) | ||
| { | ||
| /* Reset bits. */ | ||
| buffer[byte_pos] = 0; | ||
|
|
||
| /* Scan 4 slots. */ | ||
| for(bits_pos = 0; bits_pos < 8; bits_pos += 2) | ||
| { | ||
|
|
||
| /* 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); | ||
|
|
||
| /* Check if there is change notification. */ | ||
| 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 change bit. */ | ||
| icc_mask |= (UCHAR)0x02u; | ||
| } | ||
|
|
||
| /* Modify bits. */ | ||
| buffer[byte_pos] |= (UCHAR)(icc_mask << bits_pos); | ||
|
|
||
| /* Next slot. */ | ||
| i ++; | ||
| if (i >= parameter -> ux_device_class_ccid_max_n_slots) | ||
| break; | ||
| slot ++; | ||
| } | ||
| if (i >= parameter -> ux_device_class_ccid_max_n_slots) | ||
| break; | ||
| } | ||
|
|
||
| /* Buffer length should include last byte. */ | ||
| length = byte_pos + 1; | ||
| } | ||
|
|
||
| _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); | ||
|
|
||
| /* Check message to see if there is message to send. */ | ||
| if (buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] == 0) | ||
| continue; | ||
|
|
||
| /* Send request. */ | ||
| status = _ux_device_stack_transfer_request(transfer, length, length); | ||
| } | ||
| } | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_response PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function sends bulk IN response of the USB CCID device. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid Pointer to ccid instance */ | ||
| /* buffer Pointer to data buffer */ | ||
| /* length Data length */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* USBX Source Code */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_response(UX_DEVICE_CLASS_CCID *ccid, UCHAR *buffer, ULONG length) | ||
| { | ||
|
|
||
| UX_SLAVE_ENDPOINT *endpoint; | ||
| UX_SLAVE_TRANSFER *transfer; | ||
| UINT status; | ||
|
|
||
| /* Get bulk IN endpoint. */ | ||
| endpoint = ccid -> ux_device_class_ccid_endpoint_in; | ||
|
|
||
| /* Get transfer request. */ | ||
| transfer = &endpoint -> ux_slave_endpoint_transfer_request; | ||
|
|
||
| /* Lock bulk IN. */ | ||
| _ux_device_mutex_on(&ccid -> ux_device_class_ccid_response_mutex); | ||
|
|
||
| /* Prepare data to transfer. */ | ||
| if (length > 0 && buffer != UX_NULL && | ||
| transfer -> ux_slave_transfer_request_data_pointer != buffer) | ||
| { | ||
| _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer, | ||
| buffer, length); /* Use case of memcpy is verified. */ | ||
| } | ||
|
|
||
| /* Transfer data. */ | ||
| status = _ux_device_stack_transfer_request(transfer, length, length); | ||
|
|
||
| /* Unlock bulk IN. */ | ||
| _ux_device_mutex_off(&ccid -> ux_device_class_ccid_response_mutex); | ||
|
|
||
| /* Return transfer status. */ | ||
| return(status); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,232 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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_thread_entry PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function is the thread of the CCID command handling. It */ | ||
| /* is waiting for the event to start command processing. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid_runner Address of CCID runner (32b) */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* None */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* _ux_device_stack_transfer_request Request transfer */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* ThreadX */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| VOID _ux_device_class_ccid_runner_thread_entry(ULONG ccid_runner) | ||
| { | ||
|
|
||
| UX_SLAVE_DEVICE *device; | ||
| UX_DEVICE_CLASS_CCID *ccid; | ||
| 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 event_mask, flags; | ||
| ULONG cmd_checks; | ||
| UINT status; | ||
|
|
||
| /* Cast properly the ccid runner. */ | ||
| UX_THREAD_EXTENSION_PTR_GET(runner, UX_DEVICE_CLASS_CCID_RUNNER, ccid_runner) | ||
|
|
||
| /* Get the pointer to the device. */ | ||
| device = &_ux_system_slave -> ux_system_slave_device; | ||
|
|
||
| /* Get CCID instance. */ | ||
| ccid = runner -> ux_device_class_ccid_runner_ccid; | ||
|
|
||
| /* Get CCID parameter. */ | ||
| parameter = &ccid -> ux_device_class_ccid_parameter; | ||
|
|
||
| /* Get event mask to wait. */ | ||
| event_mask = 1u << runner -> ux_device_class_ccid_runner_id; | ||
|
|
||
| /* This thread runs forever but can be suspended or resumed by the user application. */ | ||
| status = UX_SUCCESS; | ||
| while(1) | ||
| { | ||
|
|
||
| /* Check device state. */ | ||
| if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) | ||
| { | ||
| _ux_utility_thread_suspend(&runner -> ux_device_class_ccid_runner_thread); | ||
| continue; | ||
| } | ||
|
|
||
| /* Wait signal. */ | ||
| status = _ux_utility_event_flags_get(&ccid -> ux_device_class_ccid_events, | ||
| event_mask, UX_OR_CLEAR, &flags, UX_WAIT_FOREVER); | ||
| if (status != UX_SUCCESS) | ||
| { | ||
| _ux_utility_thread_suspend(&runner -> ux_device_class_ccid_runner_thread); | ||
| continue; | ||
| } | ||
|
|
||
| /* We have a command to process. */ | ||
| 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; | ||
|
|
||
| /* Slot to handle. */ | ||
| slot = ccid -> ux_device_class_ccid_slots; | ||
| slot += runner -> ux_device_class_ccid_runner_slot; | ||
|
|
||
| /* 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; | ||
| } | ||
|
|
||
| /* Check auto sequencing! */ | ||
| else 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; | ||
| } | ||
|
|
||
| /* Process command, application can fill status. */ | ||
| else | ||
| { | ||
|
|
||
| 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; | ||
| } | ||
|
|
||
| /* Invoke application callback. */ | ||
| status = handle(cmd -> bSlot, &messages); | ||
|
|
||
| /* Save application status updates. */ | ||
|
|
||
| /* Save bmICCStatus. */ | ||
| slot -> ux_device_class_ccid_slot_icc_status = rsp->bStatus & | ||
| UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_MASK; | ||
|
|
||
| /* Save bClockStatus. */ | ||
| slot -> ux_device_class_ccid_slot_clock_status = rsp->bClockStatus; | ||
| } | ||
|
|
||
| /* If failed (aborted), no response. */ | ||
| if (status != UX_SUCCESS) | ||
| continue; | ||
| if (slot -> ux_device_class_ccid_slot_aborting) | ||
| continue; | ||
|
|
||
| /* Send response. */ | ||
| _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); | ||
|
|
||
| /* Free runner. */ | ||
| runner -> ux_device_class_ccid_runner_slot = -1; | ||
| ccid -> ux_device_class_ccid_n_busy --; | ||
|
|
||
| /* Clear slot busy. */ | ||
| slot -> ux_device_class_ccid_slot_runner = -1; | ||
|
|
||
| _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex); | ||
| } | ||
| } | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_time_extension PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function sends bulk IN time_extension of the USB CCID device. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* ccid Pointer to ccid instance */ | ||
| /* slot Slot to extend time */ | ||
| /* wt BWT (T=1) or WWT (T=0) */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* USBX Source Code */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_time_extension(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG wt) | ||
| { | ||
|
|
||
| UX_SLAVE_ENDPOINT *endpoint; | ||
| UX_SLAVE_TRANSFER *transfer; | ||
| UX_DEVICE_CLASS_CCID_SLOT *ccid_slot; | ||
| UX_DEVICE_CLASS_CCID_RUNNER *runner; | ||
| UCHAR *rsp, *runner_rsp; | ||
| UINT status; | ||
|
|
||
| /* Get slot. */ | ||
| ccid_slot = ccid -> ux_device_class_ccid_slots; | ||
| ccid_slot += slot; | ||
|
|
||
| /* Check slot state. */ | ||
| if ((signed char)ccid_slot -> ux_device_class_ccid_slot_runner < 0) | ||
| return(UX_INVALID_STATE); | ||
|
|
||
| /* Get runner. */ | ||
| runner = ccid -> ux_device_class_ccid_runners; | ||
| runner += ccid_slot -> ux_device_class_ccid_slot_runner; | ||
|
|
||
| /* Get bulk IN endpoint. */ | ||
| endpoint = ccid -> ux_device_class_ccid_endpoint_in; | ||
|
|
||
| /* Get transfer request. */ | ||
| transfer = &endpoint -> ux_slave_endpoint_transfer_request; | ||
|
|
||
| /* Lock bulk IN. */ | ||
| _ux_device_mutex_on(&ccid -> ux_device_class_ccid_response_mutex); | ||
|
|
||
| /* Get response buffer. */ | ||
| rsp = transfer -> ux_slave_transfer_request_data_pointer; | ||
| runner_rsp = runner -> ux_device_class_ccid_runner_response; | ||
|
|
||
| /* Fill response. */ | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] = runner_rsp[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE]; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_LENGTH] = 0; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_LENGTH+1] = 0; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_LENGTH+2] = 0; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_LENGTH+3] = 0; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_SLOT] = runner_rsp[UX_DEVICE_CLASS_CCID_OFFSET_SLOT]; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_SEQ] = runner_rsp[UX_DEVICE_CLASS_CCID_OFFSET_SEQ]; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_STATUS] = runner_rsp[UX_DEVICE_CLASS_CCID_OFFSET_STATUS] | | ||
| UX_DEVICE_CLASS_CCID_SLOT_STATUS_TIME_EXTENSION; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_ERROR] = (UCHAR)wt; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_CHAIN_PARAMETER] = 0; | ||
| rsp[UX_DEVICE_CLASS_CCID_OFFSET_CHAIN_PARAMETER+1] = 0; | ||
|
|
||
| /* Transfer data. */ | ||
| status = _ux_device_stack_transfer_request(transfer, | ||
| UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH, | ||
| UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH); | ||
|
|
||
| /* Unlock bulk IN. */ | ||
| _ux_device_mutex_off(&ccid -> ux_device_class_ccid_response_mutex); | ||
|
|
||
| /* Return transfer status. */ | ||
| return(status); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| /**************************************************************************/ | ||
| /* */ | ||
| /* 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" | ||
|
|
||
|
|
||
| /**************************************************************************/ | ||
| /* */ | ||
| /* FUNCTION RELEASE */ | ||
| /* */ | ||
| /* _ux_device_class_ccid_uninitialize PORTABLE C */ | ||
| /* 6.1.11 */ | ||
| /* AUTHOR */ | ||
| /* */ | ||
| /* Chaoqiong Xiao, Microsoft Corporation */ | ||
| /* */ | ||
| /* DESCRIPTION */ | ||
| /* */ | ||
| /* This function uninitialize the USB CCID device. */ | ||
| /* */ | ||
| /* INPUT */ | ||
| /* */ | ||
| /* command Pointer to ccid command */ | ||
| /* */ | ||
| /* OUTPUT */ | ||
| /* */ | ||
| /* Completion Status */ | ||
| /* */ | ||
| /* CALLS */ | ||
| /* */ | ||
| /* _ux_utility_memory_free Free memory */ | ||
| /* _ux_device_mutex_delete Delete mutex */ | ||
| /* _ux_utility_event_flags_delete Delete event flags */ | ||
| /* _ux_utility_thread_delete Delete thread */ | ||
| /* */ | ||
| /* CALLED BY */ | ||
| /* */ | ||
| /* USBX Source Code */ | ||
| /* */ | ||
| /* RELEASE HISTORY */ | ||
| /* */ | ||
| /* DATE NAME DESCRIPTION */ | ||
| /* */ | ||
| /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ | ||
| /* */ | ||
| /**************************************************************************/ | ||
| UINT _ux_device_class_ccid_uninitialize(UX_SLAVE_CLASS_COMMAND *command) | ||
| { | ||
|
|
||
| UX_DEVICE_CLASS_CCID *ccid; | ||
| UX_SLAVE_CLASS *ccid_class; | ||
| #if !defined(UX_DEVICE_STANDALONE) | ||
| UX_DEVICE_CLASS_CCID_RUNNER *runner; | ||
| ULONG i; | ||
| #endif | ||
|
|
||
| /* Get the class container. */ | ||
| ccid_class = command -> ux_slave_class_command_class_ptr; | ||
|
|
||
| /* Get the CCID instance. */ | ||
| ccid = (UX_DEVICE_CLASS_CCID *)ccid_class -> ux_slave_class_instance; | ||
|
|
||
| /* Sanity check. */ | ||
| if (ccid != UX_NULL) | ||
| { | ||
|
|
||
| /* Free allocated resources. */ | ||
| #if !defined(UX_DEVICE_STANDALONE) | ||
| _ux_device_thread_delete(&ccid -> ux_device_class_ccid_notify_thread); | ||
| _ux_device_thread_delete(&ccid -> ux_device_class_ccid_thread); | ||
| for (i = 0; | ||
| i < ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_busy_slots; | ||
| i ++) | ||
| { | ||
| runner = &ccid -> ux_device_class_ccid_runners[i]; | ||
| _ux_device_thread_delete(&runner -> ux_device_class_ccid_runner_thread); | ||
| } | ||
| _ux_device_event_flags_delete(&ccid -> ux_device_class_ccid_events); | ||
| _ux_device_mutex_delete(&ccid -> ux_device_class_ccid_mutex); | ||
| _ux_device_semaphore_delete(&ccid -> ux_device_class_ccid_notify_semaphore); | ||
| _ux_device_mutex_delete(&ccid -> ux_device_class_ccid_response_mutex); | ||
| #endif | ||
|
|
||
| /* Free instance memory. */ | ||
| _ux_utility_memory_free(ccid); | ||
| } | ||
|
|
||
| /* Return completion status. */ | ||
| return(UX_SUCCESS); | ||
| } |