GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_storage_driver_entry.c Lines: 64 64 100.0 %
Date: 2024-12-12 17:16:36 Branches: 25 25 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
/**   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
/* Defined if FileX is not integrated in USBX
33
   and it's used as external module for file system.  */
34
35
/* #define UX_HOST_CLASS_STORAGE_EXT_FILEX */
36
37
#if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
38
39
#ifdef FX_API_H /* For test, confirm FX is not included before.  */
40
#error fx_api.h should not be included in this mode
41
#endif
42
43
/* FX not integrated in UX, but used as external module.  */
44
#if defined(UX_HOST_CLASS_STORAGE_EXT_FILEX)
45
46
/* FX related things needs define here.  */
47
#include "fx_api.h"
48
#define UX_MEDIA                                    FX_MEDIA
49
VOID    _ux_host_class_storage_driver_entry(UX_MEDIA *media);
50
51
/* FX driver is available to support FX as external module.  */
52
#ifndef UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE
53
#define UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE
54
#endif
55
#endif
56
#else
57
58
/* FX driver is used for RTOS mode by default.  */
59
#ifndef UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE
60
#define UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE
61
#endif
62
#endif
63
64
65
#if defined(UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE)
66
/**************************************************************************/
67
/*                                                                        */
68
/*  FUNCTION                                               RELEASE        */
69
/*                                                                        */
70
/*    _ux_host_class_storage_driver_entry                 PORTABLE C      */
71
/*                                                           6.1.12       */
72
/*  AUTHOR                                                                */
73
/*                                                                        */
74
/*    Chaoqiong Xiao, Microsoft Corporation                               */
75
/*                                                                        */
76
/*  DESCRIPTION                                                           */
77
/*                                                                        */
78
/*    This function is the entry point for the FileX file system. All     */
79
/*    FileX driver I/O calls are are multiplexed here and rerouted to     */
80
/*    the proper USB storage class functions.                             */
81
/*                                                                        */
82
/*    When the entry is for storage with FX support (not in standalone    */
83
/*    mode, and with FileX), the FX media is openned in storage mount     */
84
/*    flow, and can be directly used in application after mounted.        */
85
/*                                                                        */
86
/*    When the entry is for no FX mode (FX in external module, and USBX   */
87
/*    is compiled without FileX integration), it is an example with       */
88
/*    disk partition support. In this case the FX media does not operate  */
89
/*    inside the storage flow. Actions are taken when application mounts  */
90
/*    media to FX_MEDIA and then have access to media APIs.               */
91
/*                                                                        */
92
/*    In no FX mode demo, it assumes media is managed with partition      */
93
/*    start from sector address of FX_MEDIA::fx_media_reserved_for_user.  */
94
/*                                                                        */
95
/*    The following links are not initialized in no FX mode, they must be */
96
/*    initialized before using the entry in no FX mode:                   */
97
/*    - FX_MEDIA::fx_media_reserved_for_user                              */
98
/*                                          Partition start sector inside */
99
/*                                          the whole storage media, must */
100
/*                                          set before media open         */
101
/*    - FX_MEDIA::fx_media_driver_info      Pointer to storage media,     */
102
/*                                          assigned while calling media  */
103
/*                                          open (fx_media_open)          */
104
/*                                                                        */
105
/*  INPUT                                                                 */
106
/*                                                                        */
107
/*    media                                 FileX media pointer           */
108
/*                                                                        */
109
/*  OUTPUT                                                                */
110
/*                                                                        */
111
/*    None                                                                */
112
/*                                                                        */
113
/*  CALLS                                                                 */
114
/*                                                                        */
115
/*    _ux_host_class_storage_sense_code_translate                         */
116
/*                                          Translate error status codes  */
117
/*    _ux_host_class_storage_media_read     Read sector(s)                */
118
/*    _ux_host_class_storage_media_write    Write sector(s)               */
119
/*    _ux_host_semaphore_get                Get protection semaphore      */
120
/*    _ux_host_semaphore_put                Release protection semaphore  */
121
/*                                                                        */
122
/*  CALLED BY                                                             */
123
/*                                                                        */
124
/*    FileX                                                               */
125
/*                                                                        */
126
/*  RELEASE HISTORY                                                       */
127
/*                                                                        */
128
/*    DATE              NAME                      DESCRIPTION             */
129
/*                                                                        */
130
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
131
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
132
/*                                            added option to disable FX  */
133
/*                                            media integration,          */
134
/*                                            resulting in version 6.1    */
135
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
136
/*                                            resulting in version 6.1.10 */
137
/*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
138
/*                                            added implement to support  */
139
/*                                            external FX mode,           */
140
/*                                            resulting in version 6.1.11 */
141
/*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
142
/*                                            improved external FX mode,  */
143
/*                                            resulting in version 6.1.12 */
144
/*                                                                        */
145
/**************************************************************************/
146
1152
VOID  _ux_host_class_storage_driver_entry(FX_MEDIA *media)
147
{
148
149
UINT                            status;
150
UX_HOST_CLASS_STORAGE           *storage;
151
UX_HOST_CLASS_STORAGE_MEDIA     *storage_media;
152
ULONG                           partition_start;
153
154
155
    /* Get the pointers to the instances and partition start.  */
156
#if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
157
1152
    storage =  (UX_HOST_CLASS_STORAGE *) media -> fx_media_driver_info;
158
1152
    storage_media =  (UX_HOST_CLASS_STORAGE_MEDIA *) media -> fx_media_reserved_for_user;
159
1152
    partition_start = storage_media -> ux_host_class_storage_media_partition_start;
160
#else
161
    storage_media = (UX_HOST_CLASS_STORAGE_MEDIA *) media -> fx_media_driver_info;
162
    storage = storage_media -> ux_host_class_storage_media_storage;
163
    partition_start = (ULONG) media -> fx_media_reserved_for_user;
164
#endif
165
166
    /* Ensure the instance is valid.  */
167
1152
    if ((storage -> ux_host_class_storage_state !=  UX_HOST_CLASS_INSTANCE_LIVE) &&
168
542
        (storage -> ux_host_class_storage_state !=  UX_HOST_CLASS_INSTANCE_MOUNTING))
169
    {
170
171
        /* Class instance is invalid. Return an error!  */
172
155
        media -> fx_media_driver_status =  FX_PTR_ERROR;
173
155
        return;
174
    }
175
176
#if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
177
178
    /* Ensure the media is valid.  */
179
    if ((storage_media -> ux_host_class_storage_media_storage != storage) ||
180
        (storage_media -> ux_host_class_storage_media_status != UX_USED))
181
    {
182
183
        /* Media instance is invalid.  */
184
        media -> fx_media_driver_status =  FX_PTR_ERROR;
185
        return;
186
    }
187
#endif
188
189
    /* Protect Thread reentry to this instance.  */
190
997
    status = _ux_host_class_storage_lock(storage, UX_WAIT_FOREVER);
191
997
    if (status != UX_SUCCESS)
192
    {
193
194
        /* Unable to lock, return an error.  */
195
14
        media -> fx_media_driver_status =  FX_INVALID_STATE;
196
14
        return;
197
    }
198
199
    /* Restore the LUN number from the media instance.  */
200
983
    storage -> ux_host_class_storage_lun =  storage_media -> ux_host_class_storage_media_lun;
201
202
    /* And the sector size.  */
203
983
    storage -> ux_host_class_storage_sector_size =
204
983
                storage_media -> ux_host_class_storage_media_sector_size;
205
206
#if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
207
208
    /* Restore current used last sector number.  */
209
    storage -> ux_host_class_storage_last_sector_number =
210
                storage_media -> ux_host_class_storage_media_number_sectors - 1;
211
#endif
212
213
    /* Look at the request specified by the FileX caller.  */
214


983
    switch (media -> fx_media_driver_request)
215
    {
216
217
256
    case FX_DRIVER_READ:
218
219
        /* Read one or more sectors.  */
220
256
        status =  _ux_host_class_storage_media_read(storage,
221
256
                                media -> fx_media_driver_logical_sector + partition_start,
222
                                media -> fx_media_driver_sectors,
223
                                media -> fx_media_driver_buffer);
224
225
        /* Check completion status.  */
226
256
        if (status == UX_SUCCESS)
227
254
            media -> fx_media_driver_status =  FX_SUCCESS;
228
        else
229
        {
230
231
#if defined(UX_HOST_STANDALONE)
232
233
            /* Poll status.  */
234
            _ux_host_class_storage_media_check(storage);
235
#endif
236
237
2
            media -> fx_media_driver_status =
238
2
                _ux_host_class_storage_sense_code_translate(storage, status);
239
        }
240
256
        break;
241
242
243
352
    case FX_DRIVER_WRITE:
244
245
        /* Write one or more sectors.  */
246
352
        status =  _ux_host_class_storage_media_write(storage,
247
352
                                media -> fx_media_driver_logical_sector + partition_start,
248
                                media -> fx_media_driver_sectors,
249
                                media -> fx_media_driver_buffer);
250
251
        /* Check completion status.  */
252
352
        if (status == UX_SUCCESS)
253
351
            media -> fx_media_driver_status =  FX_SUCCESS;
254
        else
255
        {
256
257
#if defined(UX_HOST_STANDALONE)
258
259
            /* Poll status.  */
260
            _ux_host_class_storage_media_check(storage);
261
#endif
262
263
1
            media -> fx_media_driver_status =
264
1
                _ux_host_class_storage_sense_code_translate(storage,status);
265
        }
266
352
        break;
267
268
269
35
    case FX_DRIVER_FLUSH:
270
271
        /* Nothing to do. Just return a good status!  */
272
35
        media -> fx_media_driver_status =  FX_SUCCESS;
273
35
        break;
274
275
276
1
    case FX_DRIVER_ABORT:
277
278
        /* Nothing to do. Just return a good status!  */
279
1
        media -> fx_media_driver_status =  FX_SUCCESS;
280
1
        break;
281
282
283
155
    case FX_DRIVER_INIT:
284
285
#if defined(UX_HOST_STANDALONE)
286
287
            /* Poll status.  */
288
            _ux_host_class_storage_media_check(storage);
289
#endif
290
291
        /* Check for media protection.  We must do this operation here because FileX clears all the
292
           media fields before init.  */
293
155
        if (storage -> ux_host_class_storage_write_protected_media ==  UX_TRUE)
294
295
            /* The media is Write Protected. We tell FileX.  */
296
1
            media -> fx_media_driver_write_protect = UX_TRUE;
297
298
        /* This function always succeeds.  */
299
155
        media -> fx_media_driver_status =  FX_SUCCESS;
300
155
        break;
301
302
303
28
    case FX_DRIVER_UNINIT:
304
305
        /* Nothing to do. Just return a good status!  */
306
28
        media -> fx_media_driver_status =  FX_SUCCESS;
307
28
        break;
308
309
310
153
    case FX_DRIVER_BOOT_READ:
311
312
        /* Read the media boot sector.  */
313
153
        status =  _ux_host_class_storage_media_read(storage,
314
                partition_start, 1, media -> fx_media_driver_buffer);
315
316
        /* Check completion status.  */
317
153
        if (status == UX_SUCCESS)
318
152
            media -> fx_media_driver_status =  FX_SUCCESS;
319
        else
320
        {
321
322
#if defined(UX_HOST_STANDALONE)
323
324
            /* Poll status.  */
325
            _ux_host_class_storage_media_check(storage);
326
#endif
327
328
1
            media -> fx_media_driver_status =
329
1
                _ux_host_class_storage_sense_code_translate(storage,status);
330
        }
331
153
        break;
332
333
334
2
    case FX_DRIVER_BOOT_WRITE:
335
336
        /* Write the boot sector.  */
337
2
        status =  _ux_host_class_storage_media_write(storage,
338
                partition_start, 1, media -> fx_media_driver_buffer);
339
340
        /* Check completion status.  */
341
2
        if (status == UX_SUCCESS)
342
1
            media -> fx_media_driver_status =  FX_SUCCESS;
343
        else
344
        {
345
346
#if defined(UX_HOST_STANDALONE)
347
348
            /* Poll status.  */
349
            _ux_host_class_storage_media_check(storage);
350
#endif
351
352
1
            media -> fx_media_driver_status =
353
1
                _ux_host_class_storage_sense_code_translate(storage,status);
354
        }
355
2
        break;
356
357
358
1
    default:
359
360
        /* Invalid request from FileX */
361
1
        media -> fx_media_driver_status =  FX_IO_ERROR;
362
1
        break;
363
    }
364
365
    /* Unprotect thread reentry to this instance.  */
366
983
    _ux_host_class_storage_unlock(storage);
367
}
368
#endif