GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_storage_media_read.c Lines: 23 27 85.2 %
Date: 2024-12-12 17:16:36 Branches: 8 12 66.7 %

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
#if defined(UX_HOST_STANDALONE)
33
VOID _ux_host_class_storage_read_initialize(UX_HOST_CLASS_STORAGE *storage,
34
                ULONG sector_start, ULONG sector_count);
35
36
VOID
37
#else
38
static inline VOID
39
#endif
40
610
_ux_host_class_storage_read_initialize(UX_HOST_CLASS_STORAGE *storage,
41
                ULONG sector_start, ULONG sector_count)
42
{
43
UCHAR       *cbw;
44
UCHAR       *cbw_cb;
45
ULONG       command_length;
46
47
    /* Use a pointer for the cbw, easier to manipulate.  */
48
610
    cbw = (UCHAR *)storage -> ux_host_class_storage_cbw;
49
610
    cbw_cb = cbw + UX_HOST_CLASS_STORAGE_CBW_CB;
50
51
    /* Get the Read Command Length.  */
52
#ifdef UX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT
53
    if (storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceSubClass ==
54
        UX_HOST_CLASS_STORAGE_SUBCLASS_UFI)
55
        command_length =  UX_HOST_CLASS_STORAGE_READ_COMMAND_LENGTH_UFI;
56
    else
57
        command_length =  UX_HOST_CLASS_STORAGE_READ_COMMAND_LENGTH_SBC;
58
#else
59
610
    command_length =  UX_HOST_CLASS_STORAGE_READ_COMMAND_LENGTH_SBC;
60
#endif
61
62
    /* Initialize the CBW for this command.  */
63
610
    _ux_host_class_storage_cbw_initialize(storage,
64
                    UX_HOST_CLASS_STORAGE_DATA_IN,
65
610
                    sector_count * storage -> ux_host_class_storage_sector_size,
66
                    command_length);
67
68
    /* Prepare the MEDIA READ command block.  */
69
610
    *(cbw_cb + UX_HOST_CLASS_STORAGE_READ_OPERATION) =  UX_HOST_CLASS_STORAGE_SCSI_READ16;
70
71
    /* Store the sector start (LBA field).  */
72
610
    _ux_utility_long_put_big_endian(cbw_cb + UX_HOST_CLASS_STORAGE_READ_LBA, sector_start);
73
74
    /* Store the number of sectors to read.  */
75
610
    _ux_utility_short_put_big_endian(cbw_cb + UX_HOST_CLASS_STORAGE_READ_TRANSFER_LENGTH, (USHORT) sector_count);
76
610
}
77
78
79
/**************************************************************************/
80
/*                                                                        */
81
/*  FUNCTION                                               RELEASE        */
82
/*                                                                        */
83
/*    _ux_host_class_storage_media_read                   PORTABLE C      */
84
/*                                                           6.2.1        */
85
/*  AUTHOR                                                                */
86
/*                                                                        */
87
/*    Chaoqiong Xiao, Microsoft Corporation                               */
88
/*                                                                        */
89
/*  DESCRIPTION                                                           */
90
/*                                                                        */
91
/*    This function will read one or more logical sector from the media.  */
92
/*                                                                        */
93
/*  INPUT                                                                 */
94
/*                                                                        */
95
/*    storage                               Pointer to storage class      */
96
/*    sector_start                          Starting sector               */
97
/*    sector_count                          Number of sectors to read     */
98
/*    data_pointer                          Pointer to data to read       */
99
/*                                                                        */
100
/*  OUTPUT                                                                */
101
/*                                                                        */
102
/*    Completion Status                                                   */
103
/*                                                                        */
104
/*  CALLS                                                                 */
105
/*                                                                        */
106
/*    _ux_host_class_storage_cbw_initialize Initialize the CBW            */
107
/*    _ux_host_class_storage_transport      Send command                  */
108
/*    _ux_utility_long_put_big_endian       Put 32-bit word               */
109
/*    _ux_utility_short_put_big_endian      Put 16-bit word               */
110
/*                                                                        */
111
/*  CALLED BY                                                             */
112
/*                                                                        */
113
/*    Storage Class                                                       */
114
/*                                                                        */
115
/*  RELEASE HISTORY                                                       */
116
/*                                                                        */
117
/*    DATE              NAME                      DESCRIPTION             */
118
/*                                                                        */
119
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
120
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
121
/*                                            resulting in version 6.1    */
122
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
123
/*                                            added standalone support,   */
124
/*                                            resulting in version 6.1.10 */
125
/*  03-08-2023     Chaoqiong Xiao           Modified comment(s),          */
126
/*                                            checked device removal,     */
127
/*                                            resulting in version 6.2.1  */
128
/*                                                                        */
129
/**************************************************************************/
130
581
UINT  _ux_host_class_storage_media_read(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start,
131
                                    ULONG sector_count, UCHAR *data_pointer)
