Ignore:
File:
1 edited

Legend:

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

    r56fd7cf r9d58539  
    3838
    3939#include <assert.h>
    40 #include <byteorder.h>
    4140#include <stdio.h>
    4241#include <errno.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>
     
    6970
    7071/** Obtain PCI function soft-state from DDF function node */
    71 static pci_fun_t *pci_fun(ddf_fun_t *fnode)
    72 {
    73         return ddf_fun_data_get(fnode);
    74 }
     72#define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data)
    7573
    7674/** Obtain PCI bus soft-state from DDF device node */
    77 #if 0
    78 static pci_bus_t *pci_bus(ddf_dev_t *dnode)
    79 {
    80         return ddf_dev_data_get(dnode);
    81 }
    82 #endif
     75#define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data)
    8376
    8477/** Obtain PCI bus soft-state from function soft-state */
    85 static pci_bus_t *pci_bus_from_fun(pci_fun_t *fun)
    86 {
    87         return fun->busptr;
    88 }
     78#define PCI_BUS_FROM_FUN(fun) ((fun)->busptr)
    8979
    9080/** Max is 47, align to something nice. */
     
    9383static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode)
    9484{
    95         pci_fun_t *fun = pci_fun(fnode);
     85        pci_fun_t *fun = PCI_FUN(fnode);
    9686       
    9787        if (fun == NULL)
     
    10494        /* This is an old ugly way */
    10595        assert(fnode);
    106         pci_fun_t *dev_data = pci_fun(fnode);
     96        pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
    10797       
    10898        sysarg_t apic;
     
    147137        if (address > 252)
    148138                return EINVAL;
    149         pci_conf_write_32(pci_fun(fun), address, data);
     139        pci_conf_write_32(PCI_FUN(fun), address, data);
    150140        return EOK;
    151141}
     
    156146        if (address > 254)
    157147                return EINVAL;
    158         pci_conf_write_16(pci_fun(fun), address, data);
     148        pci_conf_write_16(PCI_FUN(fun), address, data);
    159149        return EOK;
    160150}
     
    165155        if (address > 255)
    166156                return EINVAL;
    167         pci_conf_write_8(pci_fun(fun), address, data);
     157        pci_conf_write_8(PCI_FUN(fun), address, data);
    168158        return EOK;
    169159}
     
    174164        if (address > 252)
    175165                return EINVAL;
    176         *data = pci_conf_read_32(pci_fun(fun), address);
     166        *data = pci_conf_read_32(PCI_FUN(fun), address);
    177167        return EOK;
    178168}
     
    183173        if (address > 254)
    184174                return EINVAL;
    185         *data = pci_conf_read_16(pci_fun(fun), address);
     175        *data = pci_conf_read_16(PCI_FUN(fun), address);
    186176        return EOK;
    187177}
     
    192182        if (address > 255)
    193183                return EINVAL;
    194         *data = pci_conf_read_8(pci_fun(fun), address);
     184        *data = pci_conf_read_8(PCI_FUN(fun), address);
    195185        return EOK;
    196186}
     
    234224static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    235225{
    236         pci_bus_t *bus = pci_bus_from_fun(fun);
     226        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
    237227       
    238228        fibril_mutex_lock(&bus->conf_mutex);
     
    241231        void *addr = bus->conf_data_port + (reg & 3);
    242232       
    243         pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
     233        pio_write_32(bus->conf_addr_port, conf_addr);
    244234       
    245235        switch (len) {
    246236        case 1:
    247                 /* No endianness change for 1 byte */
    248237                buf[0] = pio_read_8(addr);
    249238                break;
    250239        case 2:
    251                 ((uint16_t *) buf)[0] = uint16_t_le2host(pio_read_16(addr));
     240                ((uint16_t *) buf)[0] = pio_read_16(addr);
    252241                break;
    253242        case 4:
    254                 ((uint32_t *) buf)[0] = uint32_t_le2host(pio_read_32(addr));
     243                ((uint32_t *) buf)[0] = pio_read_32(addr);
    255244                break;
    256245        }
     
    261250static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    262251{
    263         pci_bus_t *bus = pci_bus_from_fun(fun);
     252        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
    264253       
    265254        fibril_mutex_lock(&bus->conf_mutex);
    266255       
    267         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);
    268258        void *addr = bus->conf_data_port + (reg & 3);
    269259       
    270         pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
     260        pio_write_32(bus->conf_addr_port, conf_addr);
    271261       
    272262        switch (len) {
    273263        case 1:
    274                 /* No endianness change for 1 byte */
    275264                pio_write_8(addr, buf[0]);
    276265                break;
    277266        case 2:
    278                 pio_write_16(addr, host2uint16_t_le(((uint16_t *) buf)[0]));
     267                pio_write_16(addr, ((uint16_t *) buf)[0]);
    279268                break;
    280269        case 4:
    281                 pio_write_32(addr, host2uint32_t_le(((uint32_t *) buf)[0]));
     270                pio_write_32(addr, ((uint32_t *) buf)[0]);
    282271                break;
    283272        }
     
    489478        if (range_addr != 0) {
    490479                ddf_msg(LVL_DEBUG, "Function %s : address = %" PRIx64
    491                     ", size = %x", ddf_fun_get_name(fun->fnode), range_addr,
     480                    ", size = %x", fun->fnode->name, range_addr,
    492481                    (unsigned int) range_size);
    493482        }
     
    515504        hw_res_list->count++;
    516505       
    517         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);
    518507}
    519508
     
    532521void pci_bus_scan(pci_bus_t *bus, int bus_num)
    533522{
     523        ddf_fun_t *fnode;
    534524        pci_fun_t *fun;
    535         int rc;
    536525       
    537526        int child_bus = 0;
     
    540529        uint8_t header_type;
    541530       
     531        fun = pci_fun_new(bus);
     532       
    542533        for (dnum = 0; dnum < 32; dnum++) {
    543534                multi = true;
    544535                for (fnum = 0; multi && fnum < 8; fnum++) {
    545                         fun = pci_fun_new(bus);
    546                        
    547536                        pci_fun_init(fun, bus_num, dnum, fnum);
    548537                        if (fun->vendor_id == 0xffff) {
    549                                 pci_fun_delete(fun);
    550538                                /*
    551539                                 * The device is not present, go on scanning the
     
    569557                        if (fun_name == NULL) {
    570558                                ddf_msg(LVL_ERROR, "Out of memory.");
    571                                 pci_fun_delete(fun);
    572559                                return;
    573560                        }
    574561                       
    575                         rc = ddf_fun_set_name(fun->fnode, fun_name);
     562                        fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
    576563                        free(fun_name);
    577                         if (rc != EOK) {
    578                                 ddf_msg(LVL_ERROR, "Failed setting function name.");
    579                                 pci_fun_delete(fun);
     564                        if (fnode == NULL) {
     565                                ddf_msg(LVL_ERROR, "Failed creating function.");
    580566                                return;
    581567                        }
     568                       
     569                        fun->fnode = fnode;
    582570                       
    583571                        pci_alloc_resource_list(fun);
     
    585573                        pci_read_interrupt(fun);
    586574                       
    587                         ddf_fun_set_ops(fun->fnode, &pci_fun_ops);
     575                        fnode->ops = &pci_fun_ops;
     576                        fnode->driver_data = fun;
    588577                       
    589578                        ddf_msg(LVL_DEBUG, "Adding new function %s.",
    590                             ddf_fun_get_name(fun->fnode));
     579                            fnode->name);
    591580                       
    592581                        pci_fun_create_match_ids(fun);
    593582                       
    594                         if (ddf_fun_bind(fun->fnode) != EOK) {
     583                        if (ddf_fun_bind(fnode) != EOK) {
    595584                                pci_clean_resource_list(fun);
    596                                 pci_fun_delete(fun);
     585                                clean_match_ids(&fnode->match_ids);
     586                                free((char *) fnode->name);
     587                                fnode->name = NULL;
    597588                                continue;
    598589                        }
     
    608599                                        pci_bus_scan(bus, child_bus);
    609600                        }
     601                       
     602                        fun = pci_fun_new(bus);
    610603                }
     604        }
     605       
     606        if (fun->vendor_id == 0xffff) {
     607                /* Free the auxiliary function structure. */
     608                pci_fun_delete(fun);
    611609        }
    612610}
     
    617615        ddf_fun_t *ctl = NULL;
    618616        bool got_res = false;
    619         async_sess_t *sess;
    620617        int rc;
    621618       
    622619        ddf_msg(LVL_DEBUG, "pci_dev_add");
     620        dnode->parent_sess = NULL;
    623621       
    624622        bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t));
     
    631629
    632630        bus->dnode = dnode;
    633        
    634         sess = ddf_dev_parent_sess_create(dnode, EXCHANGE_SERIALIZE);
    635         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) {
    636636                ddf_msg(LVL_ERROR, "pci_dev_add failed to connect to the "
    637637                    "parent driver.");
     
    642642        hw_resource_list_t hw_resources;
    643643       
    644         rc = hw_res_get_resource_list(sess, &hw_resources);
     644        rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources);
    645645        if (rc != EOK) {
    646646                ddf_msg(LVL_ERROR, "pci_dev_add failed to get hw resources "
     
    650650        got_res = true;
    651651       
    652        
    653         assert(hw_resources.count > 1);
    654         assert(hw_resources.resources[0].type == IO_RANGE);
    655         assert(hw_resources.resources[0].res.io_range.size >= 4);
    656        
    657         assert(hw_resources.resources[1].type == IO_RANGE);
    658         assert(hw_resources.resources[1].res.io_range.size >= 4);
    659        
    660652        ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".",
    661653            hw_resources.resources[0].res.io_range.address);
    662         ddf_msg(LVL_DEBUG, "data_addr = %" PRIx64 ".",
    663             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);
    664658       
    665659        bus->conf_io_addr =
    666660            (uint32_t) hw_resources.resources[0].res.io_range.address;
    667         bus->conf_io_data =
    668             (uint32_t) hw_resources.resources[1].res.io_range.address;
    669        
    670         if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 4,
     661       
     662        if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8,
    671663            &bus->conf_addr_port)) {
    672664                ddf_msg(LVL_ERROR, "Failed to enable configuration ports.");
     
    674666                goto fail;
    675667        }
    676         if (pio_enable((void *)(uintptr_t)bus->conf_io_data, 4,
    677             &bus->conf_data_port)) {
    678                 ddf_msg(LVL_ERROR, "Failed to enable configuration ports.");
    679                 rc = EADDRNOTAVAIL;
    680                 goto fail;
    681         }
     668        bus->conf_data_port = (char *) bus->conf_addr_port + 4;
    682669       
    683670        /* Make the bus device more visible. It has no use yet. */
     
    706693       
    707694fail:
     695        if (dnode->parent_sess)
     696                async_hangup(dnode->parent_sess);
     697       
    708698        if (got_res)
    709699                hw_res_clean_resource_list(&hw_resources);
     
    737727{
    738728        pci_fun_t *fun;
    739         ddf_fun_t *fnode;
    740        
    741         fnode = ddf_fun_create(bus->dnode, fun_inner, NULL);
    742         if (fnode == NULL)
    743                 return NULL;
    744 
    745         fun = ddf_fun_data_alloc(fnode, sizeof(pci_fun_t));
     729       
     730        fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t));
    746731        if (fun == NULL)
    747732                return NULL;
    748733
    749734        fun->busptr = bus;
    750         fun->fnode = fnode;
    751735        return fun;
    752736}
     
    767751void pci_fun_delete(pci_fun_t *fun)
    768752{
     753        assert(fun != NULL);
    769754        hw_res_clean_resource_list(&fun->hw_resources);
    770         if (fun->fnode != NULL)
    771                 ddf_fun_destroy(fun->fnode);
     755        free(fun);
    772756}
    773757
Note: See TracChangeset for help on using the changeset viewer.