GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_storage_activate.c Lines: 32 34 94.1 %
Date: 2024-12-12 17:16:36 Branches: 13 14 92.9 %

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_activate                     PORTABLE C      */
37
/*                                                           6.3.0        */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Chaoqiong Xiao, Microsoft Corporation                               */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function activates an instance of the storage class.           */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    command                               Pointer to class command      */
49
/*                                                                        */
50
/*  OUTPUT                                                                */
51
/*                                                                        */
52
/*    Completion Status                                                   */
53
/*                                                                        */
54
/*  CALLS                                                                 */
55
/*                                                                        */
56
/*    _ux_host_class_storage_configure      Configure storage device      */
57
/*    _ux_host_class_storage_device_support_check                         */
58
/*                                          Check protocol support        */
59
/*    _ux_host_class_storage_endpoints_get  Get all endpoints             */
60
/*    _ux_host_class_storage_device_initialize                            */
61
/*                                          Initialize storage device     */
62
/*    _ux_host_stack_class_instance_create  Create class instance         */
63
/*    _ux_host_stack_class_instance_destroy Destroy class instance        */
64
/*    _ux_utility_memory_allocate           Allocate memory block         */
65
/*    _ux_utility_memory_free               Free memory block             */
66
/*    _ux_host_semaphore_create             Create semaphore              */
67
/*                                                                        */
68
/*  CALLED BY                                                             */
69
/*                                                                        */
70
/*    Storage Class                                                       */
71
/*                                                                        */
72
/*  RELEASE HISTORY                                                       */
73
/*                                                                        */
74
/*    DATE              NAME                      DESCRIPTION             */
75
/*                                                                        */
76
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
77
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
78
/*                                            resulting in version 6.1    */
79
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
80
/*                                            added standalone support.   */
81
/*                                            resulting in version 6.1.10 */
82
/*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
83
/*                                            fixed parameter/variable    */
84
/*                                            names conflict C++ keyword, */
85
/*                                            resulting in version 6.1.12 */
86
/*  10-31-2023     Chaoqiong Xiao           Modified comment(s),          */
87
/*                                            moved class/sub/protocol    */
88
/*                                            check and endpoints get     */
89
/*                                            into _activate function,    */
90
/*                                            resulting in version 6.3.0  */
91
/*                                                                        */
92
/**************************************************************************/
93
139
UINT  _ux_host_class_storage_activate(UX_HOST_CLASS_COMMAND *command)
94
{
95
96
UX_INTERFACE            *interface_ptr;
97
UX_HOST_CLASS_STORAGE   *storage;
98
UINT                    status;
99
100
101
    /* The storage is always activated by the interface descriptor and not the
102
       device descriptor.  */
103
139
    interface_ptr =  (UX_INTERFACE *) command -> ux_host_class_command_container;
104
105
    /* Obtain memory for this class instance.  The memory used MUST BE allocated from a CACHE SAFE memory
106
       since the buffer for the CSW is an array contained within each storage instance. */
107
139
    storage =  _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, sizeof(UX_HOST_CLASS_STORAGE));
108
139
    if (storage == UX_NULL)
109
1
        return(UX_MEMORY_INSUFFICIENT);
110
111
    /* Store the class container into this instance */
112
138
    storage -> ux_host_class_storage_class =  command -> ux_host_class_command_class_ptr;
113
114
    /* Store the interface container into the storage class instance.  */
115
138
    storage -> ux_host_class_storage_interface =  interface_ptr;
116
117
    /* Store the device container into the storage class instance.  */
118
138
    storage -> ux_host_class_storage_device =  interface_ptr -> ux_interface_configuration -> ux_configuration_device;
119
120
    /* Check class,sub class, protocol.  */
121
138
    status =  _ux_host_class_storage_device_support_check(storage);
122
138
    if (status != UX_SUCCESS)
123
    {
124
        _ux_utility_memory_free(storage);
125
        return(status);
126
    }
