1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
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
_ux_host_class_storage_write_initialize(UX_HOST_CLASS_STORAGE * storage,ULONG sector_start,ULONG sector_count)41 _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 cbw = (UCHAR *)storage -> ux_host_class_storage_cbw;
50 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 command_length = UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC;
61 #endif
62
63 /* Initialize the CBW for this command. */
64 _ux_host_class_storage_cbw_initialize(storage, UX_HOST_CLASS_STORAGE_DATA_OUT,
65 sector_count * storage -> ux_host_class_storage_sector_size,
66 command_length);
67
68 /* Prepare the MEDIA WRITE command block. */
69 *(cbw_cb + UX_HOST_CLASS_STORAGE_WRITE_OPERATION) = UX_HOST_CLASS_STORAGE_SCSI_WRITE16;
70
71 /* Store the sector start (LBA field). */
72 _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 _ux_utility_short_put_big_endian(cbw_cb + UX_HOST_CLASS_STORAGE_WRITE_TRANSFER_LENGTH, (USHORT) sector_count);
76 }
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 /* 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 /**************************************************************************/
_ux_host_class_storage_media_write(UX_HOST_CLASS_STORAGE * storage,ULONG sector_start,ULONG sector_count,UCHAR * data_pointer)130 UINT _ux_host_class_storage_media_write(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_FALSE,
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_WRITE, storage, sector_start, sector_count, data_pointer, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
148
149 /* Initialize CBW. */
150 _ux_host_class_storage_write_initialize(storage, sector_start, sector_count);
151
152 /* Reset the retry count. */
153 media_retry = UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RETRY;
154
155 /* We may need several attempts. */
156 while (media_retry-- != 0)
157 {
158
159 /* Send the command to transport layer. */
160 status = _ux_host_class_storage_transport(storage, data_pointer);
161 if (status != UX_SUCCESS)
162 return(status);
163
164 /* Check the sense code */
165 if (storage -> ux_host_class_storage_sense_code == UX_SUCCESS)
166 return(UX_SUCCESS);
167 }
168
169 /* Return sense error. */
170 return(UX_HOST_CLASS_STORAGE_SENSE_ERROR);
171 #endif
172 }
173
174