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 /** Device Storage Class */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define UX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "ux_api.h"
28 #include "ux_device_class_storage.h"
29 #include "ux_device_stack.h"
30
31 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_PROFILE_LENGTH 228
32 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_HEADER_LENGTH 8
33 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_DESCRIPTOR_LENGTH 32
34 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_HEADER_LENGTH 4
35 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_LENGTH (USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_PROFILE_LENGTH - USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_DESCRIPTOR_LENGTH - USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_HEADER_LENGTH)
36 UCHAR usbx_device_class_storage_configuration_profile[] = {
37
38 /* Feature Header */
39 0x00, 0x00, /* Entire length of profile filled by firmware */
40 0x00, 0x00,
41 0x00, 0x00,
42 0x00, 0x00, /* Current profile */
43
44 /* Feature Descriptor */
45 0x00, 0x00, /* Feature Code : profile list */
46 0x00, /* Persistent/current */
47 0x1c, /* Additional Length */
48
49 0x00, 0x12, 0x00, 0x00, /* DVD-RAM */
50 0x00, 0x11, 0x00, 0x00, /* DVD-R */
51 0x00, 0x10, 0x00, 0x00, /* DVD-ROM */
52 0x00, 0x0A, 0x00, 0x00, /* CD-RW */
53 0x00, 0x09, 0x00, 0x00, /* CD-R */
54 0x00, 0x08, 0x00, 0x00, /* CD-ROM */
55 0x00, 0x02, 0x00, 0x00, /* Writable capable with removable media. */
56
57
58 /* Feature Descriptor */
59 0x00, 0x01, /* Feature Code : core feature */
60 0x0b, /* Persistent/current */
61 0x08, /* Additional Length */
62
63 0x00, 0x00, 0x00, 0x07, /* Physical Interface Standard */
64 0x01, 0x00, 0x00, 0x00, /* */
65
66 /* Feature Descriptor */
67 0x00, 0x02, /* Feature Code : morphing (Ability to notify initiator about
68 operational changes and accept initiator requests to prevent
69 operational changes) */
70 0x07, /* Persistent/current */
71 0x04, /* Additional Length */
72
73 0x02, 0x00, 0x00, 0x00, /* Physical Interface Standard */
74
75 /* Feature Descriptor */
76 0x00, 0x03, /* Feature Code : Removable Medium (The medium may be removed
77 from the device ) */
78 0x0b, /* Persistent/current */
79 0x04, /* Additional Length */
80
81 0x2b, 0x00, 0x00, 0x00, /* Physical Interface Standard */
82
83 /* Feature Descriptor */
84 0x00, 0x10, /* Feature Code : Random Readable (Read ability for storage devices
85 with random addressing) */
86 0x00, /* Persistent/current */
87 0x08, /* Additional Length */
88
89 0x00, 0x00, 0x08, 0x00, /* */
90 0x00, 0x01, 0x01, 0x00, /* */
91
92 /* Feature Descriptor */
93 0x00, 0x1d, /* Feature Code : MultiRead (The logical unit can read all CD media types) */
94 0x00, /* Persistent/current */
95 0x00, /* Additional Length */
96
97
98 /* Feature Descriptor */
99 0x00, 0x1e, /* Feature Code : CD Read (The ability to read CD specific structures) */
100 0x08, /* Persistent/current */
101 0x04, /* Additional Length */
102
103 0x03, 0x00, 0x00, 0x00, /* */
104
105 /* Feature Descriptor */
106 0x00, 0x1f, /* Feature Code : DVD Read (The ability to read DVD specific structures) */
107 0x08, /* Persistent/current */
108 0x04, /* Additional Length */
109
110 0x01, 0x00, 0x01, 0x00, /* */
111
112 /* Feature Descriptor */
113 0x00, 0x20, /* Feature Code : Random Writable (Write support for randomly addressed writes) */
114 0x04, /* Persistent/current */
115 0x0c, /* Additional Length */
116
117 0x00, 0x00, 0x00, 0x00, /* */
118 0x00, 0x00, 0x08, 0x00, /* */
119 0x00, 0x00, 0x01, 0x00, /* */
120
121
122 /* Feature Descriptor */
123 0x00, 0x21, /* Feature Code : Incremental Streaming Writable (Write support for sequential recording) */
124 0x0C, /* Persistent/current */
125 0x08, /* Additional Length */
126
127 0x00, 0x00, 0x00, 0x00, /* */
128 0x00, 0x00, 0x00, 0x00, /* */
129
130 /* Feature Descriptor */
131 0x00, 0x23, /* Feature Code : Formattable (Support for formatting of media.) */
132 0x08, /* Persistent/current */
133 0x08, /* Additional Length */
134
135 0x00, 0x00, 0x00, 0x00, /* */
136 0x00, 0x00, 0x00, 0x00, /* */
137
138 /* Feature Descriptor */
139 0x00, 0x24, /* Feature Code : Defect Management (Ability of the drive/media system to provide an
140 apparently defect-free space.) */
141 0x04, /* Persistent/current */
142 0x04, /* Additional Length */
143
144 0x80, 0x00, 0x00, 0x00, /* */
145
146 /* Feature Descriptor */
147 0x00, 0x26, /* Feature Code : Restricted Overwrite (Write support for media that must be written
148 in multiples of logical blocks.) */
149 0x00, /* Persistent/current */
150 0x00, /* Additional Length */
151
152
153 /* Feature Descriptor */
154 0x00, 0x2d, /* Feature Code : CD Track at Once (Ability to write CD with Track at Once recording) */
155 0x08, /* Persistent/current */
156 0x04, /* Additional Length */
157
158 0x46, 0x00, 0x3f, 0x0f, /* */
159
160 /* Feature Descriptor */
161 0x00, 0x2e, /* Feature Code : CD Mastering (The ability to write CD with Session at Once or Raw write methods.) */
162 0x04, /* Persistent/current */
163 0x04, /* Additional Length */
164
165 0x7f, 0x00, 0x0d, 0x00, /* */
166
167 /* Feature Descriptor */
168 0x00, 0x2f, /* Feature Code : DVD-R Write (The ability to write DVD specific structures) */
169 0x08, /* Persistent/current */
170 0x04, /* Additional Length */
171
172 0x4e, 0x00, 0x00, 0x00, /* */
173
174
175 0x01, 0x00, /* Feature Code : Power Management (Initiator and device directed power management) */
176 0x07, /* Persistent/current */
177 0x04, /* Additional Length */
178
179 0x00, 0x00, 0x00, 0x00, /* */
180
181
182 0x01, 0x01, /* Feature Code : S.M.A.R.T. (Self Monitoring Analysis and Reporting Technology (Failure prediction)) */
183 0x00, /* Persistent/current */
184 0x04, /* Additional Length */
185
186 0x00, 0x00, 0x00, 0x00, /* */
187
188 0x01, 0x08, /* Feature Code : Logical Unit serial number (Logical unit has a unique identifier) */
189 0x03, /* Persistent/current */
190 0x10, /* Additional Length */
191
192 0x53, 0x31, 0x33, 0x36, /* Serial Number */
193 0x36, 0x59, 0x42, 0x46,
194 0x37, 0x30, 0x30, 0x39,
195 0x45, 0x48, 0x20, 0x20,
196
197 0x01, 0x0a, /* Feature Code : Not sure : says FDC STC TOC */
198 0x00, /* Persistent/current */
199 0x0c, /* Additional Length */
200
201 0x46, 0x44, 0x43, 0x00,
202 0x53, 0x54, 0x43, 0x00,
203 0x54, 0x4F, 0x43, 0x00,
204 };
205
206
207 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_PROFILE_LENGTH 112
208 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_HEADER_LENGTH 8
209 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_FEATURE_DESCRIPTOR_LENGTH 32
210 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_FEATURE_HEADER_LENGTH 4
211 #define USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_FEATURE_LENGTH (USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_PROFILE_LENGTH - USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_FEATURE_DESCRIPTOR_LENGTH - USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_HEADER_LENGTH)
212 UCHAR usbx_device_class_storage_configuration_active_profile[] = {
213
214 /* Feature Header */
215 0x00, 0x00, /* Entire length of profile filled by firmware */
216 0x00, 0x00,
217 0x00, 0x00,
218 0x00, 0x08, /* Current profile is CD-ROM*/
219
220 /* Feature Descriptor */
221 0x00, 0x00, /* Feature Code : profile list */
222 0x00, /* Persistent/current */
223 0x1c, /* Additional Length */
224
225 0x00, 0x12, 0x00, 0x00, /* DVD-RAM */
226 0x00, 0x11, 0x00, 0x00, /* DVD-R */
227 0x00, 0x10, 0x00, 0x00, /* DVD-ROM */
228 0x00, 0x0A, 0x00, 0x00, /* CD-RW */
229 0x00, 0x09, 0x00, 0x00, /* CD-R */
230 0x00, 0x08, 0x01, 0x00, /* CD-ROM : active profile */
231 0x00, 0x02, 0x00, 0x00, /* Writable capable with removable media. */
232
233
234 /* Feature Descriptor */
235 0x00, 0x01, /* Feature Code : core feature */
236 0x0b, /* Persistent/current */
237 0x08, /* Additional Length */
238
239 0x00, 0x00, 0x00, 0x07, /* Physical Interface Standard */
240 0x01, 0x00, 0x00, 0x00, /* */
241
242 /* Feature Descriptor */
243 0x00, 0x02, /* Feature Code : morphing (Ability to notify initiator about
244 operational changes and accept initiator requests to prevent
245 operational changes) */
246 0x07, /* Persistent/current */
247 0x04, /* Additional Length */
248
249 0x02, 0x00, 0x00, 0x00, /* Physical Interface Standard */
250
251 /* Feature Descriptor */
252 0x00, 0x03, /* Feature Code : Removable Medium (The medium may be removed
253 from the device ) */
254 0x0b, /* Persistent/current */
255 0x04, /* Additional Length */
256
257 0x2b, 0x00, 0x00, 0x00, /* Physical Interface Standard */
258
259 /* Feature Descriptor */
260 0x00, 0x10, /* Feature Code : Random Readable (Read ability for storage devices
261 with random addressing) */
262 0x01, /* Persistent/current */
263 0x08, /* Additional Length */
264
265 0x00, 0x00, 0x08, 0x00, /* */
266 0x00, 0x01, 0x01, 0x00, /* */
267
268 /* Feature Descriptor */
269 0x00, 0x1d, /* Feature Code : MultiRead (The logical unit can read all CD media types) */
270 0x01, /* Persistent/current */
271 0x00, /* Additional Length */
272
273
274 /* Feature Descriptor */
275 0x00, 0x1e, /* Feature Code : CD Read (The ability to read CD specific structures) */
276 0x09, /* Persistent/current */
277 0x04, /* Additional Length */
278
279 0x03, 0x00, 0x00, 0x00, /* */
280
281
282 0x01, 0x08, /* Feature Code : Logical Unit serial number (Logical unit has a unique identifier) */
283 0x03, /* Persistent/current */
284 0x10, /* Additional Length */
285
286 0x53, 0x31, 0x33, 0x36, /* Serial Number */
287 0x36, 0x59, 0x42, 0x46,
288 0x37, 0x30, 0x30, 0x39,
289 0x45, 0x48, 0x20, 0x20,
290
291 };
292
293 #if (UX_SLAVE_REQUEST_DATA_MAX_LENGTH < USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_PROFILE_LENGTH) ||\
294 (UX_SLAVE_REQUEST_DATA_MAX_LENGTH < USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_PROFILE_LENGTH)
295 /* #error UX_SLAVE_REQUEST_DATA_MAX_LENGTH too small, please check */
296 /* Build option checked runtime by UX_ASSERT */
297 #endif
298
299
300 /**************************************************************************/
301 /* */
302 /* FUNCTION RELEASE */
303 /* */
304 /* _ux_device_class_storage_get_configuration PORTABLE C */
305 /* 6.3.0 */
306 /* AUTHOR */
307 /* */
308 /* Chaoqiong Xiao, Microsoft Corporation */
309 /* */
310 /* DESCRIPTION */
311 /* */
312 /* This function performs a GET_CONFIGURATION command. */
313 /* */
314 /* INPUT */
315 /* */
316 /* storage Pointer to storage class */
317 /* endpoint_in Pointer to IN endpoint */
318 /* endpoint_out Pointer to OUT endpoint */
319 /* cbwcb Pointer to CBWCB */
320 /* */
321 /* OUTPUT */
322 /* */
323 /* Completion Status */
324 /* */
325 /* CALLS */
326 /* */
327 /* _ux_device_class_storage_csw_send Send CSW */
328 /* _ux_device_stack_transfer_request Transfer request */
329 /* _ux_device_stack_endpoint_stall Stall endpoint */
330 /* _ux_utility_short_get_big_endian Get 16-bit big endian */
331 /* _ux_utility_long_put_big_endian Put 32-bit big endian */
332 /* _ux_utility_memory_copy Copy memory */
333 /* */
334 /* CALLED BY */
335 /* */
336 /* Device Storage Class */
337 /* */
338 /* RELEASE HISTORY */
339 /* */
340 /* DATE NAME DESCRIPTION */
341 /* */
342 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
343 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
344 /* optimized command logic, */
345 /* verified memset and memcpy */
346 /* cases, */
347 /* resulting in version 6.1 */
348 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
349 /* added standalone support, */
350 /* resulting in version 6.1.10 */
351 /* 10-31-2023 Chaoqiong Xiao Modified comment(s), */
352 /* checked compiling options */
353 /* by runtime UX_ASSERT, */
354 /* resulting in version 6.3.0 */
355 /* */
356 /**************************************************************************/
_ux_device_class_storage_get_configuration(UX_SLAVE_CLASS_STORAGE * storage,ULONG lun,UX_SLAVE_ENDPOINT * endpoint_in,UX_SLAVE_ENDPOINT * endpoint_out,UCHAR * cbwcb)357 UINT _ux_device_class_storage_get_configuration(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun,
358 UX_SLAVE_ENDPOINT *endpoint_in,
359 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR * cbwcb)
360 {
361
362 UINT status = 0;
363 UX_SLAVE_TRANSFER *transfer_request;
364 ULONG starting_feature;
365 ULONG allocation_length;
366 ULONG additional_length;
367 ULONG profile_counter;
368 UCHAR *profile_pointer;
369 ULONG feature;
370
371 UX_PARAMETER_NOT_USED(endpoint_out);
372
373 /* Build option check. */
374 UX_ASSERT((UX_SLAVE_REQUEST_DATA_MAX_LENGTH >=
375 USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_PROFILE_LENGTH) &&
376 (UX_SLAVE_REQUEST_DATA_MAX_LENGTH >=
377 USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_PROFILE_LENGTH));
378
379 /* If trace is enabled, insert this event into the trace buffer. */
380 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_STORAGE_GET_CONFIGURATION, storage, lun, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
381
382 /* Initialize the length of the configuration profile. */
383 _ux_utility_long_put_big_endian(usbx_device_class_storage_configuration_profile, (USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_PROFILE_LENGTH - 4));
384
385 /* Initialize the length of the active configuration profile. */
386 _ux_utility_long_put_big_endian(usbx_device_class_storage_configuration_active_profile, (USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_PROFILE_LENGTH - 4));
387
388 /* Obtain the pointer to the transfer request. */
389 transfer_request = &endpoint_in -> ux_slave_endpoint_transfer_request;
390
391 /* Get the Starting Feature. */
392 starting_feature = _ux_utility_short_get_big_endian(cbwcb + UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_STARTING_FEATURE);
393
394 /* Get the allocation length. */
395 allocation_length = _ux_utility_short_get_big_endian(cbwcb + UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_ALLOCATION_LENGTH);
396
397 /* Default CSW to success. */
398 storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PASSED;
399
400 /* Is the request demanding all the features ? */
401 if (starting_feature == 0)
402 {
403
404 /* Is the requester demanding the active profile ? */
405 if ((*(cbwcb + UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_RT) & 3) == 1)
406 {
407
408 /* We get the active profile. */
409 /* Can we send all the activeconfiguration profile ? If not, the host may demand the first part of the configuration to get the entire length.
410 In this case, return the length demanded by the host. */
411 if (allocation_length >= USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_PROFILE_LENGTH)
412
413 /* Adjust allocation length to maximum allowed. */
414 allocation_length = USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_ACTIVE_PROFILE_LENGTH;
415
416 /* Copy the CSW into the transfer request memory. */
417 _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
418 usbx_device_class_storage_configuration_active_profile,
419 allocation_length); /* Use case of memcpy is verified. */
420 }
421 else
422 {
423
424 /* We get the whole profile. */
425 /* Can we send all the configuration profile ? If not, the host may demand the first part of the configuration to get the entire length.
426 In this case, return the length demanded by the host. */
427 if (allocation_length >= USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_PROFILE_LENGTH)
428
429 /* Adjust allocation length to maximum allowed. */
430 allocation_length = USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_PROFILE_LENGTH;
431
432 /* Copy the CSW into the transfer request memory. */
433 _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
434 usbx_device_class_storage_configuration_profile,
435 allocation_length); /* Use case of memcpy is verified. */
436
437 }
438
439 /* Now success. */
440 status = UX_SUCCESS;
441 }
442 else
443 {
444
445 /* The caller has demanded a specific feature. Scan our configuration profile. Jump over the beginning sections. */
446 profile_pointer = usbx_device_class_storage_configuration_profile + USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_HEADER_LENGTH +
447 USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_DESCRIPTOR_LENGTH;
448 profile_counter = USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_LENGTH;
449
450 /* Scan our configuration profile. */
451 while (profile_counter != 0)
452 {
453
454 /* Extract the feature from the configuration profile. */
455 feature = _ux_utility_short_get_big_endian(profile_pointer + USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_CODE);
456
457 /* Extract the feature length from the configuration profile. */
458 additional_length = (ULONG ) *(profile_pointer + USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_ADD_LENGTH);
459
460 /* Compare the Feature extracted with the one demanded. */
461 if (feature == starting_feature)
462 {
463
464 /* We found the feature, we check if the requester has enough space for us to return it. */
465 if (allocation_length >= (additional_length + USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_HEADER_LENGTH +
466 USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_HEADER_LENGTH))
467
468 /* Need to adjust the allocation length. */
469 allocation_length = additional_length + USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_HEADER_LENGTH +
470 USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_HEADER_LENGTH;
471
472 /* Copy the CSW into the transfer request memory. */
473 _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
474 profile_pointer,
475 allocation_length); /* Use case of memcpy is verified. */
476
477 /* Now success. */
478 status = UX_SUCCESS;
479
480 /* Get out of the loop. */
481 break;
482 }
483 else
484 {
485
486 /* We have not yet found the feature, keep parsing. */
487 if (profile_counter - additional_length - USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_HEADER_LENGTH <= 0)
488 {
489
490 /* We are either at the end of the profile or the profile is corrupted. */
491
492 /* And update the REQUEST_SENSE codes. */
493 storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_request_sense_status =
494 UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(UX_SLAVE_CLASS_STORAGE_SENSE_KEY_ILLEGAL_REQUEST,0x26,0x02);
495
496 /* Now we set the CSW with failure. */
497 storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_FAILED;
498
499 /* Set status to error. */
500 status = UX_ERROR;
501
502 /* Get out of the loop. */
503 break;
504
505 }
506 else
507 {
508
509 /* Update the profile pointer. */
510 profile_pointer += additional_length + USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_HEADER_LENGTH;
511
512 /* Update the length remaining to parse in profile. */
513 profile_counter -= additional_length + USBX_DEVICE_CLASS_STORAGE_CONFIGURATION_FEATURE_HEADER_LENGTH;
514 }
515 }
516 }
517 }
518
519 /* Success, send data. */
520 if (status == UX_SUCCESS)
521 {
522
523 #if defined(UX_DEVICE_STANDALONE)
524
525 /* Next: Transfer (DATA). */
526 storage -> ux_device_class_storage_state = UX_DEVICE_CLASS_STORAGE_STATE_TRANS_START;
527 storage -> ux_device_class_storage_cmd_state = UX_DEVICE_CLASS_STORAGE_CMD_READ;
528
529 storage -> ux_device_class_storage_transfer = transfer_request;
530 storage -> ux_device_class_storage_device_length = allocation_length;
531 storage -> ux_device_class_storage_data_length = allocation_length;
532 storage -> ux_device_class_storage_data_count = 0;
533 UX_SLAVE_TRANSFER_STATE_RESET(storage -> ux_device_class_storage_transfer);
534 #else
535
536 /* Send a data payload with the read_capacity response buffer. */
537 _ux_device_stack_transfer_request(transfer_request,
538 allocation_length,
539 allocation_length);
540 #endif
541
542 }
543 else
544 {
545
546 /* Error, stall. */
547 #if !defined(UX_DEVICE_STANDALONE)
548 _ux_device_stack_endpoint_stall(endpoint_in);
549 #endif
550 }
551
552 /* Return completion status. */
553 return(status);
554 }
555
556