Changeset a35b458 in mainline for uspace/drv/bus/pci/pciintel/pci.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/pci/pciintel/pci.c
r3061bc1 ra35b458 93 93 { 94 94 pci_fun_t *fun = pci_fun(fnode); 95 95 96 96 if (fun == NULL) 97 97 return NULL; … … 103 103 size_t i; 104 104 hw_resource_list_t *res = &fun->hw_resources; 105 105 106 106 for (i = 0; i < res->count; i++) { 107 107 if (res->resources[i].type == INTERRUPT && … … 110 110 } 111 111 } 112 112 113 113 return false; 114 114 } … … 117 117 { 118 118 pci_fun_t *fun = pci_fun(fnode); 119 119 120 120 if (!pciintel_fun_owns_interrupt(fun, irq)) 121 121 return EINVAL; … … 127 127 { 128 128 pci_fun_t *fun = pci_fun(fnode); 129 129 130 130 if (!pciintel_fun_owns_interrupt(fun, irq)) 131 131 return EINVAL; … … 137 137 { 138 138 pci_fun_t *fun = pci_fun(fnode); 139 139 140 140 if (!pciintel_fun_owns_interrupt(fun, irq)) 141 141 return EINVAL; … … 147 147 { 148 148 pci_fun_t *fun = pci_fun(fnode); 149 149 150 150 if (fun == NULL) 151 151 return NULL; … … 256 256 pci_bus_t *bus = pci_bus_from_fun(fun); 257 257 uint32_t val; 258 258 259 259 fibril_mutex_lock(&bus->conf_mutex); 260 260 … … 285 285 break; 286 286 } 287 287 288 288 fibril_mutex_unlock(&bus->conf_mutex); 289 289 } … … 294 294 pci_bus_t *bus = pci_bus_from_fun(fun); 295 295 uint32_t val = 0; 296 296 297 297 fibril_mutex_lock(&bus->conf_mutex); 298 298 … … 317 317 } 318 318 } 319 319 320 320 switch (len) { 321 321 case 1: … … 340 340 host2uint32_t_le(val)); 341 341 } 342 342 343 343 fibril_mutex_unlock(&bus->conf_mutex); 344 344 } … … 458 458 hw_resource_t *hw_resources = hw_res_list->resources; 459 459 size_t count = hw_res_list->count; 460 460 461 461 assert(hw_resources != NULL); 462 462 assert(count < PCI_MAX_HW_RES); 463 463 464 464 if (io) { 465 465 hw_resources[count].type = IO_RANGE; … … 475 475 hw_resources[count].res.mem_range.endianness = LITTLE_ENDIAN; 476 476 } 477 477 478 478 hw_res_list->count++; 479 479 } … … 498 498 /* 64-bit wide address */ 499 499 bool addrw64; 500 500 501 501 /* Size of the io or memory range specified by the BAR */ 502 502 size_t range_size; 503 503 /* Beginning of the io or memory range specified by the BAR */ 504 504 uint64_t range_addr; 505 505 506 506 /* Get the value of the BAR. */ 507 507 val = pci_conf_read_32(fun, addr); … … 509 509 #define IO_MASK (~0x3) 510 510 #define MEM_MASK (~0xf) 511 511 512 512 io = (val & 1) != 0; 513 513 if (io) { … … 528 528 } 529 529 } 530 530 531 531 /* Get the address mask. */ 532 532 pci_conf_write_32(fun, addr, 0xffffffff); … … 544 544 pci_conf_write_32(fun, addr, val); 545 545 val = pci_conf_read_32(fun, addr); 546 546 547 547 range_size = pci_bar_mask_to_size(mask); 548 548 549 549 if (addrw64) { 550 550 range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) | … … 553 553 range_addr = (val & 0xfffffff0); 554 554 } 555 555 556 556 if (range_addr != 0) { 557 557 ddf_msg(LVL_DEBUG, "Function %s : address = %" PRIx64 … … 559 559 (unsigned int) range_size); 560 560 } 561 561 562 562 pci_add_range(fun, range_addr, range_size, io); 563 563 564 564 if (addrw64) 565 565 return addr + 8; 566 566 567 567 return addr + 4; 568 568 } … … 573 573 hw_resource_t *hw_resources = hw_res_list->resources; 574 574 size_t count = hw_res_list->count; 575 575 576 576 assert(NULL != hw_resources); 577 577 assert(count < PCI_MAX_HW_RES); 578 578 579 579 hw_resources[count].type = INTERRUPT; 580 580 hw_resources[count].res.interrupt.irq = irq; 581 581 582 582 hw_res_list->count++; 583 583 584 584 ddf_msg(LVL_NOTE, "Function %s uses irq %x.", ddf_fun_get_name(fun->fnode), irq); 585 585 } … … 603 603 pci_fun_t *fun; 604 604 errno_t rc; 605 605 606 606 int child_bus = 0; 607 607 int dnum, fnum; 608 608 bool multi; 609 609 uint8_t header_type; 610 610 611 611 for (dnum = 0; dnum < 32; dnum++) { 612 612 multi = true; 613 613 for (fnum = 0; multi && fnum < 8; fnum++) { 614 614 fun = pci_fun_new(bus); 615 615 616 616 pci_fun_init(fun, bus_num, dnum, fnum); 617 617 if (fun->vendor_id == 0xffff) { … … 626 626 continue; 627 627 } 628 628 629 629 header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE); 630 630 if (fnum == 0) { … … 634 634 /* Clear the multifunction bit. */ 635 635 header_type = header_type & 0x7F; 636 636 637 637 char *fun_name = pci_fun_create_name(fun); 638 638 if (fun_name == NULL) { … … 641 641 return; 642 642 } 643 643 644 644 rc = ddf_fun_set_name(fun->fnode, fun_name); 645 645 free(fun_name); … … 649 649 return; 650 650 } 651 651 652 652 pci_alloc_resource_list(fun); 653 653 pci_read_bars(fun); … … 656 656 /* Propagate the PIO window to the function. */ 657 657 fun->pio_window = bus->pio_win; 658 658 659 659 ddf_fun_set_ops(fun->fnode, &pci_fun_ops); 660 660 661 661 ddf_msg(LVL_DEBUG, "Adding new function %s.", 662 662 ddf_fun_get_name(fun->fnode)); 663 663 664 664 pci_fun_create_match_ids(fun); 665 665 666 666 if (ddf_fun_bind(fun->fnode) != EOK) { 667 667 pci_clean_resource_list(fun); … … 669 669 continue; 670 670 } 671 671 672 672 if (header_type == PCI_HEADER_TYPE_BRIDGE || 673 673 header_type == PCI_HEADER_TYPE_CARDBUS) { … … 692 692 async_sess_t *sess; 693 693 errno_t rc; 694 694 695 695 ddf_msg(LVL_DEBUG, "pci_dev_add"); 696 696 697 697 bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t)); 698 698 if (bus == NULL) { … … 704 704 705 705 bus->dnode = dnode; 706 706 707 707 sess = ddf_dev_parent_sess_get(dnode); 708 708 if (sess == NULL) { … … 719 719 goto fail; 720 720 } 721 721 722 722 rc = hw_res_get_resource_list(sess, &hw_resources); 723 723 if (rc != EOK) { … … 727 727 } 728 728 got_res = true; 729 730 729 730 731 731 assert(hw_resources.count >= 1); 732 732 … … 745 745 goto fail; 746 746 } 747 747 748 748 } else { 749 749 assert(hw_resources.resources[0].type == IO_RANGE); 750 750 assert(hw_resources.resources[0].res.io_range.size >= 4); 751 751 752 752 assert(hw_resources.resources[1].type == IO_RANGE); 753 753 assert(hw_resources.resources[1].res.io_range.size >= 4); 754 754 755 755 ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".", 756 756 hw_resources.resources[0].res.io_range.address); 757 757 ddf_msg(LVL_DEBUG, "data_addr = %" PRIx64 ".", 758 758 hw_resources.resources[1].res.io_range.address); 759 759 760 760 if (pio_enable_resource(&bus->pio_win, 761 761 &hw_resources.resources[0], … … 775 775 } 776 776 } 777 777 778 778 /* Make the bus device more visible. It has no use yet. */ 779 779 ddf_msg(LVL_DEBUG, "Adding a 'ctl' function"); 780 780 781 781 ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl"); 782 782 if (ctl == NULL) { … … 785 785 goto fail; 786 786 } 787 787 788 788 rc = ddf_fun_bind(ctl); 789 789 if (rc != EOK) { … … 791 791 goto fail; 792 792 } 793 793 794 794 /* Enumerate functions. */ 795 795 ddf_msg(LVL_DEBUG, "Scanning the bus"); 796 796 pci_bus_scan(bus, 0); 797 797 798 798 hw_res_clean_resource_list(&hw_resources); 799 799 800 800 return EOK; 801 801 802 802 fail: 803 803 if (got_res) 804 804 hw_res_clean_resource_list(&hw_resources); 805 805 806 806 if (ctl != NULL) 807 807 ddf_fun_destroy(ctl); 808 808 809 809 return rc; 810 810 } … … 831 831 pci_fun_t *fun; 832 832 ddf_fun_t *fnode; 833 833 834 834 fnode = ddf_fun_create(bus->dnode, fun_inner, NULL); 835 835 if (fnode == NULL) … … 852 852 fun->vendor_id = pci_conf_read_16(fun, PCI_VENDOR_ID); 853 853 fun->device_id = pci_conf_read_16(fun, PCI_DEVICE_ID); 854 854 855 855 /* Explicitly enable PCI bus mastering */ 856 856 fun->command = pci_conf_read_16(fun, PCI_COMMAND) | 857 857 PCI_COMMAND_MASTER; 858 858 pci_conf_write_16(fun, PCI_COMMAND, fun->command); 859 859 860 860 fun->class_code = pci_conf_read_8(fun, PCI_BASE_CLASS); 861 861 fun->subclass_code = pci_conf_read_8(fun, PCI_SUB_CLASS); … … 874 874 { 875 875 char *name = NULL; 876 876 877 877 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 878 878 fun->fn); … … 903 903 */ 904 904 int addr = PCI_BASE_ADDR_0; 905 905 906 906 while (addr <= PCI_BASE_ADDR_5) 907 907 addr = pci_read_bar(fun, addr);
Note:
See TracChangeset
for help on using the changeset viewer.