Changeset e50cd7f in mainline for uspace/drv/usbhub/usbhub.c
- Timestamp:
- 2011-04-17T19:17:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63517c2, cfbbe1d3
- Parents:
- ef354b6 (diff), 8595577b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
ref354b6 re50cd7f 37 37 #include <errno.h> 38 38 #include <str_error.h> 39 #include <inttypes.h> 39 40 40 41 #include <usb_iface.h> … … 44 45 #include <usb/request.h> 45 46 #include <usb/classes/hub.h> 47 #include <usb/devpoll.h> 46 48 #include <stdio.h> 47 49 … … 53 55 #include "usb/classes/classes.h" 54 56 55 static int usb_hub_trigger_connecting_non_removable_devices( 56 usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor); 57 57 58 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev); 59 60 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info); 61 62 static int usb_hub_set_configuration(usb_hub_info_t * hub_info); 63 64 static int usb_hub_start_hub_fibril(usb_hub_info_t * hub_info); 65 66 static int usb_process_hub_over_current(usb_hub_info_t * hub_info, 67 usb_hub_status_t status); 68 69 static int usb_process_hub_power_change(usb_hub_info_t * hub_info, 70 usb_hub_status_t status); 71 72 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info); 73 74 75 /// \TODO malloc checking 58 76 59 77 //********************************************* 60 78 // 61 79 // hub driver code, initialization 80 // 81 //********************************************* 82 83 /** 84 * Initialize hub device driver fibril 85 * 86 * Creates hub representation and fibril that periodically checks hub`s status. 87 * Hub representation is passed to the fibril. 88 * @param usb_dev generic usb device information 89 * @return error code 90 */ 91 int usb_hub_add_device(usb_device_t * usb_dev) { 92 if (!usb_dev) return EINVAL; 93 usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev); 94 //create hc connection 95 usb_log_debug("Initializing USB wire abstraction.\n"); 96 int opResult = usb_hc_connection_initialize_from_device( 97 &hub_info->connection, 98 hub_info->usb_device->ddf_dev); 99 if (opResult != EOK) { 100 usb_log_error("could not initialize connection to device, " 101 "errno %d\n", 102 opResult); 103 free(hub_info); 104 return opResult; 105 } 106 107 //usb_pipe_start_session(hub_info->control_pipe); 108 //set hub configuration 109 opResult = usb_hub_set_configuration(hub_info); 110 if (opResult != EOK) { 111 usb_log_error("could not set hub configuration, errno %d\n", 112 opResult); 113 free(hub_info); 114 return opResult; 115 } 116 //get port count and create attached_devs 117 opResult = usb_hub_process_hub_specific_info(hub_info); 118 if (opResult != EOK) { 119 usb_log_error("could process hub specific info, errno %d\n", 120 opResult); 121 free(hub_info); 122 return opResult; 123 } 124 //usb_pipe_end_session(hub_info->control_pipe); 125 126 127 usb_log_debug("Creating 'hub' function in DDF.\n"); 128 ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev, 129 fun_exposed, "hub"); 130 assert(hub_fun != NULL); 131 hub_fun->ops = NULL; 132 133 opResult = ddf_fun_bind(hub_fun); 134 assert(opResult == EOK); 135 opResult = ddf_fun_add_to_class(hub_fun, "hub"); 136 assert(opResult == EOK); 137 138 opResult = usb_hub_start_hub_fibril(hub_info); 139 if(opResult!=EOK) 140 free(hub_info); 141 return opResult; 142 } 143 144 145 /** Callback for polling hub for changes. 146 * 147 * @param dev Device where the change occured. 148 * @param change_bitmap Bitmap of changed ports. 149 * @param change_bitmap_size Size of the bitmap in bytes. 150 * @param arg Custom argument, points to @c usb_hub_info_t. 151 * @return Whether to continue polling. 152 */ 153 bool hub_port_changes_callback(usb_device_t *dev, 154 uint8_t *change_bitmap, size_t change_bitmap_size, void *arg) { 155 usb_log_debug("hub_port_changes_callback\n"); 156 usb_hub_info_t *hub = (usb_hub_info_t *) arg; 157 158 /* FIXME: check that we received enough bytes. */ 159 if (change_bitmap_size == 0) { 160 goto leave; 161 } 162 163 bool change; 164 change = ((uint8_t*) change_bitmap)[0] & 1; 165 if (change) { 166 usb_hub_process_global_interrupt(hub); 167 } 168 169 size_t port; 170 for (port = 1; port < hub->port_count + 1; port++) { 171 bool change = (change_bitmap[port / 8] >> (port % 8)) % 2; 172 if (change) { 173 usb_hub_process_interrupt(hub, port); 174 } 175 } 176 leave: 177 /* FIXME: proper interval. */ 178 async_usleep(1000 * 1000 * 10); 179 180 return true; 181 } 182 183 184 //********************************************* 185 // 186 // support functions 62 187 // 63 188 //********************************************* … … 71 196 */ 72 197 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) { 73 usb_hub_info_t * result = usb_new(usb_hub_info_t);74 if (!result) return NULL;198 usb_hub_info_t * result = malloc(sizeof(usb_hub_info_t)); 199 if (!result) return NULL; 75 200 result->usb_device = usb_dev; 76 201 result->status_change_pipe = usb_dev->pipes[0].pipe; … … 90 215 * @return error code 91 216 */ 92 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info) {217 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info) { 93 218 // get hub descriptor 94 219 usb_log_debug("creating serialized descriptor\n"); 95 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE); 220 //void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE); 221 uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE]; 96 222 usb_hub_descriptor_t * descriptor; 97 98 /* this was one fix of some bug, should not be needed anymore 99 * these lines allow to reset hub once more, it can be used as 100 * brute-force initialization for non-removable devices 101 int opResult = usb_request_set_configuration(&result->endpoints.control, 1); 102 if(opResult!=EOK){ 103 usb_log_error("could not set default configuration, errno %d",opResult); 104 return opResult; 105 } 106 */ 223 int opResult; 224 107 225 size_t received_size; 108 int opResult = usb_request_get_descriptor(&hub_info->usb_device->ctrl_pipe,109 110 USB_DESCTYPE_HUB,111 0, 0, serialized_descriptor,112 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 113 114 if (opResult != EOK) {115 usb_log_error("failed when receiving hub descriptor,badcode = %d\n",116 226 opResult = usb_request_get_descriptor(hub_info->control_pipe, 227 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, 228 USB_DESCTYPE_HUB, 0, 0, serialized_descriptor, 229 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 230 231 if (opResult != EOK) { 232 usb_log_error("failed when receiving hub descriptor, " 233 "badcode = %d\n", 234 opResult); 117 235 free(serialized_descriptor); 118 236 return opResult; 119 237 } 120 238 usb_log_debug2("deserializing descriptor\n"); 121 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor); 122 if(descriptor==NULL){ 239 descriptor = usb_create_deserialized_hub_desriptor( 240 serialized_descriptor); 241 if (descriptor == NULL) { 123 242 usb_log_warning("could not deserialize descriptor \n"); 124 return opResult;125 } 126 usb_log_debug("setting port count to %d\n", descriptor->ports_count);243 return ENOMEM; 244 } 245 usb_log_debug("setting port count to %d\n", descriptor->ports_count); 127 246 hub_info->port_count = descriptor->ports_count; 128 hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1)); 247 /// \TODO this is not semantically correct 248 bool is_power_switched = 249 ((descriptor->hub_characteristics & 1) ==0); 250 bool has_individual_port_powering = 251 ((descriptor->hub_characteristics & 1) !=0); 252 hub_info->ports = malloc( 253 sizeof (usb_hub_port_t) * (hub_info->port_count + 1)); 129 254 size_t port; 130 255 for (port = 0; port < hub_info->port_count + 1; port++) { 131 256 usb_hub_port_init(&hub_info->ports[port]); 132 257 } 133 //handle non-removable devices 134 usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor); 258 if(is_power_switched){ 259 usb_log_debug("is_power_switched\n"); 260 if(has_individual_port_powering){ 261 usb_log_debug("has_individual_port_powering\n"); 262 for (port = 0; port < hub_info->port_count; port++) { 263 opResult = usb_hub_set_port_feature(hub_info->control_pipe, 264 port+1, USB_HUB_FEATURE_PORT_POWER); 265 if (opResult != EOK) { 266 usb_log_error("cannot power on port %d; %d\n", 267 port+1, opResult); 268 } 269 } 270 }else{ 271 usb_log_debug("!has_individual_port_powering\n"); 272 opResult = usb_hub_set_feature(hub_info->control_pipe, 273 USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 274 if (opResult != EOK) { 275 usb_log_error("cannot power hub; %d\n", 276 opResult); 277 } 278 } 279 }else{ 280 usb_log_debug("!is_power_switched\n"); 281 } 135 282 usb_log_debug2("freeing data\n"); 136 free(serialized_descriptor);137 free(descriptor->devices_removable);283 //free(serialized_descriptor); 284 //free(descriptor->devices_removable); 138 285 free(descriptor); 139 286 return EOK; 140 287 } 288 141 289 /** 142 290 * Set configuration of hub … … 147 295 * @return error code 148 296 */ 149 static int usb_hub_set_configuration(usb_hub_info_t * hub_info) {297 static int usb_hub_set_configuration(usb_hub_info_t * hub_info) { 150 298 //device descriptor 151 299 usb_standard_device_descriptor_t *std_descriptor … … 153 301 usb_log_debug("hub has %d configurations\n", 154 302 std_descriptor->configuration_count); 155 if (std_descriptor->configuration_count<1){303 if (std_descriptor->configuration_count < 1) { 156 304 usb_log_error("there are no configurations available\n"); 157 305 return EINVAL; … … 173 321 } 174 322 usb_log_debug("\tused configuration %d\n", 175 323 config_descriptor->configuration_number); 176 324 177 325 return EOK; … … 179 327 180 328 /** 181 * Initialize hub device driver fibril 182 * 183 * Creates hub representation and fibril that periodically checks hub`s status. 184 * Hub representation is passed to the fibril. 185 * @param usb_dev generic usb device information 186 * @return error code 187 */ 188 int usb_hub_add_device(usb_device_t * usb_dev){ 189 if(!usb_dev) return EINVAL; 190 usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev); 191 //create hc connection 192 usb_log_debug("Initializing USB wire abstraction.\n"); 193 int opResult = usb_hc_connection_initialize_from_device( 194 &hub_info->connection, 195 hub_info->usb_device->ddf_dev); 196 if(opResult != EOK){ 197 usb_log_error("could not initialize connection to device, errno %d\n", 198 opResult); 199 free(hub_info); 200 return opResult; 201 } 202 203 usb_pipe_start_session(hub_info->control_pipe); 204 //set hub configuration 205 opResult = usb_hub_set_configuration(hub_info); 206 if(opResult!=EOK){ 207 usb_log_error("could not set hub configuration, errno %d\n",opResult); 208 free(hub_info); 209 return opResult; 210 } 211 //get port count and create attached_devs 212 opResult = usb_hub_process_hub_specific_info(hub_info); 213 if(opResult!=EOK){ 214 usb_log_error("could not set hub configuration, errno %d\n",opResult); 215 free(hub_info); 216 return opResult; 217 } 218 usb_pipe_end_session(hub_info->control_pipe); 219 220 221 /// \TODO what is this? 222 usb_log_debug("Creating `hub' function.\n"); 223 ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev, 224 fun_exposed, "hub"); 225 assert(hub_fun != NULL); 226 hub_fun->ops = NULL; 227 228 int rc = ddf_fun_bind(hub_fun); 229 assert(rc == EOK); 230 rc = ddf_fun_add_to_class(hub_fun, "hub"); 231 assert(rc == EOK); 232 329 * create and start fibril with hub control loop 330 * 331 * Before the fibril is started, the control pipe and host controller 332 * connection of the hub is open. 333 * 334 * @param hub_info hub representing structure 335 * @return error code 336 */ 337 static int usb_hub_start_hub_fibril(usb_hub_info_t * hub_info){ 233 338 /* 234 339 * The processing will require opened control pipe and connection … … 239 344 * auto destruction, this could work better. 240 345 */ 241 rc = usb_pipe_start_session(&usb_dev->ctrl_pipe);346 int rc = usb_hc_connection_open(&hub_info->connection); 242 347 if (rc != EOK) { 243 usb_log_error("Failed to start session on control pipe: %s.\n", 244 str_error(rc)); 245 goto leave; 246 } 247 rc = usb_hc_connection_open(&hub_info->connection); 248 if (rc != EOK) { 249 usb_pipe_end_session(&usb_dev->ctrl_pipe); 348 //usb_pipe_end_session(hub_info->control_pipe); 250 349 usb_log_error("Failed to open connection to HC: %s.\n", 251 350 str_error(rc)); 252 goto leave;351 return rc; 253 352 } 254 353 255 354 rc = usb_device_auto_poll(hub_info->usb_device, 0, 256 hub_port_changes_callback, ((hub_info->port_count +1) / 8) + 1,355 hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1, 257 356 NULL, hub_info); 258 357 if (rc != EOK) { … … 266 365 hub_info->usb_device->ddf_dev->name, hub_info->port_count); 267 366 return EOK; 268 269 leave: 270 free(hub_info); 271 272 return rc; 273 } 274 275 276 //********************************************* 277 // 278 // hub driver code, main loop and port handling 279 // 280 //********************************************* 281 282 /** 283 * triggers actions to connect non0removable devices 284 * 285 * This will trigger operations leading to activated non-removable device. 286 * Control pipe of the hub must be open fo communication. 287 * @param hub hub representation 288 * @param descriptor usb hub descriptor 289 * @return error code 290 */ 291 static int usb_hub_trigger_connecting_non_removable_devices(usb_hub_info_t * hub, 292 usb_hub_descriptor_t * descriptor) 293 { 294 usb_log_info("attaching non-removable devices(if any)\n"); 367 } 368 369 //********************************************* 370 // 371 // change handling functions 372 // 373 //********************************************* 374 375 376 /** 377 * process hub over current change 378 * 379 * This means either to power off the hub or power it on. 380 * @param hub_info hub instance 381 * @param status hub status bitmask 382 * @return error code 383 */ 384 static int usb_process_hub_over_current(usb_hub_info_t * hub_info, 385 usb_hub_status_t status) { 386 int opResult; 387 if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_OVER_CURRENT)){ 388 opResult = usb_hub_clear_feature(hub_info->control_pipe, 389 USB_HUB_FEATURE_HUB_LOCAL_POWER); 390 if (opResult != EOK) { 391 usb_log_error("cannot power off hub: %d\n", 392 opResult); 393 } 394 } else { 395 opResult = usb_hub_set_feature(hub_info->control_pipe, 396 USB_HUB_FEATURE_HUB_LOCAL_POWER); 397 if (opResult != EOK) { 398 usb_log_error("cannot power on hub: %d\n", 399 opResult); 400 } 401 } 402 return opResult; 403 } 404 405 /** 406 * process hub power change 407 * 408 * If the power has been lost, reestablish it. 409 * If it was reestablished, re-power all ports. 410 * @param hub_info hub instance 411 * @param status hub status bitmask 412 * @return error code 413 */ 414 static int usb_process_hub_power_change(usb_hub_info_t * hub_info, 415 usb_hub_status_t status) { 416 int opResult; 417 if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) { 418 //restart power on hub 419 opResult = usb_hub_set_feature(hub_info->control_pipe, 420 USB_HUB_FEATURE_HUB_LOCAL_POWER); 421 if (opResult != EOK) { 422 usb_log_error("cannot power on hub: %d\n", 423 opResult); 424 } 425 } else {//power reestablished on hub- restart ports 426 size_t port; 427 for (port = 0; port < hub_info->port_count; ++port) { 428 opResult = usb_hub_set_port_feature( 429 hub_info->control_pipe, 430 port, USB_HUB_FEATURE_PORT_POWER); 431 if (opResult != EOK) { 432 usb_log_error("cannot power on port %d; %d\n", 433 port, opResult); 434 } 435 } 436 } 437 return opResult; 438 } 439 440 /** 441 * process hub interrupts 442 * 443 * The change can be either in the over-current condition or 444 * local-power lost condition. 445 * @param hub_info hub instance 446 */ 447 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info) { 448 usb_log_debug("global interrupt on a hub\n"); 449 usb_pipe_t *pipe = hub_info->control_pipe; 450 int opResult; 451 452 usb_port_status_t status; 453 size_t rcvd_size; 295 454 usb_device_request_setup_packet_t request; 296 int opResult; 297 size_t rcvd_size; 298 usb_port_status_t status; 299 uint8_t * non_removable_dev_bitmap = descriptor->devices_removable; 300 int port; 301 for(port=1;port<=descriptor->ports_count;++port){ 302 bool is_non_removable = 303 ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2; 304 if(is_non_removable){ 305 usb_log_debug("non-removable device on port %d\n",port); 306 usb_hub_set_port_status_request(&request, port); 307 opResult = usb_pipe_control_read( 308 hub->control_pipe, 309 &request, sizeof(usb_device_request_setup_packet_t), 310 &status, 4, &rcvd_size 311 ); 312 if (opResult != EOK) { 313 usb_log_error("could not get port status of port %d errno:%d\n", 314 port, opResult); 315 return opResult; 316 } 317 //set the status change bit, so it will be noticed in driver loop 318 if(usb_port_dev_connected(&status)){ 319 usb_hub_set_disable_port_feature_request(&request, port, 320 USB_HUB_FEATURE_PORT_CONNECTION); 321 opResult = usb_pipe_control_read( 322 hub->control_pipe, 323 &request, sizeof(usb_device_request_setup_packet_t), 324 &status, 4, &rcvd_size 325 ); 326 if (opResult != EOK) { 327 usb_log_warning( 328 "could not clear port connection on port %d errno:%d\n", 329 port, opResult); 330 } 331 usb_log_debug("cleared port connection\n"); 332 usb_hub_set_enable_port_feature_request(&request, port, 333 USB_HUB_FEATURE_PORT_ENABLE); 334 opResult = usb_pipe_control_read( 335 hub->control_pipe, 336 &request, sizeof(usb_device_request_setup_packet_t), 337 &status, 4, &rcvd_size 338 ); 339 if (opResult != EOK) { 340 usb_log_warning( 341 "could not set port enabled on port %d errno:%d\n", 342 port, opResult); 343 } 344 usb_log_debug("port set to enabled - should lead to connection change\n"); 345 } 346 } 347 } 348 /// \TODO this is just a debug code 349 for(port=1;port<=descriptor->ports_count;++port){ 350 bool is_non_removable = 351 ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2; 352 if(is_non_removable){ 353 usb_log_debug("port %d is non-removable\n",port); 354 usb_port_status_t status; 355 size_t rcvd_size; 356 usb_device_request_setup_packet_t request; 357 //int opResult; 358 usb_hub_set_port_status_request(&request, port); 359 //endpoint 0 360 opResult = usb_pipe_control_read( 361 hub->control_pipe, 362 &request, sizeof(usb_device_request_setup_packet_t), 363 &status, 4, &rcvd_size 364 ); 365 if (opResult != EOK) { 366 usb_log_error("could not get port status %d\n",opResult); 367 } 368 if (rcvd_size != sizeof (usb_port_status_t)) { 369 usb_log_error("received status has incorrect size\n"); 370 } 371 //something connected/disconnected 372 if (usb_port_connect_change(&status)) { 373 usb_log_debug("some connection changed\n"); 374 } 375 usb_log_debug("status: %s\n",usb_debug_str_buffer( 376 (uint8_t *)&status,4,4)); 377 } 378 } 379 return EOK; 380 } 381 382 383 /** 384 * release default address used by given hub 385 * 386 * Also unsets hub->is_default_address_used. Convenience wrapper function. 387 * @note hub->connection MUST be open for communication 388 * @param hub hub representation 389 * @return error code 390 */ 391 static int usb_hub_release_default_address(usb_hub_info_t * hub){ 392 int opResult = usb_hc_release_default_address(&hub->connection); 393 if(opResult!=EOK){ 394 usb_log_error("could not release default address, errno %d\n",opResult); 395 return opResult; 396 } 397 hub->is_default_address_used = false; 398 return EOK; 399 } 400 401 /** 402 * routine called when a device on port has been removed 403 * 404 * If the device on port had default address, it releases default address. 405 * Otherwise does not do anything, because DDF does not allow to remove device 406 * from it`s device tree. 407 * @param hub hub representation 408 * @param port port number, starting from 1 409 */ 410 void usb_hub_removed_device( 411 usb_hub_info_t * hub,uint16_t port) { 412 413 int opResult = usb_hub_clear_port_feature(hub->control_pipe, 414 port, USB_HUB_FEATURE_C_PORT_CONNECTION); 415 if(opResult != EOK){ 416 usb_log_warning("could not clear port-change-connection flag\n"); 417 } 418 /** \TODO remove device from device manager - not yet implemented in 419 * devide manager 420 */ 421 422 //close address 423 if(hub->ports[port].attached_device.address >= 0){ 424 /*uncomment this code to use it when DDF allows device removal 425 opResult = usb_hc_unregister_device( 426 &hub->connection, hub->attached_devs[port].address); 427 if(opResult != EOK) { 428 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \ 429 "removed device: %d", opResult); 430 } 431 hub->attached_devs[port].address = 0; 432 hub->attached_devs[port].handle = 0; 433 */ 434 }else{ 435 usb_log_warning("this is strange, disconnected device had no address\n"); 436 //device was disconnected before it`s port was reset - return default address 437 usb_hub_release_default_address(hub); 438 } 439 } 440 441 442 /** 443 * Process over current condition on port. 444 * 445 * Turn off the power on the port. 446 * 447 * @param hub hub representation 448 * @param port port number, starting from 1 449 */ 450 void usb_hub_over_current( usb_hub_info_t * hub, 451 uint16_t port){ 452 int opResult; 453 opResult = usb_hub_clear_port_feature(hub->control_pipe, 454 port, USB_HUB_FEATURE_PORT_POWER); 455 if(opResult!=EOK){ 456 usb_log_error("cannot power off port %d; %d\n", 457 port, opResult); 458 } 459 } 460 455 //int opResult; 456 usb_hub_set_hub_status_request(&request); 457 //endpoint 0 458 459 opResult = usb_pipe_control_read( 460 pipe, 461 &request, sizeof (usb_device_request_setup_packet_t), 462 &status, 4, &rcvd_size 463 ); 464 if (opResult != EOK) { 465 usb_log_error("could not get hub status\n"); 466 return; 467 } 468 if (rcvd_size != sizeof (usb_port_status_t)) { 469 usb_log_error("received status has incorrect size\n"); 470 return; 471 } 472 //port reset 473 if ( 474 usb_hub_is_status(status,16+USB_HUB_FEATURE_C_HUB_OVER_CURRENT)) { 475 usb_process_hub_over_current(hub_info, status); 476 } 477 if ( 478 usb_hub_is_status(status,16+USB_HUB_FEATURE_C_HUB_LOCAL_POWER)) { 479 usb_process_hub_power_change(hub_info, status); 480 } 481 } 461 482 462 483 /**
Note:
See TracChangeset
for help on using the changeset viewer.