GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_storage_endpoints_get.c Lines: 30 32 93.8 %
Date: 2024-12-12 17:16:36 Branches: 18 20 90.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
/**   Storage 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_storage.h"
29
#include "ux_host_stack.h"
30
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _ux_host_class_storage_endpoints_get                PORTABLE C      */
37
/*                                                           6.3.0        */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Chaoqiong Xiao, Microsoft Corporation                               */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function searches for the handle of the bulk out endpoint and  */
45
/*    optionally the bulk in endpoint.                                    */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    storage                               Pointer to storage class      */
50
/*                                                                        */
51
/*  OUTPUT                                                                */
52
/*                                                                        */
53
/*    Completion Status                                                   */
54
/*                                                                        */
55
/*  CALLS                                                                 */
56
/*                                                                        */
57
/*    _ux_host_stack_interface_endpoint_get Get an endpoint pointer       */
58
/*    _ux_utility_memory_allocate           Allocate memory               */
59
/*                                                                        */
60
/*  CALLED BY                                                             */
61
/*                                                                        */
62
/*    Storage Class                                                       */
63
/*                                                                        */
64
/*  RELEASE HISTORY                                                       */
65
/*                                                                        */
66
/*    DATE              NAME                      DESCRIPTION             */
67
/*                                                                        */
68
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
69
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
70
/*                                            resulting in version 6.1    */
71
/*  10-15-2021     Chaoqiong Xiao           Modified comment(s),          */
72
/*                                            use pre-calculated value    */
73
/*                                            instead of wMaxPacketSize,  */
74
/*                                            resulting in version 6.1.9  */
75
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
76
/*                                            initial the timeout value,  */
77
/*                                            resulting in version 6.1.10 */
78
/*  10-31-2023     Chaoqiong Xiao           Modified comment(s),          */
79
/*                                            checked endpoint get status,*/
80
/*                                            resulting in version 6.3.0  */
81
/*                                                                        */
82
/**************************************************************************/
83
138
UINT  _ux_host_class_storage_endpoints_get(UX_HOST_CLASS_STORAGE *storage)
84
{
85
86
UINT            endpoint_index;
87
UX_ENDPOINT     *endpoint;
88
UINT            status;
89
90
91
    /* Search for the bulk OUT endpoint. It is attached to the interface container.  */
92
257
    for (endpoint_index = 0; endpoint_index < storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bNumEndpoints;
93
119
                        endpoint_index++)
94
    {
95
96
        /* Get an endpoint.  */
97
251
        status = _ux_host_stack_interface_endpoint_get(storage -> ux_host_class_storage_interface, endpoint_index, &endpoint);
98
99
        /* Check status.  */
100
251
        if (status != UX_SUCCESS)
101
            continue;
102
103
        /* We have an endpoint. Check if endpoint is bulk and OUT.  */
104
251
        if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT) &&
105
135
            ((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT))
106
        {
107
108
            /* We have found the bulk OUT endpoint, save it!  */
109
132
            storage -> ux_host_class_storage_bulk_out_endpoint =  endpoint;
110
111
            /* This transfer request always has the OUT direction.  */
112
132
            endpoint -> ux_endpoint_transfer_request.ux_transfer_request_type =  UX_REQUEST_OUT;
113
114
132
            break;
115
        }
116
    }
117
118
    /* The bulk OUT endpoint is mandatory.  */
119
138
    if (storage -> ux_host_class_storage_bulk_out_endpoint == UX_NULL)
120
    {
121
122
        /* Error trap. */
123
6
        _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
124
125
        /* If trace is enabled, insert this event into the trace buffer.  */
126
        UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_ENDPOINT_HANDLE_UNKNOWN, storage, 0, 0, UX_TRACE_ERRORS, 0, 0)
127
128
6
        return(UX_ENDPOINT_HANDLE_UNKNOWN);
129
    }
130
131
    /* Search for the bulk IN endpoint. It is attached to the interface container.  */
132
175
    for (endpoint_index = 0; endpoint_index < storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bNumEndpoints;
133
43
                        endpoint_index++)
134
    {
135
136
        /* Get an endpoint.  */
137
169
        status = _ux_host_stack_interface_endpoint_get(storage -> ux_host_class_storage_interface, endpoint_index, &endpoint);
138
139
        /* Check status.  */
140
169
        if (status != UX_SUCCESS)
141
            continue;
142
143
        /* We have an endpoint. Check if endpoint is bulk and IN.  */
144
169
        if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN) &&
