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: 2026-03-06 18:57:10 Branches: 6 8 75.0 %

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
#if defined(UX_HOST_STANDALONE)
34
VOID _ux_host_class_storage_write_initialize(UX_HOST_CLASS_STORAGE *storage,
35
                ULONG sector_start, ULONG sector_count);
36
37
VOID
38
#else
39
static inline VOID
40
#endif
41
359
_ux_host_class_storage_write_initialize(UX_HOST_CLASS_STORAGE *storage,
42
                ULONG sector_start, ULONG sector_count)
43
{
44
UCHAR       *cbw;
45
UCHAR       *cbw_cb;
46
ULONG       command_length;
47
48
    /* Use a pointer for the cbw, easier to manipulate.  */
49
359
    cbw = (UCHAR *)storage -> ux_host_class_storage_cbw;
50
359
    cbw_cb = cbw + UX_HOST_CLASS_STORAGE_CBW_CB;
51
52
    /* Get the Write Command Length.  */
53
#ifdef UX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT
54
    if (storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceSubClass ==
55
        UX_HOST_CLASS_STORAGE_SUBCLASS_UFI)
56
        command_length =  UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_UFI;
57
    else
58
        command_length =  UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC;
59
#else
60
359
    command_length =  UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC;
61
#endif
62
63
    /* Initialize the CBW for this command.  */
64
359
    _ux_host_class_storage_cbw_initialize(storage, UX_HOST_CLASS_STORAGE_DATA_OUT,
65
359
                                    sector_count * storage -> ux_host_class_storage_sector_size,
66
                                    command_length);
67
68
    /* Prepare the MEDIA WRITE command block.  */
69
359
    *(cbw_cb + UX_HOST_CLASS_STORAGE_WRITE_OPERATION) =  UX_HOST_CLASS_STORAGE_SCSI_WRITE16;
70
71
    /* Store the sector start (LBA field).  */
72
359
    _ux_utility_long_put_big_endian(cbw_cb + UX_HOST_CLASS_STORAGE_WRITE_LBA, sector_start);
73
74
    /* Store the number of sectors to write.  */
75
359
    _ux_utility_short_put_big_endian(cbw_cb + UX_HOST_CLASS_STORAGE_WRITE_TRANSFER_LENGTH, (USHORT) sector_count);
76
359
}
77
78
79
/**************************************************************************/
80
/*                                                                        */
81
/*  FUNCTION                                               RELEASE        */
82
/*                                                                        */
83
/*    _ux_host_class_storage_media_write                  PORTABLE C      */
84
/*                                                           6.2.1        */
85
/*  AUTHOR                                                                */
86
/*                                                                        */
87
/*    Chaoqiong Xiao, Microsoft Corporation                               */
88
/*                                                                        */
89
/*  DESCRIPTION                                                           */
90
/*                                                                        */
91
/*    This function will write one or more logical sector to the media.   */
92
/*                                                                        */
93
/*  INPUT                                                                 */
94
/*                                                                        */
95
/*    storage                               Pointer to storage class      */
96
/*    sector_start                          Starting sector               */
97
/*    sector_count                          Number of sectors to write    */
98
/*    data_pointer                          Pointer to data to write      */
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
/**************************************************************************/
116
359
UINT  _ux_host_class_storage_media_write(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start,
117
                                        ULONG sector_count, UCHAR *data_pointer)
118
{
119
#if defined(UX_HOST_STANDALONE)
120
UINT            status;
121
    do {
122
        status = _ux_host_class_storage_read_write_run(storage, UX_FALSE,
123
                                    sector_start, sector_count, data_pointer);
124
    } while(status == UX_STATE_WAIT);
125
    if (status < UX_STATE_IDLE)
126
        return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
127
    return(storage -> ux_host_class_storage_status);
128
#else
129
UINT            status;
130
UINT            media_retry;
131
132
    /* If trace is enabled, insert this event into the trace buffer.  */
133
    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)
134
135
    /* Initialize CBW.  */
136
359
    _ux_host_class_storage_write_initialize(storage, sector_start, sector_count);
137
138
    /* Reset the retry count.  */
139
359
    media_retry =  UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RETRY;
140
141
    /* We may need several attempts.  */
142
391
    while (media_retry-- != 0)
143
    {
144
145
        /* Send the command to transport layer.  */
146
388
        status =  _ux_host_class_storage_transport(storage, data_pointer);
147
388
        if (status != UX_SUCCESS)
148
2
            return(status);
149
150
        /* Check the sense code */
151
386
        if (storage -> ux_host_class_storage_sense_code == UX_SUCCESS)
152
354
            return(UX_SUCCESS);
153
    }
154
155
    /* Return sense error.  */
156
3
    return(UX_HOST_CLASS_STORAGE_SENSE_ERROR);
157
#endif
158
}
159
160
161
/**************************************************************************/
162
/*                                                                        */
163
/*  FUNCTION                                               RELEASE        */
164
/*                                                                        */
165
/*    _ux_host_class_storage_media_write                  PORTABLE C      */
166
/*                                                           6.3.0        */
167
/*  AUTHOR                                                                */
168
/*                                                                        */
169
/*    Chaoqiong Xiao, Microsoft Corporation                               */
170
/*                                                                        */
171
/*  DESCRIPTION                                                           */
172
/*                                                                        */
173
/*    This function checks errors in storage media write function call.   */
174
/*                                                                        */
175
/*  INPUT                                                                 */
176
/*                                                                        */
177
/*    storage                               Pointer to storage class      */
178
/*    sector_start                          Starting sector               */
179
/*    sector_count                          Number of sectors to write    */
180
/*    data_pointer                          Pointer to data to write      */
181
/*                                                                        */
182
/*  OUTPUT                                                                */
183
/*                                                                        */
184
/*    Status                                                              */
185
/*                                                                        */
186
/*  CALLS                                                                 */
187
/*                                                                        */
188
/*    _ux_host_class_storage_media_write     write storage media          */
189
/*                                                                        */
190
/*  CALLED BY                                                             */
191
/*                                                                        */
192
/*    Application                                                         */
193
/*                                                                        */
194
/**************************************************************************/
195
UINT  _uxe_host_class_storage_media_write(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start,
196
                                    ULONG sector_count, UCHAR *data_pointer)
197
{
198
199
    /* Sanity check.  */
200
    if (storage == UX_NULL)
201
        return(UX_INVALID_PARAMETER);
202
203
    /* Invoke storage media write function.  */
204
    return(_ux_host_class_storage_media_write(storage, sector_start, sector_count, data_pointer));
205
}