Ignore:
File:
1 edited

Legend:

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

    rebcb05a r79ae36dd  
    5252#include <ipc/devman.h>
    5353#include <ipc/dev_iface.h>
     54#include <ipc/irc.h>
     55#include <ns.h>
     56#include <ipc/services.h>
     57#include <sysinfo.h>
    5458#include <ops/hw_res.h>
    5559#include <device/hw_res.h>
    5660#include <ddi.h>
    5761#include <libarch/ddi.h>
     62#include <pci_dev_iface.h>
    5863
    5964#include "pci.h"
     
    8489static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
    8590{
    86         /* TODO */
    87        
    88         return false;
     91        /* This is an old ugly way, copied from ne2000 driver */
     92        assert(fnode);
     93        pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
     94       
     95        sysarg_t apic;
     96        sysarg_t i8259;
     97       
     98        async_sess_t *irc_sess = NULL;
     99       
     100        if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
     101            || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
     102                irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
     103                    SERVICE_IRC, 0, 0);
     104        }
     105       
     106        if (!irc_sess)
     107                return false;
     108       
     109        size_t i = 0;
     110        hw_resource_list_t *res = &dev_data->hw_resources;
     111        for (; i < res->count; i++) {
     112                if (res->resources[i].type == INTERRUPT) {
     113                        const int irq = res->resources[i].res.interrupt.irq;
     114                       
     115                        async_exch_t *exch = async_exchange_begin(irc_sess);
     116                        const int rc =
     117                            async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq);
     118                        async_exchange_end(exch);
     119                       
     120                        if (rc != EOK) {
     121                                async_hangup(irc_sess);
     122                                return false;
     123                        }
     124                }
     125        }
     126       
     127        async_hangup(irc_sess);
     128        return true;
     129}
     130
     131static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address,
     132    uint32_t data)
     133{
     134        if (address > 252)
     135                return EINVAL;
     136        pci_conf_write_32(PCI_FUN(fun), address, data);
     137        return EOK;
     138}
     139
     140static int pci_config_space_write_16(
     141    ddf_fun_t *fun, uint32_t address, uint16_t data)
     142{
     143        if (address > 254)
     144                return EINVAL;
     145        pci_conf_write_16(PCI_FUN(fun), address, data);
     146        return EOK;
     147}
     148
     149static int pci_config_space_write_8(
     150    ddf_fun_t *fun, uint32_t address, uint8_t data)
     151{
     152        if (address > 255)
     153                return EINVAL;
     154        pci_conf_write_8(PCI_FUN(fun), address, data);
     155        return EOK;
     156}
     157
     158static int pci_config_space_read_32(
     159    ddf_fun_t *fun, uint32_t address, uint32_t *data)
     160{
     161        if (address > 252)
     162                return EINVAL;
     163        *data = pci_conf_read_32(PCI_FUN(fun), address);
     164        return EOK;
     165}
     166
     167static int pci_config_space_read_16(
     168    ddf_fun_t *fun, uint32_t address, uint16_t *data)
     169{
     170        if (address > 254)
     171                return EINVAL;
     172        *data = pci_conf_read_16(PCI_FUN(fun), address);
     173        return EOK;
     174}
     175
     176static int pci_config_space_read_8(
     177    ddf_fun_t *fun, uint32_t address, uint8_t *data)
     178{
     179        if (address > 255)
     180                return EINVAL;
     181        *data = pci_conf_read_8(PCI_FUN(fun), address);
     182        return EOK;
    89183}
    90184
     
    94188};
    95189
    96 static ddf_dev_ops_t pci_fun_ops;
     190static pci_dev_iface_t pci_dev_ops = {
     191        .config_space_read_8 = &pci_config_space_read_8,
     192        .config_space_read_16 = &pci_config_space_read_16,
     193        .config_space_read_32 = &pci_config_space_read_32,
     194        .config_space_write_8 = &pci_config_space_write_8,
     195        .config_space_write_16 = &pci_config_space_write_16,
     196        .config_space_write_32 = &pci_config_space_write_32
     197};
     198
     199static ddf_dev_ops_t pci_fun_ops = {
     200        .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops,
     201        .interfaces[PCI_DEV_IFACE] = &pci_dev_ops
     202};
    97203
    98204static int pci_add_device(ddf_dev_t *);
     
    288394        /* Get the value of the BAR. */
    289395        val = pci_conf_read_32(fun, addr);
     396
     397#define IO_MASK  (~0x3)
     398#define MEM_MASK (~0xf)
    290399       
    291400        io = (bool) (val & 1);
    292401        if (io) {
    293402                addrw64 = false;
     403                mask = IO_MASK;
    294404        } else {
     405                mask = MEM_MASK;
    295406                switch ((val >> 1) & 3) {
    296407                case 0:
     
    308419        /* Get the address mask. */
    309420        pci_conf_write_32(fun, addr, 0xffffffff);
    310         mask = pci_conf_read_32(fun, addr);
     421        mask &= pci_conf_read_32(fun, addr);
    311422       
    312423        /* Restore the original value. */
     
    469580       
    470581        ddf_msg(LVL_DEBUG, "pci_add_device");
    471         dnode->parent_phone = -1;
     582        dnode->parent_sess = NULL;
    472583       
    473584        bus = pci_bus_new();
     
    480591        dnode->driver_data = bus;
    481592       
    482         dnode->parent_phone = devman_parent_device_connect(dnode->handle,
    483             IPC_FLAG_BLOCKING);
    484         if (dnode->parent_phone < 0) {
     593        dnode->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
     594            dnode->handle, IPC_FLAG_BLOCKING);
     595        if (!dnode->parent_sess) {
    485596                ddf_msg(LVL_ERROR, "pci_add_device failed to connect to the "
    486                     "parent's driver.");
    487                 rc = dnode->parent_phone;
     597                    "parent driver.");
     598                rc = ENOENT;
    488599                goto fail;
    489600        }
     
    491602        hw_resource_list_t hw_resources;
    492603       
    493         rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
     604        rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources);
    494605        if (rc != EOK) {
    495606                ddf_msg(LVL_ERROR, "pci_add_device failed to get hw resources "
     
    544655        if (bus != NULL)
    545656                pci_bus_delete(bus);
    546         if (dnode->parent_phone >= 0)
    547                 async_hangup(dnode->parent_phone);
     657       
     658        if (dnode->parent_sess)
     659                async_hangup(dnode->parent_sess);
     660       
    548661        if (got_res)
    549662                hw_res_clean_resource_list(&hw_resources);
     663       
    550664        if (ctl != NULL)
    551665                ddf_fun_destroy(ctl);
    552 
     666       
    553667        return rc;
    554668}
     
    558672        ddf_log_init(NAME, LVL_ERROR);
    559673        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     674        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
    560675}
    561676
     
    629744size_t pci_bar_mask_to_size(uint32_t mask)
    630745{
    631         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     746        size_t size = mask & ~(mask - 1);
     747        return size;
    632748}
    633749
Note: See TracChangeset for help on using the changeset viewer.