132
{
133
#if defined(UX_HOST_STANDALONE)
134
UINT            status;
135
    do {
136
        status = _ux_host_class_storage_read_write_run(storage, UX_TRUE,
137
                                    sector_start, sector_count, data_pointer);
138
    } while(status == UX_STATE_WAIT);
139
    if (status < UX_STATE_IDLE)
140
        return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
141
    return(storage -> ux_host_class_storage_status);
142
#else
143
UINT            status;
144
UINT            media_retry;
145
146
    /* If trace is enabled, insert this event into the trace buffer.  */
147
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_STORAGE_MEDIA_READ, storage, sector_start, sector_count, data_pointer, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
148
149
    /* Reset the retry count.  */
150
581
    media_retry =  UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RETRY;
151
152
    /* We may need several attempts.  */
153
613
    while (media_retry-- != 0)
154
    {
155
156
        /* Initialize CBW.  */
157
610
        _ux_host_class_storage_read_initialize(storage, sector_start, sector_count);
158
159
        /* Send the command to transport layer.  */
160
610
        status =  _ux_host_class_storage_transport(storage, data_pointer);
161
610
        if (status != UX_SUCCESS)
162
3
            return(status);
163
164
        /* Did the command succeed?  */
165
607
        if (storage -> ux_host_class_storage_sense_code == UX_SUCCESS)
166
        {
167
168
            /* Check for completeness of sector read.  */
169
575
            if (storage -> ux_host_class_storage_data_phase_length != sector_count * storage -> ux_host_class_storage_sector_size)
170
            {
171
172
                /* This can happen if the device sent less data than the host
173
                   requested. This does not fit our definition of success and
174
                   retrying shouldn't change the outcome, so we return an error.  */
175
176
                /* We got an error during read. Packet not complete.  */
177
1
                _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_DATA_LESS_THAN_EXPECTED);
178
179
                /* Return to UX_MEDIA (default FileX).  */
180
1
                return(UX_ERROR);
181
            }
182
183
            /* The read succeeded.  */
184
574
            return(UX_SUCCESS);
185
        }
186
187
        /* The command did not succeed. Retry.  */
188
    }
189
190
    /* Check if the media in the device has been removed. If so
191
       we have to tell UX_MEDIA (default FileX) that the media is closed.  */
192
3
    return(UX_HOST_CLASS_STORAGE_SENSE_ERROR);
193
#endif
194
}
195
196
197
/**************************************************************************/
198
/*                                                                        */
199
/*  FUNCTION                                               RELEASE        */
200
/*                                                                        */
201
/*    _ux_host_class_storage_media_read                   PORTABLE C      */
202
/*                                                           6.3.0        */
203
/*  AUTHOR                                                                */
204
/*                                                                        */
205
/*    Chaoqiong Xiao, Microsoft Corporation                               */
206
/*                                                                        */
207
/*  DESCRIPTION                                                           */
208
/*                                                                        */
209
/*    This function checks errors in storage media read function call.    */
210
/*                                                                        */
211
/*  INPUT                                                                 */
212
/*                                                                        */
213
/*    storage                               Pointer to storage class      */
214
/*    sector_start                          Starting sector               */
215
/*    sector_count                          Number of sectors to read     */
216
/*    data_pointer                          Pointer to data to read       */
217
/*                                                                        */
218
/*  OUTPUT                                                                */
219
/*                                                                        */
220
/*    Status                                                              */
221
/*                                                                        */
222
/*  CALLS                                                                 */
223
/*                                                                        */
224
/*    _ux_host_class_storage_media_read     Read storage media            */
225
/*                                                                        */
226
/*  CALLED BY                                                             */
227
/*                                                                        */
228
/*    Application                                                         */
229
/*                                                                        */
230
/*  RELEASE HISTORY                                                       */
231
/*                                                                        */
232
/*    DATE              NAME                      DESCRIPTION             */
233
/*                                                                        */
234
/*  10-31-2023     Chaoqiong Xiao           Initial Version 6.3.0         */
235
/*                                                                        */
236
/**************************************************************************/
237
UINT  _uxe_host_class_storage_media_read(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start,
238
                                    ULONG sector_count, UCHAR *data_pointer)
239
{
240
241
    /* Sanity checks.  */
242
    if ((storage == UX_NULL) || (data_pointer == UX_NULL))
243
        return(UX_INVALID_PARAMETER);
244
245
    /* Invoke storage media read function.  */
246
    return(_ux_host_class_storage_media_read(storage, sector_start, sector_count, data_pointer));
247
}