Changeset 48d4231 in mainline for uspace/drv/ohci/root_hub.c
- Timestamp:
- 2011-03-30T19:44:49Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ecb107b
- Parents:
- f62468c (diff), 27bdfa5 (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
rf62468c r48d4231 43 43 #include <usb/classes/hub.h> 44 44 45 /** 46 * standart device descriptor for ohci root hub 47 */ 45 48 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = 46 49 { … … 61 64 }; 62 65 66 /** 67 * standart configuration descriptor with filled common values 68 * for ohci root hubs 69 */ 63 70 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = 64 71 { … … 73 80 }; 74 81 82 /** 83 * standart ohci root hub interface descriptor 84 */ 75 85 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = 76 86 { … … 87 97 }; 88 98 99 /** 100 * standart ohci root hub endpoint descriptor 101 */ 89 102 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = 90 103 { … … 117 130 /*----------------------------------------------------------------------------*/ 118 131 119 132 /** 133 * create answer to port status_request 134 * 135 * Copy content of corresponding port status register to answer buffer. 136 * 137 * @param instance root hub instance 138 * @param port port number, counted from 1 139 * @param request structure containing both request and response information 140 * @return error code 141 */ 120 142 static int process_get_port_status_request(rh_t *instance, uint16_t port, 121 143 usb_transfer_batch_t * request){ … … 128 150 } 129 151 152 /** 153 * create answer to port status_request 154 * 155 * Copy content of hub status register to answer buffer. 156 * 157 * @param instance root hub instance 158 * @param request structure containing both request and response information 159 * @return error code 160 */ 130 161 static int process_get_hub_status_request(rh_t *instance, 131 162 usb_transfer_batch_t * request){ … … 139 170 } 140 171 141 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result, 172 /** 173 * Create hub descriptor used in hub-driver <-> hub communication 174 * 175 * This means creating byt array from data in root hub registers. For more 176 * info see usb hub specification. 177 * 178 * @param instance root hub instance 179 * @param@out out_result pointer to resultant serialized descriptor 180 * @param@out out_size size of serialized descriptor 181 */ 182 static void usb_create_serialized_hub_descriptor(rh_t *instance, 183 uint8_t ** out_result, 142 184 size_t * out_size) { 143 185 //base size … … 179 221 180 222 223 /** 224 * create answer to status request 225 * 226 * This might be either hub status or port status request. If neither, 227 * ENOTSUP is returned. 228 * @param instance root hub instance 229 * @param request structure containing both request and response information 230 * @return error code 231 */ 181 232 static int process_get_status_request(rh_t *instance, 182 233 usb_transfer_batch_t * request) … … 201 252 } 202 253 254 /** 255 * create answer to status interrupt consisting of change bitmap 256 * 257 * Result contains bitmap where bit 0 indicates change on hub and 258 * bit i indicates change on i`th port (i>0). For more info see 259 * Hub and Port status bitmap specification in USB specification. 260 * @param instance root hub instance 261 * @param@out buffer pointer to created interrupt mas 262 * @param@out buffer_size size of created interrupt mask 263 */ 203 264 static void create_interrupt_mask(rh_t *instance, void ** buffer, 204 265 size_t * buffer_size){ … … 224 285 } 225 286 226 287 /** 288 * create standart configuration descriptor for the root hub instance 289 * @param instance root hub instance 290 * @return newly allocated descriptor 291 */ 292 static usb_standard_configuration_descriptor_t * 293 usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){ 294 usb_standard_configuration_descriptor_t * descriptor = 295 malloc(sizeof(usb_standard_configuration_descriptor_t)); 296 memcpy(descriptor, &ohci_rh_conf_descriptor, 297 sizeof(usb_standard_configuration_descriptor_t)); 298 /// \TODO should this include device descriptor? 299 const size_t hub_descriptor_size = 7 + 300 2* (instance->port_count / 8 + 301 ((instance->port_count % 8 > 0) ? 1 : 0)); 302 descriptor->total_length = 303 sizeof(usb_standard_configuration_descriptor_t)+ 304 sizeof(usb_standard_endpoint_descriptor_t)+ 305 sizeof(usb_standard_interface_descriptor_t)+ 306 hub_descriptor_size; 307 return descriptor; 308 } 309 310 /** 311 * create answer to a descriptor request 312 * 313 * This might be a request for standard (configuration, device, endpoint or 314 * interface) or device specific (hub) descriptor. 315 * @param instance root hub instance 316 * @param request structure containing both request and response information 317 * @return error code 318 */ 227 319 static int process_get_descriptor_request(rh_t *instance, 228 320 usb_transfer_batch_t *request){ 229 /// \TODO230 321 usb_device_request_setup_packet_t * setup_request = 231 322 (usb_device_request_setup_packet_t*)request->setup_buffer; 232 323 size_t size; 233 const void * result_descriptor ;324 const void * result_descriptor = NULL; 234 325 const uint16_t setup_request_value = setup_request->value_high; 235 326 //(setup_request->value_low << 8); 236 327 bool del = false; 237 238 328 switch (setup_request_value) 239 329 { 240 case USB_DESCTYPE_HUB: { 241 uint8_t * descriptor; 242 usb_create_serialized_hub_descriptor( 243 instance, &descriptor, &size); 244 result_descriptor = descriptor; 245 break; 246 } 247 case USB_DESCTYPE_DEVICE: { 248 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 249 result_descriptor = &ohci_rh_device_descriptor; 250 size = sizeof(ohci_rh_device_descriptor); 251 break; 252 } 253 case USB_DESCTYPE_CONFIGURATION: { 254 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 255 usb_standard_configuration_descriptor_t * descriptor = 256 malloc(sizeof(usb_standard_configuration_descriptor_t)); 257 memcpy(descriptor, &ohci_rh_conf_descriptor, 258 sizeof(usb_standard_configuration_descriptor_t)); 259 /// \TODO should this include device descriptor? 260 const size_t hub_descriptor_size = 7 + 261 2* (instance->port_count / 8 + 262 ((instance->port_count % 8 > 0) ? 1 : 0)); 263 descriptor->total_length = 264 sizeof(usb_standard_configuration_descriptor_t)+ 265 sizeof(usb_standard_endpoint_descriptor_t)+ 266 sizeof(usb_standard_interface_descriptor_t)+ 267 hub_descriptor_size; 268 result_descriptor = descriptor; 269 size = sizeof(usb_standard_configuration_descriptor_t); 270 del = true; 271 break; 272 } 273 case USB_DESCTYPE_INTERFACE: { 274 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 275 result_descriptor = &ohci_rh_iface_descriptor; 276 size = sizeof(ohci_rh_iface_descriptor); 277 break; 278 } 279 case USB_DESCTYPE_ENDPOINT: { 280 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 281 result_descriptor = &ohci_rh_ep_descriptor; 282 size = sizeof(ohci_rh_ep_descriptor); 283 break; 284 } 285 default: { 286 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 287 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 288 setup_request->request_type, 289 setup_request->request, 290 setup_request_value, 291 setup_request->index, 292 setup_request->length 293 ); 294 return EINVAL; 295 } 296 } 297 #if 0 298 if(setup_request_value == USB_DESCTYPE_HUB){ 299 usb_log_debug("USB_DESCTYPE_HUB\n"); 300 //create hub descriptor 301 uint8_t * descriptor; 302 usb_create_serialized_hub_descriptor(instance, 303 &descriptor, &size); 304 result_descriptor = descriptor; 305 }else if(setup_request_value == USB_DESCTYPE_DEVICE){ 306 //create std device descriptor 307 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; 327 size = sizeof(usb_standard_device_descriptor_t); 328 }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){ 329 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; 351 size = sizeof(usb_standard_configuration_descriptor_t); 352 353 }else if(setup_request_value == USB_DESCTYPE_INTERFACE){ 354 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; 369 size = sizeof(usb_standard_interface_descriptor_t); 370 }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){ 371 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; 382 size = sizeof(usb_standard_endpoint_descriptor_t); 383 }else{ 384 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 385 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 386 setup_request->request_type, 387 setup_request->request, 388 setup_request_value, 389 setup_request->index, 390 setup_request->length 391 ); 392 return EINVAL; 393 } 394 #endif 330 case USB_DESCTYPE_HUB: { 331 uint8_t * descriptor; 332 usb_create_serialized_hub_descriptor( 333 instance, &descriptor, &size); 334 result_descriptor = descriptor; 335 if(result_descriptor) del = true; 336 break; 337 } 338 case USB_DESCTYPE_DEVICE: { 339 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 340 result_descriptor = &ohci_rh_device_descriptor; 341 size = sizeof(ohci_rh_device_descriptor); 342 break; 343 } 344 case USB_DESCTYPE_CONFIGURATION: { 345 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 346 usb_standard_configuration_descriptor_t * descriptor = 347 usb_ohci_rh_create_standart_configuration_descriptor( 348 instance); 349 result_descriptor = descriptor; 350 size = sizeof(usb_standard_configuration_descriptor_t); 351 del = true; 352 break; 353 } 354 case USB_DESCTYPE_INTERFACE: { 355 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 356 result_descriptor = &ohci_rh_iface_descriptor; 357 size = sizeof(ohci_rh_iface_descriptor); 358 break; 359 } 360 case USB_DESCTYPE_ENDPOINT: { 361 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 362 result_descriptor = &ohci_rh_ep_descriptor; 363 size = sizeof(ohci_rh_ep_descriptor); 364 break; 365 } 366 default: { 367 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 368 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 369 setup_request->request_type, 370 setup_request->request, 371 setup_request_value, 372 setup_request->index, 373 setup_request->length 374 ); 375 return EINVAL; 376 } 377 } 395 378 if(request->buffer_size < size){ 396 379 size = request->buffer_size; … … 403 386 } 404 387 388 /** 389 * answer to get configuration request 390 * 391 * Root hub works independently on the configuration. 392 * @param instance root hub instance 393 * @param request structure containing both request and response information 394 * @return error code 395 */ 405 396 static int process_get_configuration_request(rh_t *instance, 406 397 usb_transfer_batch_t *request){ … … 414 405 } 415 406 407 /** 408 * process feature-enabling/disabling request on hub 409 * 410 * @param instance root hub instance 411 * @param feature feature selector 412 * @param enable enable or disable specified feature 413 * @return error code 414 */ 416 415 static int process_hub_feature_set_request(rh_t *instance, 417 416 uint16_t feature, bool enable){ … … 427 426 } 428 427 428 /** 429 * process feature-enabling/disabling request on hub 430 * 431 * @param instance root hub instance 432 * @param feature feature selector 433 * @param port port number, counted from 1 434 * @param enable enable or disable the specified feature 435 * @return error code 436 */ 429 437 static int process_port_feature_set_request(rh_t *instance, 430 438 uint16_t feature, uint16_t port, bool enable){ … … 442 450 } 443 451 452 /** 453 * register address to this device 454 * 455 * @param instance root hub instance 456 * @param address new address 457 * @return error code 458 */ 444 459 static int process_address_set_request(rh_t *instance, 445 460 uint16_t address){ … … 448 463 } 449 464 465 /** 466 * process one of requests that requere output data 467 * 468 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or 469 * USB_DEVREQ_GET_CONFIGURATION. 470 * @param instance root hub instance 471 * @param request structure containing both request and response information 472 * @return error code 473 */ 450 474 static int process_request_with_output(rh_t *instance, 451 475 usb_transfer_batch_t *request){ … … 467 491 } 468 492 493 /** 494 * process one of requests that carry input data 495 * 496 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or 497 * USB_DEVREQ_SET_CONFIGURATION. 498 * @param instance root hub instance 499 * @param request structure containing both request and response information 500 * @return error code 501 */ 469 502 static int process_request_with_input(rh_t *instance, 470 503 usb_transfer_batch_t *request){ … … 483 516 } 484 517 485 518 /** 519 * process one of requests that do not request nor carry additional data 520 * 521 * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or 522 * USB_DEVREQ_SET_ADDRESS. 523 * @param instance root hub instance 524 * @param request structure containing both request and response information 525 * @return error code 526 */ 486 527 static int process_request_without_data(rh_t *instance, 487 528 usb_transfer_batch_t *request){ … … 513 554 } 514 555 515 516 /** 517 * 518 * @param instance 519 * @param request 520 * @return 556 /** 557 * process hub control request 558 * 559 * If needed, writes answer into the request structure. 560 * Request can be one of 561 * USB_DEVREQ_GET_STATUS, 562 * USB_DEVREQ_GET_DESCRIPTOR, 563 * USB_DEVREQ_GET_CONFIGURATION, 564 * USB_DEVREQ_CLEAR_FEATURE, 565 * USB_DEVREQ_SET_FEATURE, 566 * USB_DEVREQ_SET_ADDRESS, 567 * USB_DEVREQ_SET_DESCRIPTOR or 568 * USB_DEVREQ_SET_CONFIGURATION. 569 * 570 * @param instance root hub instance 571 * @param request structure containing both request and response information 572 * @return error code 573 */ 574 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){ 575 int opResult; 576 if (request->setup_buffer) { 577 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 578 usb_log_error("setup packet too small\n"); 579 return EINVAL; 580 } 581 usb_log_info("CTRL packet: %s.\n", 582 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 583 usb_device_request_setup_packet_t * setup_request = 584 (usb_device_request_setup_packet_t*)request->setup_buffer; 585 if( 586 setup_request->request == USB_DEVREQ_GET_STATUS 587 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 588 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 589 ){ 590 usb_log_debug("processing request with output\n"); 591 opResult = process_request_with_output(instance,request); 592 }else if( 593 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 594 || setup_request->request == USB_DEVREQ_SET_FEATURE 595 || setup_request->request == USB_DEVREQ_SET_ADDRESS 596 ){ 597 usb_log_debug("processing request without additional data\n"); 598 opResult = process_request_without_data(instance,request); 599 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 600 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 601 ){ 602 usb_log_debug("processing request with input\n"); 603 opResult = process_request_with_input(instance,request); 604 }else{ 605 usb_log_warning("received unsuported request: %d\n", 606 setup_request->request 607 ); 608 opResult = ENOTSUP; 609 } 610 }else{ 611 usb_log_error("root hub received empty transaction?"); 612 opResult = EINVAL; 613 } 614 return opResult; 615 } 616 617 /** 618 * process root hub request 619 * 620 * @param instance root hub instance 621 * @param request structure containing both request and response information 622 * @return error code 521 623 */ 522 624 int rh_request(rh_t *instance, usb_transfer_batch_t *request) … … 526 628 int opResult; 527 629 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 } 630 usb_log_info("Root hub got CONTROL packet\n"); 631 opResult = process_ctrl_request(instance,request); 566 632 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 567 633 usb_log_info("Root hub got INTERRUPT packet\n"); … … 582 648 void rh_interrupt(rh_t *instance) 583 649 { 584 usb_log_ error("Root hub interrupt not implemented.\n");585 /* TODO: implement */650 usb_log_info("Whoa whoa wait, I`m not supposed to receive any interrupts, am I?\n"); 651 /* TODO: implement? */ 586 652 } 587 653 /**
Note:
See TracChangeset
for help on using the changeset viewer.