Changes in uspace/drv/bus/usb/usbhub/usbhub.c [58563585:fab2746] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhub/usbhub.c
r58563585 rfab2746 27 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 */ 29 30 29 /** @addtogroup drvusbhub 31 30 * @{ … … 46 45 #include <usb/dev/pipes.h> 47 46 #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 = 072 };73 59 74 60 /** Standard get hub global status request */ … … 113 99 fibril_condvar_initialize(&hub_dev->pending_ops_cv); 114 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 115 109 /* Set hub's first configuration. (There should be only one) */ 116 int opResult = usb_set_first_configuration(usb_dev); 117 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); 118 113 usb_log_error("Could not set hub configuration: %s\n", 119 114 str_error(opResult)); … … 124 119 opResult = usb_hub_process_hub_specific_info(hub_dev); 125 120 if (opResult != EOK) { 121 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe); 126 122 usb_log_error("Could process hub specific info, %s\n", 127 123 str_error(opResult)); … … 131 127 /* Create hub control function. */ 132 128 usb_log_debug("Creating DDF function '" HUB_FNC_NAME "'.\n"); 133 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, 134 130 fun_exposed, HUB_FNC_NAME); 135 131 if (hub_dev->hub_fun == NULL) { 132 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe); 136 133 usb_log_error("Failed to create hub function.\n"); 137 134 return ENOMEM; … … 141 138 opResult = ddf_fun_bind(hub_dev->hub_fun); 142 139 if (opResult != EOK) { 140 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe); 143 141 usb_log_error("Failed to bind hub function: %s.\n", 144 142 str_error(opResult)); … … 148 146 149 147 /* Start hub operation. */ 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) {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); 155 153 /* Function is already bound */ 156 154 ddf_fun_unbind(hub_dev->hub_fun); … … 161 159 } 162 160 hub_dev->running = true; 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 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); 167 165 return EOK; 168 166 } … … 187 185 { 188 186 assert(usb_dev); 189 usb_hub_dev_t *hub = usb_dev ice_data_get(usb_dev);187 usb_hub_dev_t *hub = usb_dev->driver_data; 190 188 assert(hub); 191 189 unsigned tries = 10; … … 193 191 async_usleep(100000); 194 192 if (!tries--) { 195 usb_log_error("(%p): Can't remove hub, still running.", 196 hub); 193 usb_log_error("Can't remove hub, still running.\n"); 197 194 return EBUSY; 198 195 } … … 202 199 203 200 for (size_t port = 0; port < hub->port_count; ++port) { 204 const int ret = usb_hub_port_fini(&hub->ports[port], hub); 205 if (ret != EOK) 206 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 } 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(" (%p) Failed to unbind '%s' function: %s.",213 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)); 214 214 return ret; 215 215 } 216 216 ddf_fun_destroy(hub->hub_fun); 217 217 218 usb_log_info(" (%p) USB hub driver stopped and cleaned.", hub);218 usb_log_info("USB hub driver, stopped and cleaned.\n"); 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"); 233 234 usb_hub_dev_t *hub = arg; 234 235 assert(hub); … … 246 247 247 248 /* N + 1 bit indicates change on port N */ 248 for (size_t port = 0; port < hub->port_count ; ++port) {249 for (size_t port = 0; port < hub->port_count + 1; port++) { 249 250 const size_t bit = port + 1; 250 251 const bool change = (change_bitmap[bit / 8] >> (bit % 8)) & 1; … … 271 272 272 273 /* Get hub descriptor. */ 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); 274 usb_log_debug("Retrieving descriptor\n"); 275 usb_pipe_t *control_pipe = &hub_dev->usb_device->ctrl_pipe; 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(" (%p):Failed to receive hub descriptor: %s.\n",285 hub_dev,str_error(opResult));284 usb_log_error("Failed to receive hub descriptor: %s.\n", 285 str_error(opResult)); 286 286 return opResult; 287 287 } 288 288 289 usb_log_debug("(%p): Setting port count to %d.\n", hub_dev, 290 descriptor.port_count); 289 usb_log_debug("Setting port count to %d.\n", descriptor.port_count); 291 290 hub_dev->port_count = descriptor.port_count; 292 291 … … 307 306 308 307 if (!hub_dev->power_switched) { 309 usb_log_info( "(%p): Power switching not supported, "310 "ports always powered.", hub_dev);308 usb_log_info( 309 "Power switching not supported, ports always powered.\n"); 311 310 return EOK; 312 311 } 313 312 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); 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); 319 317 const int ret = usb_hub_port_set_feature( 320 318 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 321 319 322 320 if (ret != EOK) { 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)); 321 usb_log_error("Cannot power on port %zu: %s.\n", 322 hub_dev->ports[port].port_number, str_error(ret)); 326 323 } else { 327 324 if (!hub_dev->per_port_power) { 328 usb_log_debug(" (%p)Ganged power switching, "329 "one port is enough. ", hub_dev);325 usb_log_debug("Ganged power switching, " 326 "one port is enough.\n"); 330 327 break; 331 328 } … … 348 345 /* Get number of possible configurations from device descriptor */ 349 346 const size_t configuration_count = 350 usb_device _descriptors(usb_device)->device.configuration_count;347 usb_device->descriptors.device.configuration_count; 351 348 usb_log_debug("Hub has %zu configurations.\n", configuration_count); 352 349 … … 356 353 } 357 354 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)) { 355 if (usb_device->descriptors.configuration_size 356 < sizeof(usb_standard_configuration_descriptor_t)) { 364 357 usb_log_error("Configuration descriptor is not big enough" 365 358 " to fit standard configuration descriptor.\n"); … … 367 360 } 368 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 369 367 /* Set configuration. Use the configuration that was in 370 368 * usb_device->descriptors.configuration i.e. The first one. */ 371 369 const int opResult = usb_request_set_configuration( 372 usb_device_get_default_pipe(usb_device), 373 config_descriptor->configuration_number); 370 &usb_device->ctrl_pipe, config_descriptor->configuration_number); 374 371 if (opResult != EOK) { 375 372 usb_log_error("Failed to set hub configuration: %s.\n", … … 395 392 if (status & USB_HUB_STATUS_OVER_CURRENT) { 396 393 /* Hub should remove power from all ports if it detects OC */ 397 usb_log_warning(" (%p)Detected hub over-current condition, "398 "all ports should be powered off." , hub_dev);394 usb_log_warning("Detected hub over-current condition, " 395 "all ports should be powered off."); 399 396 return; 400 397 } … … 409 406 &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER); 410 407 if (ret != EOK) { 411 usb_log_warning(" (%p-%u): HUB OVER-CURRENT GONE: Cannot"412 " po wer on port: %s\n", hub_dev,413 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)); 414 411 } else { 415 412 if (!hub_dev->per_port_power) … … 430 427 assert(hub_dev); 431 428 assert(hub_dev->usb_device); 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); 429 usb_log_debug("Global interrupt on a hub\n"); 430 usb_pipe_t *control_pipe = &hub_dev->usb_device->ctrl_pipe; 435 431 436 432 usb_hub_status_t status; … … 442 438 &status, sizeof(usb_hub_status_t), &rcvd_size); 443 439 if (opResult != EOK) { 444 usb_log_error(" (%p): Could not get hub status: %s.", hub_dev,440 usb_log_error("Could not get hub status: %s\n", 445 441 str_error(opResult)); 446 442 return; 447 443 } 448 444 if (rcvd_size != sizeof(usb_hub_status_t)) { 449 usb_log_error("(%p): Received status has incorrect size: " 450 "%zu != %zu", hub_dev, rcvd_size, sizeof(usb_hub_status_t)); 445 usb_log_error("Received status has incorrect size\n"); 451 446 return; 452 447 } … … 457 452 /* Ack change in hub OC flag */ 458 453 const int ret = usb_request_clear_feature( 459 control_pipe, USB_REQUEST_TYPE_CLASS,454 &hub_dev->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS, 460 455 USB_REQUEST_RECIPIENT_DEVICE, 461 456 USB_HUB_FEATURE_C_HUB_OVER_CURRENT, 0); 462 457 if (ret != EOK) { 463 usb_log_error(" (%p):Failed to clear hub over-current "464 "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)); 465 460 } 466 461 } … … 485 480 USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0); 486 481 if (opResult != EOK) { 487 usb_log_error(" (%p):Failed to clear hub power change "488 "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)); 489 484 } 490 485 }
Note:
See TracChangeset
for help on using the changeset viewer.