Changes in uspace/drv/ohci/root_hub.c [d0c060b:361fcec] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
rd0c060b r361fcec 108 108 109 109 static const uint32_t hub_clear_feature_valid_mask = 110 110 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) | 111 111 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 112 112 113 113 static const uint32_t hub_clear_feature_by_writing_one_mask = 114 114 1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER; 115 115 116 116 static const uint32_t hub_set_feature_valid_mask = 117 117 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) | 118 118 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 119 119 120 120 121 121 static const uint32_t hub_set_feature_direct_mask = 122 122 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 123 123 124 124 static const uint32_t port_set_feature_valid_mask = 125 125 (1 << USB_HUB_FEATURE_PORT_ENABLE) | 126 126 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 127 127 (1 << USB_HUB_FEATURE_PORT_RESET) | … … 129 129 130 130 static const uint32_t port_clear_feature_valid_mask = 131 131 (1 << USB_HUB_FEATURE_PORT_CONNECTION) | 132 132 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 133 133 (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) | … … 142 142 143 143 static const uint32_t port_status_change_mask = 144 (1<< USB_HUB_FEATURE_C_PORT_CONNECTION) |145 (1 146 (1 147 (1 148 (1 144 (1<< USB_HUB_FEATURE_C_PORT_CONNECTION) | 145 (1<< USB_HUB_FEATURE_C_PORT_ENABLE) | 146 (1<< USB_HUB_FEATURE_C_PORT_OVER_CURRENT) | 147 (1<< USB_HUB_FEATURE_C_PORT_RESET) | 148 (1<< USB_HUB_FEATURE_C_PORT_SUSPEND); 149 149 150 150 … … 153 153 static int rh_init_descriptors(rh_t *instance); 154 154 155 static void rh_check_port_connectivity(rh_t * instance);156 157 155 static int process_get_port_status_request(rh_t *instance, uint16_t port, 158 156 usb_transfer_batch_t * request); 159 157 160 158 static int process_get_hub_status_request(rh_t *instance, 161 159 usb_transfer_batch_t * request); 162 160 163 161 static int process_get_status_request(rh_t *instance, 164 162 usb_transfer_batch_t * request); 165 163 166 164 static void create_interrupt_mask_in_instance(rh_t *instance); 167 165 168 166 static int process_get_descriptor_request(rh_t *instance, 169 167 usb_transfer_batch_t *request); 170 168 171 169 static int process_get_configuration_request(rh_t *instance, 172 170 usb_transfer_batch_t *request); 173 171 174 172 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature); 175 173 176 174 static int process_hub_feature_clear_request(rh_t *instance, 177 175 uint16_t feature); 178 176 179 177 static int process_port_feature_set_request(rh_t *instance, 180 178 uint16_t feature, uint16_t port); 181 179 182 180 static int process_port_feature_clear_request(rh_t *instance, 183 181 uint16_t feature, uint16_t port); 184 182 185 183 static int process_address_set_request(rh_t *instance, 186 184 uint16_t address); 187 185 188 186 static int process_request_with_output(rh_t *instance, 189 187 usb_transfer_batch_t *request); 190 188 191 189 static int process_request_with_input(rh_t *instance, 192 190 usb_transfer_batch_t *request); 193 191 194 192 static int process_request_without_data(rh_t *instance, 195 193 usb_transfer_batch_t *request); 196 194 197 195 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); … … 200 198 201 199 static bool is_zeros(void * buffer, size_t size); 200 201 202 202 203 203 /** Root hub initialization … … 210 210 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 211 211 int opResult = rh_init_descriptors(instance); 212 if (opResult != EOK){212 if(opResult != EOK){ 213 213 return opResult; 214 214 } … … 216 216 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 217 217 instance->unfinished_interrupt_transfer = NULL; 218 instance->interrupt_mask_size = (instance->port_count + 8) /8;218 instance->interrupt_mask_size = (instance->port_count + 8)/8; 219 219 instance->interrupt_buffer = malloc(instance->interrupt_mask_size); 220 if 220 if(!instance->interrupt_buffer) 221 221 return ENOMEM; 222 rh_check_port_connectivity(instance); 223 222 224 223 225 224 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 226 227 225 return EOK; 228 226 } … … 247 245 usb_log_info("Root hub got INTERRUPT packet\n"); 248 246 create_interrupt_mask_in_instance(instance); 249 if 250 instance->interrupt_mask_size)) 247 if(is_zeros(instance->interrupt_buffer, 248 instance->interrupt_mask_size)){ 251 249 usb_log_debug("no changes..\n"); 252 250 instance->unfinished_interrupt_transfer = request; 253 251 //will be finished later 254 } else{252 }else{ 255 253 usb_log_debug("processing changes..\n"); 256 254 process_interrupt_mask_in_instance(instance, request); … … 258 256 opResult = EOK; 259 257 } else { 260 261 258 opResult = EINVAL; 262 259 usb_transfer_batch_finish_error(request, opResult); … … 274 271 */ 275 272 void rh_interrupt(rh_t *instance) { 276 if (!instance->unfinished_interrupt_transfer) { 277 273 if(!instance->unfinished_interrupt_transfer){ 278 274 return; 279 275 } … … 296 292 static int create_serialized_hub_descriptor(rh_t *instance) { 297 293 size_t size = 7 + 298 ((instance->port_count + 7)/ 8) * 2;299 size_t var_size = (instance->port_count + 7)/ 8;294 ((instance->port_count +7 )/ 8) * 2; 295 size_t var_size = (instance->port_count +7 )/ 8; 300 296 uint8_t * result = (uint8_t*) malloc(size); 301 if 297 if(!result) return ENOMEM; 302 298 303 299 bzero(result, size); … … 309 305 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 310 306 result[3] = 311 312 313 314 315 307 ((hub_desc_reg >> 8) % 2) + 308 (((hub_desc_reg >> 9) % 2) << 1) + 309 (((hub_desc_reg >> 10) % 2) << 2) + 310 (((hub_desc_reg >> 11) % 2) << 3) + 311 (((hub_desc_reg >> 12) % 2) << 4); 316 312 result[4] = 0; 317 313 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; 318 314 result[6] = 50; 319 315 320 size_t port;316 int port; 321 317 for (port = 1; port <= instance->port_count; ++port) { 322 318 uint8_t is_non_removable = 323 319 instance->registers->rh_desc_b >> port % 2; 324 320 result[7 + port / 8] += 325 321 is_non_removable << (port % 8); 326 322 } 327 323 size_t i; … … 331 327 instance->hub_descriptor = result; 332 328 instance->descriptor_size = size; 333 334 329 return EOK; 335 330 } … … 345 340 static int rh_init_descriptors(rh_t *instance) { 346 341 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 347 348 342 sizeof (ohci_rh_device_descriptor) 343 ); 349 344 usb_standard_configuration_descriptor_t descriptor; 350 345 memcpy(&descriptor, &ohci_rh_conf_descriptor, 351 346 sizeof (ohci_rh_conf_descriptor)); 352 347 353 348 int opResult = create_serialized_hub_descriptor(instance); 354 if (opResult != EOK){349 if(opResult != EOK){ 355 350 return opResult; 356 351 } 357 352 descriptor.total_length = 358 359 360 361 353 sizeof (usb_standard_configuration_descriptor_t) + 354 sizeof (usb_standard_endpoint_descriptor_t) + 355 sizeof (usb_standard_interface_descriptor_t) + 356 instance->descriptor_size; 362 357 363 358 uint8_t * full_config_descriptor = 364 365 if (!full_config_descriptor){359 (uint8_t*) malloc(descriptor.total_length); 360 if(!full_config_descriptor){ 366 361 return ENOMEM; 367 362 } 368 363 memcpy(full_config_descriptor, &descriptor, sizeof (descriptor)); 369 364 memcpy(full_config_descriptor + sizeof (descriptor), 370 365 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor)); 371 366 memcpy(full_config_descriptor + sizeof (descriptor) + 372 373 367 sizeof (ohci_rh_iface_descriptor), 368 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor)); 374 369 memcpy(full_config_descriptor + sizeof (descriptor) + 375 376 377 378 370 sizeof (ohci_rh_iface_descriptor) + 371 sizeof (ohci_rh_ep_descriptor), 372 instance->hub_descriptor, instance->descriptor_size); 373 379 374 instance->descriptors.configuration = full_config_descriptor; 380 375 instance->descriptors.configuration_size = descriptor.total_length; 381 382 return EOK; 383 } 384 /*----------------------------------------------------------------------------*/ 385 386 /** 387 * check whether there are connected devices on ports and if yes, indicate 388 * connection change 389 * 390 * @param instance 391 */ 392 static void rh_check_port_connectivity(rh_t * instance) { 393 size_t port; 394 for (port = 1; port < instance->port_count; ++port) { 395 bool connected = 396 ((instance->registers->rh_port_status[port - 1]) & 397 (1 << USB_HUB_FEATURE_PORT_CONNECTION)) != 0; 398 if (connected) { 399 usb_log_debug("port %d has connected device\n", port); 400 instance->registers->rh_port_status[port - 1] = 401 instance->registers->rh_port_status[port - 1] 402 | (1 << USB_HUB_FEATURE_C_PORT_CONNECTION); 403 usb_log_debug("change indicated to status " 404 "register\n"); 405 } 406 } 407 } 408 409 376 return EOK; 377 } 410 378 /*----------------------------------------------------------------------------*/ 411 379 … … 421 389 */ 422 390 static int process_get_port_status_request(rh_t *instance, uint16_t port, 423 391 usb_transfer_batch_t * request) { 424 392 if (port < 1 || port > instance->port_count) 425 393 return EINVAL; … … 430 398 int i; 431 399 for (i = 0; i < instance->port_count; ++i) { 432 433 400 usb_log_debug("port status %d,x%x\n", 434 435 401 instance->registers->rh_port_status[i], 402 instance->registers->rh_port_status[i]); 436 403 } 437 404 #endif … … 450 417 */ 451 418 static int process_get_hub_status_request(rh_t *instance, 452 419 usb_transfer_batch_t * request) { 453 420 uint32_t * uint32_buffer = (uint32_t*) request->data_buffer; 454 421 request->transfered_size = 4; … … 456 423 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 457 424 uint32_buffer[0] = mask & instance->registers->rh_status; 458 459 425 return EOK; 460 426 } … … 471 437 */ 472 438 static int process_get_status_request(rh_t *instance, 473 439 usb_transfer_batch_t * request) { 474 440 size_t buffer_size = request->buffer_size; 475 441 usb_device_request_setup_packet_t * request_packet = 476 477 442 (usb_device_request_setup_packet_t*) 443 request->setup_buffer; 478 444 479 445 usb_hub_bm_request_type_t request_type = request_packet->request_type; … … 487 453 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 488 454 return process_get_port_status_request(instance, 489 request_packet->index, 490 request); 491 455 request_packet->index, 456 request); 492 457 return ENOTSUP; 493 458 } … … 507 472 uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer); 508 473 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 509 474 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 510 475 bzero(bitmap, instance->interrupt_mask_size); 511 476 if (instance->registers->rh_status & mask) { 512 477 bitmap[0] = 1; 513 478 } 514 size_t port;479 int port; 515 480 mask = port_status_change_mask; 516 481 for (port = 1; port <= instance->port_count; ++port) { 517 482 if (mask & instance->registers->rh_port_status[port - 1]) { 518 519 483 bitmap[(port) / 8] += 1 << (port % 8); 520 484 } … … 533 497 */ 534 498 static int process_get_descriptor_request(rh_t *instance, 535 499 usb_transfer_batch_t *request) { 536 500 usb_device_request_setup_packet_t * setup_request = 537 501 (usb_device_request_setup_packet_t*) request->setup_buffer; 538 502 size_t size; 539 503 const void * result_descriptor = NULL; … … 579 543 { 580 544 usb_log_debug("USB_DESCTYPE_EINVAL %d \n", 581 545 setup_request->value); 582 546 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue " 583 584 585 586 587 588 589 547 "%d\n\tindex %d\n\tlen %d\n ", 548 setup_request->request_type, 549 setup_request->request, 550 setup_request_value, 551 setup_request->index, 552 setup_request->length 553 ); 590 554 return EINVAL; 591 555 } … … 596 560 request->transfered_size = size; 597 561 memcpy(request->data_buffer, result_descriptor, size); 598 599 562 return EOK; 600 563 } … … 610 573 */ 611 574 static int process_get_configuration_request(rh_t *instance, 612 575 usb_transfer_batch_t *request) { 613 576 //set and get configuration requests do not have any meaning, only dummy 614 577 //values are returned … … 617 580 request->data_buffer[0] = 1; 618 581 request->transfered_size = 1; 619 620 582 return EOK; 621 583 } … … 630 592 */ 631 593 static int process_hub_feature_set_request(rh_t *instance, 632 594 uint16_t feature) { 633 595 if (!((1 << feature) & hub_set_feature_valid_mask)) 634 596 return EINVAL; 635 if 597 if(feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER) 636 598 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16; 637 599 instance->registers->rh_status = 638 (instance->registers->rh_status | (1 << feature)) 639 & (~hub_clear_feature_by_writing_one_mask); 640 600 (instance->registers->rh_status | (1 << feature)) 601 & (~hub_clear_feature_by_writing_one_mask); 641 602 return EOK; 642 603 } … … 651 612 */ 652 613 static int process_hub_feature_clear_request(rh_t *instance, 653 614 uint16_t feature) { 654 615 if (!((1 << feature) & hub_clear_feature_valid_mask)) 655 616 return EINVAL; … … 657 618 if ((1 << feature) & hub_set_feature_direct_mask) { 658 619 instance->registers->rh_status = 659 660 620 (instance->registers->rh_status & (~(1 << feature))) 621 & (~hub_clear_feature_by_writing_one_mask); 661 622 } else {//the feature is cleared by writing '1' 662 663 623 instance->registers->rh_status = 664 665 666 624 (instance->registers->rh_status 625 & (~hub_clear_feature_by_writing_one_mask)) 626 | (1 << feature); 667 627 } 668 628 return EOK; … … 680 640 */ 681 641 static int process_port_feature_set_request(rh_t *instance, 682 642 uint16_t feature, uint16_t port) { 683 643 if (!((1 << feature) & port_set_feature_valid_mask)) 684 644 return EINVAL; … … 686 646 return EINVAL; 687 647 instance->registers->rh_port_status[port - 1] = 688 689 648 (instance->registers->rh_port_status[port - 1] | (1 << feature)) 649 & (~port_clear_feature_valid_mask); 690 650 /// \TODO any error? 691 692 651 return EOK; 693 652 } … … 704 663 */ 705 664 static int process_port_feature_clear_request(rh_t *instance, 706 665 uint16_t feature, uint16_t port) { 707 666 if (!((1 << feature) & port_clear_feature_valid_mask)) 708 667 return EINVAL; … … 714 673 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 715 674 instance->registers->rh_port_status[port - 1] = 716 717 718 675 (instance->registers->rh_port_status[port - 1] 676 & (~port_clear_feature_valid_mask)) 677 | (1 << feature); 719 678 /// \TODO any error? 720 721 679 return EOK; 722 680 } … … 731 689 */ 732 690 static int process_address_set_request(rh_t *instance, 733 691 uint16_t address) { 734 692 instance->address = address; 735 736 693 return EOK; 737 694 } … … 748 705 */ 749 706 static int process_request_with_output(rh_t *instance, 750 707 usb_transfer_batch_t *request) { 751 708 usb_device_request_setup_packet_t * setup_request = 752 709 (usb_device_request_setup_packet_t*) request->setup_buffer; 753 710 if (setup_request->request == USB_DEVREQ_GET_STATUS) { 754 711 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); … … 761 718 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) { 762 719 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 763 764 720 return process_get_configuration_request(instance, request); 765 721 } … … 778 734 */ 779 735 static int process_request_with_input(rh_t *instance, 780 736 usb_transfer_batch_t *request) { 781 737 usb_device_request_setup_packet_t * setup_request = 782 738 (usb_device_request_setup_packet_t*) request->setup_buffer; 783 739 request->transfered_size = 0; 784 740 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) { … … 788 744 //set and get configuration requests do not have any meaning, 789 745 //only dummy values are returned 790 791 746 return EOK; 792 747 } … … 805 760 */ 806 761 static int process_request_without_data(rh_t *instance, 807 762 usb_transfer_batch_t *request) { 808 763 usb_device_request_setup_packet_t * setup_request = 809 764 (usb_device_request_setup_packet_t*) request->setup_buffer; 810 765 request->transfered_size = 0; 811 766 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) { … … 813 768 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 814 769 return process_hub_feature_clear_request(instance, 815 770 setup_request->value); 816 771 } 817 772 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 818 773 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 819 774 return process_port_feature_clear_request(instance, 820 821 775 setup_request->value, 776 setup_request->index); 822 777 } 823 778 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 824 779 setup_request->request_type); 825 780 return EINVAL; 826 781 } … … 829 784 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 830 785 return process_hub_feature_set_request(instance, 831 786 setup_request->value); 832 787 } 833 788 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 834 789 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 835 790 return process_port_feature_set_request(instance, 836 837 791 setup_request->value, 792 setup_request->index); 838 793 } 839 794 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 840 795 setup_request->request_type); 841 796 return EINVAL; 842 797 } … … 844 799 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 845 800 return process_address_set_request(instance, 846 801 setup_request->value); 847 802 } 848 803 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n", 849 setup_request->request_type); 850 804 setup_request->request_type); 851 805 return ENOTSUP; 852 806 } … … 882 836 } 883 837 usb_log_info("CTRL packet: %s.\n", 884 885 838 usb_debug_str_buffer( 839 (const uint8_t *) request->setup_buffer, 8, 8)); 886 840 usb_device_request_setup_packet_t * setup_request = 887 888 841 (usb_device_request_setup_packet_t*) 842 request->setup_buffer; 889 843 switch (setup_request->request) { 890 844 case USB_DEVREQ_GET_STATUS: … … 893 847 usb_log_debug("processing request with output\n"); 894 848 opResult = process_request_with_output( 895 849 instance, request); 896 850 break; 897 851 case USB_DEVREQ_CLEAR_FEATURE: … … 899 853 case USB_DEVREQ_SET_ADDRESS: 900 854 usb_log_debug("processing request without " 901 855 "additional data\n"); 902 856 opResult = process_request_without_data( 903 857 instance, request); 904 858 break; 905 859 case USB_DEVREQ_SET_DESCRIPTOR: 906 860 case USB_DEVREQ_SET_CONFIGURATION: 907 861 usb_log_debug("processing request with " 908 862 "input\n"); 909 863 opResult = process_request_with_input( 910 instance, request); 911 864 instance, request); 912 865 break; 913 866 default: 914 867 usb_log_warning("received unsuported request: " 915 916 917 868 "%d\n", 869 setup_request->request 870 ); 918 871 opResult = ENOTSUP; 919 872 } … … 935 888 * @return 936 889 */ 937 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request) 890 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request){ 938 891 memcpy(request->data_buffer, instance->interrupt_buffer, 939 892 instance->interrupt_mask_size); … … 941 894 instance->unfinished_interrupt_transfer = NULL; 942 895 usb_transfer_batch_finish_error(request, EOK); 943 944 896 return EOK; 945 897 } … … 955 907 * @return 956 908 */ 957 static bool is_zeros(void * buffer, size_t size) 958 if 959 if 909 static bool is_zeros(void * buffer, size_t size){ 910 if(!buffer) return true; 911 if(!size) return true; 960 912 size_t i; 961 for (i = 0; i < size; ++i){962 if (((char*)buffer)[i])913 for(i=0;i<size;++i){ 914 if(((char*)buffer)[i]) 963 915 return false; 964 916 }
Note:
See TracChangeset
for help on using the changeset viewer.