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
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_device_class_storage_deactivate PORTABLE C */
37 /* 6.1.12 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function deactivate an instance of the storage class. */
45 /* */
46 /* INPUT */
47 /* */
48 /* command Pointer to a class command */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* Completion Status */
53 /* */
54 /* CALLS */
55 /* */
56 /* _ux_device_stack_transfer_all_request_abort Abort all transfers */
57 /* */
58 /* CALLED BY */
59 /* */
60 /* Device Storage Class */
61 /* */
62 /* RELEASE HISTORY */
63 /* */
64 /* DATE NAME DESCRIPTION */
65 /* */
66 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
67 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
68 /* resulting in version 6.1 */
69 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
70 /* added standalone support, */
71 /* resulting in version 6.1.10 */
72 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
73 /* fixed parameter/variable */
74 /* names conflict C++ keyword, */
75 /* resulting in version 6.1.12 */
76 /* */
77 /**************************************************************************/
_ux_device_class_storage_deactivate(UX_SLAVE_CLASS_COMMAND * command)78 UINT _ux_device_class_storage_deactivate(UX_SLAVE_CLASS_COMMAND *command)
79 {
80
81 UX_SLAVE_CLASS_STORAGE *storage;
82 UX_SLAVE_ENDPOINT *endpoint_in;
83 UX_SLAVE_ENDPOINT *endpoint_out;
84 UX_SLAVE_CLASS *class_ptr;
85
86 /* Get the class container. */
87 class_ptr = command -> ux_slave_class_command_class_ptr;
88
89 /* Get the class instance in the container. */
90 storage = (UX_SLAVE_CLASS_STORAGE *)class_ptr -> ux_slave_class_instance;
91
92 #if defined(UX_DEVICE_STANDALONE)
93
94 endpoint_in = storage -> ux_device_class_storage_ep_in;
95 endpoint_out = storage -> ux_device_class_storage_ep_out;
96 _ux_device_stack_transfer_all_request_abort(endpoint_in, UX_TRANSFER_BUS_RESET);
97 _ux_device_stack_transfer_all_request_abort(endpoint_out, UX_TRANSFER_BUS_RESET);
98 endpoint_out -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer =
99 storage -> ux_device_class_storage_buffer[0];
100 endpoint_in -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer =
101 storage -> ux_device_class_storage_buffer[1];
102 #else
103
104 /* Locate the endpoints. */
105 endpoint_in = storage -> ux_slave_class_storage_interface -> ux_slave_interface_first_endpoint;
106
107 /* Check the endpoint direction, if IN we have the correct endpoint. */
108 if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN)
109 {
110
111 /* Wrong direction, we found the OUT endpoint first. */
112 endpoint_out = endpoint_in;
113
114 /* So the next endpoint has to be the IN endpoint. */
115 endpoint_in = endpoint_out -> ux_slave_endpoint_next_endpoint;
116 }
117 else
118 {
119
120 /* We found the endpoint IN first, so next endpoint is OUT. */
121 endpoint_out = endpoint_in -> ux_slave_endpoint_next_endpoint;
122 }
123
124 /* Terminate the transactions pending on the endpoints. */
125 _ux_device_stack_transfer_all_request_abort(endpoint_in, UX_TRANSFER_BUS_RESET);
126 _ux_device_stack_transfer_all_request_abort(endpoint_out, UX_TRANSFER_BUS_RESET);
127 #endif
128
129 /* If there is a deactivate function call it. */
130 if (storage -> ux_slave_class_storage_instance_deactivate != UX_NULL)
131 {
132
133 /* Invoke the application. */
134 storage -> ux_slave_class_storage_instance_deactivate(storage);
135 }
136
137 /* If trace is enabled, insert this event into the trace buffer. */
138 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_STORAGE_DEACTIVATE, storage, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
139
140 /* If trace is enabled, register this object. */
141 UX_TRACE_OBJECT_UNREGISTER(storage);
142
143 /* Return completion status. */
144 return(UX_SUCCESS);
145 }
146
147