GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_storage_media_mount.c Lines: 26 26 100.0 %
Date: 2026-03-06 18:57:10 Branches: 21 22 95.5 %

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
/**   Storage Class                                                       */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
24
/* Include necessary system files.  */
25
26
#define UX_SOURCE_CODE
27
28
#include "ux_api.h"
29
#include "ux_host_class_storage.h"
30
#include "ux_host_stack.h"
31
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _ux_host_class_storage_media_mount                  PORTABLE C      */
38
/*                                                           6.1.9        */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Chaoqiong Xiao, Microsoft Corporation                               */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function tries to read the first sector on the media. It then  */
46
/*    determines if this is a partition sector or a boot sector. If the   */
47
/*    sector contains partition information, each partition is checked    */
48
/*    for a DOS aware partition and mounted by UX_MEDIA (default FileX).  */
49
/*                                                                        */
50
/*    If there is no partition sector or boot sector, we simply inform    */
51
/*    UX_MEDIA (default FileX) that a device is present and that its boot */
52
/*    sector  should be periodically read to see if the device is mounted.*/
53
/*    This mechanism applies to storage where the media can be removed    */
54
/*    (floppy, ZIP, flash/smart media readers).                           */
55
/*                                                                        */
56
/*  INPUT                                                                 */
57
/*                                                                        */
58
/*    storage                               Pointer to storage class      */
59
/*    sector                                Boot sector start             */
60
/*                                                                        */
61
/*  OUTPUT                                                                */
62
/*                                                                        */
63
/*    Completion Status                                                   */
64
/*                                                                        */
65
/*  CALLS                                                                 */
66
/*                                                                        */
67
/*    _ux_host_class_storage_media_mount    Mount media                   */
68
/*    _ux_host_class_storage_media_open     Open media                    */
69
/*    _ux_host_class_storage_partition_read Read partition                */
70
/*    _ux_host_class_storage_media_read     Read sectors of media         */
71
/*    _ux_host_class_storage_start_stop     Start the media               */
72
/*    _ux_host_class_storage_unit_ready_test                              */
73
/*                                          Test unit ready               */
74
/*    _ux_utility_memory_allocate           Allocate memory block         */
75
/*    _ux_utility_memory_free               Release memory block          */
76
/*    _ux_utility_short_get                 Get 16-bit value              */
77
/*                                                                        */
78
/*  CALLED BY                                                             */
79
/*                                                                        */
80
/*    Storage Class                                                       */
81
/*                                                                        */
82
/**************************************************************************/
83
171
UINT  _ux_host_class_storage_media_mount(UX_HOST_CLASS_STORAGE *storage, ULONG sector)
84
{
85
86
#if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
87
    UX_PARAMETER_NOT_USED(storage);
88
    UX_PARAMETER_NOT_USED(sector);
89
    return(UX_FUNCTION_NOT_SUPPORTED);
90
#else
91
UCHAR           *sector_memory;
92
UINT            status;
93
94
    /* If trace is enabled, insert this event into the trace buffer.  */
95
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_STORAGE_MEDIA_MOUNT, storage, sector, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
96
97
#ifdef UX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT
98
    /* If the device is UFI, we need to start it.  */
99
    if (storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceProtocol == UX_HOST_CLASS_STORAGE_PROTOCOL_CBI)
100
    {
101
102
        /* Start the media.  */
103
        status =  _ux_host_class_storage_start_stop(storage, UX_HOST_CLASS_STORAGE_START_MEDIA);
104
105
        /* Check the status. If the device does not start, fail the operation.
106
           But we still return SUCCESS otherwise the storage thread has no chance to inspect this instance.  */
107
        if (status != UX_SUCCESS)
108
            return(UX_SUCCESS);
109
    }
110
#endif
111
112
    /* Obtain memory for reading the partition sector, we do not use the storage instance
113
       memory because this function is reentrant.  */
114
171
    sector_memory =  _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, storage -> ux_host_class_storage_sector_size);
115
171
    if (sector_memory == UX_NULL)
116
2
        return(UX_MEMORY_INSUFFICIENT);
117
118
    /* Check if the device is now ready.  */
119
169
    status =  _ux_host_class_storage_unit_ready_test(storage);
120
121
    /* Check the status. There may be a transport error or the device is not ready.  */
122
169
    if (status == UX_SUCCESS)
123
124
        /* Read the very first sector from the media.  */
125
168
        status =  _ux_host_class_storage_media_read(storage, sector, 1, sector_memory);
126
127
    /* Check the status. There may be a transport error or the device is not ready.  */
128
169
    if (status != UX_SUCCESS)
129
    {
130
131
        /* In any case, we free the sector memory.  */
132
3
        _ux_utility_memory_free(sector_memory);
133
134
3
        if (status == UX_HOST_CLASS_STORAGE_SENSE_ERROR)
135
136
            /* The media is not there, so we will try to check for it at the storage
137
               thread level every x seconds.  */
138
1
            return(UX_SUCCESS);
139
140
        /* Since there was a transport error or command error, we do not try to mount
141
           a fake media.  */
142
2
        return(status);
143
    }
144
145
    /* We need to examine this sector and determine if this is a partition sector
146
       or a boot sector.  */
147
166
    if (_ux_utility_short_get(sector_memory + 510) == UX_HOST_CLASS_STORAGE_PARTITION_SIGNATURE)
148
    {
149
150
        /* If we have a signature, we know it is a valid media and it may be formatted.
151
           If there is no signature, the media exist but maybe not formatted. Now determine
152
           if this is a boot sector. The boot sector has a special signature in the first
153
           couple of bytes.
154
           BUT !!! The first boot sector of an iPod is actually a partition, so we need to
155
           look further and see if the number of sector per FAT and the first partition are
156
           set to 0. This will indicate a partition sector. Though exFAT has no BIOS parameters
157
           block and should be excluded in this case.
158
           */
159

165
        if ((*sector_memory == 0xe9) || ((*sector_memory == 0xeb) && *(sector_memory + 2) == 0x90))
160
        {
161
162
            /* Check for fake boot sector.  */
163

155
            if (_ux_utility_short_get(sector_memory + 0x16) != 0x0 ||
164
2
                _ux_utility_long_get(sector_memory + 0x24) != 0x0 ||
165
1
                (*(sector_memory + 1) == 0x76) /* exFAT volume  */)
166
            {
167
168
                /* This is a boot sector signature.  */
169
152
                _ux_host_class_storage_media_open(storage, sector);
170
152
                _ux_utility_memory_free(sector_memory);
171
152
                return(UX_SUCCESS);
172
            }
173
        }
174
175
13
        _ux_host_class_storage_partition_read(storage, sector_memory, sector);
176
13
        _ux_utility_memory_free(sector_memory);
177
13
        return(UX_SUCCESS);
178
    }
179
    else
180
    {
181
182
        /* The drive does not contain a partition table or FAT MBR at LBA 0*/
183
1
        status =  UX_ERROR;
184
    }
185
186
    /* Free all resources used.  */
187
1
    _ux_utility_memory_free(sector_memory);
188
189
    /* Return completion status.  */
190
1
    return(status);
191
#endif /* !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) */
192
}