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