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