Changeset cee51fd in mainline for uspace/drv/ohci/root_hub.c
- Timestamp:
- 2011-03-26T17:24:33Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b330b309
- Parents:
- c9f5e238 (diff), aee6c73 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
rc9f5e238 rcee51fd 117 117 /*----------------------------------------------------------------------------*/ 118 118 119 119 /** 120 * create answer to port status_request 121 * 122 * Copy content of corresponding port status register to answer buffer. 123 * 124 * @param instance root hub instance 125 * @param port port number, counted from 1 126 * @param request structure containing both request and response information 127 * @return error code 128 */ 120 129 static int process_get_port_status_request(rh_t *instance, uint16_t port, 121 130 usb_transfer_batch_t * request){ … … 128 137 } 129 138 139 /** 140 * create answer to port status_request 141 * 142 * Copy content of hub status register to answer buffer. 143 * 144 * @param instance root hub instance 145 * @param request structure containing both request and response information 146 * @return error code 147 */ 130 148 static int process_get_hub_status_request(rh_t *instance, 131 149 usb_transfer_batch_t * request){ … … 139 157 } 140 158 141 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result, 159 /** 160 * Create hub descriptor used in hub-driver <-> hub communication 161 * 162 * This means creating byt array from data in root hub registers. For more 163 * info see usb hub specification. 164 * 165 * @param instance root hub instance 166 * @param@out out_result pointer to resultant serialized descriptor 167 * @param@out out_size size of serialized descriptor 168 */ 169 static void usb_create_serialized_hub_descriptor(rh_t *instance, 170 uint8_t ** out_result, 142 171 size_t * out_size) { 143 172 //base size … … 179 208 180 209 210 /** 211 * create answer to status request 212 * 213 * This might be either hub status or port status request. If neither, 214 * ENOTSUP is returned. 215 * @param instance root hub instance 216 * @param request structure containing both request and response information 217 * @return error code 218 */ 181 219 static int process_get_status_request(rh_t *instance, 182 220 usb_transfer_batch_t * request) … … 201 239 } 202 240 241 /** 242 * create answer to status interrupt consisting of change bitmap 243 * 244 * Result contains bitmap where bit 0 indicates change on hub and 245 * bit i indicates change on i`th port (i>0). For more info see 246 * Hub and Port status bitmap specification in USB specification. 247 * @param instance root hub instance 248 * @param@out buffer pointer to created interrupt mas 249 * @param@out buffer_size size of created interrupt mask 250 */ 203 251 static void create_interrupt_mask(rh_t *instance, void ** buffer, 204 252 size_t * buffer_size){ … … 224 272 } 225 273 226 274 /** 275 * create standard device descriptor for a hub 276 * @return newly allocated descriptor 277 */ 278 static usb_standard_device_descriptor_t * 279 usb_ohci_rh_create_standard_device_descriptor(){ 280 usb_standard_device_descriptor_t * descriptor = 281 (usb_standard_device_descriptor_t*) 282 malloc(sizeof(usb_standard_device_descriptor_t)); 283 descriptor->configuration_count = 1; 284 descriptor->descriptor_type = USB_DESCTYPE_DEVICE; 285 descriptor->device_class = USB_CLASS_HUB; 286 descriptor->device_protocol = 0; 287 descriptor->device_subclass = 0; 288 descriptor->device_version = 0; 289 descriptor->length = sizeof(usb_standard_device_descriptor_t); 290 /// \TODO this value is guessed 291 descriptor->max_packet_size = 8; 292 descriptor->product_id = 0x0001; 293 /// \TODO these values migt be different 294 descriptor->str_serial_number = 0; 295 descriptor->str_serial_number = 0; 296 descriptor->usb_spec_version = 0; 297 descriptor->vendor_id = 0x16db; 298 return descriptor; 299 } 300 301 /** 302 * create standart configuration descriptor for the root hub instance 303 * @param instance root hub instance 304 * @return newly allocated descriptor 305 */ 306 static usb_standard_configuration_descriptor_t * 307 usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){ 308 usb_standard_configuration_descriptor_t * descriptor = 309 (usb_standard_configuration_descriptor_t*) 310 malloc(sizeof(usb_standard_configuration_descriptor_t)); 311 /// \TODO some values are default or guessed 312 descriptor->attributes = 1<<7; 313 descriptor->configuration_number = 1; 314 descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION; 315 descriptor->interface_count = 1; 316 descriptor->length = sizeof(usb_standard_configuration_descriptor_t); 317 descriptor->max_power = 100; 318 descriptor->str_configuration = 0; 319 /// \TODO should this include device descriptor? 320 size_t hub_descriptor_size = 7 + 321 2* (instance->port_count / 8 + 322 ((instance->port_count % 8 > 0) ? 1 : 0)); 323 descriptor->total_length = 324 sizeof(usb_standard_configuration_descriptor_t)+ 325 sizeof(usb_standard_endpoint_descriptor_t)+ 326 sizeof(usb_standard_interface_descriptor_t)+ 327 hub_descriptor_size; 328 return descriptor; 329 } 330 331 /** 332 * create standard interface descriptor for a root hub 333 * @return newly allocated descriptor 334 */ 335 static usb_standard_interface_descriptor_t * 336 usb_ohci_rh_create_standard_interface_descriptor(){ 337 usb_standard_interface_descriptor_t * descriptor = 338 (usb_standard_interface_descriptor_t*) 339 malloc(sizeof(usb_standard_interface_descriptor_t)); 340 descriptor->alternate_setting = 0; 341 descriptor->descriptor_type = USB_DESCTYPE_INTERFACE; 342 descriptor->endpoint_count = 1; 343 descriptor->interface_class = USB_CLASS_HUB; 344 /// \TODO is this correct? 345 descriptor->interface_number = 1; 346 descriptor->interface_protocol = 0; 347 descriptor->interface_subclass = 0; 348 descriptor->length = sizeof(usb_standard_interface_descriptor_t); 349 descriptor->str_interface = 0; 350 return descriptor; 351 } 352 353 /** 354 * create standard endpoint descriptor for a root hub 355 * @return newly allocated descriptor 356 */ 357 static usb_standard_endpoint_descriptor_t * 358 usb_ohci_rh_create_standard_endpoint_descriptor(){ 359 usb_standard_endpoint_descriptor_t * descriptor = 360 (usb_standard_endpoint_descriptor_t*) 361 malloc(sizeof(usb_standard_endpoint_descriptor_t)); 362 descriptor->attributes = USB_TRANSFER_INTERRUPT; 363 descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT; 364 descriptor->endpoint_address = 1 + (1<<7); 365 descriptor->length = sizeof(usb_standard_endpoint_descriptor_t); 366 descriptor->max_packet_size = 8; 367 descriptor->poll_interval = 255; 368 return descriptor; 369 } 370 371 /** 372 * create answer to a descriptor request 373 * 374 * This might be a request for standard (configuration, device, endpoint or 375 * interface) or device specific (hub) descriptor. 376 * @param instance root hub instance 377 * @param request structure containing both request and response information 378 * @return error code 379 */ 227 380 static int process_get_descriptor_request(rh_t *instance, 228 381 usb_transfer_batch_t *request){ 229 /// \TODO230 382 usb_device_request_setup_packet_t * setup_request = 231 383 (usb_device_request_setup_packet_t*)request->setup_buffer; 232 384 size_t size; 233 const void * result_descriptor ;385 const void * result_descriptor = NULL; 234 386 const uint16_t setup_request_value = setup_request->value_high; 235 387 //(setup_request->value_low << 8); 388 #if 0 236 389 bool del = false; 237 390 //this code was merged from development and has to be reviewed 238 391 switch (setup_request_value) 239 392 { … … 295 448 } 296 449 } 297 # if 0450 #endif 298 451 if(setup_request_value == USB_DESCTYPE_HUB){ 299 452 usb_log_debug("USB_DESCTYPE_HUB\n"); … … 306 459 //create std device descriptor 307 460 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 308 usb_standard_device_descriptor_t * descriptor = 309 (usb_standard_device_descriptor_t*) 310 malloc(sizeof(usb_standard_device_descriptor_t)); 311 descriptor->configuration_count = 1; 312 descriptor->descriptor_type = USB_DESCTYPE_DEVICE; 313 descriptor->device_class = USB_CLASS_HUB; 314 descriptor->device_protocol = 0; 315 descriptor->device_subclass = 0; 316 descriptor->device_version = 0; 317 descriptor->length = sizeof(usb_standard_device_descriptor_t); 318 /// \TODO this value is guessed 319 descriptor->max_packet_size = 8; 320 descriptor->product_id = 0x0001; 321 /// \TODO these values migt be different 322 descriptor->str_serial_number = 0; 323 descriptor->str_serial_number = 0; 324 descriptor->usb_spec_version = 0; 325 descriptor->vendor_id = 0x16db; 326 result_descriptor = descriptor; 461 result_descriptor = 462 usb_ohci_rh_create_standard_device_descriptor(); 327 463 size = sizeof(usb_standard_device_descriptor_t); 328 464 }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){ 329 465 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 330 usb_standard_configuration_descriptor_t * descriptor = 331 (usb_standard_configuration_descriptor_t*) 332 malloc(sizeof(usb_standard_configuration_descriptor_t)); 333 /// \TODO some values are default or guessed 334 descriptor->attributes = 1<<7; 335 descriptor->configuration_number = 1; 336 descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION; 337 descriptor->interface_count = 1; 338 descriptor->length = sizeof(usb_standard_configuration_descriptor_t); 339 descriptor->max_power = 100; 340 descriptor->str_configuration = 0; 341 /// \TODO should this include device descriptor? 342 size_t hub_descriptor_size = 7 + 343 2* (instance->port_count / 8 + 344 ((instance->port_count % 8 > 0) ? 1 : 0)); 345 descriptor->total_length = 346 sizeof(usb_standard_configuration_descriptor_t)+ 347 sizeof(usb_standard_endpoint_descriptor_t)+ 348 sizeof(usb_standard_interface_descriptor_t)+ 349 hub_descriptor_size; 350 result_descriptor = descriptor; 466 result_descriptor = 467 usb_ohci_rh_create_standart_configuration_descriptor(instance); 351 468 size = sizeof(usb_standard_configuration_descriptor_t); 352 469 353 470 }else if(setup_request_value == USB_DESCTYPE_INTERFACE){ 354 471 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 355 usb_standard_interface_descriptor_t * descriptor = 356 (usb_standard_interface_descriptor_t*) 357 malloc(sizeof(usb_standard_interface_descriptor_t)); 358 descriptor->alternate_setting = 0; 359 descriptor->descriptor_type = USB_DESCTYPE_INTERFACE; 360 descriptor->endpoint_count = 1; 361 descriptor->interface_class = USB_CLASS_HUB; 362 /// \TODO is this correct? 363 descriptor->interface_number = 1; 364 descriptor->interface_protocol = 0; 365 descriptor->interface_subclass = 0; 366 descriptor->length = sizeof(usb_standard_interface_descriptor_t); 367 descriptor->str_interface = 0; 368 result_descriptor = descriptor; 472 result_descriptor = 473 usb_ohci_rh_create_standard_interface_descriptor(); 369 474 size = sizeof(usb_standard_interface_descriptor_t); 370 475 }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){ 371 476 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 372 usb_standard_endpoint_descriptor_t * descriptor = 373 (usb_standard_endpoint_descriptor_t*) 374 malloc(sizeof(usb_standard_endpoint_descriptor_t)); 375 descriptor->attributes = USB_TRANSFER_INTERRUPT; 376 descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT; 377 descriptor->endpoint_address = 1 + (1<<7); 378 descriptor->length = sizeof(usb_standard_endpoint_descriptor_t); 379 descriptor->max_packet_size = 8; 380 descriptor->poll_interval = 255; 381 result_descriptor = descriptor; 477 result_descriptor = 478 usb_ohci_rh_create_standard_endpoint_descriptor(); 382 479 size = sizeof(usb_standard_endpoint_descriptor_t); 383 480 }else{ … … 392 489 return EINVAL; 393 490 } 394 #endif395 491 if(request->buffer_size < size){ 396 492 size = request->buffer_size; … … 398 494 request->transfered_size = size; 399 495 memcpy(request->buffer,result_descriptor,size); 400 if ( del)496 if (result_descriptor) 401 497 free(result_descriptor); 402 498 return EOK; 403 499 } 404 500 501 /** 502 * answer to get configuration request 503 * 504 * Root hub works independently on the configuration. 505 * @param instance root hub instance 506 * @param request structure containing both request and response information 507 * @return error code 508 */ 405 509 static int process_get_configuration_request(rh_t *instance, 406 510 usb_transfer_batch_t *request){ … … 414 518 } 415 519 520 /** 521 * process feature-enabling/disabling request on hub 522 * 523 * @param instance root hub instance 524 * @param feature feature selector 525 * @param enable enable or disable specified feature 526 * @return error code 527 */ 416 528 static int process_hub_feature_set_request(rh_t *instance, 417 529 uint16_t feature, bool enable){ … … 427 539 } 428 540 541 /** 542 * process feature-enabling/disabling request on hub 543 * 544 * @param instance root hub instance 545 * @param feature feature selector 546 * @param port port number, counted from 1 547 * @param enable enable or disable the specified feature 548 * @return error code 549 */ 429 550 static int process_port_feature_set_request(rh_t *instance, 430 551 uint16_t feature, uint16_t port, bool enable){ … … 442 563 } 443 564 565 /** 566 * register address to this device 567 * 568 * @param instance root hub instance 569 * @param address new address 570 * @return error code 571 */ 444 572 static int process_address_set_request(rh_t *instance, 445 573 uint16_t address){ … … 448 576 } 449 577 578 /** 579 * process one of requests that requere output data 580 * 581 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or 582 * USB_DEVREQ_GET_CONFIGURATION. 583 * @param instance root hub instance 584 * @param request structure containing both request and response information 585 * @return error code 586 */ 450 587 static int process_request_with_output(rh_t *instance, 451 588 usb_transfer_batch_t *request){ … … 467 604 } 468 605 606 /** 607 * process one of requests that carry input data 608 * 609 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or 610 * USB_DEVREQ_SET_CONFIGURATION. 611 * @param instance root hub instance 612 * @param request structure containing both request and response information 613 * @return error code 614 */ 469 615 static int process_request_with_input(rh_t *instance, 470 616 usb_transfer_batch_t *request){ … … 483 629 } 484 630 485 631 /** 632 * process one of requests that do not request nor carry additional data 633 * 634 * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or 635 * USB_DEVREQ_SET_ADDRESS. 636 * @param instance root hub instance 637 * @param request structure containing both request and response information 638 * @return error code 639 */ 486 640 static int process_request_without_data(rh_t *instance, 487 641 usb_transfer_batch_t *request){ … … 513 667 } 514 668 515 516 /** 517 * 518 * @param instance 519 * @param request 520 * @return 669 /** 670 * process hub control request 671 * 672 * If needed, writes answer into the request structure. 673 * Request can be one of 674 * USB_DEVREQ_GET_STATUS, 675 * USB_DEVREQ_GET_DESCRIPTOR, 676 * USB_DEVREQ_GET_CONFIGURATION, 677 * USB_DEVREQ_CLEAR_FEATURE, 678 * USB_DEVREQ_SET_FEATURE, 679 * USB_DEVREQ_SET_ADDRESS, 680 * USB_DEVREQ_SET_DESCRIPTOR or 681 * USB_DEVREQ_SET_CONFIGURATION. 682 * 683 * @param instance root hub instance 684 * @param request structure containing both request and response information 685 * @return error code 686 */ 687 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){ 688 int opResult; 689 if (request->setup_buffer) { 690 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 691 usb_log_error("setup packet too small\n"); 692 return EINVAL; 693 } 694 usb_log_info("CTRL packet: %s.\n", 695 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 696 usb_device_request_setup_packet_t * setup_request = 697 (usb_device_request_setup_packet_t*)request->setup_buffer; 698 if( 699 setup_request->request == USB_DEVREQ_GET_STATUS 700 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 701 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 702 ){ 703 usb_log_debug("processing request with output\n"); 704 opResult = process_request_with_output(instance,request); 705 }else if( 706 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 707 || setup_request->request == USB_DEVREQ_SET_FEATURE 708 || setup_request->request == USB_DEVREQ_SET_ADDRESS 709 ){ 710 usb_log_debug("processing request without additional data\n"); 711 opResult = process_request_without_data(instance,request); 712 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 713 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 714 ){ 715 usb_log_debug("processing request with input\n"); 716 opResult = process_request_with_input(instance,request); 717 }else{ 718 usb_log_warning("received unsuported request: %d\n", 719 setup_request->request 720 ); 721 opResult = ENOTSUP; 722 } 723 }else{ 724 usb_log_error("root hub received empty transaction?"); 725 opResult = EINVAL; 726 } 727 return opResult; 728 } 729 730 /** 731 * process root hub request 732 * 733 * @param instance root hub instance 734 * @param request structure containing both request and response information 735 * @return error code 521 736 */ 522 737 int rh_request(rh_t *instance, usb_transfer_batch_t *request) … … 526 741 int opResult; 527 742 if(request->transfer_type == USB_TRANSFER_CONTROL){ 528 if (request->setup_buffer) { 529 usb_log_info("Root hub got CTRL packet: %s.\n", 530 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 531 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 532 usb_log_error("setup packet too small\n"); 533 return EINVAL; 534 } 535 usb_device_request_setup_packet_t * setup_request = 536 (usb_device_request_setup_packet_t*)request->setup_buffer; 537 if( 538 setup_request->request == USB_DEVREQ_GET_STATUS 539 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 540 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 541 ){ 542 usb_log_debug("processing request with output\n"); 543 opResult = process_request_with_output(instance,request); 544 }else if( 545 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 546 || setup_request->request == USB_DEVREQ_SET_FEATURE 547 || setup_request->request == USB_DEVREQ_SET_ADDRESS 548 ){ 549 usb_log_debug("processing request without additional data\n"); 550 opResult = process_request_without_data(instance,request); 551 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 552 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 553 ){ 554 usb_log_debug("processing request with input\n"); 555 opResult = process_request_with_input(instance,request); 556 }else{ 557 usb_log_warning("received unsuported request: %d\n", 558 setup_request->request 559 ); 560 opResult = ENOTSUP; 561 } 562 }else{ 563 usb_log_error("root hub received empty transaction?"); 564 opResult = EINVAL; 565 } 743 usb_log_info("Root hub got CONTROL packet\n"); 744 opResult = process_ctrl_request(instance,request); 566 745 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 567 746 usb_log_info("Root hub got INTERRUPT packet\n"); … … 582 761 void rh_interrupt(rh_t *instance) 583 762 { 584 usb_log_ error("Root hub interrupt not implemented.\n");585 /* TODO: implement */763 usb_log_info("Whoa whoa wait, I`m not supposed to receive interrupts, am I?\n"); 764 /* TODO: implement? */ 586 765 } 587 766 /**
Note:
See TracChangeset
for help on using the changeset viewer.