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