145
129
            ((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT))
146
        {
147
148
            /* We have found the bulk IN endpoint, save it!  */
149
126
            storage -> ux_host_class_storage_bulk_in_endpoint =  endpoint;
150
151
            /* This transfer request always has the IN direction.  */
152
126
            endpoint -> ux_endpoint_transfer_request.ux_transfer_request_type =  UX_REQUEST_IN;
153
154
126
            break;
155
        }
156
    }
157
158
    /* The bulk IN endpoint is mandatory */
159
132
    if (storage -> ux_host_class_storage_bulk_in_endpoint == UX_NULL)
160
    {
161
162
        /* Error trap. */
163
6
        _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
164
165
        /* If trace is enabled, insert this event into the trace buffer.  */
166
        UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_ENDPOINT_HANDLE_UNKNOWN, storage, 0, 0, UX_TRACE_ERRORS, 0, 0)
167
168
6
        return(UX_ENDPOINT_HANDLE_UNKNOWN);
169
    }
170
171
    /* Set default transfer timeout value.  */
172
126
    endpoint = storage -> ux_host_class_storage_bulk_in_endpoint;
173
126
    endpoint -> ux_endpoint_transfer_request.ux_transfer_request_timeout_value =
174
                UX_MS_TO_TICK_NON_ZERO(UX_HOST_CLASS_STORAGE_TRANSFER_TIMEOUT);
175
126
    endpoint = storage -> ux_host_class_storage_bulk_out_endpoint;
176
126
    endpoint -> ux_endpoint_transfer_request.ux_transfer_request_timeout_value =
177
                UX_MS_TO_TICK_NON_ZERO(UX_HOST_CLASS_STORAGE_TRANSFER_TIMEOUT);
178
179
#ifdef UX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT
180
    /* Search the Interrupt IN endpoint. This endpoint is optional and only valid for
181
       storage devices that use the CBI protocol.  */
182
    if (storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceProtocol == UX_HOST_CLASS_STORAGE_PROTOCOL_CBI)
183
    {
184
185
        /* Yes, CBI protocol is present.  Search for Interrupt IN endpoint.  */
186
        for (endpoint_index = 0; endpoint_index < storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bNumEndpoints;
187
                            endpoint_index++)
188
        {
189
190
            /* Get an endpoint.  */
191
            status = _ux_host_stack_interface_endpoint_get(storage -> ux_host_class_storage_interface, endpoint_index, &endpoint);
192
193
            /* Check status.  */
194
            if (status != UX_SUCCESS)
195
                continue;
196
197
            /* Check if endpoint is Interrupt and IN.  */
198
            if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN) &&
199
                ((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_INTERRUPT_ENDPOINT))
200
            {
201
202
                /* We have found the Interrupt IN endpoint, save it!  */
203
                storage -> ux_host_class_storage_interrupt_endpoint =  endpoint;
204
205
                /* This transfer request always has the IN direction.  */
206
                endpoint -> ux_endpoint_transfer_request.ux_transfer_request_type =  UX_REQUEST_IN;
207
208
                /* The size of the transfer is fixed to the endpoint size.  */
209
                endpoint -> ux_endpoint_transfer_request.ux_transfer_request_requested_length =
210
                                            endpoint -> ux_endpoint_transfer_request.ux_transfer_request_packet_length;
211
212
                /* Get some memory for this data transfer.  */
213
                endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer =
214
                                                        _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY,
215
                                                                                endpoint -> ux_endpoint_descriptor.wMaxPacketSize);
216
217
                /* Check the memory pointer.  */
218
                if (endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer == UX_NULL)
219
                    return(UX_MEMORY_INSUFFICIENT);
220
221
                break;
222
            }
223
        }
224
225
        if (storage -> ux_host_class_storage_interrupt_endpoint == UX_NULL)
226
        {
227
228
            /* Error trap. */
229
            _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
230
231
            /* If trace is enabled, insert this event into the trace buffer.  */
232
            UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_ENDPOINT_HANDLE_UNKNOWN, endpoint, 0, 0, UX_TRACE_ERRORS, 0, 0)
233
234
            return(UX_ENDPOINT_HANDLE_UNKNOWN);
235
        }
236
    }
237
#endif
238
239
    /* Return successful completion.  */
240
126
    return(UX_SUCCESS);
241
}
242