1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** USBX Component */ 16 /** */ 17 /** CDC_ECM Class */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 23 /* Include necessary system files. */ 24 25 #define UX_SOURCE_CODE 26 27 #include "ux_api.h" 28 #include "ux_host_class_cdc_ecm.h" 29 #include "ux_host_stack.h" 30 31 32 #if !defined(UX_HOST_STANDALONE) 33 /**************************************************************************/ 34 /* */ 35 /* FUNCTION RELEASE */ 36 /* */ 37 /* _ux_host_class_cdc_ecm_transmit_queue_clean PORTABLE C */ 38 /* 6.1.11 */ 39 /* AUTHOR */ 40 /* */ 41 /* Chaoqiong Xiao, Microsoft Corporation */ 42 /* */ 43 /* DESCRIPTION */ 44 /* */ 45 /* This function cleans the transmit queue. */ 46 /* */ 47 /* INPUT */ 48 /* */ 49 /* cdc_ecm CDC ECM instance */ 50 /* */ 51 /* OUTPUT */ 52 /* */ 53 /* No return value */ 54 /* */ 55 /* CALLS */ 56 /* */ 57 /* _ux_host_semaphore_get Get bulk out semaphore */ 58 /* _ux_host_stack_endpoint_transfer_abort Abort endpoint transfer */ 59 /* nx_packet_transmit_release Release NetX packet */ 60 /* */ 61 /* CALLED BY */ 62 /* */ 63 /* CDC ECM thread and deactivation */ 64 /* */ 65 /* RELEASE HISTORY */ 66 /* */ 67 /* DATE NAME DESCRIPTION */ 68 /* */ 69 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 70 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 71 /* used UX prefix to refer to */ 72 /* TX symbols instead of using */ 73 /* them directly, */ 74 /* resulting in version 6.1 */ 75 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ 76 /* refined macros names, */ 77 /* resulting in version 6.1.10 */ 78 /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ 79 /* fixed standalone compile, */ 80 /* resulting in version 6.1.11 */ 81 /* */ 82 /**************************************************************************/ _ux_host_class_cdc_ecm_transmit_queue_clean(UX_HOST_CLASS_CDC_ECM * cdc_ecm)83VOID _ux_host_class_cdc_ecm_transmit_queue_clean(UX_HOST_CLASS_CDC_ECM *cdc_ecm) 84 { 85 86 UX_INTERRUPT_SAVE_AREA 87 88 NX_PACKET *current_packet; 89 NX_PACKET *next_packet; 90 91 /* Disable interrupts while we check the write in process flag and 92 set our own state. */ 93 UX_DISABLE 94 95 /* Is there a write in process? */ 96 if (cdc_ecm -> ux_host_class_cdc_ecm_bulk_out_transfer_check_and_arm_in_process == UX_TRUE) 97 { 98 99 /* Wait for writes to complete. Note that once these writes complete, 100 no more should occur since the link state is pending down. */ 101 102 /* Mark this thread as suspended so it will be woken up. */ 103 cdc_ecm -> ux_host_class_cdc_ecm_bulk_out_transfer_waiting_for_check_and_arm_to_finish = UX_TRUE; 104 105 /* Restore interrupts while we wait. */ 106 UX_RESTORE 107 108 /* Wait for write function to resume us. */ 109 _ux_host_semaphore_get_norc(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_out_transfer_waiting_for_check_and_arm_to_finish_semaphore, UX_WAIT_FOREVER); 110 111 /* We're done waiting. */ 112 cdc_ecm -> ux_host_class_cdc_ecm_bulk_out_transfer_waiting_for_check_and_arm_to_finish = UX_FALSE; 113 } 114 else 115 { 116 117 /* No writes are in process. Restore interrupts and go on to free 118 the xmit queue. */ 119 UX_RESTORE 120 } 121 122 /* Abort transfers on the bulk out endpoint. Note we need to do this 123 before accessing the queue since the transmission callback might 124 modify it. */ 125 _ux_host_stack_transfer_request_abort(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_out_endpoint -> ux_endpoint_transfer_request); 126 127 /* Get the first packet. */ 128 current_packet = cdc_ecm -> ux_host_class_cdc_ecm_xmit_queue_head; 129 130 /* We need to free the packets that will not be sent. */ 131 while (current_packet != UX_NULL) 132 { 133 134 /* We must get the next packet before releasing the current packet 135 because nxe_packet_transmit_release sets the pointer we pass 136 to null. */ 137 next_packet = current_packet -> nx_packet_queue_next; 138 139 /* Free the packet. First do some housekeeping. */ 140 current_packet -> nx_packet_prepend_ptr = current_packet -> nx_packet_prepend_ptr + UX_HOST_CLASS_CDC_ECM_ETHERNET_SIZE; 141 current_packet -> nx_packet_length = current_packet -> nx_packet_length - UX_HOST_CLASS_CDC_ECM_ETHERNET_SIZE; 142 143 /* And ask Netx to release it. */ 144 nx_packet_transmit_release(current_packet); 145 146 /* Next packet becomes the current one. */ 147 current_packet = next_packet; 148 } 149 150 /* Clear the queue. */ 151 cdc_ecm -> ux_host_class_cdc_ecm_xmit_queue_head = UX_NULL; 152 } 153 #endif 154