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 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _ux_host_class_storage_max_lun_get PORTABLE C */
38 /* 6.1.10 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function retrieves the maximum number of LUNs from the device. */
46 /* */
47 /* INPUT */
48 /* */
49 /* storage Pointer to storage class */
50 /* */
51 /* OUTPUT */
52 /* */
53 /* Completion Status */
54 /* */
55 /* CALLS */
56 /* */
57 /* _ux_host_stack_transfer_request Process transfer request */
58 /* _ux_utility_memory_allocate Allocate memory block */
59 /* _ux_utility_memory_free Release memory block */
60 /* _ux_host_semaphore_get Get semaphore */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Storage Class */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
71 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
74 /* added standalone support, */
75 /* resulting in version 6.1.10 */
76 /* */
77 /**************************************************************************/
_ux_host_class_storage_max_lun_get(UX_HOST_CLASS_STORAGE * storage)78 UINT _ux_host_class_storage_max_lun_get(UX_HOST_CLASS_STORAGE *storage)
79 {
80
81 UX_ENDPOINT *control_endpoint;
82 UX_TRANSFER *transfer_request;
83 UINT status;
84 UCHAR *storage_data_buffer;
85
86
87 /* In the case of non BO device or an error on the command the number of lun should be
88 set to 0, indicating 1 lun. */
89 storage -> ux_host_class_storage_max_lun = 0;
90
91 #ifdef UX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT
92 /* Check the device type. */
93 if (storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceProtocol == UX_HOST_CLASS_STORAGE_PROTOCOL_BO)
94 {
95 #endif
96
97 /* We need to get the default control endpoint transfer_request pointer. */
98 control_endpoint = &storage -> ux_host_class_storage_device -> ux_device_control_endpoint;
99 transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
100
101 /* We need to prevent other threads from simultaneously using the control endpoint. */
102 status = _ux_host_semaphore_get(&control_endpoint -> ux_endpoint_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
103 if (status != UX_SUCCESS)
104 return(status);
105
106 /* Need to allocate memory for the descriptor. */
107 storage_data_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 1);
108 if (storage_data_buffer == UX_NULL)
109 return(UX_MEMORY_INSUFFICIENT);
110
111 /* Create a transfer_request for the GET_MAX_LUN request. */
112 transfer_request -> ux_transfer_request_data_pointer = storage_data_buffer;
113 transfer_request -> ux_transfer_request_requested_length = 1;
114 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_STORAGE_GET_MAX_LUN;
115 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
116 transfer_request -> ux_transfer_request_value = 0;
117 transfer_request -> ux_transfer_request_index = storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceNumber;
118
119 #if defined(UX_HOST_STANDALONE)
120 storage -> ux_host_class_storage_memory = storage_data_buffer;
121 storage -> ux_host_class_storage_trans = transfer_request;
122 storage -> ux_host_class_storage_state_state = UX_HOST_CLASS_STORAGE_STATE_TRANSFER;
123 storage -> ux_host_class_storage_state_next = UX_HOST_CLASS_STORAGE_STATE_MAX_LUN_SAVE;
124 UX_TRANSFER_STATE_RESET(transfer_request);
125 #else
126
127 /* Send request to HCD layer. */
128 status = _ux_host_stack_transfer_request(transfer_request);
129
130 /* Check for correct transfer and entire descriptor returned. */
131 if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == 1))
132 {
133
134 /* Retrieve the number of max LUN for this device. */
135 storage -> ux_host_class_storage_max_lun = *storage_data_buffer;
136
137 /* Is the max LUN index greater than our LUN array's? */
138 if (storage -> ux_host_class_storage_max_lun > UX_MAX_HOST_LUN - 1)
139 {
140
141 /* Cap it off. */
142 storage -> ux_host_class_storage_max_lun = UX_MAX_HOST_LUN - 1;
143
144 /* Notify application so it knows to increase UX_MAX_HOST_LUN. */
145 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_MEMORY_ERROR);
146
147 /* If trace is enabled, insert this event into the trace buffer. */
148 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_MEMORY_ERROR, storage, 0, 0, UX_TRACE_ERRORS, 0, 0)
149 }
150 }
151
152 /* Free all used resources. */
153 _ux_utility_memory_free(storage_data_buffer);
154 #endif
155
156 #ifdef UX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT
157 }
158 #if defined(UX_HOST_STANDALONE)
159 else
160 {
161 storage -> ux_host_class_storage_trans = UX_NULL;
162 storage -> ux_host_class_storage_state_state = UX_HOST_CLASS_STORAGE_STATE_MAX_LUN_SAVE;
163 }
164 #endif
165 #endif
166
167 /* We always succeed. */
168 return(UX_SUCCESS);
169 }
170
171