Changeset bfc5c9dd in mainline for uspace/drv/bus/usb/ohci/root_hub.c
- Timestamp:
- 2012-02-23T20:42:30Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 815b244a
- Parents:
- ffcc5776
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/root_hub.c
rffcc5776 rbfc5c9dd 154 154 155 155 instance->registers = regs; 156 instance->port_count = RHDA_NDS(instance->registers->rh_desc_a);157 usb_log_debug ("rh_desc_a: %x.\n", instance->registers->rh_desc_a);156 instance->port_count = OHCI_RD(regs->rh_desc_a) & RHDA_NDS_MASK; 157 usb_log_debug2("rh_desc_a: %x.\n", OHCI_RD(regs->rh_desc_a)); 158 158 if (instance->port_count > 15) { 159 159 usb_log_warning("OHCI specification does not allow more than 15" … … 167 167 168 168 #if defined OHCI_POWER_SWITCH_no 169 usb_log_debug("OHCI rh: Set power mode to no power switching.\n"); 169 170 /* Set port power mode to no power-switching. (always on) */ 170 instance->registers->rh_desc_a |= RHDA_NPS_FLAG;171 OHCI_SET(regs->rh_desc_a, RHDA_NPS_FLAG); 171 172 172 173 /* Set to no over-current reporting */ 173 instance->registers->rh_desc_a |= RHDA_NOCP_FLAG;174 OHCI_SET(regs->rh_desc_a, RHDA_NOCP_FLAG); 174 175 175 176 #elif defined OHCI_POWER_SWITCH_ganged 176 /* Set port power mode to no ganged power-switching. */ 177 instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG; 178 instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG; 179 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 177 usb_log_debug("OHCI rh: Set power mode to ganged power switching.\n"); 178 /* Set port power mode to ganged power-switching. */ 179 OHCI_CLEAR(regs->rh_desc_a, RHDA_NPS_FLAG); 180 OHCI_CLEAR(regs->rh_desc_a, RHDA_PSM_FLAG); 181 182 /* Turn off power (hub driver will turn this back on)*/ 183 OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER); 180 184 181 185 /* Set to global over-current */ 182 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;183 instance->registers->rh_desc_a &= ~RHDA_OCPM_FLAG;186 OHCI_CLEAR(regs->rh_desc_a, RHDA_NOCP_FLAG); 187 OHCI_CLEAR(regs->rh_desc_a, RHDA_OCPM_FLAG); 184 188 #else 185 /* Set port power mode to no per port power-switching. */ 186 instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG; 187 instance->registers->rh_desc_a |= RHDA_PSM_FLAG; 189 usb_log_debug("OHCI rh: Set power mode to per-port power switching.\n"); 190 /* Set port power mode to per port power-switching. */ 191 OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG); 192 OHCI_SET(regs->rh_desc_a, RHDA_PSM_FLAG); 188 193 189 194 /* Control all ports by global switch and turn them off */ 190 instance->registers->rh_desc_b &= ~RHDB_PCC_WRITE(~0);191 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;195 OHCI_CLR(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT); 196 OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER); 192 197 193 198 /* Return control to per port state */ 194 instance->registers->rh_desc_b |= RHDB_PCC_WRITE(~0);199 OHCI_SET(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT); 195 200 196 201 /* Set per port over-current */ 197 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;198 instance->registers->rh_desc_a |= RHDA_OCPM_FLAG;202 OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG); 203 OHCI_SET(regs->rh_desc_a, RHDA_OCPM_FLAG); 199 204 #endif 200 205 … … 285 290 instance->hub_descriptor_size = size; 286 291 287 const uint32_t hub_desc = instance->registers->rh_desc_a;288 const uint32_t port_desc = instance->registers->rh_desc_b;292 const uint32_t hub_desc = OHCI_RD(instance->registers->rh_desc_a); 293 const uint32_t port_desc = OHCI_RD(instance->registers->rh_desc_b); 289 294 290 295 /* bDescLength */ … … 308 313 instance->descriptors.hub[4] = 0; 309 314 /* bPwrOn2PwrGood */ 310 instance->descriptors.hub[5] = RHDA_POTPGT(hub_desc);315 instance->descriptors.hub[5] = hub_desc >> RHDA_POTPGT_SHIFT; 311 316 /* bHubContrCurrent, root hubs don't need no power. */ 312 317 instance->descriptors.hub[6] = 0; 313 318 314 319 /* Device Removable and some legacy 1.0 stuff*/ 315 instance->descriptors.hub[7] = RHDB_DR_READ(port_desc) & 0xff;320 instance->descriptors.hub[7] = (port_desc >> RHDB_DR_SHIFT) & 0xff; 316 321 instance->descriptors.hub[8] = 0xff; 317 322 if (instance->interrupt_mask_size == 2) { 318 instance->descriptors.hub[8] = RHDB_DR_READ(port_desc) >> 8; 323 instance->descriptors.hub[8] = 324 (port_desc >> RHDB_DR_SHIFT) >> 8; 319 325 instance->descriptors.hub[9] = 0xff; 320 326 instance->descriptors.hub[10] = 0xff; … … 364 370 365 371 /* Only local power source change and over-current change can happen */ 366 if (instance->registers->rh_status & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) { 372 if (OHCI_RD(instance->registers->rh_status) 373 & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) { 367 374 mask |= 1; 368 375 } 369 376 for (size_t port = 1; port <= instance->port_count; ++port) { 370 377 /* Write-clean bits are those that indicate change */ 371 if (RHPS_CHANGE_WC_MASK 372 & instance->registers->rh_port_status[port - 1]) { 373 378 if (OHCI_RD(instance->registers->rh_port_status[port - 1]) 379 & RHPS_CHANGE_WC_MASK) { 374 380 mask |= (1 << port); 375 381 } … … 396 402 usb_device_request_setup_packet_t *request_packet = 397 403 (usb_device_request_setup_packet_t*)request->setup_buffer; 404 405 const uint16_t index = uint16_usb2host(request_packet->index); 398 406 399 407 switch (request_packet->request_type) … … 406 414 TRANSFER_END(request, EOVERFLOW); 407 415 } else { 408 uint32_t data = instance->registers->rh_status & 409 (RHS_LPS_FLAG | RHS_LPSC_FLAG 410 | RHS_OCI_FLAG | RHS_OCIC_FLAG); 416 const uint32_t data = 417 OHCI_RD(instance->registers->rh_status) & 418 (RHS_LPS_FLAG | RHS_LPSC_FLAG 419 | RHS_OCI_FLAG | RHS_OCIC_FLAG); 411 420 TRANSFER_END_DATA(request, &data, sizeof(data)); 412 421 } … … 420 429 TRANSFER_END(request, EOVERFLOW); 421 430 } else { 422 unsigned port = request_packet->index;431 const unsigned port = index; 423 432 if (port < 1 || port > instance->port_count) 424 433 TRANSFER_END(request, EINVAL); 425 426 uint32_t data = 427 instance->registers->rh_port_status[port - 1]; 434 /* Register format matches the format of port status 435 * field */ 436 const uint32_t data = uint32_usb2host(OHCI_RD( 437 instance->registers->rh_port_status[port - 1])); 428 438 TRANSFER_END_DATA(request, &data, sizeof(data)); 429 439 } … … 441 451 case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE): 442 452 /* Hubs are allowed to have only one interface */ 443 if ( request_packet->index != 0)453 if (index != 0) 444 454 TRANSFER_END(request, EINVAL); 445 455 /* Fall through, as the answer will be the same: 0x0000 */ 446 456 case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT): 447 457 /* Endpoint 0 (default control) and 1 (interrupt) */ 448 if ( request_packet->index >= 2)458 if (index >= 2) 449 459 TRANSFER_END(request, EINVAL); 450 460 … … 455 465 } else { 456 466 /* Endpoints are OK. (We don't halt) */ 457 uint16_t data = 0;467 const uint16_t data = 0; 458 468 TRANSFER_END_DATA(request, &data, sizeof(data)); 459 469 } … … 556 566 switch (feature) 557 567 { 558 case USB_HUB_FEATURE_PORT_POWER: //8 559 /* No power switching */ 560 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG) 561 return EOK; 562 /* Ganged power switching */ 563 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) { 564 instance->registers->rh_status = RHS_SET_GLOBAL_POWER; 565 return EOK; 568 case USB_HUB_FEATURE_PORT_POWER: /*8*/ 569 { 570 const uint32_t rhda = 571 OHCI_RD(instance->registers->rh_desc_a); 572 /* No power switching */ 573 if (rhda & RHDA_NPS_FLAG) 574 return EOK; 575 /* Ganged power switching, one port powers all */ 576 if (!(rhda & RHDA_PSM_FLAG)) { 577 OHCI_WR(instance->registers->rh_status, 578 RHS_SET_GLOBAL_POWER); 579 return EOK; 580 } 566 581 } 567 case USB_HUB_FEATURE_PORT_ENABLE: //1568 case USB_HUB_FEATURE_PORT_ SUSPEND: //2569 case USB_HUB_FEATURE_PORT_ RESET: //4570 usb_log_debug2(571 "Setting port ENABLE, SUSPEND or RESET on port %zu.\n",572 port);573 instance->registers->rh_port_status[port - 1] =574 RHPS_FEATURE_BIT(feature);582 /* Fall through */ 583 case USB_HUB_FEATURE_PORT_ENABLE: /*1*/ 584 case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/ 585 case USB_HUB_FEATURE_PORT_RESET: /*4*/ 586 usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET " 587 "on port %zu.\n", port); 588 OHCI_WR(instance->registers->rh_port_status[port - 1], 589 1 << feature); 575 590 return EOK; 576 591 default: … … 598 613 switch (feature) 599 614 { 600 case USB_HUB_FEATURE_PORT_POWER: //8 601 /* No power switching */ 602 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG) 603 return ENOTSUP; 604 /* Ganged power switching */ 605 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) { 606 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 615 case USB_HUB_FEATURE_PORT_POWER: /*8*/ 616 { 617 const uint32_t rhda = 618 OHCI_RD(instance->registers->rh_desc_a); 619 /* No power switching */ 620 if (rhda & RHDA_NPS_FLAG) 621 return ENOTSUP; 622 /* Ganged power switching, one port powers all */ 623 if (!(rhda & RHDA_PSM_FLAG)) { 624 OHCI_WR(instance->registers->rh_status, 625 RHS_CLEAR_GLOBAL_POWER); 626 return EOK; 627 } 628 OHCI_WR(instance->registers->rh_port_status[port - 1], 629 RHPS_CLEAR_PORT_POWER); 607 630 return EOK; 608 631 } 609 instance->registers->rh_port_status[port - 1] = 610 RHPS_CLEAR_PORT_POWER; 632 633 case USB_HUB_FEATURE_PORT_ENABLE: /*1*/ 634 OHCI_WR(instance->registers->rh_port_status[port - 1], 635 RHPS_CLEAR_PORT_ENABLE); 611 636 return EOK; 612 637 613 case USB_HUB_FEATURE_PORT_ ENABLE: //1614 instance->registers->rh_port_status[port - 1] =615 RHPS_CLEAR_PORT_ENABLE;638 case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/ 639 OHCI_WR(instance->registers->rh_port_status[port - 1], 640 RHPS_CLEAR_PORT_SUSPEND); 616 641 return EOK; 617 642 618 case USB_HUB_FEATURE_PORT_SUSPEND: //2 619 instance->registers->rh_port_status[port - 1] = 620 RHPS_CLEAR_PORT_SUSPEND; 621 return EOK; 622 623 case USB_HUB_FEATURE_C_PORT_CONNECTION: //16 624 case USB_HUB_FEATURE_C_PORT_ENABLE: //17 625 case USB_HUB_FEATURE_C_PORT_SUSPEND: //18 626 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: //19 627 case USB_HUB_FEATURE_C_PORT_RESET: //20 643 case USB_HUB_FEATURE_C_PORT_CONNECTION: /*16*/ 644 case USB_HUB_FEATURE_C_PORT_ENABLE: /*17*/ 645 case USB_HUB_FEATURE_C_PORT_SUSPEND: /*18*/ 646 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/ 647 case USB_HUB_FEATURE_C_PORT_RESET: /*20*/ 628 648 usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, " 629 "C_SUSPEND or C_RESET on port %zu.\n",630 port);631 instance->registers->rh_port_status[port - 1] =632 RHPS_FEATURE_BIT(feature);649 "C_SUSPEND, C_OC or C_RESET on port %zu.\n", port); 650 /* Bit offsets correspond to the feature number */ 651 OHCI_WR(instance->registers->rh_port_status[port - 1], 652 1 << feature); 633 653 return EOK; 634 654 … … 658 678 case USB_HUB_REQ_TYPE_SET_PORT_FEATURE: 659 679 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 660 int ret = set_feature_port(instance,680 const int ret = set_feature_port(instance, 661 681 setup_request->value, setup_request->index); 662 682 TRANSFER_END(request, ret); … … 697 717 case USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE: 698 718 usb_log_debug("USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE\n"); 699 int ret = clear_feature_port(instance,719 const int ret = clear_feature_port(instance, 700 720 setup_request->value, setup_request->index); 701 721 TRANSFER_END(request, ret); … … 710 730 * as root hubs do not support local power status feature. 711 731 * (OHCI pg. 127) */ 712 if (setup_request->value == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) { 713 instance->registers->rh_status = RHS_OCIC_FLAG; 732 if (uint16_usb2host(setup_request->value) 733 == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) { 734 OHCI_WR(instance->registers->rh_status, RHS_OCIC_FLAG); 714 735 TRANSFER_END(request, EOK); 715 736 } … … 775 796 if (request->buffer_size == 0) 776 797 TRANSFER_END(request, EOVERFLOW); 777 uint8_t config = 1;798 const uint8_t config = 1; 778 799 TRANSFER_END_DATA(request, &config, sizeof(config)); 779 800 … … 794 815 TRANSFER_END(request, EINVAL); 795 816 796 instance->address = setup_request->value;817 instance->address = uint16_usb2host(setup_request->value); 797 818 TRANSFER_END(request, EOK); 798 819
Note:
See TracChangeset
for help on using the changeset viewer.