Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/pci/pciintel/pci.c

    rc90aed4 r2df6f6fe  
    3838
    3939#include <assert.h>
    40 #include <byteorder.h>
    4140#include <stdio.h>
    4241#include <errno.h>
    43 #include <stdbool.h>
     42#include <bool.h>
    4443#include <fibril_synch.h>
    4544#include <str.h>
     
    5049#include <ddf/driver.h>
    5150#include <ddf/log.h>
     51#include <devman.h>
     52#include <ipc/devman.h>
    5253#include <ipc/dev_iface.h>
    5354#include <ipc/irc.h>
     
    5859#include <device/hw_res.h>
    5960#include <ddi.h>
     61#include <libarch/ddi.h>
    6062#include <pci_dev_iface.h>
    6163
     
    6870
    6971/** 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)
    7473
    7574/** 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)
    8276
    8377/** 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)
    8879
    8980/** Max is 47, align to something nice. */
     
    9283static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode)
    9384{
    94         pci_fun_t *fun = pci_fun(fnode);
     85        pci_fun_t *fun = PCI_FUN(fnode);
    9586       
    9687        if (fun == NULL)
     
    10394        /* This is an old ugly way */
    10495        assert(fnode);
    105         pci_fun_t *dev_data = pci_fun(fnode);
     96        pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
    10697       
    10798        sysarg_t apic;
     
    146137        if (address > 252)
    147138                return EINVAL;
    148         pci_conf_write_32(pci_fun(fun), address, data);
     139        pci_conf_write_32(PCI_FUN(fun), address, data);
    149140        return EOK;
    150141}
     
    155146        if (address > 254)
    156147                return EINVAL;
    157         pci_conf_write_16(pci_fun(fun), address, data);
     148        pci_conf_write_16(PCI_FUN(fun), address, data);
    158149        return EOK;
    159150}
     
    164155        if (address > 255)
    165156                return EINVAL;
    166         pci_conf_write_8(pci_fun(fun), address, data);
     157        pci_conf_write_8(PCI_FUN(fun), address, data);
    167158        return EOK;
    168159}
     
    173164        if (address > 252)
    174165                return EINVAL;
    175         *data = pci_conf_read_32(pci_fun(fun), address);
     166        *data = pci_conf_read_32(PCI_FUN(fun), address);
    176167        return EOK;
    177168}
     
    182173        if (address > 254)
    183174                return EINVAL;
    184         *data = pci_conf_read_16(pci_fun(fun), address);
     175        *data = pci_conf_read_16(PCI_FUN(fun), address);
    185176        return EOK;
    186177}
     
    191182        if (address > 255)
    192183                return EINVAL;
    193         *data = pci_conf_read_8(pci_fun(fun), address);
     184        *data = pci_conf_read_8(PCI_FUN(fun), address);
    194185        return EOK;
    195186}
     
    233224static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    234225{
    235         pci_bus_t *bus = pci_bus_from_fun(fun);
     226        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
    236227       
    237228        fibril_mutex_lock(&bus->conf_mutex);
     
    240231        void *addr = bus->conf_data_port + (reg & 3);
    241232       
    242         pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
     233        pio_write_32(bus->conf_addr_port, conf_addr);
    243234       
    244235        switch (len) {
    245236        case 1:
    246                 /* No endianness change for 1 byte */
    247237                buf[0] = pio_read_8(addr);
    248238                break;
    249239        case 2:
    250                 ((uint16_t *) buf)[0] = uint16_t_le2host(pio_read_16(addr));
     240                ((uint16_t *) buf)[0] = pio_read_16(addr);
    251241                break;
    252242        case 4:
    253                 ((uint32_t *) buf)[0] = uint32_t_le2host(pio_read_32(addr));
     243                ((uint32_t *) buf)[0] = pio_read_32(addr);
    254244                break;
    255245        }
     
    260250static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    261251{
    262         pci_bus_t *bus = pci_bus_from_fun(fun);
     252        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
    263253       
    264254        fibril_mutex_lock(&bus->conf_mutex);
    265255       
    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);
    267258        void *addr = bus->conf_data_port + (reg & 3);
    268259       
    269         pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
     260        pio_write_32(bus->conf_addr_port, conf_addr);
    270261       
    271262        switch (len) {
    272263        case 1:
    273                 /* No endianness change for 1 byte */
    274264                pio_write_8(addr, buf[0]);
    275265                break;
    276266        case 2:
    277                 pio_write_16(addr, host2uint16_t_le(((uint16_t *) buf)[0]));
     267                pio_write_16(addr, ((uint16_t *) buf)[0]);
    278268                break;
    279269        case 4:
    280                 pio_write_32(addr, host2uint32_t_le(((uint32_t *) buf)[0]));
     270                pio_write_32(addr, ((uint32_t *) buf)[0]);
    281271                break;
    282272        }
     
    327317
    328318        /* 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);
    331321        if (rc < 0) {
    332322                ddf_msg(LVL_ERROR, "Failed creating match ID str: %s",
     
    488478        if (range_addr != 0) {
    489479                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,
    491481                    (unsigned int) range_size);
    492482        }
     
    514504        hw_res_list->count++;
    515505       
    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);
    517507}
    518508
     
    531521void pci_bus_scan(pci_bus_t *bus, int bus_num)
    532522{
     523        ddf_fun_t *fnode;
    533524        pci_fun_t *fun;
    534         int rc;
    535525       
    536526        int child_bus = 0;
     
    539529        uint8_t header_type;
    540530       
     531        fun = pci_fun_new(bus);
     532       
    541533        for (dnum = 0; dnum < 32; dnum++) {
    542534                multi = true;
    543535                for (fnum = 0; multi && fnum < 8; fnum++) {
    544                         fun = pci_fun_new(bus);
    545                        
    546536                        pci_fun_init(fun, bus_num, dnum, fnum);
    547537                        if (fun->vendor_id == 0xffff) {
    548                                 pci_fun_delete(fun);
    549538                                /*
    550539                                 * The device is not present, go on scanning the
     
    568557                        if (fun_name == NULL) {
    569558                                ddf_msg(LVL_ERROR, "Out of memory.");
    570                                 pci_fun_delete(fun);
    571559                                return;
    572560                        }
    573561                       
    574                         rc = ddf_fun_set_name(fun->fnode, fun_name);
     562                        fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
    575563                        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.");
    579566                                return;
    580567                        }
     568                       
     569                        fun->fnode = fnode;
    581570                       
    582571                        pci_alloc_resource_list(fun);
     
    584573                        pci_read_interrupt(fun);
    585574                       
    586                         ddf_fun_set_ops(fun->fnode, &pci_fun_ops);
     575                        fnode->ops = &pci_fun_ops;
     576                        fnode->driver_data = fun;
    587577                       
    588578                        ddf_msg(LVL_DEBUG, "Adding new function %s.",
    589                             ddf_fun_get_name(fun->fnode));
     579                            fnode->name);
    590580                       
    591581                        pci_fun_create_match_ids(fun);
    592582                       
    593                         if (ddf_fun_bind(fun->fnode) != EOK) {
     583                        if (ddf_fun_bind(fnode) != EOK) {
    594584                                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;
    596588                                continue;
    597589                        }
     
    607599                                        pci_bus_scan(bus, child_bus);
    608600                        }
     601                       
     602                        fun = pci_fun_new(bus);
    609603                }
     604        }
     605       
     606        if (fun->vendor_id == 0xffff) {
     607                /* Free the auxiliary function structure. */
     608                pci_fun_delete(fun);
    610609        }
    611610}
     
    616615        ddf_fun_t *ctl = NULL;
    617616        bool got_res = false;
    618         async_sess_t *sess;
    619617        int rc;
    620618       
    621619        ddf_msg(LVL_DEBUG, "pci_dev_add");
     620        dnode->parent_sess = NULL;
    622621       
    623622        bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t));
     
    630629
    631630        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) {
    635636                ddf_msg(LVL_ERROR, "pci_dev_add failed to connect to the "
    636637                    "parent driver.");
     
    641642        hw_resource_list_t hw_resources;
    642643       
    643         rc = hw_res_get_resource_list(sess, &hw_resources);
     644        rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources);
    644645        if (rc != EOK) {
    645646                ddf_msg(LVL_ERROR, "pci_dev_add failed to get hw resources "
     
    649650        got_res = true;
    650651       
    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        
    659652        ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".",
    660653            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);
    663658       
    664659        bus->conf_io_addr =
    665660            (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,
    670663            &bus->conf_addr_port)) {
    671664                ddf_msg(LVL_ERROR, "Failed to enable configuration ports.");
     
    673666                goto fail;
    674667        }
    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;
    681669       
    682670        /* Make the bus device more visible. It has no use yet. */
     
    705693       
    706694fail:
     695        if (dnode->parent_sess)
     696                async_hangup(dnode->parent_sess);
     697       
    707698        if (got_res)
    708699                hw_res_clean_resource_list(&hw_resources);
     
    728719static void pciintel_init(void)
    729720{
    730         ddf_log_init(NAME);
     721        ddf_log_init(NAME, LVL_ERROR);
    731722        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
    732723        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
     
    736727{
    737728        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));
    745731        if (fun == NULL)
    746732                return NULL;
    747733
    748734        fun->busptr = bus;
    749         fun->fnode = fnode;
    750735        return fun;
    751736}
     
    758743        fun->vendor_id = pci_conf_read_16(fun, PCI_VENDOR_ID);
    759744        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        
    766745        fun->class_code = pci_conf_read_8(fun, PCI_BASE_CLASS);
    767746        fun->subclass_code = pci_conf_read_8(fun, PCI_SUB_CLASS);
     
    772751void pci_fun_delete(pci_fun_t *fun)
    773752{
     753        assert(fun != NULL);
    774754        hw_res_clean_resource_list(&fun->hw_resources);
    775         if (fun->fnode != NULL)
    776                 ddf_fun_destroy(fun->fnode);
     755        free(fun);
    777756}
    778757
Note: See TracChangeset for help on using the changeset viewer.