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 /** Host Stack */
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_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_stack_transfer_request_abort PORTABLE C */
37 /* 6.2.0 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function aborts a pending transfer request that has been */
45 /* previously submitted. This function only cancels the specific */
46 /* transfer request. */
47 /* */
48 /* The call back to the function will have the */
49 /* UX_TRANSFER_STATUS_ABORT status. */
50 /* */
51 /* INPUT */
52 /* */
53 /* transfer_request Transfer request structure */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* Completion Status If UX_SUCCESS, transfer was */
58 /* successfully aborted */
59 /* */
60 /* CALLS */
61 /* */
62 /* HCD Entry Function */
63 /* Transfer Completion Function */
64 /* _ux_utility_semaphore_put Put semaphore */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* Application */
69 /* USBX Components */
70 /* */
71 /* RELEASE HISTORY */
72 /* */
73 /* DATE NAME DESCRIPTION */
74 /* */
75 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
76 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
77 /* optimized based on compile */
78 /* definitions, */
79 /* resulting in version 6.1 */
80 /* 06-02-2021 Chaoqiong Xiao Modified comment(s), */
81 /* fixed trace enabled error, */
82 /* resulting in version 6.1.7 */
83 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
84 /* added standalone support, */
85 /* resulting in version 6.1.10 */
86 /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
87 /* resulting in version 6.2.0 */
88 /* */
89 /**************************************************************************/
_ux_host_stack_transfer_request_abort(UX_TRANSFER * transfer_request)90 UINT _ux_host_stack_transfer_request_abort(UX_TRANSFER *transfer_request)
91 {
92
93 UX_HCD *hcd;
94 ULONG completion_code;
95
96
97 /* If trace is enabled, insert this event into the trace buffer. */
98 UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_TRANSFER_REQUEST_ABORT,
99 transfer_request -> ux_transfer_request_endpoint -> ux_endpoint_device,
100 transfer_request -> ux_transfer_request_endpoint,
101 transfer_request, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
102
103 /* With the device we have the pointer to the HCD. */
104 hcd = UX_DEVICE_HCD_GET(transfer_request -> ux_transfer_request_endpoint -> ux_endpoint_device);
105
106 /* Check pending transaction. */
107 if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
108 {
109
110 /* Send the abort command to the controller. */
111 hcd -> ux_hcd_entry_function(hcd, UX_HCD_TRANSFER_ABORT, transfer_request);
112
113 /* Save the completion code since we're about to set it to ABORT. The
114 reason we can't just assume its value is PENDING is that in between
115 the completion code check and this line, it's possible that the transfer
116 completed (by HCD function call below, or ISR), which would've
117 changed the completion code to SUCCESS and put the semaphore.
118 Even it's recommended to keep completion code untouched to let things
119 changed later here.
120 Such a case is valid, and we want to make sure we don't put() the
121 transfer request's semaphore again. */
122 completion_code = transfer_request -> ux_transfer_request_completion_code;
123
124 /* Set the transfer_request status to abort. */
125 transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_STATUS_ABORT;
126
127 /* We need to inform the class that owns this transfer_request of the
128 abort if there is a call back mechanism. */
129 if (transfer_request -> ux_transfer_request_completion_function != UX_NULL)
130 transfer_request -> ux_transfer_request_completion_function(transfer_request);
131
132 /* Is a thread waiting on the semaphore? */
133 if (/* Is the transfer pending? */
134 completion_code == UX_TRANSFER_STATUS_PENDING &&
135 #if !defined(UX_HOST_STANDALONE)
136 /* Is the thread waiting not this one? (clearly we're not waiting!) */
137 transfer_request -> ux_transfer_request_thread_pending != _ux_utility_thread_identify() &&
138 #endif
139 /* Does the transfer request not have a completion function? */
140 transfer_request -> ux_transfer_request_completion_function == UX_NULL)
141
142 /* Wake up the semaphore for this request. */
143 _ux_host_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
144 }
145
146 /* This function never fails! */
147 return(UX_SUCCESS);
148 }
149
150