Changes in uspace/drv/bus/pci/pciintel/pci.c [2df6f6fe:c90aed4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/pci/pciintel/pci.c
r2df6f6fe rc90aed4 38 38 39 39 #include <assert.h> 40 #include <byteorder.h> 40 41 #include <stdio.h> 41 42 #include <errno.h> 42 #include < bool.h>43 #include <stdbool.h> 43 44 #include <fibril_synch.h> 44 45 #include <str.h> … … 49 50 #include <ddf/driver.h> 50 51 #include <ddf/log.h> 51 #include <devman.h>52 #include <ipc/devman.h>53 52 #include <ipc/dev_iface.h> 54 53 #include <ipc/irc.h> … … 59 58 #include <device/hw_res.h> 60 59 #include <ddi.h> 61 #include <libarch/ddi.h>62 60 #include <pci_dev_iface.h> 63 61 … … 70 68 71 69 /** Obtain PCI function soft-state from DDF function node */ 72 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data) 70 static pci_fun_t *pci_fun(ddf_fun_t *fnode) 71 { 72 return ddf_fun_data_get(fnode); 73 } 73 74 74 75 /** Obtain PCI bus soft-state from DDF device node */ 75 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data) 76 #if 0 77 static pci_bus_t *pci_bus(ddf_dev_t *dnode) 78 { 79 return ddf_dev_data_get(dnode); 80 } 81 #endif 76 82 77 83 /** Obtain PCI bus soft-state from function soft-state */ 78 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 84 static pci_bus_t *pci_bus_from_fun(pci_fun_t *fun) 85 { 86 return fun->busptr; 87 } 79 88 80 89 /** Max is 47, align to something nice. */ … … 83 92 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) 84 93 { 85 pci_fun_t *fun = PCI_FUN(fnode);94 pci_fun_t *fun = pci_fun(fnode); 86 95 87 96 if (fun == NULL) … … 94 103 /* This is an old ugly way */ 95 104 assert(fnode); 96 pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;105 pci_fun_t *dev_data = pci_fun(fnode); 97 106 98 107 sysarg_t apic; … … 137 146 if (address > 252) 138 147 return EINVAL; 139 pci_conf_write_32( PCI_FUN(fun), address, data);148 pci_conf_write_32(pci_fun(fun), address, data); 140 149 return EOK; 141 150 } … … 146 155 if (address > 254) 147 156 return EINVAL; 148 pci_conf_write_16( PCI_FUN(fun), address, data);157 pci_conf_write_16(pci_fun(fun), address, data); 149 158 return EOK; 150 159 } … … 155 164 if (address > 255) 156 165 return EINVAL; 157 pci_conf_write_8( PCI_FUN(fun), address, data);166 pci_conf_write_8(pci_fun(fun), address, data); 158 167 return EOK; 159 168 } … … 164 173 if (address > 252) 165 174 return EINVAL; 166 *data = pci_conf_read_32( PCI_FUN(fun), address);175 *data = pci_conf_read_32(pci_fun(fun), address); 167 176 return EOK; 168 177 } … … 173 182 if (address > 254) 174 183 return EINVAL; 175 *data = pci_conf_read_16( PCI_FUN(fun), address);184 *data = pci_conf_read_16(pci_fun(fun), address); 176 185 return EOK; 177 186 } … … 182 191 if (address > 255) 183 192 return EINVAL; 184 *data = pci_conf_read_8( PCI_FUN(fun), address);193 *data = pci_conf_read_8(pci_fun(fun), address); 185 194 return EOK; 186 195 } … … 224 233 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 225 234 { 226 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);235 pci_bus_t *bus = pci_bus_from_fun(fun); 227 236 228 237 fibril_mutex_lock(&bus->conf_mutex); … … 231 240 void *addr = bus->conf_data_port + (reg & 3); 232 241 233 pio_write_32(bus->conf_addr_port, conf_addr);242 pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr)); 234 243 235 244 switch (len) { 236 245 case 1: 246 /* No endianness change for 1 byte */ 237 247 buf[0] = pio_read_8(addr); 238 248 break; 239 249 case 2: 240 ((uint16_t *) buf)[0] = pio_read_16(addr);250 ((uint16_t *) buf)[0] = uint16_t_le2host(pio_read_16(addr)); 241 251 break; 242 252 case 4: 243 ((uint32_t *) buf)[0] = pio_read_32(addr);253 ((uint32_t *) buf)[0] = uint32_t_le2host(pio_read_32(addr)); 244 254 break; 245 255 } … … 250 260 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 251 261 { 252 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);262 pci_bus_t *bus = pci_bus_from_fun(fun); 253 263 254 264 fibril_mutex_lock(&bus->conf_mutex); 255 265 256 uint32_t conf_addr; 257 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 266 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 258 267 void *addr = bus->conf_data_port + (reg & 3); 259 268 260 pio_write_32(bus->conf_addr_port, conf_addr);269 pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr)); 261 270 262 271 switch (len) { 263 272 case 1: 273 /* No endianness change for 1 byte */ 264 274 pio_write_8(addr, buf[0]); 265 275 break; 266 276 case 2: 267 pio_write_16(addr, ((uint16_t *) buf)[0]);277 pio_write_16(addr, host2uint16_t_le(((uint16_t *) buf)[0])); 268 278 break; 269 279 case 4: 270 pio_write_32(addr, ((uint32_t *) buf)[0]);280 pio_write_32(addr, host2uint32_t_le(((uint32_t *) buf)[0])); 271 281 break; 272 282 } … … 317 327 318 328 /* Vendor ID & Device ID, length(incl \0) 22 */ 319 rc = snprintf(match_id_str, ID_MAX_STR_LEN, "pci/ven=%04 x&dev=%04x",320 fun->vendor_id, fun->device_id);329 rc = snprintf(match_id_str, ID_MAX_STR_LEN, "pci/ven=%04" 330 PRIx16 "&dev=%04" PRIx16, fun->vendor_id, fun->device_id); 321 331 if (rc < 0) { 322 332 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", … … 478 488 if (range_addr != 0) { 479 489 ddf_msg(LVL_DEBUG, "Function %s : address = %" PRIx64 480 ", size = %x", fun->fnode->name, range_addr,490 ", size = %x", ddf_fun_get_name(fun->fnode), range_addr, 481 491 (unsigned int) range_size); 482 492 } … … 504 514 hw_res_list->count++; 505 515 506 ddf_msg(LVL_NOTE, "Function %s uses irq %x.", fun->fnode->name, irq);516 ddf_msg(LVL_NOTE, "Function %s uses irq %x.", ddf_fun_get_name(fun->fnode), irq); 507 517 } 508 518 … … 521 531 void pci_bus_scan(pci_bus_t *bus, int bus_num) 522 532 { 523 ddf_fun_t *fnode;524 533 pci_fun_t *fun; 534 int rc; 525 535 526 536 int child_bus = 0; … … 529 539 uint8_t header_type; 530 540 531 fun = pci_fun_new(bus);532 533 541 for (dnum = 0; dnum < 32; dnum++) { 534 542 multi = true; 535 543 for (fnum = 0; multi && fnum < 8; fnum++) { 544 fun = pci_fun_new(bus); 545 536 546 pci_fun_init(fun, bus_num, dnum, fnum); 537 547 if (fun->vendor_id == 0xffff) { 548 pci_fun_delete(fun); 538 549 /* 539 550 * The device is not present, go on scanning the … … 557 568 if (fun_name == NULL) { 558 569 ddf_msg(LVL_ERROR, "Out of memory."); 570 pci_fun_delete(fun); 559 571 return; 560 572 } 561 573 562 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);574 rc = ddf_fun_set_name(fun->fnode, fun_name); 563 575 free(fun_name); 564 if (fnode == NULL) { 565 ddf_msg(LVL_ERROR, "Failed creating function."); 576 if (rc != EOK) { 577 ddf_msg(LVL_ERROR, "Failed setting function name."); 578 pci_fun_delete(fun); 566 579 return; 567 580 } 568 569 fun->fnode = fnode;570 581 571 582 pci_alloc_resource_list(fun); … … 573 584 pci_read_interrupt(fun); 574 585 575 fnode->ops = &pci_fun_ops; 576 fnode->driver_data = fun; 586 ddf_fun_set_ops(fun->fnode, &pci_fun_ops); 577 587 578 588 ddf_msg(LVL_DEBUG, "Adding new function %s.", 579 fnode->name);589 ddf_fun_get_name(fun->fnode)); 580 590 581 591 pci_fun_create_match_ids(fun); 582 592 583 if (ddf_fun_bind(f node) != EOK) {593 if (ddf_fun_bind(fun->fnode) != EOK) { 584 594 pci_clean_resource_list(fun); 585 clean_match_ids(&fnode->match_ids); 586 free((char *) fnode->name); 587 fnode->name = NULL; 595 pci_fun_delete(fun); 588 596 continue; 589 597 } … … 599 607 pci_bus_scan(bus, child_bus); 600 608 } 601 602 fun = pci_fun_new(bus);603 609 } 604 }605 606 if (fun->vendor_id == 0xffff) {607 /* Free the auxiliary function structure. */608 pci_fun_delete(fun);609 610 } 610 611 } … … 615 616 ddf_fun_t *ctl = NULL; 616 617 bool got_res = false; 618 async_sess_t *sess; 617 619 int rc; 618 620 619 621 ddf_msg(LVL_DEBUG, "pci_dev_add"); 620 dnode->parent_sess = NULL;621 622 622 623 bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t)); … … 629 630 630 631 bus->dnode = dnode; 631 dnode->driver_data = bus; 632 633 dnode->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE, 634 dnode->handle, IPC_FLAG_BLOCKING); 635 if (!dnode->parent_sess) { 632 633 sess = ddf_dev_parent_sess_create(dnode, EXCHANGE_SERIALIZE); 634 if (sess == NULL) { 636 635 ddf_msg(LVL_ERROR, "pci_dev_add failed to connect to the " 637 636 "parent driver."); … … 642 641 hw_resource_list_t hw_resources; 643 642 644 rc = hw_res_get_resource_list( dnode->parent_sess, &hw_resources);643 rc = hw_res_get_resource_list(sess, &hw_resources); 645 644 if (rc != EOK) { 646 645 ddf_msg(LVL_ERROR, "pci_dev_add failed to get hw resources " … … 650 649 got_res = true; 651 650 651 652 assert(hw_resources.count > 1); 653 assert(hw_resources.resources[0].type == IO_RANGE); 654 assert(hw_resources.resources[0].res.io_range.size >= 4); 655 656 assert(hw_resources.resources[1].type == IO_RANGE); 657 assert(hw_resources.resources[1].res.io_range.size >= 4); 658 652 659 ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".", 653 660 hw_resources.resources[0].res.io_range.address); 654 655 assert(hw_resources.count > 0); 656 assert(hw_resources.resources[0].type == IO_RANGE); 657 assert(hw_resources.resources[0].res.io_range.size == 8); 661 ddf_msg(LVL_DEBUG, "data_addr = %" PRIx64 ".", 662 hw_resources.resources[1].res.io_range.address); 658 663 659 664 bus->conf_io_addr = 660 665 (uint32_t) hw_resources.resources[0].res.io_range.address; 661 662 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8, 666 bus->conf_io_data = 667 (uint32_t) hw_resources.resources[1].res.io_range.address; 668 669 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 4, 663 670 &bus->conf_addr_port)) { 664 671 ddf_msg(LVL_ERROR, "Failed to enable configuration ports."); … … 666 673 goto fail; 667 674 } 668 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 675 if (pio_enable((void *)(uintptr_t)bus->conf_io_data, 4, 676 &bus->conf_data_port)) { 677 ddf_msg(LVL_ERROR, "Failed to enable configuration ports."); 678 rc = EADDRNOTAVAIL; 679 goto fail; 680 } 669 681 670 682 /* Make the bus device more visible. It has no use yet. */ … … 693 705 694 706 fail: 695 if (dnode->parent_sess)696 async_hangup(dnode->parent_sess);697 698 707 if (got_res) 699 708 hw_res_clean_resource_list(&hw_resources); … … 719 728 static void pciintel_init(void) 720 729 { 721 ddf_log_init(NAME , LVL_ERROR);730 ddf_log_init(NAME); 722 731 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 723 732 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops; … … 727 736 { 728 737 pci_fun_t *fun; 729 730 fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t)); 738 ddf_fun_t *fnode; 739 740 fnode = ddf_fun_create(bus->dnode, fun_inner, NULL); 741 if (fnode == NULL) 742 return NULL; 743 744 fun = ddf_fun_data_alloc(fnode, sizeof(pci_fun_t)); 731 745 if (fun == NULL) 732 746 return NULL; 733 747 734 748 fun->busptr = bus; 749 fun->fnode = fnode; 735 750 return fun; 736 751 } … … 743 758 fun->vendor_id = pci_conf_read_16(fun, PCI_VENDOR_ID); 744 759 fun->device_id = pci_conf_read_16(fun, PCI_DEVICE_ID); 760 761 /* Explicitly enable PCI bus mastering */ 762 fun->command = pci_conf_read_16(fun, PCI_COMMAND) | 763 PCI_COMMAND_MASTER; 764 pci_conf_write_16(fun, PCI_COMMAND, fun->command); 765 745 766 fun->class_code = pci_conf_read_8(fun, PCI_BASE_CLASS); 746 767 fun->subclass_code = pci_conf_read_8(fun, PCI_SUB_CLASS); … … 751 772 void pci_fun_delete(pci_fun_t *fun) 752 773 { 753 assert(fun != NULL);754 774 hw_res_clean_resource_list(&fun->hw_resources); 755 free(fun); 775 if (fun->fnode != NULL) 776 ddf_fun_destroy(fun->fnode); 756 777 } 757 778
Note:
See TracChangeset
for help on using the changeset viewer.