GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_storage_media_write.c Lines: 20 24 83.3 %
Date: 2024-12-12 17:16:36 Branches: 6 8 75.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
#if defined(UX_HOST_STANDALONE)
33
VOID _ux_host_class_storage_write_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
359
_ux_host_class_storage_write_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
359
    cbw = (UCHAR *)storage -> ux_host_class_storage_cbw;
49
359
    cbw_cb = cbw + UX_HOST_CLASS_STORAGE_CBW_CB;
50
51
    /* Get the Write 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_WRITE_COMMAND_LENGTH_UFI;
56
    else
57
        command_length =  UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC;
58
#else
59
359
    command_length =  UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC;
60
#endif
61
62
    /* Initialize the CBW for this command.  */
63
359
    _ux_host_class_storage_cbw_initialize(storage, UX_HOST_CLASS_STORAGE_DATA_OUT,
64
359
                                    sector_count * storage -> ux_host_class_storage_sector_size,
65
                                    command_length);
66
67
    /* Prepare the MEDIA WRITE command block.  */
68
359
    *(cbw_cb + UX_HOST_CLASS_STORAGE_WRITE_OPERATION) =  UX_HOST_CLASS_STORAGE_SCSI_WRITE16;
69
70
    /* Store the sector start (LBA field).  */
71
359
    _ux_utility_long_put_big_endian(cbw_cb + UX_HOST_CLASS_STORAGE_WRITE_LBA, sector_start);
72
73
    /* Store the number of sectors to write.  */
74
359
    _ux_utility_short_put_big_endian(cbw_cb + UX_HOST_CLASS_STORAGE_WRITE_TRANSFER_LENGTH, (USHORT) sector_count);
75
359
}
76
77
78
/**************************************************************************/
79
/*                                                                        */
80
/*  FUNCTION                                               RELEASE        */
81
/*                                                                        */
82
/*    _ux_host_class_storage_media_write                  PORTABLE C      */
83
/*                                                           6.2.1        */
84
/*  AUTHOR                                                                */
85
/*                                                                        */
86
/*    Chaoqiong Xiao, Microsoft Corporation                               */
87
/*                                                                        */
88
/*  DESCRIPTION                                                           */
89
/*                                                                        */
90
/*    This function will write one or more logical sector to the media.   */
91
/*                                                                        */
92
/*  INPUT                                                                 */
93
/*                                                                        */
94
/*    storage                               Pointer to storage class      */
95
/*    sector_start                          Starting sector               */
96
/*    sector_count                          Number of sectors to write    */
97
/*    data_pointer                          Pointer to data to write      */
98
/*                                                                        */
99
/*  OUTPUT                                                                */
100
/*                                                                        */
101
/*    Completion Status                                                   */
102
/*                                                                        */
103
/*  CALLS                                                                 */
104
/*                                                                        */
105
/*    _ux_host_class_storage_cbw_initialize Initialize the CBW            */
106
/*    _ux_host_class_storage_transport      Send command                  */
107
/*    _ux_utility_long_put_big_endian       Put 32-bit word               */
108
/*    _ux_utility_short_put_big_endian      Put 16-bit word               */
109
/*                                                                        */
110
/*  CALLED BY                                                             */
111
/*                                                                        */
112
/*    Storage Class                                                       */
113
/*                                                                        */
114
/*  RELEASE HISTORY                                                       */
115
/*                                                                        */
116
/*    DATE              NAME                      DESCRIPTION             */
117
/*                                                                        */
118
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
119
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
120
/*                                            resulting in version 6.1    */
121
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
122
/*                                            added standalone support,   */
123
/*                                            resulting in version 6.1.10 */
124
/*  03-08-2023     Chaoqiong Xiao           Modified comment(s),          */
125
/*                                            checked device removal,     */
126
/*                                            resulting in version 6.2.1  */
127
/*                                                                        */
128
/**************************************************************************/
129
359
UINT  _ux_host_class_storage_media_write(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start,
130
                                        ULONG sector_count, UCHAR *data_pointer)
131
{
132
#if defined(UX_HOST_STANDALONE)
133
UINT            status;
134
    do {
135
        status = _ux_host_class_storage_read_write_run(storage, UX_FALSE,
136
                                    sector_start, sector_count, data_pointer);
137
    } while(status == UX_STATE_WAIT);
138
    if (status < UX_STATE_IDLE)
139
        return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
140
    return(storage -> ux_host_class_storage_status);
141
#else
142
UINT            status;
143
UINT            media_retry;
144
145
    /* If trace is enabled, insert this event into the trace buffer.  */
146
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_STORAGE_MEDIA_WRITE, storage, sector_start, sector_count, data_pointer, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
147
148
    /* Initialize CBW.  */
149
359
    _ux_host_class_storage_write_initialize(storage, sector_start, sector_count);
150
151
    /* Reset the retry count.  */
152
359
    media_retry =  UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RETRY;
153
154
    /* We may need several attempts.  */
155
391
    while (media_retry-- != 0)
156
    {
157
158
        /* Send the command to transport layer.  */
159
388
        status =  _ux_host_class_storage_transport(storage, data_pointer);
160
388
        if (status != UX_SUCCESS)
161
2
            return(status);
162
163
        /* Check the sense code */
164
386
        if (storage -> ux_host_class_storage_sense_code == UX_SUCCESS)
165
354
            return(UX_SUCCESS);
166
    }
167
168
    /* Return sense error.  */
169
3
    return(UX_HOST_CLASS_STORAGE_SENSE_ERROR);
170
#endif
171
}
172
173
174
/**************************************************************************/
175
/*                                                                        */
176
/*  FUNCTION                                               RELEASE        */
177
/*                                                                        */
178
/*    _ux_host_class_storage_media_write                  PORTABLE C      */
179
/*                                                           6.3.0        */
180
/*  AUTHOR                                                                */
181
/*                                                                        */
182
/*    Chaoqiong Xiao, Microsoft Corporation                               */
183
/*                                                                        */
184
/*  DESCRIPTION                                                           */
185
/*                                                                        */
186
/*    This function checks errors in storage media write function call.   */
187
/*                                                                        */
188
/*  INPUT                                                                 */
189
/*                                                                        */
190
/*    storage                               Pointer to storage class      */
191
/*    sector_start                          Starting sector               */
192
/*    sector_count                          Number of sectors to write    */
193
/*    data_pointer                          Pointer to data to write      */
194
/*                                                                        */
195
/*  OUTPUT                                                                */
196
/*                                                                        */
197
/*    Status                                                              */
198
/*                                                                        */
199
/*  CALLS                                                                 */
200
/*                                                                        */
201
/*    _ux_host_class_storage_media_write     write storage media          */
202
/*                                                                        */
203
/*  CALLED BY                                                             */
204
/*                                                                        */
205
/*    Application                                                         */
206
/*                                                                        */
207
/*  RELEASE HISTORY                                                       */
208
/*                                                                        */
209
/*    DATE              NAME                      DESCRIPTION             */
210
/*                                                                        */
211
/*  10-31-2023     Chaoqiong Xiao           Initial Version 6.3.0         */
212
/*                                                                        */
213
/**************************************************************************/
214
UINT  _uxe_host_class_storage_media_write(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start,
215
                                    ULONG sector_count, UCHAR *data_pointer)
216
{
217
218
    /* Sanity check.  */
219
    if (storage == UX_NULL)
220
        return(UX_INVALID_PARAMETER);
221
222
    /* Invoke storage media write function.  */
223
    return(_ux_host_class_storage_media_write(storage, sector_start, sector_count, data_pointer));
224
}