Changeset 1e1b1a9 in mainline
- Timestamp:
- 2011-04-09T15:06:34Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f35b294
- Parents:
- 8961c22
- Location:
- uspace/drv/usbhub
- Files:
-
- 2 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/Makefile
r8961c22 r1e1b1a9 36 36 utils.c \ 37 37 usbhub.c \ 38 usblist.c38 ports.c 39 39 40 40 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/usbhub/usbhub.c
r8961c22 r1e1b1a9 55 55 56 56 57 /** Information for fibril for device discovery. */58 struct add_device_phase1 {59 usb_hub_info_t *hub;60 size_t port;61 usb_speed_t speed;62 };63 64 65 57 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev); 66 58 … … 69 61 static int usb_hub_set_configuration(usb_hub_info_t * hub_info); 70 62 71 static int usb_hub_release_default_address(usb_hub_info_t * hub); 72 73 //static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port, 74 // usb_speed_t speed); 75 76 //static void usb_hub_finalize_add_device(usb_hub_info_t * hub, 77 // uint16_t port, usb_speed_t speed); 78 79 static void usb_hub_removed_device( 80 usb_hub_info_t * hub, uint16_t port); 81 82 static void usb_hub_port_over_current(usb_hub_info_t * hub, 83 uint16_t port, uint32_t status); 84 85 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port, 86 usb_port_status_t *status); 87 88 static int enable_port_callback(int port_no, void *arg); 89 90 static int add_device_phase1_worker_fibril(void *arg); 91 92 static int add_device_phase1_new_fibril(usb_hub_info_t *hub, size_t port, 93 usb_speed_t speed); 94 95 static void usb_hub_process_interrupt(usb_hub_info_t * hub, 96 uint16_t port); 63 //static int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param); 97 64 98 65 static int usb_process_hub_over_current(usb_hub_info_t * hub_info, … … 104 71 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info); 105 72 106 //static int initialize_non_removable(usb_hub_info_t * hub_info, 107 // unsigned int port); 108 109 //static int usb_hub_trigger_connecting_non_removable_devices( 110 // usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor); 111 112 113 /** 114 * control loop running in hub`s fibril 115 * 116 * Hub`s fibril periodically asks for changes on hub and if needded calls 117 * change handling routine. 118 * @warning currently hub driver asks for changes once a second 119 * @param hub_info_param hub representation pointer 120 * @return zero 121 */ 122 /* 123 int usb_hub_control_loop(void * hub_info_param) { 124 usb_hub_info_t * hub_info = (usb_hub_info_t*) hub_info_param; 125 int errorCode = EOK; 126 127 while (errorCode == EOK) { 128 async_usleep(1000 * 1000 * 10); /// \TODO proper number once 129 errorCode = usb_hub_check_hub_changes(hub_info); 130 } 131 usb_log_error("something in ctrl loop went wrong, errno %d\n", 132 errorCode); 133 134 return 0; 135 } 136 */ 73 137 74 /// \TODO malloc checking 138 75 … … 250 187 251 188 252 /** Callback for polling hub for portchanges.189 /** Callback for polling hub for changes. 253 190 * 254 191 * @param dev Device where the change occured. … … 266 203 if (change_bitmap_size == 0) { 267 204 goto leave; 205 } 206 207 bool change; 208 change = ((uint8_t*)change_bitmap)[0] & 1; 209 if(change){ 210 usb_hub_process_global_interrupt(hub); 268 211 } 269 212 … … 277 220 278 221 222 223 224 279 225 leave: 280 226 /* FIXME: proper interval. */ … … 286 232 287 233 /** 288 * check changes on hub 289 * 290 * Handles changes on each port with a status change. 291 * @param hub_info hub representation 292 * @return error code 293 */ 294 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) { 295 int opResult; 296 opResult = usb_pipe_start_session( 297 hub_info->status_change_pipe); 298 //this might not be necessary - if all non-removables are ok, it is 299 //not needed here 300 opResult = usb_pipe_start_session(hub_info->control_pipe); 301 if (opResult != EOK) { 302 usb_log_error("could not initialize communication for hub; %d\n", 303 opResult); 304 return opResult; 305 } 306 307 size_t port_count = hub_info->port_count; 308 //first check non-removable devices 309 /* 310 { 311 unsigned int port; 312 for (port = 0; port < port_count; ++port) { 313 bool is_non_removable = 314 hub_info->not_initialized_non_removables[port/8] 315 & (1 << (port-1 % 8)); 316 if (is_non_removable) { 317 opResult = initialize_non_removable(hub_info, 318 port+1); 319 } 320 } 321 } 322 */ 323 324 /// FIXME: count properly 325 size_t byte_length = ((port_count + 1) / 8) + 1; 326 void *change_bitmap = malloc(byte_length); 327 size_t actual_size; 328 329 /* 330 * Send the request. 331 */ 332 opResult = usb_pipe_read( 333 hub_info->status_change_pipe, 334 change_bitmap, byte_length, &actual_size 335 ); 336 337 if (opResult != EOK) { 338 free(change_bitmap); 339 usb_log_warning("something went wrong while getting the" 340 "status of hub\n"); 341 usb_pipe_end_session(hub_info->status_change_pipe); 342 return opResult; 343 } 344 unsigned int port; 345 346 if (opResult != EOK) { 347 usb_log_error("could not start control pipe session %d\n", 348 opResult); 349 usb_pipe_end_session(hub_info->status_change_pipe); 350 return opResult; 351 } 352 opResult = usb_hc_connection_open(&hub_info->connection); 353 if (opResult != EOK) { 354 usb_log_error("could not start host controller session %d\n", 355 opResult); 356 usb_pipe_end_session(hub_info->control_pipe); 357 usb_pipe_end_session(hub_info->status_change_pipe); 358 return opResult; 359 } 360 361 ///todo, opresult check, pre obe konekce 362 bool interrupt; 363 interrupt = ((uint8_t*)change_bitmap)[0] & 1; 364 if(interrupt){ 365 usb_hub_process_global_interrupt(hub_info); 366 } 367 for (port = 1; port < port_count + 1; ++port) { 368 interrupt = 369 ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8)); 370 if (interrupt) { 371 usb_hub_process_interrupt( 372 hub_info, port); 373 } 374 } 375 /// \todo check hub status 376 usb_hc_connection_close(&hub_info->connection); 377 usb_pipe_end_session(hub_info->control_pipe); 378 usb_pipe_end_session(hub_info->status_change_pipe); 379 free(change_bitmap); 234 * release default address used by given hub 235 * 236 * Also unsets hub->is_default_address_used. Convenience wrapper function. 237 * @note hub->connection MUST be open for communication 238 * @param hub hub representation 239 * @return error code 240 */ 241 int usb_hub_release_default_address(usb_hub_info_t * hub) { 242 int opResult = usb_hc_release_default_address(&hub->connection); 243 if (opResult != EOK) { 244 usb_log_error("could not release default address, errno %d\n", 245 opResult); 246 return opResult; 247 } 248 hub->is_default_address_used = false; 380 249 return EOK; 381 250 } 251 382 252 383 253 //********************************************* … … 422 292 int opResult; 423 293 424 /* this was one fix of some bug, should not be needed anymore425 * these lines allow to reset hub once more, it can be used as426 * brute-force initialization for non-removable devices427 *428 opResult = usb_request_set_configuration(hub_info->control_pipe,429 1);430 if (opResult != EOK) {431 usb_log_error("could not set default configuration, errno %d",432 opResult);433 return opResult;434 }*/435 436 437 294 size_t received_size; 438 295 opResult = usb_request_get_descriptor(hub_info->control_pipe, … … 457 314 usb_log_debug("setting port count to %d\n", descriptor->ports_count); 458 315 hub_info->port_count = descriptor->ports_count; 459 /// \TODO check attached_devices array: this is not semantically correct 460 //hub_info->attached_devs = (usb_hc_attached_device_t*) 461 // malloc((hub_info->port_count + 1) * 462 // sizeof (usb_hc_attached_device_t) 463 // ); 316 /// \TODO this is not semantically correct 464 317 hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1)); 465 318 size_t port; … … 467 320 usb_hub_port_init(&hub_info->ports[port]); 468 321 } 469 //handle non-removable devices470 //usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);471 322 usb_log_debug2("freeing data\n"); 472 323 free(serialized_descriptor); … … 515 366 } 516 367 517 /** 518 * release default address used by given hub 519 * 520 * Also unsets hub->is_default_address_used. Convenience wrapper function. 521 * @note hub->connection MUST be open for communication 522 * @param hub hub representation 523 * @return error code 524 */ 525 static int usb_hub_release_default_address(usb_hub_info_t * hub) { 526 int opResult = usb_hc_release_default_address(&hub->connection); 527 if (opResult != EOK) { 528 usb_log_error("could not release default address, errno %d\n", 529 opResult); 530 return opResult; 531 } 532 hub->is_default_address_used = false; 368 #if 0 369 /** 370 * check changes on hub 371 * 372 * Handles changes on each port with a status change. 373 * @param hub_info hub representation 374 * @return error code 375 */ 376 static int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) { 377 int opResult; 378 opResult = usb_pipe_start_session( 379 hub_info->status_change_pipe); 380 //this might not be necessary - if all non-removables are ok, it is 381 //not needed here 382 opResult = usb_pipe_start_session(hub_info->control_pipe); 383 if (opResult != EOK) { 384 usb_log_error("could not initialize communication for hub; %d\n", 385 opResult); 386 return opResult; 387 } 388 389 size_t port_count = hub_info->port_count; 390 size_t byte_length = ((port_count + 1) / 8) + 1; 391 void *change_bitmap = malloc(byte_length); 392 size_t actual_size; 393 394 /* 395 * Send the request. 396 */ 397 opResult = usb_pipe_read( 398 hub_info->status_change_pipe, 399 change_bitmap, byte_length, &actual_size 400 ); 401 402 if (opResult != EOK) { 403 free(change_bitmap); 404 usb_log_warning("something went wrong while getting the" 405 "status of hub\n"); 406 usb_pipe_end_session(hub_info->status_change_pipe); 407 return opResult; 408 } 409 unsigned int port; 410 411 if (opResult != EOK) { 412 usb_log_error("could not start control pipe session %d\n", 413 opResult); 414 usb_pipe_end_session(hub_info->status_change_pipe); 415 return opResult; 416 } 417 opResult = usb_hc_connection_open(&hub_info->connection); 418 if (opResult != EOK) { 419 usb_log_error("could not start host controller session %d\n", 420 opResult); 421 usb_pipe_end_session(hub_info->control_pipe); 422 usb_pipe_end_session(hub_info->status_change_pipe); 423 return opResult; 424 } 425 426 ///todo, opresult check, pre obe konekce 427 bool interrupt; 428 interrupt = ((uint8_t*)change_bitmap)[0] & 1; 429 if(interrupt){ 430 usb_hub_process_global_interrupt(hub_info); 431 } 432 for (port = 1; port < port_count + 1; ++port) { 433 interrupt = 434 ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8)); 435 if (interrupt) { 436 usb_hub_process_interrupt( 437 hub_info, port); 438 } 439 } 440 /// \todo check hub status 441 usb_hc_connection_close(&hub_info->connection); 442 usb_pipe_end_session(hub_info->control_pipe); 443 usb_pipe_end_session(hub_info->status_change_pipe); 444 free(change_bitmap); 533 445 return EOK; 534 446 } 535 447 536 #if 0537 /**538 * Reset the port with new device and reserve the default address.539 * @param hub hub representation540 * @param port port number, starting from 1541 * @param speed transfer speed of attached device, one of low, full or high542 * @return error code543 */544 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,545 usb_speed_t speed) {546 //if this hub already uses default address, it cannot request it once more547 if (hub->is_default_address_used) {548 usb_log_info("default address used, another time\n");549 return EREFUSED;550 }551 usb_log_debug("some connection changed\n");552 assert(hub->control_pipe->hc_phone);553 int opResult = usb_hub_clear_port_feature(hub->control_pipe,554 port, USB_HUB_FEATURE_C_PORT_CONNECTION);555 if (opResult != EOK) {556 usb_log_warning("could not clear port-change-connection flag\n");557 }558 usb_device_request_setup_packet_t request;559 560 //get default address561 opResult = usb_hc_reserve_default_address(&hub->connection, speed);562 563 if (opResult != EOK) {564 usb_log_warning("cannot assign default address, it is probably "565 "used %d\n",566 opResult);567 return opResult;568 }569 hub->is_default_address_used = true;570 //reset port571 usb_hub_set_reset_port_request(&request, port);572 opResult = usb_pipe_control_write(573 hub->control_pipe,574 &request, sizeof (usb_device_request_setup_packet_t),575 NULL, 0576 );577 if (opResult != EOK) {578 usb_log_error("something went wrong when reseting a port %d\n",579 opResult);580 usb_hub_release_default_address(hub);581 }582 return opResult;583 }584 448 #endif 585 586 #if 0587 /**588 * Finalize adding new device after port reset589 *590 * Set device`s address and start it`s driver.591 * @param hub hub representation592 * @param port port number, starting from 1593 * @param speed transfer speed of attached device, one of low, full or high594 */595 static void usb_hub_finalize_add_device(usb_hub_info_t * hub,596 uint16_t port, usb_speed_t speed) {597 598 int opResult;599 usb_log_debug("finalizing add device\n");600 opResult = usb_hub_clear_port_feature(hub->control_pipe,601 port, USB_HUB_FEATURE_C_PORT_RESET);602 603 if (opResult != EOK) {604 usb_log_error("failed to clear port reset feature\n");605 usb_hub_release_default_address(hub);606 return;607 }608 //create connection to device609 usb_pipe_t new_device_pipe;610 usb_device_connection_t new_device_connection;611 usb_device_connection_initialize_on_default_address(612 &new_device_connection,613 &hub->connection614 );615 usb_pipe_initialize_default_control(616 &new_device_pipe,617 &new_device_connection);618 usb_pipe_probe_default_control(&new_device_pipe);619 620 /* Request address from host controller. */621 usb_address_t new_device_address = usb_hc_request_address(622 &hub->connection,623 speed624 );625 if (new_device_address < 0) {626 usb_log_error("failed to get free USB address\n");627 opResult = new_device_address;628 usb_hub_release_default_address(hub);629 return;630 }631 usb_log_debug("setting new address %d\n", new_device_address);632 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,633 // new_device_address);634 usb_pipe_start_session(&new_device_pipe);635 opResult = usb_request_set_address(&new_device_pipe,636 new_device_address);637 usb_pipe_end_session(&new_device_pipe);638 if (opResult != EOK) {639 usb_log_error("could not set address for new device %d\n",640 opResult);641 usb_hub_release_default_address(hub);642 return;643 }644 645 //opResult = usb_hub_release_default_address(hc);646 opResult = usb_hub_release_default_address(hub);647 if (opResult != EOK) {648 return;649 }650 651 devman_handle_t child_handle;652 //??653 opResult = usb_device_register_child_in_devman(new_device_address,654 hub->connection.hc_handle, hub->usb_device->ddf_dev,655 &child_handle,656 NULL, NULL, NULL);657 658 if (opResult != EOK) {659 usb_log_error("could not start driver for new device %d\n",660 opResult);661 return;662 }663 hub->attached_devs[port].handle = child_handle;664 hub->attached_devs[port].address = new_device_address;665 666 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);667 opResult = usb_hc_register_device(668 &hub->connection,669 &hub->attached_devs[port]);670 if (opResult != EOK) {671 usb_log_error("could not assign address of device in hcd %d\n",672 opResult);673 return;674 }675 usb_log_info("Detected new device on `%s' (port %d), " \676 "address %d (handle %llu).\n",677 hub->usb_device->ddf_dev->name, (int) port,678 new_device_address, child_handle);679 }680 #endif681 682 /**683 * routine called when a device on port has been removed684 *685 * If the device on port had default address, it releases default address.686 * Otherwise does not do anything, because DDF does not allow to remove device687 * from it`s device tree.688 * @param hub hub representation689 * @param port port number, starting from 1690 */691 static void usb_hub_removed_device(692 usb_hub_info_t * hub, uint16_t port) {693 694 int opResult = usb_hub_clear_port_feature(hub->control_pipe,695 port, USB_HUB_FEATURE_C_PORT_CONNECTION);696 if (opResult != EOK) {697 usb_log_warning("could not clear port-change-connection flag\n");698 }699 /** \TODO remove device from device manager - not yet implemented in700 * devide manager701 */702 703 //close address704 //if (hub->attached_devs[port].address != 0) {705 if(hub->ports[port].attached_device.address >= 0){706 /*uncomment this code to use it when DDF allows device removal707 opResult = usb_hc_unregister_device(708 &hub->connection,709 hub->attached_devs[port].address);710 if(opResult != EOK) {711 dprintf(USB_LOG_LEVEL_WARNING, "could not release "712 "address of "713 "removed device: %d", opResult);714 }715 hub->attached_devs[port].address = 0;716 hub->attached_devs[port].handle = 0;717 */718 } else {719 usb_log_warning("this is strange, disconnected device had "720 "no address\n");721 //device was disconnected before it`s port was reset -722 //return default address723 usb_hub_release_default_address(hub);724 }725 }726 727 /**728 * Process over current condition on port.729 *730 * Turn off the power on the port.731 *732 * @param hub hub representation733 * @param port port number, starting from 1734 */735 static void usb_hub_port_over_current(usb_hub_info_t * hub,736 uint16_t port, uint32_t status) {737 int opResult;738 if(usb_port_over_current(&status)){739 opResult = usb_hub_clear_port_feature(hub->control_pipe,740 port, USB_HUB_FEATURE_PORT_POWER);741 if (opResult != EOK) {742 usb_log_error("cannot power off port %d; %d\n",743 port, opResult);744 }745 }else{746 opResult = usb_hub_set_port_feature(hub->control_pipe,747 port, USB_HUB_FEATURE_PORT_POWER);748 if (opResult != EOK) {749 usb_log_error("cannot power on port %d; %d\n",750 port, opResult);751 }752 }753 }754 755 /** Retrieve port status.756 *757 * @param[in] ctrl_pipe Control pipe to use.758 * @param[in] port Port number (starting at 1).759 * @param[out] status Where to store the port status.760 * @return Error code.761 */762 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,763 usb_port_status_t *status)764 {765 size_t recv_size;766 usb_device_request_setup_packet_t request;767 usb_port_status_t status_tmp;768 769 usb_hub_set_port_status_request(&request, port);770 int rc = usb_pipe_control_read(ctrl_pipe,771 &request, sizeof(usb_device_request_setup_packet_t),772 &status_tmp, sizeof(status_tmp), &recv_size);773 if (rc != EOK) {774 return rc;775 }776 777 if (recv_size != sizeof (status_tmp)) {778 return ELIMIT;779 }780 781 if (status != NULL) {782 *status = status_tmp;783 }784 785 return EOK;786 }787 788 /** Callback for enabling a specific port.789 *790 * We wait on a CV until port is reseted.791 * That is announced via change on interrupt pipe.792 *793 * @param port_no Port number (starting at 1).794 * @param arg Custom argument, points to @c usb_hub_info_t.795 * @return Error code.796 */797 static int enable_port_callback(int port_no, void *arg)798 {799 usb_hub_info_t *hub = (usb_hub_info_t *) arg;800 int rc;801 usb_device_request_setup_packet_t request;802 usb_hub_port_t *my_port = hub->ports + port_no;803 804 usb_hub_set_reset_port_request(&request, port_no);805 rc = usb_pipe_control_write(hub->control_pipe,806 &request, sizeof(request), NULL, 0);807 if (rc != EOK) {808 usb_log_warning("Port reset failed: %s.\n", str_error(rc));809 return rc;810 }811 812 /*813 * Wait until reset completes.814 */815 fibril_mutex_lock(&my_port->reset_mutex);816 while (!my_port->reset_completed) {817 fibril_condvar_wait(&my_port->reset_cv, &my_port->reset_mutex);818 }819 fibril_mutex_unlock(&my_port->reset_mutex);820 821 /* Clear the port reset change. */822 rc = usb_hub_clear_port_feature(hub->control_pipe,823 port_no, USB_HUB_FEATURE_C_PORT_RESET);824 if (rc != EOK) {825 usb_log_error("Failed to clear port %d reset feature: %s.\n",826 port_no, str_error(rc));827 return rc;828 }829 830 return EOK;831 }832 833 /** Fibril for adding a new device.834 *835 * Separate fibril is needed because the port reset completion is announced836 * via interrupt pipe and thus we cannot block here.837 *838 * @param arg Pointer to struct add_device_phase1.839 * @return 0 Always.840 */841 static int add_device_phase1_worker_fibril(void *arg)842 {843 struct add_device_phase1 *data844 = (struct add_device_phase1 *) arg;845 846 usb_address_t new_address;847 devman_handle_t child_handle;848 849 int rc = usb_hc_new_device_wrapper(data->hub->usb_device->ddf_dev,850 &data->hub->connection, data->speed,851 enable_port_callback, (int) data->port, data->hub,852 &new_address, &child_handle,853 NULL, NULL, NULL);854 855 if (rc != EOK) {856 usb_log_error("Failed registering device on port %zu: %s.\n",857 data->port, str_error(rc));858 goto leave;859 }860 861 data->hub->ports[data->port].attached_device.handle = child_handle;862 data->hub->ports[data->port].attached_device.address = new_address;863 864 usb_log_info("Detected new device on `%s' (port %zu), "865 "address %d (handle %" PRIun ").\n",866 data->hub->usb_device->ddf_dev->name, data->port,867 new_address, child_handle);868 869 leave:870 free(arg);871 872 return EOK;873 }874 875 876 /** Start device adding when connection change is detected.877 *878 * This fires a new fibril to complete the device addition.879 *880 * @param hub Hub where the change occured.881 * @param port Port index (starting at 1).882 * @param speed Speed of the device.883 * @return Error code.884 */885 static int add_device_phase1_new_fibril(usb_hub_info_t *hub, size_t port,886 usb_speed_t speed)887 {888 struct add_device_phase1 *data889 = malloc(sizeof(struct add_device_phase1));890 if (data == NULL) {891 return ENOMEM;892 }893 data->hub = hub;894 data->port = port;895 data->speed = speed;896 897 usb_hub_port_t *the_port = hub->ports + port;898 899 fibril_mutex_lock(&the_port->reset_mutex);900 the_port->reset_completed = false;901 fibril_mutex_unlock(&the_port->reset_mutex);902 903 int rc = usb_hub_clear_port_feature(hub->control_pipe, port,904 USB_HUB_FEATURE_C_PORT_CONNECTION);905 if (rc != EOK) {906 free(data);907 usb_log_warning("Failed to clear port change flag: %s.\n",908 str_error(rc));909 return rc;910 }911 912 fid_t fibril = fibril_create(add_device_phase1_worker_fibril, data);913 if (fibril == 0) {914 free(data);915 return ENOMEM;916 }917 fibril_add_ready(fibril);918 919 return EOK;920 }921 922 923 /**924 * Process interrupts on given hub port925 *926 * Accepts connection, over current and port reset change.927 * @param hub hub representation928 * @param port port number, starting from 1929 */930 static void usb_hub_process_interrupt(usb_hub_info_t * hub,931 uint16_t port) {932 usb_log_debug("interrupt at port %d\n", port);933 //determine type of change934 //usb_pipe_t *pipe = hub->control_pipe;935 936 int opResult;937 938 usb_port_status_t status;939 opResult = get_port_status(&hub->usb_device->ctrl_pipe, port, &status);940 if (opResult != EOK) {941 usb_log_error("Failed to get port %zu status: %s.\n",942 port, str_error(opResult));943 return;944 }945 946 //something connected/disconnected947 /*948 if (usb_port_connect_change(&status)) {949 usb_log_debug("connection change on port\n");950 if (usb_port_dev_connected(&status)) {951 usb_hub_init_add_device(hub, port,952 usb_port_speed(&status));953 } else {954 usb_hub_removed_device(hub, port);955 }956 }*/957 if (usb_port_connect_change(&status)) {958 bool device_connected = usb_port_dev_connected(&status);959 usb_log_debug("Connection change on port %zu: %s.\n", port,960 device_connected ? "device attached" : "device removed");961 962 if (device_connected) {963 opResult = add_device_phase1_new_fibril(hub, port,964 usb_port_speed(&status));965 if (opResult != EOK) {966 usb_log_error(967 "Cannot handle change on port %zu: %s.\n",968 str_error(opResult));969 }970 } else {971 usb_hub_removed_device(hub, port);972 }973 }974 //over current975 if (usb_port_overcurrent_change(&status)) {976 //check if it was not auto-resolved977 usb_log_debug("overcurrent change on port\n");978 usb_hub_port_over_current(hub, port, status);979 }980 //port reset981 if (usb_port_reset_completed(&status)) {982 /*983 usb_log_debug("port reset complete\n");984 if (usb_port_enabled(&status)) {985 usb_hub_finalize_add_device(hub, port,986 usb_port_speed(&status));987 } else {988 usb_log_warning("port reset, but port still not "989 "enabled\n");990 }991 * */992 usb_log_debug("Port %zu reset complete.\n", port);993 if (usb_port_enabled(&status)) {994 /* Finalize device adding. */995 usb_hub_port_t *the_port = hub->ports + port;996 fibril_mutex_lock(&the_port->reset_mutex);997 the_port->reset_completed = true;998 fibril_condvar_broadcast(&the_port->reset_cv);999 fibril_mutex_unlock(&the_port->reset_mutex);1000 } else {1001 usb_log_warning(1002 "Port %zu reset complete but port not enabled.\n",1003 port);1004 }1005 }1006 usb_log_debug("status x%x : %d\n ", status, status);1007 1008 usb_port_set_connect_change(&status, false);1009 usb_port_set_reset(&status, false);1010 usb_port_set_reset_completed(&status, false);1011 usb_port_set_dev_connected(&status, false);1012 usb_port_set_overcurrent_change(&status,false);1013 /// \TODO what about port power change?1014 if (status >> 16) {1015 usb_log_info("there was unsupported change on port %d: %X\n",1016 port, status);1017 1018 }1019 }1020 449 1021 450 /** -
uspace/drv/usbhub/usbhub.h
r8961c22 r1e1b1a9 37 37 38 38 #include <ipc/devman.h> 39 #include <usb/usb.h>40 39 #include <ddf/driver.h> 41 42 #define NAME "usbhub"43 40 44 41 #include <usb/hub.h> … … 50 47 #include <fibril_synch.h> 51 48 49 #define NAME "usbhub" 52 50 53 /** Information about single port on a hub. */ 54 typedef struct { 55 /** Mutex needed by CV for checking port reset. */ 56 fibril_mutex_t reset_mutex; 57 /** CV for waiting to port reset completion. */ 58 fibril_condvar_t reset_cv; 59 /** Whether port reset is completed. 60 * Guarded by @c reset_mutex. 61 */ 62 bool reset_completed; 51 #include "ports.h" 63 52 64 /** Information about attached device. */65 usb_hc_attached_device_t attached_device;66 } usb_hub_port_t;67 53 68 /** Initialize hub port information.69 *70 * @param port Port to be initialized.71 */72 static inline void usb_hub_port_init(usb_hub_port_t *port) {73 port->attached_device.address = -1;74 port->attached_device.handle = 0;75 fibril_mutex_initialize(&port->reset_mutex);76 fibril_condvar_initialize(&port->reset_cv);77 }78 54 79 55 /** Information about attached hub. */ 80 typedef struct {56 typedef struct usb_hub_info_t{ 81 57 /** Number of ports. */ 82 58 size_t port_count; … … 119 95 int usb_hub_add_device(usb_device_t * usb_dev); 120 96 121 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);122 123 97 bool hub_port_changes_callback(usb_device_t *dev, 124 98 uint8_t *change_bitmap, size_t change_bitmap_size, void *arg); 99 100 int usb_hub_release_default_address(usb_hub_info_t * hub); 101 125 102 #endif 126 103 /** -
uspace/drv/usbhub/usbhub_private.h
r8961c22 r1e1b1a9 38 38 39 39 #include "usbhub.h" 40 #include "usblist.h"41 40 42 41 #include <adt/list.h>
Note:
See TracChangeset
for help on using the changeset viewer.