Ignore:
File:
1 edited

Legend:

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

    r2df6f6fe rc90aed4  
    3838
    3939#include <assert.h>
     40#include <byteorder.h>
    4041#include <stdio.h>
    4142#include <errno.h>
    42 #include <bool.h>
     43#include <stdbool.h>
    4344#include <fibril_synch.h>
    4445#include <str.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>
     
    5958#include <device/hw_res.h>
    6059#include <ddi.h>
    61 #include <libarch/ddi.h>
    6260#include <pci_dev_iface.h>
    6361
     
    7068
    7169/** Obtain PCI function soft-state from DDF function node */
    72 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data)
     70static pci_fun_t *pci_fun(ddf_fun_t *fnode)
     71{
     72        return ddf_fun_data_get(fnode);
     73}
    7374
    7475/** Obtain PCI bus soft-state from DDF device node */
    75 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data)
     76#if 0
     77static pci_bus_t *pci_bus(ddf_dev_t *dnode)
     78{
     79        return ddf_dev_data_get(dnode);
     80}
     81#endif
    7682
    7783/** Obtain PCI bus soft-state from function soft-state */
    78 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr)
     84static pci_bus_t *pci_bus_from_fun(pci_fun_t *fun)
     85{
     86        return fun->busptr;
     87}
    7988
    8089/** Max is 47, align to something nice. */
     
    8392static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode)
    8493{
    85         pci_fun_t *fun = PCI_FUN(fnode);
     94        pci_fun_t *fun = pci_fun(fnode);
    8695       
    8796        if (fun == NULL)
     
    94103        /* This is an old ugly way */
    95104        assert(fnode);
    96         pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
     105        pci_fun_t *dev_data = pci_fun(fnode);
    97106       
    98107        sysarg_t apic;
     
    137146        if (address > 252)
    138147                return EINVAL;
    139         pci_conf_write_32(PCI_FUN(fun), address, data);
     148        pci_conf_write_32(pci_fun(fun), address, data);
    140149        return EOK;
    141150}
     
    146155        if (address > 254)
    147156                return EINVAL;
    148         pci_conf_write_16(PCI_FUN(fun), address, data);
     157        pci_conf_write_16(pci_fun(fun), address, data);
    149158        return EOK;
    150159}
     
    155164        if (address > 255)
    156165                return EINVAL;
    157         pci_conf_write_8(PCI_FUN(fun), address, data);
     166        pci_conf_write_8(pci_fun(fun), address, data);
    158167        return EOK;
    159168}
     
    164173        if (address > 252)
    165174                return EINVAL;
    166         *data = pci_conf_read_32(PCI_FUN(fun), address);
     175        *data = pci_conf_read_32(pci_fun(fun), address);
    167176        return EOK;
    168177}
     
    173182        if (address > 254)
    174183                return EINVAL;
    175         *data = pci_conf_read_16(PCI_FUN(fun), address);
     184        *data = pci_conf_read_16(pci_fun(fun), address);
    176185        return EOK;
    177186}
     
    182191        if (address > 255)
    183192                return EINVAL;
    184         *data = pci_conf_read_8(PCI_FUN(fun), address);
     193        *data = pci_conf_read_8(pci_fun(fun), address);
    185194        return EOK;
    186195}
     
    224233static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    225234{
    226         pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     235        pci_bus_t *bus = pci_bus_from_fun(fun);
    227236       
    228237        fibril_mutex_lock(&bus->conf_mutex);
     
    231240        void *addr = bus->conf_data_port + (reg & 3);
    232241       
    233         pio_write_32(bus->conf_addr_port, conf_addr);
     242        pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
    234243       
    235244        switch (len) {
    236245        case 1:
     246                /* No endianness change for 1 byte */
    237247                buf[0] = pio_read_8(addr);
    238248                break;
    239249        case 2:
    240                 ((uint16_t *) buf)[0] = pio_read_16(addr);
     250                ((uint16_t *) buf)[0] = uint16_t_le2host(pio_read_16(addr));
    241251                break;
    242252        case 4:
    243                 ((uint32_t *) buf)[0] = pio_read_32(addr);
     253                ((uint32_t *) buf)[0] = uint32_t_le2host(pio_read_32(addr));
    244254                break;
    245255        }
     
    250260static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    251261{
    252         pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     262        pci_bus_t *bus = pci_bus_from_fun(fun);
    253263       
    254264        fibril_mutex_lock(&bus->conf_mutex);
    255265       
    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);
    258267        void *addr = bus->conf_data_port + (reg & 3);
    259268       
    260         pio_write_32(bus->conf_addr_port, conf_addr);
     269        pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
    261270       
    262271        switch (len) {
    263272        case 1:
     273                /* No endianness change for 1 byte */
    264274                pio_write_8(addr, buf[0]);
    265275                break;
    266276        case 2:
    267                 pio_write_16(addr, ((uint16_t *) buf)[0]);
     277                pio_write_16(addr, host2uint16_t_le(((uint16_t *) buf)[0]));
    268278                break;
    269279        case 4:
    270                 pio_write_32(addr, ((uint32_t *) buf)[0]);
     280                pio_write_32(addr, host2uint32_t_le(((uint32_t *) buf)[0]));
    271281                break;
    272282        }
     
    317327
    318328        /* Vendor ID & Device ID, length(incl \0) 22 */
    319         rc = snprintf(match_id_str, ID_MAX_STR_LEN, "pci/ven=%04x&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);
    321331        if (rc < 0) {
    322332                ddf_msg(LVL_ERROR, "Failed creating match ID str: %s",
     
    478488        if (range_addr != 0) {
    479489                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,
    481491                    (unsigned int) range_size);
    482492        }
     
    504514        hw_res_list->count++;
    505515       
    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);
    507517}
    508518
     
    521531void pci_bus_scan(pci_bus_t *bus, int bus_num)
    522532{
    523         ddf_fun_t *fnode;
    524533        pci_fun_t *fun;
     534        int rc;
    525535       
    526536        int child_bus = 0;
     
    529539        uint8_t header_type;
    530540       
    531         fun = pci_fun_new(bus);
    532        
    533541        for (dnum = 0; dnum < 32; dnum++) {
    534542                multi = true;
    535543                for (fnum = 0; multi && fnum < 8; fnum++) {
     544                        fun = pci_fun_new(bus);
     545                       
    536546                        pci_fun_init(fun, bus_num, dnum, fnum);
    537547                        if (fun->vendor_id == 0xffff) {
     548                                pci_fun_delete(fun);
    538549                                /*
    539550                                 * The device is not present, go on scanning the
     
    557568                        if (fun_name == NULL) {
    558569                                ddf_msg(LVL_ERROR, "Out of memory.");
     570                                pci_fun_delete(fun);
    559571                                return;
    560572                        }
    561573                       
    562                         fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
     574                        rc = ddf_fun_set_name(fun->fnode, fun_name);
    563575                        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);
    566579                                return;
    567580                        }
    568                        
    569                         fun->fnode = fnode;
    570581                       
    571582                        pci_alloc_resource_list(fun);
     
    573584                        pci_read_interrupt(fun);
    574585                       
    575                         fnode->ops = &pci_fun_ops;
    576                         fnode->driver_data = fun;
     586                        ddf_fun_set_ops(fun->fnode, &pci_fun_ops);
    577587                       
    578588                        ddf_msg(LVL_DEBUG, "Adding new function %s.",
    579                             fnode->name);
     589                            ddf_fun_get_name(fun->fnode));
    580590                       
    581591                        pci_fun_create_match_ids(fun);
    582592                       
    583                         if (ddf_fun_bind(fnode) != EOK) {
     593                        if (ddf_fun_bind(fun->fnode) != EOK) {
    584594                                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);
    588596                                continue;
    589597                        }
     
    599607                                        pci_bus_scan(bus, child_bus);
    600608                        }
    601                        
    602                         fun = pci_fun_new(bus);
    603609                }
    604         }
    605        
    606         if (fun->vendor_id == 0xffff) {
    607                 /* Free the auxiliary function structure. */
    608                 pci_fun_delete(fun);
    609610        }
    610611}
     
    615616        ddf_fun_t *ctl = NULL;
    616617        bool got_res = false;
     618        async_sess_t *sess;
    617619        int rc;
    618620       
    619621        ddf_msg(LVL_DEBUG, "pci_dev_add");
    620         dnode->parent_sess = NULL;
    621622       
    622623        bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t));
     
    629630
    630631        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) {
    636635                ddf_msg(LVL_ERROR, "pci_dev_add failed to connect to the "
    637636                    "parent driver.");
     
    642641        hw_resource_list_t hw_resources;
    643642       
    644         rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources);
     643        rc = hw_res_get_resource_list(sess, &hw_resources);
    645644        if (rc != EOK) {
    646645                ddf_msg(LVL_ERROR, "pci_dev_add failed to get hw resources "
     
    650649        got_res = true;
    651650       
     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       
    652659        ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".",
    653660            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);
    658663       
    659664        bus->conf_io_addr =
    660665            (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,
    663670            &bus->conf_addr_port)) {
    664671                ddf_msg(LVL_ERROR, "Failed to enable configuration ports.");
     
    666673                goto fail;
    667674        }
    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        }
    669681       
    670682        /* Make the bus device more visible. It has no use yet. */
     
    693705       
    694706fail:
    695         if (dnode->parent_sess)
    696                 async_hangup(dnode->parent_sess);
    697        
    698707        if (got_res)
    699708                hw_res_clean_resource_list(&hw_resources);
     
    719728static void pciintel_init(void)
    720729{
    721         ddf_log_init(NAME, LVL_ERROR);
     730        ddf_log_init(NAME);
    722731        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
    723732        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
     
    727736{
    728737        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));
    731745        if (fun == NULL)
    732746                return NULL;
    733747
    734748        fun->busptr = bus;
     749        fun->fnode = fnode;
    735750        return fun;
    736751}
     
    743758        fun->vendor_id = pci_conf_read_16(fun, PCI_VENDOR_ID);
    744759        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       
    745766        fun->class_code = pci_conf_read_8(fun, PCI_BASE_CLASS);
    746767        fun->subclass_code = pci_conf_read_8(fun, PCI_SUB_CLASS);
     
    751772void pci_fun_delete(pci_fun_t *fun)
    752773{
    753         assert(fun != NULL);
    754774        hw_res_clean_resource_list(&fun->hw_resources);
    755         free(fun);
     775        if (fun->fnode != NULL)
     776                ddf_fun_destroy(fun->fnode);
    756777}
    757778
Note: See TracChangeset for help on using the changeset viewer.