GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_cdc_ecm_interrupt_notification.c Lines: 26 26 100.0 %
Date: 2024-12-12 17:16:36 Branches: 18 18 100.0 %

Line Branch Exec Source
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
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _ux_host_class_cdc_ecm_interrupt_notification       PORTABLE C      */
37
/*                                                           6.1.11       */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Chaoqiong Xiao, Microsoft Corporation                               */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function is called by the stack when an interrupt packet as    */
45
/*    been received.                                                      */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    transfer_request                      Pointer to transfer request   */
50
/*                                                                        */
51
/*  OUTPUT                                                                */
52
/*                                                                        */
53
/*    None                                                                */
54
/*                                                                        */
55
/*  CALLS                                                                 */
56
/*                                                                        */
57
/*    None                                                                */
58
/*                                                                        */
59
/*  CALLED BY                                                             */
60
/*                                                                        */
61
/*    USBX stack                                                          */
62
/*                                                                        */
63
/*  RELEASE HISTORY                                                       */
64
/*                                                                        */
65
/*    DATE              NAME                      DESCRIPTION             */
66
/*                                                                        */
67
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
68
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
69
/*                                            resulting in version 6.1    */
70
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
71
/*                                            refined macros names,       */
72
/*                                            resulting in version 6.1.10 */
73
/*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
74
/*                                            fixed standalone compile,   */
75
/*                                            resulting in version 6.1.11 */
76
/*                                                                        */
77
/**************************************************************************/
78
114
VOID  _ux_host_class_cdc_ecm_interrupt_notification(UX_TRANSFER *transfer_request)
79
{
80
81
UX_HOST_CLASS_CDC_ECM                       *cdc_ecm;
82
ULONG                                       notification_type;
83
ULONG                                       notification_value;
84
85
86
    /* Get the control class instance for this transfer request.  */
87
114
    cdc_ecm =  (UX_HOST_CLASS_CDC_ECM *) transfer_request -> ux_transfer_request_class_instance;
88
89
    /* Check the state of the transfer.  If there is an error, we do not proceed with this notification.  */
90
114
    if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
91
92
        /* We do not proceed.  */
93
50
        return;
94
95
    /* Check if the class is in shutdown.  */
96
64
    if (cdc_ecm -> ux_host_class_cdc_ecm_state ==  UX_HOST_CLASS_INSTANCE_SHUTDOWN)
97
98
        /* We do not proceed.  */
99
1
        return;
100
101
    /* Increment the notification count.   */
102
63
    cdc_ecm -> ux_host_class_cdc_ecm_notification_count++;
103
104
    /* Get the notification.  */
105
63
    notification_type = (ULONG) *(transfer_request -> ux_transfer_request_data_pointer + UX_HOST_CLASS_CDC_ECM_NPF_NOTIFICATION_TYPE);
106
107
    /* And the value.  */
108
63
    notification_value = (ULONG) *(transfer_request -> ux_transfer_request_data_pointer + UX_HOST_CLASS_CDC_ECM_NPF_VALUE);
109
110
    /* Check if the notification is a Network notification.  */
111
63
    if (notification_type == UX_HOST_CLASS_CDC_ECM_NOTIFICATION_NETWORK_CONNECTION)
112
    {
113
114
        /* Check the state of the link.  */
115
62
        if (notification_value == UX_HOST_CLASS_CDC_ECM_NOTIFICATION_NETWORK_LINK_UP)
116
        {
117
118
            /* Link is up. See if we know about that.  */
119
51
            if (cdc_ecm -> ux_host_class_cdc_ecm_link_state != UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP &&
120
50
                cdc_ecm -> ux_host_class_cdc_ecm_link_state != UX_HOST_CLASS_CDC_ECM_LINK_STATE_PENDING_UP)
121
            {
122
123
                /* Memorize the new link state.  */
124
49
                cdc_ecm -> ux_host_class_cdc_ecm_link_state =  UX_HOST_CLASS_CDC_ECM_LINK_STATE_PENDING_UP;
125
126
                /* We need to inform the cdc_ecm thread of this change.  */
127
49
                _ux_host_semaphore_put(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore);
128
            }
129
        }
130
        else
131
        {
132
133
            /* Link is down. See if we know about that.  */
134
11
            if (cdc_ecm -> ux_host_class_cdc_ecm_link_state != UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN &&
135
9
                cdc_ecm -> ux_host_class_cdc_ecm_link_state != UX_HOST_CLASS_CDC_ECM_LINK_STATE_PENDING_DOWN)
136
            {
137
138
                /* We need to abort any transfers on the bulk in endpoint.  */
139
140
                /* Make sure no one does any more transfers.  */
141
8
                cdc_ecm -> ux_host_class_cdc_ecm_link_state =  UX_HOST_CLASS_CDC_ECM_LINK_STATE_PENDING_DOWN;
142
143
                /* Now abort all transfers. It's possible we're executing right before the transfer
144
                   is armed. If this is the case, then the transfer will not be aborted if we do the abort right now; instead,
145
                   we should wait until after the transfer is armed. We must look at the CDC-ECM thread's state.  */
146
147
                /* Is it in the process of checking the link state and arming the transfer?  */
148
8
                if (cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_check_and_arm_in_process == UX_TRUE)
149
                {
150
151
                    /* Yes. We must wait for it to finish arming the transfer.  */
152
153
                    /* Let the CDC-ECM thread know we're waiting so it can wake us up.  */
154
1
                    cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish =  UX_TRUE;
155
156
                    /* Wait for the transfer to be armed, or possibly an error. The CDC-ECM thread will wake us up.  */
157
1
                    _ux_host_semaphore_get_norc(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish_semaphore, UX_WAIT_FOREVER);
158
159
                    /* We're no longer waiting.  */
160
1
                    cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish =  UX_FALSE;
161
                }
162
163
                /* Now we can abort the transfer.  */
164
8
                _ux_host_stack_transfer_request_abort(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_endpoint -> ux_endpoint_transfer_request);
165
166
                /* We need to inform the CDC-ECM thread of this change.  */
167
8
                _ux_host_semaphore_put(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore);
168
            }
169
        }
170
    }
171
172
    /* Reactivate the CDC_ECM interrupt pipe.  */
173
63
    _ux_host_stack_transfer_request(transfer_request);
174
175
    /* If trace is enabled, insert this event into the trace buffer.  */
176
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_CDC_ECM_INTERRUPT_NOTIFICATION, cdc_ecm, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
177
178
    /* Return to caller.  */
179
63
    return;
180
}
181