Ignore:
File:
1 edited

Legend:

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

    r9d58539 r267f235  
    3838
    3939#include <assert.h>
     40#include <byteorder.h>
    4041#include <stdio.h>
    4142#include <errno.h>
     
    4950#include <ddf/driver.h>
    5051#include <ddf/log.h>
    51 #include <devman.h>
    52 #include <ipc/devman.h>
    5352#include <ipc/dev_iface.h>
    5453#include <ipc/irc.h>
     
    7069
    7170/** Obtain PCI function soft-state from DDF function node */
    72 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data)
     71static pci_fun_t *pci_fun(ddf_fun_t *fnode)
     72{
     73        return ddf_fun_data_get(fnode);
     74}
    7375
    7476/** Obtain PCI bus soft-state from DDF device node */
    75 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data)
     77#if 0
     78static pci_bus_t *pci_bus(ddf_dev_t *dnode)
     79{
     80        return ddf_dev_data_get(dnode);
     81}
     82#endif
    7683
    7784/** Obtain PCI bus soft-state from function soft-state */
    78 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr)
     85static pci_bus_t *pci_bus_from_fun(pci_fun_t *fun)
     86{
     87        return fun->busptr;
     88}
    7989
    8090/** Max is 47, align to something nice. */
     
    8393static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode)
    8494{
    85         pci_fun_t *fun = PCI_FUN(fnode);
     95        pci_fun_t *fun = pci_fun(fnode);
    8696       
    8797        if (fun == NULL)
     
    94104        /* This is an old ugly way */
    95105        assert(fnode);
    96         pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
     106        pci_fun_t *dev_data = pci_fun(fnode);
    97107       
    98108        sysarg_t apic;
     
    137147        if (address > 252)
    138148                return EINVAL;
    139         pci_conf_write_32(PCI_FUN(fun), address, data);
     149        pci_conf_write_32(pci_fun(fun), address, data);
    140150        return EOK;
    141151}
     
    146156        if (address > 254)
    147157                return EINVAL;
    148         pci_conf_write_16(PCI_FUN(fun), address, data);
     158        pci_conf_write_16(pci_fun(fun), address, data);
    149159        return EOK;
    150160}
     
    155165        if (address > 255)
    156166                return EINVAL;
    157         pci_conf_write_8(PCI_FUN(fun), address, data);
     167        pci_conf_write_8(pci_fun(fun), address, data);
    158168        return EOK;
    159169}
     
    164174        if (address > 252)
    165175                return EINVAL;
    166         *data = pci_conf_read_32(PCI_FUN(fun), address);
     176        *data = pci_conf_read_32(pci_fun(fun), address);
    167177        return EOK;
    168178}
     
    173183        if (address > 254)
    174184                return EINVAL;
    175         *data = pci_conf_read_16(PCI_FUN(fun), address);
     185        *data = pci_conf_read_16(pci_fun(fun), address);
    176186        return EOK;
    177187}
     
    182192        if (address > 255)
    183193                return EINVAL;
    184         *data = pci_conf_read_8(PCI_FUN(fun), address);
     194        *data = pci_conf_read_8(pci_fun(fun), address);
    185195        return EOK;
    186196}
     
    224234static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    225235{
    226         pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     236        pci_bus_t *bus = pci_bus_from_fun(fun);
    227237       
    228238        fibril_mutex_lock(&bus->conf_mutex);
     
    231241        void *addr = bus->conf_data_port + (reg & 3);
    232242       
    233         pio_write_32(bus->conf_addr_port, conf_addr);
     243        pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
    234244       
    235245        switch (len) {
    236246        case 1:
     247                /* No endianness change for 1 byte */
    237248                buf[0] = pio_read_8(addr);
    238249                break;
    239250        case 2:
    240                 ((uint16_t *) buf)[0] = pio_read_16(addr);
     251                ((uint16_t *) buf)[0] = uint16_t_le2host(pio_read_16(addr));
    241252                break;
    242253        case 4:
    243                 ((uint32_t *) buf)[0] = pio_read_32(addr);
     254                ((uint32_t *) buf)[0] = uint32_t_le2host(pio_read_32(addr));
    244255                break;
    245256        }
     
    250261static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    251262{
    252         pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     263        pci_bus_t *bus = pci_bus_from_fun(fun);
    253264       
    254265        fibril_mutex_lock(&bus->conf_mutex);
    255266       
    256         uint32_t conf_addr;
    257         conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     267        const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
    258268        void *addr = bus->conf_data_port + (reg & 3);
    259269       
    260         pio_write_32(bus->conf_addr_port, conf_addr);
     270        pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
    261271       
    262272        switch (len) {
    263273        case 1:
     274                /* No endianness change for 1 byte */
    264275                pio_write_8(addr, buf[0]);
    265276                break;
    266277        case 2:
    267                 pio_write_16(addr, ((uint16_t *) buf)[0]);
     278                pio_write_16(addr, host2uint16_t_le(((uint16_t *) buf)[0]));
    268279                break;
    269280        case 4:
    270                 pio_write_32(addr, ((uint32_t *) buf)[0]);
     281                pio_write_32(addr, host2uint32_t_le(((uint32_t *) buf)[0]));
    271282                break;
    272283        }
     
    478489        if (range_addr != 0) {
    479490                ddf_msg(LVL_DEBUG, "Function %s : address = %" PRIx64
    480                     ", size = %x", fun->fnode->name, range_addr,
     491                    ", size = %x", ddf_fun_get_name(fun->fnode), range_addr,
    481492                    (unsigned int) range_size);
    482493        }
     
    504515        hw_res_list->count++;
    505516       
    506         ddf_msg(LVL_NOTE, "Function %s uses irq %x.", fun->fnode->name, irq);
     517        ddf_msg(LVL_NOTE, "Function %s uses irq %x.", ddf_fun_get_name(fun->fnode), irq);
    507518}
    508519
     
    521532void pci_bus_scan(pci_bus_t *bus, int bus_num)
    522533{
    523         ddf_fun_t *fnode;
    524534        pci_fun_t *fun;
     535        int rc;
    525536       
    526537        int child_bus = 0;
     
    529540        uint8_t header_type;
    530541       
    531         fun = pci_fun_new(bus);
    532        
    533542        for (dnum = 0; dnum < 32; dnum++) {
    534543                multi = true;
    535544                for (fnum = 0; multi && fnum < 8; fnum++) {
     545                        fun = pci_fun_new(bus);
     546                       
    536547                        pci_fun_init(fun, bus_num, dnum, fnum);
    537548                        if (fun->vendor_id == 0xffff) {
     549                                pci_fun_delete(fun);
    538550                                /*
    539551                                 * The device is not present, go on scanning the
     
    557569                        if (fun_name == NULL) {
    558570                                ddf_msg(LVL_ERROR, "Out of memory.");
     571                                pci_fun_delete(fun);
    559572                                return;
    560573                        }
    561574                       
    562                         fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
     575                        rc = ddf_fun_set_name(fun->fnode, fun_name);
    563576                        free(fun_name);
    564                         if (fnode == NULL) {
    565                                 ddf_msg(LVL_ERROR, "Failed creating function.");
     577                        if (rc != EOK) {
     578                                ddf_msg(LVL_ERROR, "Failed setting function name.");
     579                                pci_fun_delete(fun);
    566580                                return;
    567581                        }
    568                        
    569                         fun->fnode = fnode;
    570582                       
    571583                        pci_alloc_resource_list(fun);
     
    573585                        pci_read_interrupt(fun);
    574586                       
    575                         fnode->ops = &pci_fun_ops;
    576                         fnode->driver_data = fun;
     587                        ddf_fun_set_ops(fun->fnode, &pci_fun_ops);
    577588                       
    578589                        ddf_msg(LVL_DEBUG, "Adding new function %s.",
    579                             fnode->name);
     590                            ddf_fun_get_name(fun->fnode));
    580591                       
    581592                        pci_fun_create_match_ids(fun);
    582593                       
    583                         if (ddf_fun_bind(fnode) != EOK) {
     594                        if (ddf_fun_bind(fun->fnode) != EOK) {
    584595                                pci_clean_resource_list(fun);
    585                                 clean_match_ids(&fnode->match_ids);
    586                                 free((char *) fnode->name);
    587                                 fnode->name = NULL;
     596                                pci_fun_delete(fun);
    588597                                continue;
    589598                        }
     
    599608                                        pci_bus_scan(bus, child_bus);
    600609                        }
    601                        
    602                         fun = pci_fun_new(bus);
    603610                }
    604         }
    605        
    606         if (fun->vendor_id == 0xffff) {
    607                 /* Free the auxiliary function structure. */
    608                 pci_fun_delete(fun);
    609611        }
    610612}
     
    615617        ddf_fun_t *ctl = NULL;
    616618        bool got_res = false;
     619        async_sess_t *sess;
    617620        int rc;
    618621       
    619622        ddf_msg(LVL_DEBUG, "pci_dev_add");
    620         dnode->parent_sess = NULL;
    621623       
    622624        bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t));
     
    629631
    630632        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) {
     633       
     634        sess = ddf_dev_parent_sess_create(dnode, EXCHANGE_SERIALIZE);
     635        if (sess == NULL) {
    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(dnode->parent_sess, &hw_resources);
     644        rc = hw_res_get_resource_list(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       
    652660        ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".",
    653661            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);
     662        ddf_msg(LVL_DEBUG, "data_addr = %" PRIx64 ".",
     663            hw_resources.resources[1].res.io_range.address);
    658664       
    659665        bus->conf_io_addr =
    660666            (uint32_t) hw_resources.resources[0].res.io_range.address;
    661        
    662         if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8,
     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,
    663671            &bus->conf_addr_port)) {
    664672                ddf_msg(LVL_ERROR, "Failed to enable configuration ports.");
     
    666674                goto fail;
    667675        }
    668         bus->conf_data_port = (char *) bus->conf_addr_port + 4;
     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        }
    669682       
    670683        /* Make the bus device more visible. It has no use yet. */
     
    693706       
    694707fail:
    695         if (dnode->parent_sess)
    696                 async_hangup(dnode->parent_sess);
    697        
    698708        if (got_res)
    699709                hw_res_clean_resource_list(&hw_resources);
     
    719729static void pciintel_init(void)
    720730{
    721         ddf_log_init(NAME, LVL_ERROR);
     731        ddf_log_init(NAME);
    722732        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
    723733        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
     
    727737{
    728738        pci_fun_t *fun;
    729        
    730         fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t));
     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));
    731746        if (fun == NULL)
    732747                return NULL;
    733748
    734749        fun->busptr = bus;
     750        fun->fnode = fnode;
    735751        return fun;
    736752}
     
    751767void pci_fun_delete(pci_fun_t *fun)
    752768{
    753         assert(fun != NULL);
    754769        hw_res_clean_resource_list(&fun->hw_resources);
    755         free(fun);
     770        if (fun->fnode != NULL)
     771                ddf_fun_destroy(fun->fnode);
    756772}
    757773
Note: See TracChangeset for help on using the changeset viewer.