GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_cdc_ecm_transmission_callback.c Lines: 31 31 100.0 %
Date: 2026-03-06 18:57:10 Branches: 16 16 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** USBX Component                                                        */
17
/**                                                                       */
18
/**   CDC-ECM Class                                                       */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
24
/* Include necessary system files.  */
25
26
#define UX_SOURCE_CODE
27
28
#include "ux_api.h"
29
#include "ux_host_class_cdc_ecm.h"
30
#include "ux_host_stack.h"
31
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _ux_host_class_cdc_ecm_transmission_callback        PORTABLE C      */
38
/*                                                           6.2.0        */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Chaoqiong Xiao, Microsoft Corporation                               */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function is the callback from the USBX transfer functions,     */
46
/*    it is called when a full or partial transfer has been done for a    */
47
/*    bulk out transfer.                                                  */
48
/*                                                                        */
49
/*  INPUT                                                                 */
50
/*                                                                        */
51
/*    transfer_request                      Pointer to transfer request   */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    None                                                                */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _ux_host_stack_transfer_request       Process transfer request      */
60
/*    nx_packet_transmit_release            Release NetX packet           */
61
/*                                                                        */
62
/*  CALLED BY                                                             */
63
/*                                                                        */
64
/*    Application                                                         */
65
/*                                                                        */
66
/**************************************************************************/
67
2131
VOID  _ux_host_class_cdc_ecm_transmission_callback(UX_TRANSFER *transfer_request)
68
{
69
#if defined(UX_HOST_STANDALONE)
70
    UX_PARAMETER_NOT_USED(transfer_request);
71
#else
72
73
UX_HOST_CLASS_CDC_ECM           *cdc_ecm;
74
NX_PACKET                       *current_packet;
75
NX_PACKET                       *next_packet;
76
UCHAR                           *packet_header;
77
#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
78
ULONG                           copied;
79
#endif
80
81
    /* Get the data and control class instances for this transfer request.  */
82
2131
    cdc_ecm =  (UX_HOST_CLASS_CDC_ECM *) transfer_request -> ux_transfer_request_class_instance;
83
84
    /* Is the link not up, or the class is shutting down?  */
85
2131
    if (cdc_ecm -> ux_host_class_cdc_ecm_link_state != UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP ||
86
2128
        cdc_ecm -> ux_host_class_cdc_ecm_state == UX_HOST_CLASS_INSTANCE_SHUTDOWN)
87
88
        /* The CDC-ECM thread or deactivation routine is in the process of freeing
89
           the queue. Just return so we are not simultaneously accessing it.  */
90
4
        return;
91
92
    /* Get the packet associated with this transfer.  */
93
2127
    current_packet =  cdc_ecm -> ux_host_class_cdc_ecm_xmit_queue_head;
94
95
    /* Do a sanity check on the packet.  */
96
2127
    if (current_packet == UX_NULL)
97
    {
98
99
        /* Error trap. */
100
1
        _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_FATAL_ERROR);
101
102
        /* If trace is enabled, insert this event into the trace buffer.  */
103
        UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, cdc_ecm, 0, 0, UX_FATAL_ERROR, 0, 0)
104
105
        /* Something went terribly wrong. Do not proceed.  */
106
1
        return;
107
    }
108
109
    /* Check the state of the transfer.  */
110
2126
    if (transfer_request -> ux_transfer_request_completion_code == UX_SUCCESS)
111
    {
112
113
        /* Check if the transfer length is not zero and it is multiple of MPS (validated on device enum).  */
114
2125
        if ((transfer_request -> ux_transfer_request_requested_length != 0) &&
115
2124
            (transfer_request -> ux_transfer_request_requested_length % transfer_request -> ux_transfer_request_packet_length) == 0)
116
        {
117
118
            /* Set transfer request length to zero.  */
119
1
            transfer_request -> ux_transfer_request_requested_length =  0;
120
121
            /* Send the transfer.  */
122
1
            _ux_host_stack_transfer_request(transfer_request);
123
124
            /* Finished processing.  */
125
1
            return;
126
        }
127
128
        /* Get the next packet associated with the first packet.  */
129
2124
        next_packet =  current_packet -> nx_packet_queue_next;
130
131
        /* Set the next packet (or a NULL value) as the head of the xmit queue. */
132
2124
        cdc_ecm -> ux_host_class_cdc_ecm_xmit_queue_head =  next_packet;
133
134
        /* If there is nothing else or if the link is down no need to rearm a packet. */
135
2124
        if (next_packet != UX_NULL)
136
        {
137
138
#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
139
140
1932
            if (next_packet -> nx_packet_next != UX_NULL)
141
            {
142
143
                /* Put packet to continuous buffer to transfer.  */
144
20
                packet_header = cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer;
145
20
                nx_packet_data_extract_offset(next_packet, 0, packet_header, next_packet -> nx_packet_length, &copied);
146
            }
147
            else
148
#endif
149
            {
150
151
                /* Load the address of the current packet header at the physical header.  */
152
1912
                packet_header =  next_packet -> nx_packet_prepend_ptr;
153
            }
154
155
            /* Prepare the values for this new transmission.  */
156
1932
            transfer_request -> ux_transfer_request_data_pointer     =  packet_header;
157
1932
            transfer_request -> ux_transfer_request_requested_length =  next_packet -> nx_packet_length;
158
159
            /* Store the packet that owns this transaction.  */
160
1932
            transfer_request -> ux_transfer_request_user_specific = next_packet;
161
162
            /* If error log is enabled, insert this message into the log buffer.  */
163
            UX_DEBUG_LOG("_ux_host_class_cdc_ecm_transmission_callback", "Sending packet", next_packet, next_packet, _ux_system_mutex_suspended_count(&_ux_system -> ux_system_mutex))
164
165
            /* If there is an error, the system will hang up. Not much we can do to
166
               fix this.  */
167
1932
            _ux_host_stack_transfer_request(transfer_request);
168
        }
169
170
        /* If error log is enabled, insert this message into the log buffer.  */
171
        UX_DEBUG_LOG("_ux_host_class_cdc_ecm_transmission_callback", "Freeing transmitted packet", 0, transfer_request, current_packet)
172
173
        /* Free the packet that was just sent.  First do some housekeeping.  */
174
2124
        current_packet -> nx_packet_prepend_ptr =  current_packet -> nx_packet_prepend_ptr + UX_HOST_CLASS_CDC_ECM_ETHERNET_SIZE;
175
2124
        current_packet -> nx_packet_length =  current_packet -> nx_packet_length - UX_HOST_CLASS_CDC_ECM_ETHERNET_SIZE;
176
177
        /* And ask Netx to release it.  */
178
2124
        nx_packet_transmit_release(current_packet);
179
    }
180
    else
181
    {
182
183
        /* The transfer failed. Retry it. Note that this can't be a transfer
184
           abort, because otherwise the link is either down or the class is in
185
           shutdown, both of which are checked for at the beginning.  */
186
1
        _ux_host_stack_transfer_request(transfer_request);
187
    }
188
189
    /* There is no status to be reported back to the stack.  */
190
2125
    return;
191
#endif
192
}