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 /** HUB 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_stack.h"
29 #include "ux_host_class_hub.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_hub_transfer_request_completed PORTABLE C */
37 /* 6.1.12 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function is called by the completion thread when a transfer */
45 /* request has been completed either because the transfer is */
46 /* successful or there was an error. */
47 /* */
48 /* Because the HUB influences the topology of the USB, the insertion */
49 /* or extraction of devices cannot be done during the transfer request */
50 /* thread. We post a signal to the topology thread to wake up and */
51 /* treat these changes on the HUB status. */
52 /* */
53 /* In RTOS mode, the interrupt pipe is not reactivated here. We will */
54 /* do this when the topology thread has investigated the reason of the */
55 /* transfer completion. */
56 /* */
57 /* In standalone mode, the interrupt pipe is reactivated here. The */
58 /* bitmap in buffer is examined in hub tasks function. */
59 /* */
60 /* INPUT */
61 /* */
62 /* transfer_request Pointer to transfer request */
63 /* */
64 /* OUTPUT */
65 /* */
66 /* None */
67 /* */
68 /* CALLS */
69 /* */
70 /* _ux_host_semaphore_put Put the signaling semaphore */
71 /* */
72 /* CALLED BY */
73 /* */
74 /* HUB Class */
75 /* */
76 /* RELEASE HISTORY */
77 /* */
78 /* DATE NAME DESCRIPTION */
79 /* */
80 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
81 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
82 /* resulting in version 6.1 */
83 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
84 /* refined macros names, */
85 /* resulting in version 6.1.10 */
86 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
87 /* added standalone support, */
88 /* resulting in version 6.1.12 */
89 /* */
90 /**************************************************************************/
_ux_host_class_hub_transfer_request_completed(UX_TRANSFER * transfer_request)91 VOID _ux_host_class_hub_transfer_request_completed(UX_TRANSFER *transfer_request)
92 {
93
94 UX_HOST_CLASS_HUB *hub;
95
96
97 /* Get the class instance for this transfer request. */
98 hub = (UX_HOST_CLASS_HUB *) transfer_request -> ux_transfer_request_class_instance;
99
100
101 /* Check the state of the transfer. If there is an error, we do not proceed with this report. */
102 if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
103 {
104
105 /* We have an error. We do not rehook another transfer if the device instance is shutting down or
106 if the transfer was aborted by the class. */
107 if ((hub -> ux_host_class_hub_state == UX_HOST_CLASS_INSTANCE_SHUTDOWN) ||
108 (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_ABORT) ||
109 (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_NO_ANSWER))
110
111 /* We do not proceed. */
112 return;
113 else
114
115 {
116
117 /* Reactivate the HUB interrupt pipe. */
118 _ux_host_stack_transfer_request(transfer_request);
119
120 /* We do not proceed. */
121 return;
122 }
123 }
124
125 #if defined(UX_HOST_STANDALONE)
126
127 /* Reactivate the HUB interrupt pipe. */
128 _ux_host_stack_transfer_request(transfer_request);
129 #else
130
131 /* We need to memorize which HUB instance has received a change signal. */
132 hub -> ux_host_class_hub_change_semaphore++;
133
134 /* Now we can set the semaphore, the enum thread will wake up and will
135 call the HUB instance which has a status change. */
136 _ux_host_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
137 #endif
138
139 /* Return to caller. */
140 return;
141 }
142