GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_device_stack_class_register.c Lines: 23 27 85.2 %
Date: 2026-03-06 18:57:10 Branches: 8 12 66.7 %

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
/**   Device Stack                                                        */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
#define UX_SOURCE_CODE
24
25
26
/* Include necessary system files.  */
27
28
#include "ux_api.h"
29
#include "ux_device_stack.h"
30
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _ux_device_stack_class_register                     PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Chaoqiong Xiao, Microsoft Corporation                               */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function registers a slave class to the slave stack.           */
45
/*                                                                        */
46
/*    Note: The C string of class_name must be NULL-terminated and the    */
47
/*    length of it (without the NULL-terminator itself) must be no larger */
48
/*    than UX_MAX_CLASS_NAME_LENGTH.                                      */
49
/*                                                                        */
50
/*  INPUT                                                                 */
51
/*                                                                        */
52
/*    class_name                            Name of class                 */
53
/*    class_function_entry                  Class entry function          */
54
/*    configuration_number                  Configuration # for this class*/
55
/*    interface_number                      Interface # for this class    */
56
/*    parameter                             Parameter specific for class  */
57
/*                                                                        */
58
/*  OUTPUT                                                                */
59
/*                                                                        */
60
/*    Completion Status                                                   */
61
/*                                                                        */
62
/*  CALLS                                                                 */
63
/*                                                                        */
64
/*    _ux_utility_string_length_check       Check C string and return     */
65
/*                                          its length if null-terminated */
66
/*    _ux_utility_memory_copy               Memory copy                   */
67
/*                                                                        */
68
/*  CALLED BY                                                             */
69
/*                                                                        */
70
/*    Application                                                         */
71
/*                                                                        */
72
/**************************************************************************/
73
518
UINT  _ux_device_stack_class_register(UCHAR *class_name,
74
                        UINT (*class_entry_function)(struct UX_SLAVE_CLASS_COMMAND_STRUCT *),
75
                        ULONG configuration_number,
76
                        ULONG interface_number,
77
                        VOID *parameter)
78
{
79
80
UX_SLAVE_CLASS              *class_inst;
81
UINT                        status;
82
UX_SLAVE_CLASS_COMMAND      command;
83
518
UINT                        class_name_length =  0;
84
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
85
ULONG                       class_index;
86
#endif
87
88
89
    /* Get the length of the class name (exclude null-terminator).  */
90
518
    status =  _ux_utility_string_length_check(class_name, &class_name_length, UX_MAX_CLASS_NAME_LENGTH);
91
518
    if (status)
92
1
        return(status);
93
94
    /* If trace is enabled, insert this event into the trace buffer.  */
95
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_CLASS_REGISTER, class_name, interface_number, parameter, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
96
97
    /* Get first class.  */
98
517
    class_inst =  _ux_system_slave -> ux_system_slave_class_array;
99
100
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
101
    /* We need to parse the class table to find an empty spot.  */
102
647
    for (class_index = 0; class_index < _ux_system_slave -> ux_system_slave_max_class; class_index++)
103
    {
104
#endif
105
106
        /* Check if this class is already used.  */
107
646
        if (class_inst -> ux_slave_class_status == UX_UNUSED)
108
        {
109
110
#if defined(UX_NAME_REFERENCED_BY_POINTER)
111
            class_inst -> ux_slave_class_name = (const UCHAR *)class_name;
112
#else
113
            /* We have found a free container for the class. Copy the name (with null-terminator).  */
114
516
            _ux_utility_memory_copy(class_inst -> ux_slave_class_name, class_name, class_name_length + 1); /* Use case of memcpy is verified. */
115
#endif
116
117
            /* Memorize the entry function of this class.  */
118
516
            class_inst -> ux_slave_class_entry_function =  class_entry_function;
119
120
            /* Memorize the pointer to the application parameter.  */
121
516
            class_inst -> ux_slave_class_interface_parameter =  parameter;
122
123
            /* Memorize the configuration number on which this instance will be called.  */
124
516
            class_inst -> ux_slave_class_configuration_number =  configuration_number;
125
126
            /* Memorize the interface number on which this instance will be called.  */
127
516
            class_inst -> ux_slave_class_interface_number =  interface_number;
128
129
            /* Build all the fields of the Class Command to initialize the class.  */
130
516
            command.ux_slave_class_command_request    =  UX_SLAVE_CLASS_COMMAND_INITIALIZE;
131
516
            command.ux_slave_class_command_parameter  =  parameter;
132
516
            command.ux_slave_class_command_class_ptr  =  class_inst;
133
134
            /* Call the class initialization routine.  */
135
516
            status = class_entry_function(&command);
136
137
            /* Check the status.  */
138
516
            if (status != UX_SUCCESS)
139
58
                return(status);
140
141
            /* Make this class used now.  */
142
458
            class_inst -> ux_slave_class_status = UX_USED;
143
144
            /* Return successful completion.  */
145
458
            return(UX_SUCCESS);
146
        }
147
148
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
149
        /* Move to the next class.  */
150
130
        class_inst ++;
151
    }
152
#endif
153
154
    /* No more entries in the class table.  */
155
1
    return(UX_MEMORY_INSUFFICIENT);
156
}
157
158
159
/**************************************************************************/
160
/*                                                                        */
161
/*  FUNCTION                                               RELEASE        */
162
/*                                                                        */
163
/*    _uxe_device_stack_class_register                    PORTABLE C      */
164
/*                                                           6.3.0        */
165
/*  AUTHOR                                                                */
166
/*                                                                        */
167
/*    Chaoqiong Xiao, Microsoft Corporation                               */
168
/*                                                                        */
169
/*  DESCRIPTION                                                           */
170
/*                                                                        */
171
/*    This function checks errors in device stack class register function */
172
/*    call.                                                               */
173
/*                                                                        */
174
/*  INPUT                                                                 */
175
/*                                                                        */
176
/*    class_name                            Name of class                 */
177
/*    class_function_entry                  Class entry function          */
178
/*    configuration_number                  Configuration # for this class*/
179
/*    interface_number                      Interface # for this class    */
180
/*    parameter                             Parameter specific for class  */
181
/*                                                                        */
182
/*  OUTPUT                                                                */
183
/*                                                                        */
184
/*    None                                                                */
185
/*                                                                        */
186
/*  CALLS                                                                 */
187
/*                                                                        */
188
/*    _ux_device_stack_class_register       Class register                */
189
/*                                                                        */
190
/*  CALLED BY                                                             */
191
/*                                                                        */
192
/*    Application                                                         */
193
/*                                                                        */
194
/**************************************************************************/
195
UINT  _uxe_device_stack_class_register(UCHAR *class_name,
196
                        UINT (*class_entry_function)(struct UX_SLAVE_CLASS_COMMAND_STRUCT *),
197
                        ULONG configuration_number,
198
                        ULONG interface_number,
199
                        VOID *parameter)
200
{
201
202
    /* Sanity checks.  */
203
    if ((class_name == UX_NULL) || (class_entry_function == UX_NULL))
204
        return(UX_INVALID_PARAMETER);
205
206
    /* Invoke class register function.  */
207
    return(_ux_device_stack_class_register(class_name, class_entry_function,
208
                            configuration_number, interface_number, parameter));
209
}