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 /**************************************************************************/ 24 /* */ 25 /* COMPONENT DEFINITION RELEASE */ 26 /* */ 27 /* ux_host_class_hub.h PORTABLE C */ 28 /* 6.3.0 */ 29 /* AUTHOR */ 30 /* */ 31 /* Chaoqiong Xiao, Microsoft Corporation */ 32 /* */ 33 /* DESCRIPTION */ 34 /* */ 35 /* This file contains all the header and extern functions used by the */ 36 /* USBX HUB class. */ 37 /* */ 38 /* RELEASE HISTORY */ 39 /* */ 40 /* DATE NAME DESCRIPTION */ 41 /* */ 42 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 43 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 44 /* resulting in version 6.1 */ 45 /* 08-02-2021 Wen Wang Modified comment(s), */ 46 /* added extern "C" keyword */ 47 /* for compatibility with C++, */ 48 /* resulting in version 6.1.8 */ 49 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ 50 /* added standalone support, */ 51 /* resulting in version 6.1.12 */ 52 /* 10-31-2023 Chaoqiong Xiao Modified comment(s), */ 53 /* optimized USB descriptors, */ 54 /* resulting in version 6.3.0 */ 55 /* */ 56 /**************************************************************************/ 57 58 #ifndef UX_HOST_CLASS_HUB_H 59 #define UX_HOST_CLASS_HUB_H 60 61 /* Determine if a C++ compiler is being used. If so, ensure that standard 62 C is used to process the API information. */ 63 64 #ifdef __cplusplus 65 66 /* Yes, C++ compiler is present. Use standard C. */ 67 extern "C" { 68 69 #endif 70 71 72 /* Define HUB Class constants. */ 73 74 #define UX_HOST_CLASS_HUB_CLASS 9 75 #define UX_HOST_CLASS_HUB_PROTOCOL_FS 0 76 #define UX_HOST_CLASS_HUB_PROTOCOL_SINGLE_TT 1 77 #define UX_HOST_CLASS_HUB_PROTOCOL_MULTIPLE_TT 2 78 79 80 /* Define HUB Class descriptor field constants. */ 81 82 #define UX_HOST_CLASS_HUB_GANG_POWER_SWITCHING 0x00 83 #define UX_HOST_CLASS_HUB_INDIVIDUAL_POWER_SWITCHING 0x01 84 #define UX_HOST_CLASS_HUB_NO_POWER_SWITCHING 0x02 85 86 #define UX_HOST_CLASS_HUB_COMPOUND_DEVICE 0x04 87 88 #define UX_HOST_CLASS_HUB_GLOBAL_OVERCURRENT 0x00 89 #define UX_HOST_CLASS_HUB_INDIVIDUAL_OVERCURRENT 0x08 90 #define UX_HOST_CLASS_HUB_NO_OVERCURRENT 0x10 91 92 93 /* Define HUB Class command constants. */ 94 95 #define UX_HOST_CLASS_HUB_GET_STATUS 0x00 96 #define UX_HOST_CLASS_HUB_CLEAR_FEATURE 0x01 97 #define UX_HOST_CLASS_HUB_GET_STATE 0x02 98 #define UX_HOST_CLASS_HUB_SET_FEATURE 0x03 99 #define UX_HOST_CLASS_HUB_GET_DESCRIPTOR 0x06 100 #define UX_HOST_CLASS_HUB_SET_DESCRIPTOR 0x07 101 102 103 /* Define HUB Class set_feature command constants. */ 104 105 #define UX_HOST_CLASS_HUB_PORT_CONNECTION 0x00 106 #define UX_HOST_CLASS_HUB_PORT_ENABLE 0x01 107 #define UX_HOST_CLASS_HUB_PORT_SUSPEND 0x02 108 #define UX_HOST_CLASS_HUB_PORT_OVER_CURRENT 0x03 109 #define UX_HOST_CLASS_HUB_PORT_RESET 0x04 110 #define UX_HOST_CLASS_HUB_PORT_POWER 0x08 111 #define UX_HOST_CLASS_HUB_PORT_LOW_SPEED 0x09 112 #define UX_HOST_CLASS_HUB_C_PORT_CONNECTION 0x10 113 #define UX_HOST_CLASS_HUB_C_PORT_ENABLE 0x11 114 #define UX_HOST_CLASS_HUB_C_PORT_SUSPEND 0x12 115 #define UX_HOST_CLASS_HUB_C_PORT_OVER_CURRENT 0x13 116 #define UX_HOST_CLASS_HUB_C_PORT_RESET 0x14 117 118 119 /* Define HUB Class port status constants. */ 120 121 #define UX_HOST_CLASS_HUB_PORT_STATUS_CONNECTION 0x0001 122 #define UX_HOST_CLASS_HUB_PORT_STATUS_ENABLE 0x0002 123 #define UX_HOST_CLASS_HUB_PORT_STATUS_SUSPEND 0x0004 124 #define UX_HOST_CLASS_HUB_PORT_STATUS_OVER_CURRENT 0x0008 125 #define UX_HOST_CLASS_HUB_PORT_STATUS_RESET 0x0010 126 #define UX_HOST_CLASS_HUB_PORT_STATUS_POWER 0x0100 127 #define UX_HOST_CLASS_HUB_PORT_STATUS_LOW_SPEED 0x0200 128 #define UX_HOST_CLASS_HUB_PORT_STATUS_HIGH_SPEED 0x0400 129 130 131 /* Define HUB Class port change constants. */ 132 133 #define UX_HOST_CLASS_HUB_PORT_CHANGE_CONNECTION 0x00001u 134 #define UX_HOST_CLASS_HUB_PORT_CHANGE_ENABLE 0x00002u 135 #define UX_HOST_CLASS_HUB_PORT_CHANGE_SUSPEND 0x00004u 136 #define UX_HOST_CLASS_HUB_PORT_CHANGE_OVER_CURRENT 0x00008u 137 #define UX_HOST_CLASS_HUB_PORT_CHANGE_RESET 0x00010u 138 139 140 /* Define HUB Class other constants. */ 141 142 #define UX_HOST_CLASS_HUB_ENABLE_RETRY_COUNT 3 143 #define UX_HOST_CLASS_HUB_ENABLE_RETRY_DELAY 100 144 #define UX_HOST_CLASS_HUB_ENUMERATION_RETRY 3 145 #define UX_HOST_CLASS_HUB_ENUMERATION_DEBOUNCE_DELAY 100 146 #define UX_HOST_CLASS_HUB_ENUMERATION_RESET_RECOVERY_DELAY 10 147 #define UX_HOST_CLASS_HUB_ENUMERATION_RETRY_DELAY 300 148 149 150 /* Define HUB Descriptor. */ 151 #define UX_HUB_DESCRIPTOR_ENTRIES 8 152 #define UX_HUB_DESCRIPTOR_LENGTH 9 153 154 /* Define HUB Class structure. */ 155 156 #define UX_MAX_HUB_PORTS 15 157 158 159 /* Define HUB state machine states. */ 160 161 #define UX_HOST_CLASS_HUB_ENUM_GET_STATUS (UX_STATE_STEP + 0) 162 #define UX_HOST_CLASS_HUB_ENUM_POWER_CHECK (UX_STATE_STEP + 1) 163 #define UX_HOST_CLASS_HUB_ENUM_SET_CONFIG (UX_STATE_STEP + 2) 164 #define UX_HOST_CLASS_HUB_ENUM_SET_CONFIG_DONE (UX_STATE_STEP + 3) 165 #define UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC (UX_STATE_STEP + 4) 166 #define UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC_DONE (UX_STATE_STEP + 5) 167 #define UX_HOST_CLASS_HUB_ENUM_PORT_POWER (UX_STATE_STEP + 6) 168 #define UX_HOST_CLASS_HUB_ENUM_PORT_POWER_DELAY (UX_STATE_STEP + 7) 169 #define UX_HOST_CLASS_HUB_ENUM_PORT_POWER_ON (UX_STATE_STEP + 8) 170 #define UX_HOST_CLASS_HUB_ENUM_PORT_NEXT (UX_STATE_STEP + 9) 171 #define UX_HOST_CLASS_HUB_ENUM_INTERRUPT_START (UX_STATE_STEP + 10) 172 #define UX_HOST_CLASS_HUB_ENUM_DONE (UX_STATE_STEP + 11) 173 #define UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT (UX_STATE_STEP + 12) 174 #define UX_HOST_CLASS_HUB_ENUM_DELAY_WAIT (UX_STATE_STEP + 13) 175 176 #define UX_HOST_CLASS_HUB_CHANGE_CHECK (UX_STATE_STEP + 0) 177 #define UX_HOST_CLASS_HUB_CHANGE_NEXT (UX_STATE_STEP + 1) 178 #define UX_HOST_CLASS_HUB_RESET (UX_STATE_STEP + 2) 179 #define UX_HOST_CLASS_HUB_STATUS_GET (UX_STATE_STEP + 3) 180 #define UX_HOST_CLASS_HUB_STATUS_GET_DONE (UX_STATE_STEP + 4) 181 #define UX_HOST_CLASS_HUB_STATUS_PROCESS (UX_STATE_STEP + 5) 182 #define UX_HOST_CLASS_HUB_RESET_PROCESS (UX_STATE_STEP + 6) 183 #define UX_HOST_CLASS_HUB_CONNECT_PROCESS (UX_STATE_STEP + 7) 184 #define UX_HOST_CLASS_HUB_DISC_DISABLED (UX_STATE_STEP + 8) 185 #define UX_HOST_CLASS_HUB_DISC_CLEAR_1 (UX_STATE_STEP + 9) 186 #define UX_HOST_CLASS_HUB_TRANS_WAIT (UX_STATE_STEP + 10) 187 #define UX_HOST_CLASS_HUB_DELAY_WAIT (UX_STATE_STEP + 11) 188 189 190 typedef struct UX_HUB_DESCRIPTOR_STRUCT 191 { 192 193 UCHAR bLength; 194 UCHAR bDescriptorType; 195 UCHAR bNbPorts; 196 UCHAR _align_wHubCharacteristics[1]; 197 USHORT wHubCharacteristics; 198 UCHAR bPwrOn2PwrGood; 199 UCHAR bHubContrCurrent; 200 UCHAR bDeviceRemovable; 201 UCHAR bPortPwrCtrlMask; 202 UCHAR _align_size[2]; 203 } UX_HUB_DESCRIPTOR; 204 205 206 /* Define HUB Class instance structure. */ 207 208 typedef struct UX_HOST_CLASS_HUB_STRUCT 209 { 210 211 struct UX_HOST_CLASS_HUB_STRUCT 212 *ux_host_class_hub_next_instance; 213 UX_HOST_CLASS *ux_host_class_hub_class; 214 UX_DEVICE *ux_host_class_hub_device; 215 UX_ENDPOINT *ux_host_class_hub_interrupt_endpoint; 216 UX_INTERFACE *ux_host_class_hub_interface; 217 UINT ux_host_class_hub_instance_status; 218 UINT ux_host_class_hub_state; 219 UINT ux_host_class_hub_change_semaphore; 220 struct UX_HUB_DESCRIPTOR_STRUCT 221 ux_host_class_hub_descriptor; 222 UINT ux_host_class_hub_port_state; 223 UINT ux_host_class_hub_port_power; 224 225 #if defined(UX_HOST_STANDALONE) 226 UINT ux_host_class_hub_run_status; 227 UCHAR *ux_host_class_hub_allocated; 228 UX_TRANSFER *ux_host_class_hub_transfer; 229 230 USHORT ux_host_class_hub_run_port_change; 231 USHORT ux_host_class_hub_run_port_status; 232 233 ULONG ux_host_class_hub_wait_start; 234 ULONG ux_host_class_hub_wait_ms; 235 236 UCHAR ux_host_class_hub_enum_state; 237 UCHAR ux_host_class_hub_run_state; 238 UCHAR ux_host_class_hub_next_state; 239 UCHAR ux_host_class_hub_run_port; 240 #endif 241 } UX_HOST_CLASS_HUB; 242 243 244 /* Define HUB Class function prototypes. */ 245 246 UINT _ux_host_class_hub_activate(UX_HOST_CLASS_COMMAND *command); 247 VOID _ux_host_class_hub_change_detect(VOID); 248 UINT _ux_host_class_hub_change_process(UX_HOST_CLASS_HUB *hub); 249 UINT _ux_host_class_hub_configure(UX_HOST_CLASS_HUB *hub); 250 UINT _ux_host_class_hub_deactivate(UX_HOST_CLASS_COMMAND *command); 251 UINT _ux_host_class_hub_descriptor_get(UX_HOST_CLASS_HUB *hub); 252 UINT _ux_host_class_hub_entry(UX_HOST_CLASS_COMMAND *command); 253 UINT _ux_host_class_hub_feature(UX_HOST_CLASS_HUB *hub, UINT port, UINT command, UINT function); 254 UINT _ux_host_class_hub_hub_change_process(UX_HOST_CLASS_HUB *hub); 255 UINT _ux_host_class_hub_interrupt_endpoint_start(UX_HOST_CLASS_HUB *hub); 256 VOID _ux_host_class_hub_port_change_connection_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status); 257 VOID _ux_host_class_hub_port_change_enable_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status); 258 VOID _ux_host_class_hub_port_change_over_current_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status); 259 UINT _ux_host_class_hub_port_change_process(UX_HOST_CLASS_HUB *hub, UINT port); 260 VOID _ux_host_class_hub_port_change_reset_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status); 261 VOID _ux_host_class_hub_port_change_suspend_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status); 262 UINT _ux_host_class_hub_port_reset(UX_HOST_CLASS_HUB *hub, UINT port); 263 UINT _ux_host_class_hub_ports_power(UX_HOST_CLASS_HUB *hub); 264 UINT _ux_host_class_hub_status_get(UX_HOST_CLASS_HUB *hub, UINT port, USHORT *port_status, USHORT *port_change); 265 VOID _ux_host_class_hub_transfer_request_completed(UX_TRANSFER *transfer_request); 266 267 UINT _ux_host_class_hub_tasks_run(UX_HOST_CLASS *hub_class); 268 269 /* Determine if a C++ compiler is being used. If so, complete the standard 270 C conditional started above. */ 271 #ifdef __cplusplus 272 } 273 #endif 274 275 #endif 276 277