Changes in uspace/drv/ohci/root_hub.c [60b3bea:361fcec] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
r60b3bea r361fcec 45 45 46 46 /** 47 * 47 * standart device descriptor for ohci root hub 48 48 */ 49 49 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = { … … 69 69 */ 70 70 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = { 71 /// \TODO some values are default or guessed 71 72 .attributes = 1 << 7, 72 73 .configuration_number = 1, … … 86 87 .endpoint_count = 1, 87 88 .interface_class = USB_CLASS_HUB, 89 /// \TODO is this correct? 88 90 .interface_number = 1, 89 91 .interface_protocol = 0, … … 105 107 }; 106 108 107 /**108 * bitmask of hub features that are valid to be cleared109 */110 109 static const uint32_t hub_clear_feature_valid_mask = 111 110 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) | 112 111 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 113 112 114 /**115 * bitmask of hub features that are cleared by writing 1 (and not 0)116 */117 113 static const uint32_t hub_clear_feature_by_writing_one_mask = 118 1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER; 119 120 /** 121 * bitmask of hub features that are valid to be set 122 */ 114 1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER; 115 123 116 static const uint32_t hub_set_feature_valid_mask = 124 117 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) | 125 118 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 126 119 127 /** 128 * bitmask of hub features that are set by writing 1 and cleared by writing 0 129 */ 120 130 121 static const uint32_t hub_set_feature_direct_mask = 131 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 132 133 /** 134 * bitmask of port features that are valid to be set 135 */ 122 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 123 136 124 static const uint32_t port_set_feature_valid_mask = 137 125 (1 << USB_HUB_FEATURE_PORT_ENABLE) | 138 126 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 139 127 (1 << USB_HUB_FEATURE_PORT_RESET) | 140 128 (1 << USB_HUB_FEATURE_PORT_POWER); 141 129 142 /**143 * bitmask of port features that can be cleared144 */145 130 static const uint32_t port_clear_feature_valid_mask = 146 131 (1 << USB_HUB_FEATURE_PORT_CONNECTION) | 147 132 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 148 133 (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) | … … 156 141 //USB_HUB_FEATURE_PORT_LOW_SPEED 157 142 158 /**159 * bitmask with port status changes160 */161 143 static const uint32_t port_status_change_mask = 162 (1<< USB_HUB_FEATURE_C_PORT_CONNECTION) |163 (1 164 (1 165 (1 166 (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); 167 149 168 150 … … 172 154 173 155 static int process_get_port_status_request(rh_t *instance, uint16_t port, 174 156 usb_transfer_batch_t * request); 175 157 176 158 static int process_get_hub_status_request(rh_t *instance, 177 159 usb_transfer_batch_t * request); 178 160 179 161 static int process_get_status_request(rh_t *instance, 180 162 usb_transfer_batch_t * request); 181 163 182 164 static void create_interrupt_mask_in_instance(rh_t *instance); 183 165 184 166 static int process_get_descriptor_request(rh_t *instance, 185 167 usb_transfer_batch_t *request); 186 168 187 169 static int process_get_configuration_request(rh_t *instance, 188 170 usb_transfer_batch_t *request); 189 171 190 172 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature); 191 173 192 174 static int process_hub_feature_clear_request(rh_t *instance, 193 175 uint16_t feature); 194 176 195 177 static int process_port_feature_set_request(rh_t *instance, 196 178 uint16_t feature, uint16_t port); 197 179 198 180 static int process_port_feature_clear_request(rh_t *instance, 199 181 uint16_t feature, uint16_t port); 200 182 201 183 static int process_address_set_request(rh_t *instance, 202 184 uint16_t address); 203 185 204 186 static int process_request_with_output(rh_t *instance, 205 187 usb_transfer_batch_t *request); 206 188 207 189 static int process_request_with_input(rh_t *instance, 208 190 usb_transfer_batch_t *request); 209 191 210 192 static int process_request_without_data(rh_t *instance, 211 193 usb_transfer_batch_t *request); 212 194 213 195 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); … … 216 198 217 199 static bool is_zeros(void * buffer, size_t size); 200 201 218 202 219 203 /** Root hub initialization … … 226 210 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 227 211 int opResult = rh_init_descriptors(instance); 228 if (opResult != EOK){212 if(opResult != EOK){ 229 213 return opResult; 230 214 } … … 232 216 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 233 217 instance->unfinished_interrupt_transfer = NULL; 234 instance->interrupt_mask_size = (instance->port_count + 8) /8;218 instance->interrupt_mask_size = (instance->port_count + 8)/8; 235 219 instance->interrupt_buffer = malloc(instance->interrupt_mask_size); 236 if 220 if(!instance->interrupt_buffer) 237 221 return ENOMEM; 238 239 usb_log_info("OHCI root hub with %zu ports initialized.\n", 240 instance->port_count); 241 222 223 224 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 242 225 return EOK; 243 226 } … … 262 245 usb_log_info("Root hub got INTERRUPT packet\n"); 263 246 create_interrupt_mask_in_instance(instance); 264 if 265 instance->interrupt_mask_size)) 247 if(is_zeros(instance->interrupt_buffer, 248 instance->interrupt_mask_size)){ 266 249 usb_log_debug("no changes..\n"); 267 250 instance->unfinished_interrupt_transfer = request; 268 251 //will be finished later 269 } else{252 }else{ 270 253 usb_log_debug("processing changes..\n"); 271 254 process_interrupt_mask_in_instance(instance, request); … … 273 256 opResult = EOK; 274 257 } else { 275 276 258 opResult = EINVAL; 277 259 usb_transfer_batch_finish_error(request, opResult); … … 289 271 */ 290 272 void rh_interrupt(rh_t *instance) { 291 if (!instance->unfinished_interrupt_transfer){273 if(!instance->unfinished_interrupt_transfer){ 292 274 return; 293 275 } … … 310 292 static int create_serialized_hub_descriptor(rh_t *instance) { 311 293 size_t size = 7 + 312 ((instance->port_count + 7)/ 8) * 2;313 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; 314 296 uint8_t * result = (uint8_t*) malloc(size); 315 if 297 if(!result) return ENOMEM; 316 298 317 299 bzero(result, size); … … 323 305 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 324 306 result[3] = 325 326 327 328 329 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); 330 312 result[4] = 0; 331 313 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; 332 314 result[6] = 50; 333 315 334 size_t port;316 int port; 335 317 for (port = 1; port <= instance->port_count; ++port) { 336 318 uint8_t is_non_removable = 337 319 instance->registers->rh_desc_b >> port % 2; 338 320 result[7 + port / 8] += 339 321 is_non_removable << (port % 8); 340 322 } 341 323 size_t i; … … 345 327 instance->hub_descriptor = result; 346 328 instance->descriptor_size = size; 347 348 329 return EOK; 349 330 } … … 359 340 static int rh_init_descriptors(rh_t *instance) { 360 341 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 361 362 342 sizeof (ohci_rh_device_descriptor) 343 ); 363 344 usb_standard_configuration_descriptor_t descriptor; 364 345 memcpy(&descriptor, &ohci_rh_conf_descriptor, 365 346 sizeof (ohci_rh_conf_descriptor)); 366 347 367 348 int opResult = create_serialized_hub_descriptor(instance); 368 if (opResult != EOK){349 if(opResult != EOK){ 369 350 return opResult; 370 351 } 371 352 descriptor.total_length = 372 373 374 375 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; 376 357 377 358 uint8_t * full_config_descriptor = 378 379 if (!full_config_descriptor){359 (uint8_t*) malloc(descriptor.total_length); 360 if(!full_config_descriptor){ 380 361 return ENOMEM; 381 362 } 382 363 memcpy(full_config_descriptor, &descriptor, sizeof (descriptor)); 383 364 memcpy(full_config_descriptor + sizeof (descriptor), 384 365 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor)); 385 366 memcpy(full_config_descriptor + sizeof (descriptor) + 386 387 367 sizeof (ohci_rh_iface_descriptor), 368 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor)); 388 369 memcpy(full_config_descriptor + sizeof (descriptor) + 389 390 391 392 370 sizeof (ohci_rh_iface_descriptor) + 371 sizeof (ohci_rh_ep_descriptor), 372 instance->hub_descriptor, instance->descriptor_size); 373 393 374 instance->descriptors.configuration = full_config_descriptor; 394 375 instance->descriptors.configuration_size = descriptor.total_length; 395 396 376 return EOK; 397 377 } … … 409 389 */ 410 390 static int process_get_port_status_request(rh_t *instance, uint16_t port, 411 391 usb_transfer_batch_t * request) { 412 392 if (port < 1 || port > instance->port_count) 413 393 return EINVAL; … … 418 398 int i; 419 399 for (i = 0; i < instance->port_count; ++i) { 420 421 400 usb_log_debug("port status %d,x%x\n", 422 423 401 instance->registers->rh_port_status[i], 402 instance->registers->rh_port_status[i]); 424 403 } 425 404 #endif … … 438 417 */ 439 418 static int process_get_hub_status_request(rh_t *instance, 440 419 usb_transfer_batch_t * request) { 441 420 uint32_t * uint32_buffer = (uint32_t*) request->data_buffer; 442 421 request->transfered_size = 4; … … 444 423 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 445 424 uint32_buffer[0] = mask & instance->registers->rh_status; 446 447 425 return EOK; 448 426 } … … 459 437 */ 460 438 static int process_get_status_request(rh_t *instance, 461 439 usb_transfer_batch_t * request) { 462 440 size_t buffer_size = request->buffer_size; 463 441 usb_device_request_setup_packet_t * request_packet = 464 465 442 (usb_device_request_setup_packet_t*) 443 request->setup_buffer; 466 444 467 445 usb_hub_bm_request_type_t request_type = request_packet->request_type; … … 475 453 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 476 454 return process_get_port_status_request(instance, 477 request_packet->index, 478 request); 479 455 request_packet->index, 456 request); 480 457 return ENOTSUP; 481 458 } … … 495 472 uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer); 496 473 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 497 474 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 498 475 bzero(bitmap, instance->interrupt_mask_size); 499 476 if (instance->registers->rh_status & mask) { 500 477 bitmap[0] = 1; 501 478 } 502 size_t port;479 int port; 503 480 mask = port_status_change_mask; 504 481 for (port = 1; port <= instance->port_count; ++port) { 505 482 if (mask & instance->registers->rh_port_status[port - 1]) { 506 507 483 bitmap[(port) / 8] += 1 << (port % 8); 508 484 } … … 521 497 */ 522 498 static int process_get_descriptor_request(rh_t *instance, 523 499 usb_transfer_batch_t *request) { 524 500 usb_device_request_setup_packet_t * setup_request = 525 501 (usb_device_request_setup_packet_t*) request->setup_buffer; 526 502 size_t size; 527 503 const void * result_descriptor = NULL; … … 567 543 { 568 544 usb_log_debug("USB_DESCTYPE_EINVAL %d \n", 569 545 setup_request->value); 570 546 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue " 571 572 573 574 575 576 577 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 ); 578 554 return EINVAL; 579 555 } … … 584 560 request->transfered_size = size; 585 561 memcpy(request->data_buffer, result_descriptor, size); 586 587 562 return EOK; 588 563 } … … 598 573 */ 599 574 static int process_get_configuration_request(rh_t *instance, 600 575 usb_transfer_batch_t *request) { 601 576 //set and get configuration requests do not have any meaning, only dummy 602 577 //values are returned … … 605 580 request->data_buffer[0] = 1; 606 581 request->transfered_size = 1; 607 608 582 return EOK; 609 583 } … … 618 592 */ 619 593 static int process_hub_feature_set_request(rh_t *instance, 620 594 uint16_t feature) { 621 595 if (!((1 << feature) & hub_set_feature_valid_mask)) 622 596 return EINVAL; 623 if 597 if(feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER) 624 598 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16; 625 599 instance->registers->rh_status = 626 (instance->registers->rh_status | (1 << feature)) 627 & (~hub_clear_feature_by_writing_one_mask); 628 600 (instance->registers->rh_status | (1 << feature)) 601 & (~hub_clear_feature_by_writing_one_mask); 629 602 return EOK; 630 603 } … … 639 612 */ 640 613 static int process_hub_feature_clear_request(rh_t *instance, 641 614 uint16_t feature) { 642 615 if (!((1 << feature) & hub_clear_feature_valid_mask)) 643 616 return EINVAL; … … 645 618 if ((1 << feature) & hub_set_feature_direct_mask) { 646 619 instance->registers->rh_status = 647 648 620 (instance->registers->rh_status & (~(1 << feature))) 621 & (~hub_clear_feature_by_writing_one_mask); 649 622 } else {//the feature is cleared by writing '1' 650 651 623 instance->registers->rh_status = 652 653 654 624 (instance->registers->rh_status 625 & (~hub_clear_feature_by_writing_one_mask)) 626 | (1 << feature); 655 627 } 656 628 return EOK; … … 668 640 */ 669 641 static int process_port_feature_set_request(rh_t *instance, 670 642 uint16_t feature, uint16_t port) { 671 643 if (!((1 << feature) & port_set_feature_valid_mask)) 672 644 return EINVAL; … … 674 646 return EINVAL; 675 647 instance->registers->rh_port_status[port - 1] = 676 677 648 (instance->registers->rh_port_status[port - 1] | (1 << feature)) 649 & (~port_clear_feature_valid_mask); 678 650 /// \TODO any error? 679 680 651 return EOK; 681 652 } … … 692 663 */ 693 664 static int process_port_feature_clear_request(rh_t *instance, 694 665 uint16_t feature, uint16_t port) { 695 666 if (!((1 << feature) & port_clear_feature_valid_mask)) 696 667 return EINVAL; … … 702 673 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 703 674 instance->registers->rh_port_status[port - 1] = 704 705 706 675 (instance->registers->rh_port_status[port - 1] 676 & (~port_clear_feature_valid_mask)) 677 | (1 << feature); 707 678 /// \TODO any error? 708 709 679 return EOK; 710 680 } … … 719 689 */ 720 690 static int process_address_set_request(rh_t *instance, 721 691 uint16_t address) { 722 692 instance->address = address; 723 724 693 return EOK; 725 694 } … … 736 705 */ 737 706 static int process_request_with_output(rh_t *instance, 738 707 usb_transfer_batch_t *request) { 739 708 usb_device_request_setup_packet_t * setup_request = 740 709 (usb_device_request_setup_packet_t*) request->setup_buffer; 741 710 if (setup_request->request == USB_DEVREQ_GET_STATUS) { 742 711 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); … … 749 718 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) { 750 719 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 751 752 720 return process_get_configuration_request(instance, request); 753 721 } … … 766 734 */ 767 735 static int process_request_with_input(rh_t *instance, 768 736 usb_transfer_batch_t *request) { 769 737 usb_device_request_setup_packet_t * setup_request = 770 738 (usb_device_request_setup_packet_t*) request->setup_buffer; 771 739 request->transfered_size = 0; 772 740 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) { … … 776 744 //set and get configuration requests do not have any meaning, 777 745 //only dummy values are returned 778 779 746 return EOK; 780 747 } … … 793 760 */ 794 761 static int process_request_without_data(rh_t *instance, 795 762 usb_transfer_batch_t *request) { 796 763 usb_device_request_setup_packet_t * setup_request = 797 764 (usb_device_request_setup_packet_t*) request->setup_buffer; 798 765 request->transfered_size = 0; 799 766 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) { … … 801 768 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 802 769 return process_hub_feature_clear_request(instance, 803 770 setup_request->value); 804 771 } 805 772 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 806 773 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 807 774 return process_port_feature_clear_request(instance, 808 809 775 setup_request->value, 776 setup_request->index); 810 777 } 811 778 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 812 779 setup_request->request_type); 813 780 return EINVAL; 814 781 } … … 817 784 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 818 785 return process_hub_feature_set_request(instance, 819 786 setup_request->value); 820 787 } 821 788 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 822 789 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 823 790 return process_port_feature_set_request(instance, 824 825 791 setup_request->value, 792 setup_request->index); 826 793 } 827 794 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 828 795 setup_request->request_type); 829 796 return EINVAL; 830 797 } … … 832 799 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 833 800 return process_address_set_request(instance, 834 801 setup_request->value); 835 802 } 836 803 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n", 837 setup_request->request_type); 838 804 setup_request->request_type); 839 805 return ENOTSUP; 840 806 } … … 870 836 } 871 837 usb_log_info("CTRL packet: %s.\n", 872 873 838 usb_debug_str_buffer( 839 (const uint8_t *) request->setup_buffer, 8, 8)); 874 840 usb_device_request_setup_packet_t * setup_request = 875 876 841 (usb_device_request_setup_packet_t*) 842 request->setup_buffer; 877 843 switch (setup_request->request) { 878 844 case USB_DEVREQ_GET_STATUS: … … 881 847 usb_log_debug("processing request with output\n"); 882 848 opResult = process_request_with_output( 883 849 instance, request); 884 850 break; 885 851 case USB_DEVREQ_CLEAR_FEATURE: … … 887 853 case USB_DEVREQ_SET_ADDRESS: 888 854 usb_log_debug("processing request without " 889 855 "additional data\n"); 890 856 opResult = process_request_without_data( 891 857 instance, request); 892 858 break; 893 859 case USB_DEVREQ_SET_DESCRIPTOR: 894 860 case USB_DEVREQ_SET_CONFIGURATION: 895 861 usb_log_debug("processing request with " 896 862 "input\n"); 897 863 opResult = process_request_with_input( 898 instance, request); 899 864 instance, request); 900 865 break; 901 866 default: 902 867 usb_log_warning("received unsuported request: " 903 904 905 868 "%d\n", 869 setup_request->request 870 ); 906 871 opResult = ENOTSUP; 907 872 } … … 923 888 * @return 924 889 */ 925 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){ 926 891 memcpy(request->data_buffer, instance->interrupt_buffer, 927 892 instance->interrupt_mask_size); … … 929 894 instance->unfinished_interrupt_transfer = NULL; 930 895 usb_transfer_batch_finish_error(request, EOK); 931 932 896 return EOK; 933 897 } … … 943 907 * @return 944 908 */ 945 static bool is_zeros(void * buffer, size_t size) 946 if 947 if 909 static bool is_zeros(void * buffer, size_t size){ 910 if(!buffer) return true; 911 if(!size) return true; 948 912 size_t i; 949 for (i = 0; i < size; ++i){950 if (((char*)buffer)[i])913 for(i=0;i<size;++i){ 914 if(((char*)buffer)[i]) 951 915 return false; 952 916 }
Note:
See TracChangeset
for help on using the changeset viewer.