Changeset a00768c in mainline for uspace/drv/bus/usb/ohci/root_hub.c
- Timestamp:
- 2011-07-11T00:49:23Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1cb4f05
- Parents:
- 1ef93fa
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/root_hub.c
r1ef93fa ra00768c 166 166 static int rh_init_descriptors(rh_t *instance); 167 167 168 static int process_get_port_status_request(rh_t *instance, uint16_t port,169 usb_transfer_batch_t * request);170 171 static int process_get_hub_status_request(rh_t *instance,172 usb_transfer_batch_t * request);173 174 static int process_get_status_request(rh_t *instance,175 usb_transfer_batch_t * request);176 177 168 static void create_interrupt_mask_in_instance(rh_t *instance); 178 169 179 static int process_get_descriptor_request(rh_t *instance, 180 usb_transfer_batch_t *request); 181 182 static int process_get_configuration_request(rh_t *instance, 183 usb_transfer_batch_t *request); 170 static int process_get_port_status_request( 171 rh_t *instance, uint16_t port, usb_transfer_batch_t *request); 172 173 static int process_get_hub_status_request( 174 rh_t *instance, usb_transfer_batch_t *request); 175 176 static int process_get_status_request( 177 rh_t *instance, usb_transfer_batch_t *request); 178 179 180 static int process_get_descriptor_request( 181 rh_t *instance, usb_transfer_batch_t *request); 182 183 static int process_get_configuration_request( 184 rh_t *instance, usb_transfer_batch_t *request); 184 185 185 186 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature); 186 187 187 static int process_hub_feature_clear_request(rh_t *instance, 188 uint16_t feature); 189 190 static int process_port_feature_set_request(rh_t *instance, 191 uint16_t feature, uint16_t port); 192 193 static int process_port_feature_clear_request(rh_t *instance, 194 uint16_t feature, uint16_t port); 195 196 static int process_address_set_request(rh_t *instance, 197 uint16_t address); 198 199 static int process_request_with_output(rh_t *instance, 200 usb_transfer_batch_t *request); 201 202 static int process_request_with_input(rh_t *instance, 203 usb_transfer_batch_t *request); 204 205 static int process_request_without_data(rh_t *instance, 206 usb_transfer_batch_t *request); 188 static int process_hub_feature_clear_request( 189 rh_t *instance, uint16_t feature); 190 191 static int process_port_feature_set_request( 192 rh_t *instance, uint16_t feature, uint16_t port); 193 194 static int process_port_feature_clear_request( 195 rh_t *instance, uint16_t feature, uint16_t port); 196 197 static int process_request_with_input( 198 rh_t *instance, usb_transfer_batch_t *request); 199 200 static int process_request_with_output( 201 rh_t *instance, usb_transfer_batch_t *request); 202 203 static int process_request_without_data( 204 rh_t *instance, usb_transfer_batch_t *request); 207 205 208 206 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); 209 207 210 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request); 211 212 static bool is_zeros(void * buffer, size_t size); 208 static int process_interrupt_mask_in_instance( 209 rh_t *instance, usb_transfer_batch_t *request); 210 211 static bool is_zeros(const void *buffer, size_t size); 212 213 /** 214 * Register address to this device 215 * 216 * @param instance Root hub instance 217 * @param address New address 218 * @return Error code 219 */ 220 static inline int process_address_set_request(rh_t *instance, uint16_t address) 221 { return ENOTSUP; } 213 222 214 223 /** Root hub initialization … … 238 247 } 239 248 /*----------------------------------------------------------------------------*/ 240 241 /** 242 * process root hub request 243 * 244 * @param instance root hub instance 245 * @param request structure containing both request and response information 246 * @return error code 247 */ 248 int rh_request(rh_t *instance, usb_transfer_batch_t *request) { 249 assert(instance); 250 assert(request); 249 /** 250 * Process root hub request. 251 * 252 * @param instance Root hub instance 253 * @param request Structure containing both request and response information 254 * @return Error code 255 */ 256 int rh_request(rh_t *instance, usb_transfer_batch_t *request) 257 { 258 assert(instance); 259 assert(request); 260 251 261 int opResult; 252 if (request->ep->transfer_type == USB_TRANSFER_CONTROL) { 262 switch (request->ep->transfer_type) 263 { 264 case USB_TRANSFER_CONTROL: 253 265 usb_log_debug("Root hub got CONTROL packet\n"); 254 266 opResult = process_ctrl_request(instance, request); 255 267 usb_transfer_batch_finish_error(request, opResult); 256 } else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) { 268 break; 269 case USB_TRANSFER_INTERRUPT: 257 270 usb_log_debug("Root hub got INTERRUPT packet\n"); 258 271 create_interrupt_mask_in_instance(instance); … … 266 279 process_interrupt_mask_in_instance(instance, request); 267 280 } 268 opResult = EOK; 269 } else { 270 271 opResult = EINVAL; 272 usb_transfer_batch_finish_error(request, opResult); 273 } 274 return EOK; 275 } 276 277 /*----------------------------------------------------------------------------*/ 278 281 break; 282 default: 283 usb_log_error("Root hub got unsupported request.\n"); 284 usb_transfer_batch_finish_error(request, EINVAL); 285 } 286 return EOK; 287 } 288 /*----------------------------------------------------------------------------*/ 279 289 /** 280 290 * process interrupt on a hub … … 283 293 * @param instance 284 294 */ 285 void rh_interrupt(rh_t *instance) { 286 if (!instance->unfinished_interrupt_transfer) { 295 void rh_interrupt(rh_t *instance) 296 { 297 if (!instance->unfinished_interrupt_transfer) 287 298 return; 288 } 299 289 300 usb_log_debug("Finalizing interrupt transfer\n"); 290 301 create_interrupt_mask_in_instance(instance); … … 293 304 } 294 305 /*----------------------------------------------------------------------------*/ 295 296 306 /** 297 307 * Create hub descriptor used in hub-driver <-> hub communication 298 308 * 299 * This means creating b yt array from data in root hub registers. For more309 * This means creating bit array from data in root hub registers. For more 300 310 * info see usb hub specification. 301 311 * 302 * @param instance root hub instance 303 * @return error code 304 */ 305 static int create_serialized_hub_descriptor(rh_t *instance) { 306 size_t size = 7 + 312 * @param instance Root hub instance 313 * @return Error code 314 */ 315 int create_serialized_hub_descriptor(rh_t *instance) 316 { 317 assert(instance); 318 319 const size_t size = 7 + 307 320 ((instance->port_count + 7) / 8) * 2; 308 size_t var_size = (instance->port_count + 7) / 8;309 uint8_t * result = (uint8_t*) malloc(size);310 if (!result)return ENOMEM;321 uint8_t * result = malloc(size); 322 if (!result) 323 return ENOMEM; 311 324 312 325 bzero(result, size); … … 316 329 result[1] = USB_DESCTYPE_HUB; 317 330 result[2] = instance->port_count; 318 uint32_t hub_desc_reg = instance->registers->rh_desc_a;331 const uint32_t hub_desc_reg = instance->registers->rh_desc_a; 319 332 result[3] = 320 333 ((hub_desc_reg >> 8) % 2) + … … 324 337 (((hub_desc_reg >> 12) % 2) << 4); 325 338 result[4] = 0; 326 result[5] = /*descriptor->pwr_on_2_good_time*/ 50;339 result[5] = 50; /*descriptor->pwr_on_2_good_time*/ 327 340 result[6] = 50; 328 341 329 size_t port ;330 for ( port = 1; port <= instance->port_count; ++port) {331 uint8_t is_non_removable =342 size_t port = 1; 343 for (; port <= instance->port_count; ++port) { 344 const uint8_t is_non_removable = 332 345 instance->registers->rh_desc_b >> port % 2; 333 346 result[7 + port / 8] += 334 347 is_non_removable << (port % 8); 335 348 } 336 size_t i; 337 for (i = 0; i < var_size; ++i) { 349 const size_t var_size = (instance->port_count + 7) / 8; 350 size_t i = 0; 351 for (; i < var_size; ++i) { 338 352 result[7 + var_size + i] = 255; 339 353 } … … 344 358 } 345 359 /*----------------------------------------------------------------------------*/ 346 347 /** initialize hub descriptors 348 * 349 * Initialized are device and full configuration descriptor. These need to 360 /** Initialize hub descriptors. 361 * 362 * Device and full configuration descriptor are created. These need to 350 363 * be initialized only once per hub. 351 * @instance root hub instance 352 * @return error code 353 */ 354 static int rh_init_descriptors(rh_t *instance) { 364 * @param instance Root hub instance 365 * @return Error code 366 */ 367 int rh_init_descriptors(rh_t *instance) 368 { 369 assert(instance); 370 355 371 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 356 372 sizeof (ohci_rh_device_descriptor) … … 370 386 instance->descriptor_size; 371 387 372 uint8_t * full_config_descriptor = 373 (uint8_t*) malloc(descriptor.total_length); 388 uint8_t * full_config_descriptor = malloc(descriptor.total_length); 374 389 if (!full_config_descriptor) { 375 390 return ENOMEM; … … 392 407 } 393 408 /*----------------------------------------------------------------------------*/ 394 395 /** 396 * create answer to port status_request 409 /** 410 * Create answer to port status_request 397 411 * 398 412 * Copy content of corresponding port status register to answer buffer. The … … 400 414 * see OHCI root hub and USB hub documentation). 401 415 * 402 * @param instance root hub instance 403 * @param port port number, counted from 1 404 * @param request structure containing both request and response information 405 * @return error code 406 */ 407 static int process_get_port_status_request(rh_t *instance, uint16_t port, 408 usb_transfer_batch_t * request) { 416 * @param instance Root hub instance 417 * @param port Port number, counted from 1 418 * @param request Structure containing both request and response information 419 * @return Error code 420 */ 421 int process_get_port_status_request( 422 rh_t *instance, uint16_t port, usb_transfer_batch_t * request) 423 { 424 assert(instance); 425 assert(request); 426 409 427 if (port < 1 || port > instance->port_count) 410 428 return EINVAL; 429 430 const uint32_t data = instance->registers->rh_port_status[port - 1]; 431 memcpy(request->data_buffer, &data, 4); 411 432 request->transfered_size = 4; 412 uint32_t data = instance->registers->rh_port_status[port - 1]; 413 memcpy(request->data_buffer, &data, 4); 414 return EOK; 415 } 416 /*----------------------------------------------------------------------------*/ 417 418 /** 419 * create answer to port status_request 433 return EOK; 434 } 435 /*----------------------------------------------------------------------------*/ 436 /** 437 * Create answer to port status_request. 420 438 * 421 439 * This copies flags in hub status register into the buffer. The format of the … … 423 441 * specification and OHCI root hub specification. 424 442 * 425 * @param instance root hub instance 426 * @param request structure containing both request and response information 427 * @return error code 428 */ 429 static int process_get_hub_status_request(rh_t *instance, 430 usb_transfer_batch_t * request) { 443 * @param instance Root hub instance. 444 * @param request Structure containing both request and response information. 445 * @return Error code 446 */ 447 int process_get_hub_status_request( 448 rh_t *instance, usb_transfer_batch_t *request) 449 { 450 assert(instance); 451 assert(request); 452 453 /* bits, 0,1,16,17 -- TODO: What do they mean?? Why not 0x0303 */ 454 const uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 455 const uint32_t data = mask & instance->registers->rh_status; 456 memcpy(request->data_buffer, &data, 4); 431 457 request->transfered_size = 4; 432 //bits, 0,1,16,17 433 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 434 uint32_t data = mask & instance->registers->rh_status; 435 memcpy(request->data_buffer, &data, 4); 436 437 return EOK; 438 } 439 /*----------------------------------------------------------------------------*/ 440 441 /** 442 * create answer to status request 458 459 return EOK; 460 } 461 /*----------------------------------------------------------------------------*/ 462 /** 463 * Create answer to status request. 443 464 * 444 465 * This might be either hub status or port status request. If neither, … … 448 469 * @return error code 449 470 */ 450 static int process_get_status_request(rh_t *instance, 451 usb_transfer_batch_t * request) { 452 size_t buffer_size = request->buffer_size; 453 usb_device_request_setup_packet_t * request_packet = 454 (usb_device_request_setup_packet_t*) 455 request->setup_buffer; 456 457 usb_hub_bm_request_type_t request_type = request_packet->request_type; 458 if (buffer_size < 4) { 459 usb_log_warning("Requested more data than buffer size\n"); 460 return EINVAL; 471 int process_get_status_request(rh_t *instance, usb_transfer_batch_t *request) 472 { 473 assert(instance); 474 assert(request); 475 476 const usb_device_request_setup_packet_t *request_packet = 477 (usb_device_request_setup_packet_t*)request->setup_buffer; 478 479 const usb_hub_bm_request_type_t request_type = 480 request_packet->request_type; 481 482 if (request->buffer_size < 4) { 483 usb_log_error("Buffer too small for get status request.\n"); 484 return EOVERFLOW; 461 485 } 462 486 … … 465 489 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 466 490 return process_get_port_status_request(instance, 467 request_packet->index, 468 request); 491 request_packet->index, request); 469 492 470 493 return ENOTSUP; 471 494 } 472 495 /*----------------------------------------------------------------------------*/ 473 474 /** 475 * create answer to status interrupt consisting of change bitmap 496 /** 497 * Create bitmap of changes to answer status interrupt. 476 498 * 477 499 * Result contains bitmap where bit 0 indicates change on hub and … … 482 504 * @param instance root hub instance 483 505 */ 484 static void create_interrupt_mask_in_instance(rh_t * instance) { 506 void create_interrupt_mask_in_instance(rh_t *instance) 507 { 508 assert(instance); 509 485 510 uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer); 486 511 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) … … 490 515 bitmap[0] = 1; 491 516 } 492 size_t port;493 517 mask = port_status_change_mask; 494 for (port = 1; port <= instance->port_count; ++port) { 518 size_t port = 1; 519 for (; port <= instance->port_count; ++port) { 495 520 if ((mask & instance->registers->rh_port_status[port - 1]) != 0) { 496 521 … … 500 525 } 501 526 /*----------------------------------------------------------------------------*/ 502 503 /** 504 * create answer to a descriptor request 527 /** 528 * Create answer to a descriptor request. 505 529 * 506 530 * This might be a request for standard (configuration, device, endpoint or 507 531 * interface) or device specific (hub) descriptor. 508 * @param instance root hub instance 509 * @param request structure containing both request and response information 510 * @return error code 511 */ 512 static int process_get_descriptor_request(rh_t *instance, 513 usb_transfer_batch_t *request) { 514 usb_device_request_setup_packet_t * setup_request = 515 (usb_device_request_setup_packet_t*) request->setup_buffer; 532 * @param instance Root hub instance 533 * @param request Structure containing both request and response information 534 * @return Error code 535 */ 536 int process_get_descriptor_request( 537 rh_t *instance, usb_transfer_batch_t *request) 538 { 539 assert(instance); 540 assert(request); 541 542 const usb_device_request_setup_packet_t *setup_request = 543 (usb_device_request_setup_packet_t *) request->setup_buffer; 516 544 size_t size; 517 545 const void * result_descriptor = NULL; 518 546 const uint16_t setup_request_value = setup_request->value_high; 519 547 //(setup_request->value_low << 8); 520 switch (setup_request_value) { 521 case USB_DESCTYPE_HUB: 522 { 523 usb_log_debug2("USB_DESCTYPE_HUB\n"); 524 result_descriptor = instance->hub_descriptor; 525 size = instance->descriptor_size; 526 break; 527 } 528 case USB_DESCTYPE_DEVICE: 529 { 530 usb_log_debug2("USB_DESCTYPE_DEVICE\n"); 531 result_descriptor = &ohci_rh_device_descriptor; 532 size = sizeof (ohci_rh_device_descriptor); 533 break; 534 } 535 case USB_DESCTYPE_CONFIGURATION: 536 { 537 usb_log_debug2("USB_DESCTYPE_CONFIGURATION\n"); 538 result_descriptor = instance->descriptors.configuration; 539 size = instance->descriptors.configuration_size; 540 break; 541 } 542 case USB_DESCTYPE_INTERFACE: 543 { 544 usb_log_debug2("USB_DESCTYPE_INTERFACE\n"); 545 result_descriptor = &ohci_rh_iface_descriptor; 546 size = sizeof (ohci_rh_iface_descriptor); 547 break; 548 } 549 case USB_DESCTYPE_ENDPOINT: 550 { 551 usb_log_debug2("USB_DESCTYPE_ENDPOINT\n"); 552 result_descriptor = &ohci_rh_ep_descriptor; 553 size = sizeof (ohci_rh_ep_descriptor); 554 break; 555 } 556 default: 557 { 558 usb_log_debug2("USB_DESCTYPE_EINVAL %d \n", 559 setup_request->value); 560 usb_log_debug2("\ttype %d\n\trequest %d\n\tvalue " 561 "%d\n\tindex %d\n\tlen %d\n ", 562 setup_request->request_type, 563 setup_request->request, 564 setup_request_value, 565 setup_request->index, 566 setup_request->length 567 ); 568 return EINVAL; 569 } 548 switch (setup_request_value) 549 { 550 case USB_DESCTYPE_HUB: 551 usb_log_debug2("USB_DESCTYPE_HUB\n"); 552 result_descriptor = instance->hub_descriptor; 553 size = instance->descriptor_size; 554 break; 555 556 case USB_DESCTYPE_DEVICE: 557 usb_log_debug2("USB_DESCTYPE_DEVICE\n"); 558 result_descriptor = &ohci_rh_device_descriptor; 559 size = sizeof(ohci_rh_device_descriptor); 560 break; 561 562 case USB_DESCTYPE_CONFIGURATION: 563 usb_log_debug2("USB_DESCTYPE_CONFIGURATION\n"); 564 result_descriptor = instance->descriptors.configuration; 565 size = instance->descriptors.configuration_size; 566 break; 567 568 case USB_DESCTYPE_INTERFACE: 569 usb_log_debug2("USB_DESCTYPE_INTERFACE\n"); 570 result_descriptor = &ohci_rh_iface_descriptor; 571 size = sizeof(ohci_rh_iface_descriptor); 572 break; 573 574 case USB_DESCTYPE_ENDPOINT: 575 usb_log_debug2("USB_DESCTYPE_ENDPOINT\n"); 576 result_descriptor = &ohci_rh_ep_descriptor; 577 size = sizeof(ohci_rh_ep_descriptor); 578 break; 579 580 default: 581 usb_log_debug2("USB_DESCTYPE_EINVAL %d \n" 582 "\ttype %d\n\trequest %d\n\tvalue " 583 "%d\n\tindex %d\n\tlen %d\n ", 584 setup_request->value, 585 setup_request->request_type, setup_request->request, 586 setup_request_value, setup_request->index, 587 setup_request->length); 588 return EINVAL; 570 589 } 571 590 if (request->buffer_size < size) { 572 591 size = request->buffer_size; 573 592 } 593 memcpy(request->data_buffer, result_descriptor, size); 574 594 request->transfered_size = size; 575 memcpy(request->data_buffer, result_descriptor, size); 576 577 return EOK; 578 } 579 /*----------------------------------------------------------------------------*/ 580 581 /** 582 * answer to get configuration request 595 596 return EOK; 597 } 598 /*----------------------------------------------------------------------------*/ 599 /** 600 * Answer to get configuration request. 583 601 * 584 602 * Root hub works independently on the configuration. 585 * @param instance root hub instance 586 * @param request structure containing both request and response information 587 * @return error code 588 */ 589 static int process_get_configuration_request(rh_t *instance, 590 usb_transfer_batch_t *request) { 591 //set and get configuration requests do not have any meaning, only dummy 592 //values are returned 603 * Set and get configuration requests do not have any meaning, 604 * dummy values are returned. 605 * 606 * @param instance Root hub instance 607 * @param request Structure containing both request and response information 608 * @return Error code 609 */ 610 int process_get_configuration_request( 611 rh_t *instance, usb_transfer_batch_t *request) 612 { 613 assert(request); 614 593 615 if (request->buffer_size != 1) 594 616 return EINVAL; … … 599 621 } 600 622 /*----------------------------------------------------------------------------*/ 601 602 623 /** 603 624 * process feature-enabling request on hub … … 620 641 } 621 642 /*----------------------------------------------------------------------------*/ 622 623 643 /** 624 644 * process feature-disabling request on hub … … 628 648 * @return error code 629 649 */ 630 static int process_hub_feature_clear_request(rh_t *instance, 631 uint16_t feature) { 650 int process_hub_feature_clear_request(rh_t *instance, uint16_t feature) 651 { 652 assert(instance); 653 632 654 if (!((1 << feature) & hub_clear_feature_valid_mask)) 633 655 return EINVAL; 656 634 657 //is the feature cleared directly? 635 658 if ((1 << feature) & hub_set_feature_direct_mask) { … … 647 670 } 648 671 /*----------------------------------------------------------------------------*/ 649 650 672 /** 651 673 * process feature-enabling request on hub … … 657 679 * @return error code 658 680 */ 659 static int process_port_feature_set_request(rh_t *instance, 660 uint16_t feature, uint16_t port) { 681 int process_port_feature_set_request( 682 rh_t *instance, uint16_t feature, uint16_t port) 683 { 684 assert(instance); 685 661 686 if (!((1 << feature) & port_set_feature_valid_mask)) 662 687 return EINVAL; 663 688 if (port < 1 || port > instance->port_count) 664 689 return EINVAL; 690 665 691 instance->registers->rh_port_status[port - 1] = 666 692 (instance->registers->rh_port_status[port - 1] | (1 << feature)) … … 669 695 } 670 696 /*----------------------------------------------------------------------------*/ 671 672 697 /** 673 698 * process feature-disabling request on hub … … 679 704 * @return error code 680 705 */ 681 static int process_port_feature_clear_request(rh_t *instance, 682 uint16_t feature, uint16_t port) { 706 int process_port_feature_clear_request( 707 rh_t *instance, uint16_t feature, uint16_t port) 708 { 709 assert(instance); 710 683 711 if (!((1 << feature) & port_clear_feature_valid_mask)) 684 712 return EINVAL; 685 713 if (port < 1 || port > instance->port_count) 686 714 return EINVAL; 715 716 /* Some weird stuff... */ 687 717 if (feature == USB_HUB_FEATURE_PORT_POWER) 688 718 feature = USB_HUB_FEATURE_PORT_LOW_SPEED; 689 719 if (feature == USB_HUB_FEATURE_PORT_SUSPEND) 690 720 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 721 691 722 instance->registers->rh_port_status[port - 1] = 692 723 (instance->registers->rh_port_status[port - 1] … … 697 728 } 698 729 /*----------------------------------------------------------------------------*/ 699 700 /**701 * register address to this device702 *703 * @param instance root hub instance704 * @param address new address705 * @return error code706 */707 static int process_address_set_request(rh_t *instance,708 uint16_t address) {709 return ENOTSUP;710 }711 /*----------------------------------------------------------------------------*/712 713 730 /** 714 731 * process one of requests that requere output data … … 720 737 * @return error code 721 738 */ 722 static int process_request_with_output(rh_t *instance, 723 usb_transfer_batch_t *request) { 724 usb_device_request_setup_packet_t * setup_request = 725 (usb_device_request_setup_packet_t*) request->setup_buffer; 726 if (setup_request->request == USB_DEVREQ_GET_STATUS) { 739 int process_request_with_output(rh_t *instance, usb_transfer_batch_t *request) 740 { 741 assert(instance); 742 assert(request); 743 744 const usb_device_request_setup_packet_t *setup_request = 745 (usb_device_request_setup_packet_t *) request->setup_buffer; 746 switch (setup_request->request) 747 { 748 case USB_DEVREQ_GET_STATUS: 727 749 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 728 750 return process_get_status_request(instance, request); 729 } 730 if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR) { 751 case USB_DEVREQ_GET_DESCRIPTOR: 731 752 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 732 753 return process_get_descriptor_request(instance, request); 733 } 734 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) { 754 case USB_DEVREQ_GET_CONFIGURATION: 735 755 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 736 737 756 return process_get_configuration_request(instance, request); 738 757 } … … 740 759 } 741 760 /*----------------------------------------------------------------------------*/ 742 743 761 /** 744 762 * process one of requests that carry input data … … 750 768 * @return error code 751 769 */ 752 static int process_request_with_input(rh_t *instance, 753 usb_transfer_batch_t *request) { 754 usb_device_request_setup_packet_t * setup_request = 755 (usb_device_request_setup_packet_t*) request->setup_buffer; 770 int process_request_with_input(rh_t *instance, usb_transfer_batch_t *request) 771 { 772 assert(instance); 773 assert(request); 774 775 const usb_device_request_setup_packet_t *setup_request = 776 (usb_device_request_setup_packet_t *) request->setup_buffer; 756 777 request->transfered_size = 0; 757 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) {758 return ENOTSUP;759 }760 778 if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION) { 761 779 //set and get configuration requests do not have any meaning, 762 780 //only dummy values are returned 763 764 781 return EOK; 765 782 } 783 /* USB_DEVREQ_SET_DESCRIPTOR is also not supported */ 766 784 return ENOTSUP; 767 785 } 768 786 /*----------------------------------------------------------------------------*/ 769 770 787 /** 771 788 * process one of requests that do not request nor carry additional data … … 777 794 * @return error code 778 795 */ 779 static int process_request_without_data(rh_t *instance, 780 usb_transfer_batch_t *request) { 781 usb_device_request_setup_packet_t * setup_request = 782 (usb_device_request_setup_packet_t*) request->setup_buffer; 796 int process_request_without_data(rh_t *instance, usb_transfer_batch_t *request) 797 { 798 assert(instance); 799 assert(request); 800 801 const usb_device_request_setup_packet_t *setup_request = 802 (usb_device_request_setup_packet_t *) request->setup_buffer; 783 803 request->transfered_size = 0; 784 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) { 785 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) { 804 const int request_type = setup_request->request_type; 805 switch (setup_request->request) 806 { 807 case USB_DEVREQ_CLEAR_FEATURE: 808 if (request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) { 786 809 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 787 810 return process_hub_feature_clear_request(instance, 788 811 setup_request->value); 789 812 } 790 if ( setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {791 usb_log_debug 2("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");813 if (request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 814 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 792 815 return process_port_feature_clear_request(instance, 793 setup_request->value, 794 setup_request->index); 816 setup_request->value, setup_request->index); 795 817 } 796 usb_log_ debug("USB_HUB_REQ_TYPE_INVALID%d\n",797 setup_request->request_type);798 return EINVAL; 799 } 800 if (setup_request->request == USB_DEVREQ_SET_FEATURE) {801 if ( setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) {818 usb_log_error("Invalid HUB clear feature request type: %d\n", 819 request_type); 820 return EINVAL; 821 822 case USB_DEVREQ_SET_FEATURE: 823 if (request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) { 802 824 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 803 825 return process_hub_feature_set_request(instance, 804 826 setup_request->value); 805 827 } 806 if ( setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {828 if (request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 807 829 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 808 830 return process_port_feature_set_request(instance, 809 setup_request->value, 810 setup_request->index); 831 setup_request->value, setup_request->index); 811 832 } 812 usb_log_ debug("USB_HUB_REQ_TYPE_INVALID%d\n",813 setup_request->request_type);814 return EINVAL; 815 } 816 if (setup_request->request == USB_DEVREQ_SET_ADDRESS) {833 usb_log_error("Invalid HUB set feature request type: %d\n", 834 request_type); 835 return EINVAL; 836 837 case USB_DEVREQ_SET_ADDRESS: 817 838 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 818 839 return process_address_set_request(instance, 819 840 setup_request->value); 820 } 821 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",822 setup_request->request_type);823 824 return ENOTSUP;825 }826 /*----------------------------------------------------------------------------*/ 827 828 /** 829 * process hub control request841 842 default: 843 usb_log_error("Invalid HUB request: %d\n", 844 setup_request->request); 845 return ENOTSUP; 846 } 847 } 848 /*----------------------------------------------------------------------------*/ 849 /** 850 * Process hub control request. 830 851 * 831 852 * If needed, writes answer into the request structure. … … 844 865 * @return error code 845 866 */ 846 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) { 867 int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) 868 { 869 assert(instance); 870 assert(request); 871 847 872 if (!request->setup_buffer) { 848 usb_log_error("root hub received empty transaction?"); 849 return EINVAL; 850 } 851 int opResult; 852 if (sizeof (usb_device_request_setup_packet_t) > request->setup_size) { 873 usb_log_error("Root hub received empty transaction!"); 874 return EINVAL; 875 } 876 if (sizeof(usb_device_request_setup_packet_t) > request->setup_size) { 853 877 usb_log_error("Setup packet too small\n"); 854 return EINVAL; 855 } 856 usb_log_debug("CTRL packet: %s.\n", 857 usb_debug_str_buffer( 858 (const uint8_t *) request->setup_buffer, 8, 8)); 859 usb_device_request_setup_packet_t * setup_request = 860 (usb_device_request_setup_packet_t*) 861 request->setup_buffer; 862 switch (setup_request->request) { 863 case USB_DEVREQ_GET_STATUS: 864 case USB_DEVREQ_GET_DESCRIPTOR: 865 case USB_DEVREQ_GET_CONFIGURATION: 866 usb_log_debug2("Processing request with output\n"); 867 opResult = process_request_with_output( 868 instance, request); 869 break; 870 case USB_DEVREQ_CLEAR_FEATURE: 871 case USB_DEVREQ_SET_FEATURE: 872 case USB_DEVREQ_SET_ADDRESS: 873 usb_log_debug2("Processing request without " 874 "additional data\n"); 875 opResult = process_request_without_data( 876 instance, request); 877 break; 878 case USB_DEVREQ_SET_DESCRIPTOR: 879 case USB_DEVREQ_SET_CONFIGURATION: 880 usb_log_debug2("Processing request with input\n"); 881 opResult = process_request_with_input( 882 instance, request); 883 884 break; 885 default: 886 usb_log_warning("Received unsupported request: %d.\n", 887 setup_request->request); 888 opResult = ENOTSUP; 889 } 890 return opResult; 891 } 892 /*----------------------------------------------------------------------------*/ 893 878 return EOVERFLOW; 879 } 880 usb_log_debug2("CTRL packet: %s.\n", 881 usb_debug_str_buffer((uint8_t *) request->setup_buffer, 8, 8)); 882 const usb_device_request_setup_packet_t *setup_request = 883 (usb_device_request_setup_packet_t *) request->setup_buffer; 884 switch (setup_request->request) 885 { 886 case USB_DEVREQ_GET_STATUS: 887 case USB_DEVREQ_GET_DESCRIPTOR: 888 case USB_DEVREQ_GET_CONFIGURATION: 889 usb_log_debug2("Processing request with output\n"); 890 return process_request_with_output(instance, request); 891 case USB_DEVREQ_CLEAR_FEATURE: 892 case USB_DEVREQ_SET_FEATURE: 893 case USB_DEVREQ_SET_ADDRESS: 894 usb_log_debug2("Processing request without " 895 "additional data\n"); 896 return process_request_without_data(instance, request); 897 case USB_DEVREQ_SET_DESCRIPTOR: 898 case USB_DEVREQ_SET_CONFIGURATION: 899 usb_log_debug2("Processing request with input\n"); 900 return process_request_with_input(instance, request); 901 default: 902 usb_log_error("Received unsupported request: %d.\n", 903 setup_request->request); 904 return ENOTSUP; 905 } 906 } 907 /*----------------------------------------------------------------------------*/ 894 908 /** 895 909 * process hanging interrupt request 896 910 * 897 911 * If an interrupt transfer has been received and there was no change, 898 * the driver stores the transfer information and waits for change to occ cur.912 * the driver stores the transfer information and waits for change to occur. 899 913 * This routine is called when that happens and it finalizes the interrupt 900 914 * transfer. … … 905 919 * @return 906 920 */ 907 static int process_interrupt_mask_in_instance(rh_t *instance, 908 usb_transfer_batch_t * request) { 921 int process_interrupt_mask_in_instance( 922 rh_t *instance, usb_transfer_batch_t *request) 923 { 924 assert(instance); 925 assert(request); 926 909 927 memcpy(request->data_buffer, instance->interrupt_buffer, 910 928 instance->interrupt_mask_size); … … 915 933 return EOK; 916 934 } 917 918 /*----------------------------------------------------------------------------*/ 919 935 /*----------------------------------------------------------------------------*/ 920 936 /** 921 937 * return whether the buffer is full of zeros … … 926 942 * @return 927 943 */ 928 static bool is_zeros(void *buffer, size_t size) { 944 bool is_zeros(const void *buffer, size_t size) 945 { 929 946 if (!buffer) return true; 930 if (!size) return true;931 size_t i;932 for ( i = 0; i < size; ++i) {933 if ( ((char*) buffer)[i])947 const char * const end = buffer + size; 948 const char *data = buffer; 949 for (; data < end; ++data) { 950 if (*data) 934 951 return false; 935 952 }
Note:
See TracChangeset
for help on using the changeset viewer.