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