127
128
    /* Search all the endpoints for the storage interface (Bulk Out, Bulk in,
129
       and optional Interrupt endpoint).  */
130
138
    status =  _ux_host_class_storage_endpoints_get(storage);
131
138
    if (status != UX_SUCCESS)
132
    {
133
12
        _ux_utility_memory_free(storage);
134
12
        return(status);
135
    }
136
137
    /* Create this class instance.  */
138
126
    _ux_host_stack_class_instance_create(command -> ux_host_class_command_class_ptr, (VOID *) storage);
139
140
    /* This instance of the device must also be stored in the interface container.  */
141
126
    interface_ptr -> ux_interface_class_instance =  (VOID *) storage;
142
143
#if defined(UX_HOST_STANDALONE)
144
145
    /* Activate storage class task function.  */
146
    storage -> ux_host_class_storage_class -> ux_host_class_task_function = _ux_host_class_storage_tasks_run;
147
148
    /* Mark the storage as live now (media mounts in task).  */
149
    storage -> ux_host_class_storage_state = UX_HOST_CLASS_INSTANCE_MOUNTING;
150
151
    /* Keep storage locked before it's initialized.  */
152
    storage -> ux_host_class_storage_flags |= UX_HOST_CLASS_STORAGE_FLAG_LOCK;
153
#else
154
155
    /* Configure the USB storage device.  */
156
126
    status =  _ux_host_class_storage_configure(storage);
157
158
    /* Create the semaphore to protect multiple threads from accessing the same storage instance.  */
159
126
    if (status == UX_SUCCESS)
160
    {
161
125
        status = _ux_host_semaphore_create(&storage -> ux_host_class_storage_semaphore, "ux_host_class_storage_semaphore", 1);
162
125
        if (status != UX_SUCCESS)
163
1
            status = UX_SEMAPHORE_ERROR;
164
    }
165
166
    /* Error case, free resources.  */
167
126
    if (status != UX_SUCCESS)
168
    {
169
170
        /* Last one, semaphore not created or created error, no need to free.  */
171
172
        /* Error, destroy the class and return an error.  */
173
2
        _ux_host_stack_class_instance_destroy(storage -> ux_host_class_storage_class, (VOID *) storage);
174
175
        /* This instance of the device must also be removed in the interface container.  */
176
2
        interface_ptr -> ux_interface_class_instance =  (VOID *) UX_NULL;
177
178
        /* Free memory for class instance.  */
179
2
        _ux_utility_memory_free(storage);
180
181
2
        return(status);
182
    }
183
184
    /* Mark the storage as mounting now.  */
185
124
    storage -> ux_host_class_storage_state =  UX_HOST_CLASS_INSTANCE_MOUNTING;
186
187
    /* Initialize the USB storage device.  We do not check the status at this stage. We let the instance of this
188
       class live even if there was a failure. Because the storage class has many media instance, we will let the
189
       disconnection signal clean the instance at a later stage.  */
190
124
    _ux_host_class_storage_device_initialize(storage);
191
192
    /* Mark the storage as live now.  */
193
124
    storage -> ux_host_class_storage_state =  UX_HOST_CLASS_INSTANCE_LIVE;
194
195
#endif
196
197
    /* If all is fine and the device is mounted, we may need to inform the application
198
       if a function has been programmed in the system structure.  */
199
124
    if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
200
    {
201
202
        /* Call system change function.  */
203
62
        _ux_system_host ->  ux_system_host_change_function(UX_DEVICE_INSERTION, storage -> ux_host_class_storage_class, (VOID *) storage);
204
    }
205
206
    /* If trace is enabled, insert this event into the trace buffer.  */
207
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_STORAGE_ACTIVATE, storage, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
208
209
    /* If trace is enabled, register this object.  */
210
    UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, storage, 0, 0, 0)
211
212
    /* Return completion status. Force it to success. */
213
124
    return(UX_SUCCESS);
214
}
215