Changes in / [aee6c73:c9f5e238] in mainline
- Location:
- uspace/drv
- Files:
-
- 2 edited
-
ohci/root_hub.c (modified) (19 diffs)
-
usbhub/usbhub.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
raee6c73 rc9f5e238 117 117 /*----------------------------------------------------------------------------*/ 118 118 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 */ 119 129 120 static int process_get_port_status_request(rh_t *instance, uint16_t port, 130 121 usb_transfer_batch_t * request){ … … 137 128 } 138 129 139 /**140 * create answer to port status_request141 *142 * Copy content of hub status register to answer buffer.143 *144 * @param instance root hub instance145 * @param request structure containing both request and response information146 * @return error code147 */148 130 static int process_get_hub_status_request(rh_t *instance, 149 131 usb_transfer_batch_t * request){ … … 157 139 } 158 140 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, 141 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result, 171 142 size_t * out_size) { 172 143 //base size … … 208 179 209 180 210 /**211 * create answer to status request212 *213 * This might be either hub status or port status request. If neither,214 * ENOTSUP is returned.215 * @param instance root hub instance216 * @param request structure containing both request and response information217 * @return error code218 */219 181 static int process_get_status_request(rh_t *instance, 220 182 usb_transfer_batch_t * request) … … 239 201 } 240 202 241 /**242 * create answer to status interrupt consisting of change bitmap243 *244 * Result contains bitmap where bit 0 indicates change on hub and245 * bit i indicates change on i`th port (i>0). For more info see246 * Hub and Port status bitmap specification in USB specification.247 * @param instance root hub instance248 * @param@out buffer pointer to created interrupt mas249 * @param@out buffer_size size of created interrupt mask250 */251 203 static void create_interrupt_mask(rh_t *instance, void ** buffer, 252 204 size_t * buffer_size){ … … 272 224 } 273 225 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 */ 226 380 227 static int process_get_descriptor_request(rh_t *instance, 381 228 usb_transfer_batch_t *request){ 229 /// \TODO 382 230 usb_device_request_setup_packet_t * setup_request = 383 231 (usb_device_request_setup_packet_t*)request->setup_buffer; 384 232 size_t size; 385 const void * result_descriptor = NULL;233 const void * result_descriptor; 386 234 const uint16_t setup_request_value = setup_request->value_high; 387 235 //(setup_request->value_low << 8); 388 #if 0389 236 bool del = false; 390 //this code was merged from development and has to be reviewed 237 391 238 switch (setup_request_value) 392 239 { … … 448 295 } 449 296 } 450 # endif297 #if 0 451 298 if(setup_request_value == USB_DESCTYPE_HUB){ 452 299 usb_log_debug("USB_DESCTYPE_HUB\n"); … … 459 306 //create std device descriptor 460 307 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 461 result_descriptor = 462 usb_ohci_rh_create_standard_device_descriptor(); 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; 463 327 size = sizeof(usb_standard_device_descriptor_t); 464 328 }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){ 465 329 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 466 result_descriptor = 467 usb_ohci_rh_create_standart_configuration_descriptor(instance); 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; 468 351 size = sizeof(usb_standard_configuration_descriptor_t); 469 352 470 353 }else if(setup_request_value == USB_DESCTYPE_INTERFACE){ 471 354 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 472 result_descriptor = 473 usb_ohci_rh_create_standard_interface_descriptor(); 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; 474 369 size = sizeof(usb_standard_interface_descriptor_t); 475 370 }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){ 476 371 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 477 result_descriptor = 478 usb_ohci_rh_create_standard_endpoint_descriptor(); 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; 479 382 size = sizeof(usb_standard_endpoint_descriptor_t); 480 383 }else{ … … 489 392 return EINVAL; 490 393 } 394 #endif 491 395 if(request->buffer_size < size){ 492 396 size = request->buffer_size; … … 494 398 request->transfered_size = size; 495 399 memcpy(request->buffer,result_descriptor,size); 496 if ( result_descriptor)400 if (del) 497 401 free(result_descriptor); 498 402 return EOK; 499 403 } 500 404 501 /**502 * answer to get configuration request503 *504 * Root hub works independently on the configuration.505 * @param instance root hub instance506 * @param request structure containing both request and response information507 * @return error code508 */509 405 static int process_get_configuration_request(rh_t *instance, 510 406 usb_transfer_batch_t *request){ … … 518 414 } 519 415 520 /**521 * process feature-enabling/disabling request on hub522 *523 * @param instance root hub instance524 * @param feature feature selector525 * @param enable enable or disable specified feature526 * @return error code527 */528 416 static int process_hub_feature_set_request(rh_t *instance, 529 417 uint16_t feature, bool enable){ … … 539 427 } 540 428 541 /**542 * process feature-enabling/disabling request on hub543 *544 * @param instance root hub instance545 * @param feature feature selector546 * @param port port number, counted from 1547 * @param enable enable or disable the specified feature548 * @return error code549 */550 429 static int process_port_feature_set_request(rh_t *instance, 551 430 uint16_t feature, uint16_t port, bool enable){ … … 563 442 } 564 443 565 /**566 * register address to this device567 *568 * @param instance root hub instance569 * @param address new address570 * @return error code571 */572 444 static int process_address_set_request(rh_t *instance, 573 445 uint16_t address){ … … 576 448 } 577 449 578 /**579 * process one of requests that requere output data580 *581 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or582 * USB_DEVREQ_GET_CONFIGURATION.583 * @param instance root hub instance584 * @param request structure containing both request and response information585 * @return error code586 */587 450 static int process_request_with_output(rh_t *instance, 588 451 usb_transfer_batch_t *request){ … … 604 467 } 605 468 606 /**607 * process one of requests that carry input data608 *609 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or610 * USB_DEVREQ_SET_CONFIGURATION.611 * @param instance root hub instance612 * @param request structure containing both request and response information613 * @return error code614 */615 469 static int process_request_with_input(rh_t *instance, 616 470 usb_transfer_batch_t *request){ … … 629 483 } 630 484 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 */ 485 640 486 static int process_request_without_data(rh_t *instance, 641 487 usb_transfer_batch_t *request){ … … 667 513 } 668 514 515 669 516 /** 670 * process hub control request671 517 * 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 518 * @param instance 519 * @param request 520 * @return 736 521 */ 737 522 int rh_request(rh_t *instance, usb_transfer_batch_t *request) … … 741 526 int opResult; 742 527 if(request->transfer_type == USB_TRANSFER_CONTROL){ 743 usb_log_info("Root hub got CONTROL packet\n"); 744 opResult = process_ctrl_request(instance,request); 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 } 745 566 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 746 567 usb_log_info("Root hub got INTERRUPT packet\n"); … … 761 582 void rh_interrupt(rh_t *instance) 762 583 { 763 usb_log_ info("Whoa whoa wait, I`m not supposed to receive interrupts, am I?\n");764 /* TODO: implement ?*/584 usb_log_error("Root hub interrupt not implemented.\n"); 585 /* TODO: implement */ 765 586 } 766 587 /** -
uspace/drv/usbhub/usbhub.c
raee6c73 rc9f5e238 53 53 #include "usb/classes/classes.h" 54 54 55 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,56 usb_speed_t speed);57 58 static int usb_hub_attach_non_removable_devices(usb_hub_info_t * hub,59 usb_hub_descriptor_t * descriptor);60 61 55 int usb_hub_control_loop(void * hub_info_param){ 62 56 usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param; … … 97 91 98 92 /** 99 * Load hub-specific information into hub_info structure and process if needed93 * Load hub-specific information into hub_info structure. 100 94 * 101 95 * Particularly read port count and initialize structure holding port 102 * information. If there are non-removable devices, start initializing them.96 * information. 103 97 * This function is hub-specific and should be run only after the hub is 104 98 * configured using usb_hub_set_configuration function. … … 106 100 * @return error code 107 101 */ 108 static int usb_hub_ process_hub_specific_info(usb_hub_info_t * hub_info){102 static int usb_hub_get_hub_specific_info(usb_hub_info_t * hub_info){ 109 103 // get hub descriptor 110 104 usb_log_debug("creating serialized descriptor\n"); … … 113 107 114 108 /* this was one fix of some bug, should not be needed anymore 115 * these lines allow to reset hub once more, it can be used as116 * brute-force initialization for non-removable devices117 109 int opResult = usb_request_set_configuration(&result->endpoints.control, 1); 118 110 if(opResult!=EOK){ … … 149 141 hub_info->attached_devs[i].address=0; 150 142 } 151 usb_hub_attach_non_removable_devices(hub_info, descriptor);152 143 usb_log_debug2("freeing data\n"); 153 144 free(serialized_descriptor); … … 227 218 } 228 219 //get port count and create attached_devs 229 opResult = usb_hub_ process_hub_specific_info(hub_info);220 opResult = usb_hub_get_hub_specific_info(hub_info); 230 221 if(opResult!=EOK){ 231 222 usb_log_error("could not set hub configuration, errno %d\n",opResult); … … 265 256 //********************************************* 266 257 // 267 // hub driver code, main loop and port handling258 // hub driver code, main loop 268 259 // 269 260 //********************************************* 270 271 /**272 * Perform \a usb_hub_init_add_device on all ports with non-removable device273 *274 * This will trigger operations leading to activated non-removable device.275 * Control pipe of the hub must be open fo communication.276 * @param hub hub instance277 * @param descriptor usb hub descriptor278 * @return error code279 */280 static int usb_hub_attach_non_removable_devices(usb_hub_info_t * hub,281 usb_hub_descriptor_t * descriptor)282 {283 usb_log_info("attaching non-removable devices(if any)\n");284 usb_device_request_setup_packet_t request;285 int opResult;286 size_t rcvd_size;287 usb_port_status_t status;288 uint8_t * non_removable_dev_bitmap = descriptor->devices_removable;289 //initialize all connected, non-removable devices290 int port;291 for(port=1;port<=descriptor->ports_count;++port){292 bool is_non_removable =293 ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2;294 if(is_non_removable){295 usb_log_debug("non-removable device on port %d\n",port);296 usb_hub_set_port_status_request(&request, port);297 opResult = usb_pipe_control_read(298 hub->control_pipe,299 &request, sizeof(usb_device_request_setup_packet_t),300 &status, 4, &rcvd_size301 );302 if (opResult != EOK) {303 usb_log_error("could not get port status of port %d errno:%d\n",304 port, opResult);305 return opResult;306 }307 //this should be true..308 if(usb_port_dev_connected(&status)){309 usb_hub_init_add_device(hub,port,usb_port_speed(&status));310 }311 }312 }313 return EOK;314 }315 316 261 317 262 /**
Note:
See TracChangeset
for help on using the changeset viewer.
