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: 2024-12-12 17:16:36 Branches: 21 22 95.5 %

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

164
        if ((*sector_memory == 0xe9) || ((*sector_memory == 0xeb) && *(sector_memory + 2) == 0x90))
172
        {
173
174
            /* Check for fake boot sector.  */
175

154
            if (_ux_utility_short_get(sector_memory + 0x16) != 0x0 ||
176
2
                _ux_utility_long_get(sector_memory + 0x24) != 0x0 ||
177
1
                (*(sector_memory + 1) == 0x76) /* exFAT volume  */)
178
            {
179
180
                /* This is a boot sector signature.  */
181
151
                _ux_host_class_storage_media_open(storage, sector);
182
151
                _ux_utility_memory_free(sector_memory);
183
151
                return(UX_SUCCESS);
184
            }
185
        }
186
187
13
        _ux_host_class_storage_partition_read(storage, sector_memory, sector);
188
13
        _ux_utility_memory_free(sector_memory);
189
13
        return(UX_SUCCESS);
190
    }
191
    else
192
    {
193
194
        /* The drive does not contain a partition table or FAT MBR at LBA 0*/
195
1
        status =  UX_ERROR;
196
    }
197
198
    /* Free all resources used.  */
199
1
    _ux_utility_memory_free(sector_memory);
200
201
    /* Return completion status.  */
202
1
    return(status);
203
#endif /* !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) */
204
}