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 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _ux_host_class_storage_check_run                    PORTABLE C      */
38 /*                                                           6.2.1        */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Chaoqiong Xiao, Microsoft Corporation                               */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This function runs state machine to check and mount/unmount storage */
46 /*    media for current locked logic unit number (LUN).                   */
47 /*                                                                        */
48 /*    It's valid only in standalone mode.                                 */
49 /*    It's non-blocking.                                                  */
50 /*                                                                        */
51 /*    Note it must be used in case following conditions are true:         */
52 /*    - storage insstance is live                                         */
53 /*    - storage is locked for specific LUN                                */
54 /*    - if check is not started yet the main storage state must be idle   */
55 /*                                                                        */
56 /*  INPUT                                                                 */
57 /*                                                                        */
58 /*    storage                               Pointer to storage class      */
59 /*                                                                        */
60 /*  OUTPUT                                                                */
61 /*                                                                        */
62 /*    Completion State Status                                             */
63 /*    UX_STATE_WAIT                         States started/in progress    */
64 /*    UX_STATE_NEXT                         Check is done, next call will */
65 /*                                          start check again.            */
66 /*                                                                        */
67 /*  CALLS                                                                 */
68 /*                                                                        */
69 /*    _ux_system_error_handler              The error trap                */
70 /*    _ux_system_tasks_run                  Run USB system tasks          */
71 /*                                                                        */
72 /*  CALLED BY                                                             */
73 /*                                                                        */
74 /*    Storage Class                                                       */
75 /*                                                                        */
76 /*  RELEASE HISTORY                                                       */
77 /*                                                                        */
78 /*    DATE              NAME                      DESCRIPTION             */
79 /*                                                                        */
80 /*  01-31-2022     Chaoqiong Xiao           Initial Version 6.1.10        */
81 /*  03-08-2023     Chaoqiong Xiao           Modified comment(s),          */
82 /*                                            checked device state,       */
83 /*                                            resulting in version 6.2.1  */
84 /*                                                                        */
85 /**************************************************************************/
_ux_host_class_storage_check_run(UX_HOST_CLASS_STORAGE * storage)86 UINT  _ux_host_class_storage_check_run(UX_HOST_CLASS_STORAGE *storage)
87 {
88 UX_DEVICE   *device;
89 
90 #if defined UX_HOST_CLASS_STORAGE_STATE_CHECK_ENABLE
91 UX_INTERRUPT_SAVE_AREA
92 
93     /* Check states - storage must be live, locked and main state machine idle.  */
94     UX_DISABLE
95     if (storage -> ux_host_class_storage_state != UX_HOST_CLASS_INSTANCE_LIVE ||
96         (storage -> ux_host_class_storage_flags & UX_HOST_CLASS_STORAGE_FLAG_LOCK) == 0 ||
97         (storage -> ux_host_class_storage_op_state != UX_STATE_WAIT &&
98          storage -> ux_host_class_storage_state_state != UX_STATE_IDLE))
99     {
100         UX_RESTORE
101 
102         /* Error trap.  */
103         _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_NOT_READY);
104 
105         /* The state is not ready for check operation.  */
106         storage -> ux_host_class_storage_status = UX_TRANSFER_NOT_READY;
107         storage -> ux_host_class_storage_op_state = UX_STATE_RESET;
108         return(UX_STATE_ERROR);
109     }
110     UX_RESTORE
111 #endif
112 
113     /* Get device.  */
114     device = storage -> ux_host_class_storage_device;
115 
116     switch(storage -> ux_host_class_storage_op_state)
117     {
118     case UX_STATE_IDLE:
119     case UX_STATE_ERROR:
120     case UX_STATE_RESET:
121 
122         /* Setup states for immediate LUN check.  */
123         storage -> ux_host_class_storage_flags |=
124                                     UX_HOST_CLASS_STORAGE_FLAG_CHECK_CURRENT;
125         storage -> ux_host_class_storage_check_lun =
126                                     (UCHAR)storage -> ux_host_class_storage_lun;
127         storage -> ux_host_class_storage_state_state =
128                                         UX_HOST_CLASS_STORAGE_STATE_TEST_READY;
129 
130         /* Next : wait  */
131         storage -> ux_host_class_storage_op_state = UX_STATE_WAIT;
132 
133         /* Fall through.  */
134     case UX_STATE_WAIT:
135 
136         /* Run tasks, including transport task.  */
137         _ux_system_host_tasks_run();
138 
139         /* Check if device is still available.  */
140         if (device -> ux_device_state != UX_DEVICE_CONFIGURED)
141         {
142 
143             /* Instance should have been destroyed, just return.  */
144             return(UX_STATE_EXIT);
145         }
146 
147         /* In case state is not idle, check if it changes back.  */
148         if (storage -> ux_host_class_storage_state_state == UX_STATE_IDLE)
149         {
150             storage -> ux_host_class_storage_op_state = UX_STATE_IDLE;
151             return(UX_STATE_NEXT);
152         }
153 
154         /* Keep waiting.  */
155         return(UX_STATE_WAIT);
156 
157     /* Unexpected states.  */
158     default:
159         storage -> ux_host_class_storage_op_state = UX_STATE_RESET;
160         break;
161     }
162 
163     /* We should never be here.  */
164     return(UX_STATE_EXIT);
165 }
166 #endif
167