Changes in uspace/drv/bus/usb/usbhub/usbhub.c [fab2746:58563585] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhub/usbhub.c
rfab2746 r58563585 27 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 */ 29 29 30 /** @addtogroup drvusbhub 30 31 * @{ … … 45 46 #include <usb/dev/pipes.h> 46 47 #include <usb/classes/classes.h> 47 #include <usb/ddfiface.h>48 48 #include <usb/descriptor.h> 49 49 #include <usb/dev/recognise.h> … … 57 57 58 58 #define HUB_FNC_NAME "hub" 59 60 /** Hub status-change endpoint description. 61 * 62 * For more information see section 11.15.1 of USB 1.1 specification. 63 */ 64 const usb_endpoint_description_t hub_status_change_endpoint_description = 65 { 66 .transfer_type = USB_TRANSFER_INTERRUPT, 67 .direction = USB_DIRECTION_IN, 68 .interface_class = USB_CLASS_HUB, 69 .interface_subclass = 0, 70 .interface_protocol = 0, 71 .flags = 0 72 }; 59 73 60 74 /** Standard get hub global status request */ … … 99 113 fibril_condvar_initialize(&hub_dev->pending_ops_cv); 100 114 101 102 int opResult = usb_pipe_start_long_transfer(&usb_dev->ctrl_pipe);103 if (opResult != EOK) {104 usb_log_error("Failed to start long ctrl pipe transfer: %s\n",105 str_error(opResult));106 return opResult;107 }108 109 115 /* Set hub's first configuration. (There should be only one) */ 110 opResult = usb_set_first_configuration(usb_dev); 111 if (opResult != EOK) { 112 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe); 116 int opResult = usb_set_first_configuration(usb_dev); 117 if (opResult != EOK) { 113 118 usb_log_error("Could not set hub configuration: %s\n", 114 119 str_error(opResult)); … … 119 124 opResult = usb_hub_process_hub_specific_info(hub_dev); 120 125 if (opResult != EOK) { 121 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);122 126 usb_log_error("Could process hub specific info, %s\n", 123 127 str_error(opResult)); … … 127 131 /* Create hub control function. */ 128 132 usb_log_debug("Creating DDF function '" HUB_FNC_NAME "'.\n"); 129 hub_dev->hub_fun = ddf_fun_create(hub_dev->usb_device->ddf_dev,133 hub_dev->hub_fun = usb_device_ddf_fun_create(hub_dev->usb_device, 130 134 fun_exposed, HUB_FNC_NAME); 131 135 if (hub_dev->hub_fun == NULL) { 132 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);133 136 usb_log_error("Failed to create hub function.\n"); 134 137 return ENOMEM; … … 138 141 opResult = ddf_fun_bind(hub_dev->hub_fun); 139 142 if (opResult != EOK) { 140 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);141 143 usb_log_error("Failed to bind hub function: %s.\n", 142 144 str_error(opResult)); … … 146 148 147 149 /* Start hub operation. */ 148 opResult = usb_device_auto_poll (hub_dev->usb_device, 0,149 hub_port_changes_callback, ((hub_dev->port_count + 1 + 8) / 8),150 usb_hub_polling_terminated_callback, hub_dev);151 if (opResult != EOK) {152 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);150 opResult = usb_device_auto_poll_desc(hub_dev->usb_device, 151 &hub_status_change_endpoint_description, 152 hub_port_changes_callback, ((hub_dev->port_count + 1 + 7) / 8), 153 -1, usb_hub_polling_terminated_callback, hub_dev); 154 if (opResult != EOK) { 153 155 /* Function is already bound */ 154 156 ddf_fun_unbind(hub_dev->hub_fun); … … 159 161 } 160 162 hub_dev->running = true; 161 usb_log_info("Controlling hub '%s' (% zu ports).\n",162 ddf_dev_get_name(hub_dev->usb_device->ddf_dev), hub_dev->port_count);163 164 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe); 163 usb_log_info("Controlling hub '%s' (%p: %zu ports).\n", 164 usb_device_get_name(hub_dev->usb_device), hub_dev, 165 hub_dev->port_count); 166 165 167 return EOK; 166 168 } … … 185 187 { 186 188 assert(usb_dev); 187 usb_hub_dev_t *hub = usb_dev ->driver_data;189 usb_hub_dev_t *hub = usb_device_data_get(usb_dev); 188 190 assert(hub); 189 191 unsigned tries = 10; … … 191 193 async_usleep(100000); 192 194 if (!tries--) { 193 usb_log_error("Can't remove hub, still running.\n"); 195 usb_log_error("(%p): Can't remove hub, still running.", 196 hub); 194 197 return EBUSY; 195 198 } … … 199 202 200 203 for (size_t port = 0; port < hub->port_count; ++port) { 201 if (hub->ports[port].attached_device.fun) { 202 const int ret = 203 usb_hub_port_fini(&hub->ports[port], hub); 204 if (ret != EOK) 205 return ret; 206 } 204 const int ret = usb_hub_port_fini(&hub->ports[port], hub); 205 if (ret != EOK) 206 return ret; 207 207 } 208 208 free(hub->ports); … … 210 210 const int ret = ddf_fun_unbind(hub->hub_fun); 211 211 if (ret != EOK) { 212 usb_log_error(" Failed to unbind '%s' function: %s.\n",213 HUB_FNC_NAME, str_error(ret));212 usb_log_error("(%p) Failed to unbind '%s' function: %s.", 213 hub, HUB_FNC_NAME, str_error(ret)); 214 214 return ret; 215 215 } 216 216 ddf_fun_destroy(hub->hub_fun); 217 217 218 usb_log_info(" USB hub driver, stopped and cleaned.\n");218 usb_log_info("(%p) USB hub driver stopped and cleaned.", hub); 219 219 return EOK; 220 220 } … … 231 231 uint8_t *change_bitmap, size_t change_bitmap_size, void *arg) 232 232 { 233 usb_log_debug("hub_port_changes_callback\n");234 233 usb_hub_dev_t *hub = arg; 235 234 assert(hub); … … 247 246 248 247 /* N + 1 bit indicates change on port N */ 249 for (size_t port = 0; port < hub->port_count + 1; port++) {248 for (size_t port = 0; port < hub->port_count; ++port) { 250 249 const size_t bit = port + 1; 251 250 const bool change = (change_bitmap[bit / 8] >> (bit % 8)) & 1; … … 272 271 273 272 /* Get hub descriptor. */ 274 usb_log_debug("Retrieving descriptor\n"); 275 usb_pipe_t *control_pipe = &hub_dev->usb_device->ctrl_pipe; 273 usb_log_debug("(%p): Retrieving descriptor.", hub_dev); 274 usb_pipe_t *control_pipe = 275 usb_device_get_default_pipe(hub_dev->usb_device); 276 276 277 277 usb_hub_descriptor_header_t descriptor; … … 282 282 sizeof(usb_hub_descriptor_header_t), &received_size); 283 283 if (opResult != EOK) { 284 usb_log_error(" Failed to receive hub descriptor: %s.\n",285 str_error(opResult));284 usb_log_error("(%p): Failed to receive hub descriptor: %s.\n", 285 hub_dev, str_error(opResult)); 286 286 return opResult; 287 287 } 288 288 289 usb_log_debug("Setting port count to %d.\n", descriptor.port_count); 289 usb_log_debug("(%p): Setting port count to %d.\n", hub_dev, 290 descriptor.port_count); 290 291 hub_dev->port_count = descriptor.port_count; 291 292 … … 306 307 307 308 if (!hub_dev->power_switched) { 308 usb_log_info( 309 "Power switching not supported, ports always powered.\n");309 usb_log_info("(%p): Power switching not supported, " 310 "ports always powered.", hub_dev); 310 311 return EOK; 311 312 } 312 313 313 usb_log_info("Hub port power switching enabled.\n"); 314 315 for (size_t port = 0; port < hub_dev->port_count; ++port) { 316 usb_log_debug("Powering port %zu.\n", port); 314 usb_log_info("(%p): Hub port power switching enabled (%s).\n", hub_dev, 315 hub_dev->per_port_power ? "per port" : "ganged"); 316 317 for (unsigned int port = 0; port < hub_dev->port_count; ++port) { 318 usb_log_debug("(%p): Powering port %u.", hub_dev, port); 317 319 const int ret = usb_hub_port_set_feature( 318 320 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 319 321 320 322 if (ret != EOK) { 321 usb_log_error("Cannot power on port %zu: %s.\n", 322 hub_dev->ports[port].port_number, str_error(ret)); 323 usb_log_error("(%p-%u): Cannot power on port: %s.\n", 324 hub_dev, hub_dev->ports[port].port_number, 325 str_error(ret)); 323 326 } else { 324 327 if (!hub_dev->per_port_power) { 325 usb_log_debug(" Ganged power switching, "326 "one port is enough. \n");328 usb_log_debug("(%p) Ganged power switching, " 329 "one port is enough.", hub_dev); 327 330 break; 328 331 } … … 345 348 /* Get number of possible configurations from device descriptor */ 346 349 const size_t configuration_count = 347 usb_device ->descriptors.device.configuration_count;350 usb_device_descriptors(usb_device)->device.configuration_count; 348 351 usb_log_debug("Hub has %zu configurations.\n", configuration_count); 349 352 … … 353 356 } 354 357 355 if (usb_device->descriptors.configuration_size 356 < sizeof(usb_standard_configuration_descriptor_t)) { 358 const size_t config_size = 359 usb_device_descriptors(usb_device)->full_config_size; 360 const usb_standard_configuration_descriptor_t *config_descriptor = 361 usb_device_descriptors(usb_device)->full_config; 362 363 if (config_size < sizeof(usb_standard_configuration_descriptor_t)) { 357 364 usb_log_error("Configuration descriptor is not big enough" 358 365 " to fit standard configuration descriptor.\n"); … … 360 367 } 361 368 362 // TODO: Make sure that the cast is correct363 usb_standard_configuration_descriptor_t *config_descriptor364 = (usb_standard_configuration_descriptor_t *)365 usb_device->descriptors.configuration;366 367 369 /* Set configuration. Use the configuration that was in 368 370 * usb_device->descriptors.configuration i.e. The first one. */ 369 371 const int opResult = usb_request_set_configuration( 370 &usb_device->ctrl_pipe, config_descriptor->configuration_number); 372 usb_device_get_default_pipe(usb_device), 373 config_descriptor->configuration_number); 371 374 if (opResult != EOK) { 372 375 usb_log_error("Failed to set hub configuration: %s.\n", … … 392 395 if (status & USB_HUB_STATUS_OVER_CURRENT) { 393 396 /* Hub should remove power from all ports if it detects OC */ 394 usb_log_warning(" Detected hub over-current condition, "395 "all ports should be powered off." );397 usb_log_warning("(%p) Detected hub over-current condition, " 398 "all ports should be powered off.", hub_dev); 396 399 return; 397 400 } … … 406 409 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 407 410 if (ret != EOK) { 408 usb_log_warning(" HUB OVER-CURRENT GONE: Cannot power on"409 " po rt %zu: %s\n", hub_dev->ports[port].port_number,410 str_error(ret));411 usb_log_warning("(%p-%u): HUB OVER-CURRENT GONE: Cannot" 412 " power on port: %s\n", hub_dev, 413 hub_dev->ports[port].port_number, str_error(ret)); 411 414 } else { 412 415 if (!hub_dev->per_port_power) … … 427 430 assert(hub_dev); 428 431 assert(hub_dev->usb_device); 429 usb_log_debug("Global interrupt on a hub\n"); 430 usb_pipe_t *control_pipe = &hub_dev->usb_device->ctrl_pipe; 432 usb_log_debug("(%p): Global interrupt on th hub.", hub_dev); 433 usb_pipe_t *control_pipe = 434 usb_device_get_default_pipe(hub_dev->usb_device); 431 435 432 436 usb_hub_status_t status; … … 438 442 &status, sizeof(usb_hub_status_t), &rcvd_size); 439 443 if (opResult != EOK) { 440 usb_log_error(" Could not get hub status: %s\n",444 usb_log_error("(%p): Could not get hub status: %s.", hub_dev, 441 445 str_error(opResult)); 442 446 return; 443 447 } 444 448 if (rcvd_size != sizeof(usb_hub_status_t)) { 445 usb_log_error("Received status has incorrect size\n"); 449 usb_log_error("(%p): Received status has incorrect size: " 450 "%zu != %zu", hub_dev, rcvd_size, sizeof(usb_hub_status_t)); 446 451 return; 447 452 } … … 452 457 /* Ack change in hub OC flag */ 453 458 const int ret = usb_request_clear_feature( 454 &hub_dev->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS,459 control_pipe, USB_REQUEST_TYPE_CLASS, 455 460 USB_REQUEST_RECIPIENT_DEVICE, 456 461 USB_HUB_FEATURE_C_HUB_OVER_CURRENT, 0); 457 462 if (ret != EOK) { 458 usb_log_error(" Failed to clear hub over-current "459 "change flag: %s.\n", str_error(opResult));463 usb_log_error("(%p): Failed to clear hub over-current " 464 "change flag: %s.\n", hub_dev, str_error(opResult)); 460 465 } 461 466 } … … 480 485 USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0); 481 486 if (opResult != EOK) { 482 usb_log_error(" Failed to clear hub power change "483 "flag: %s.\n", str_error(ret));487 usb_log_error("(%p): Failed to clear hub power change " 488 "flag: %s.\n", hub_dev, str_error(ret)); 484 489 } 485 490 }
Note:
See TracChangeset
for help on using the changeset viewer.