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)83 VOID  _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