Ignore:
File:
1 edited

Legend:

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

    raf6b5157 r91579d5  
    5151#include <ipc/devman.h>
    5252#include <ipc/dev_iface.h>
     53#include <ipc/irc.h>
     54#include <ipc/ns.h>
     55#include <ipc/services.h>
     56#include <sysinfo.h>
    5357#include <ops/hw_res.h>
    5458#include <device/hw_res.h>
    5559#include <ddi.h>
    5660#include <libarch/ddi.h>
     61#include <pci_dev_iface.h>
    5762
    5863#include "pci.h"
     
    8388static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
    8489{
    85         /* TODO */
    86        
    87         return false;
     90        /* This is an old ugly way, copied from ne2000 driver */
     91        assert(fnode);
     92        pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
     93
     94        sysarg_t apic;
     95        sysarg_t i8259;
     96
     97        int irc_phone = -1;
     98        int irc_service = -1;
     99
     100        if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
     101                irc_service = SERVICE_APIC;
     102        } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
     103                irc_service = SERVICE_I8259;
     104        }
     105
     106        if (irc_service == -1) {
     107                return false;
     108        }
     109
     110        irc_phone = service_connect_blocking(irc_service, 0, 0);
     111        if (irc_phone < 0) {
     112                return false;
     113        }
     114
     115        size_t i;
     116        for (i = 0; i < dev_data->hw_resources.count; i++) {
     117                if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
     118                        int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
     119                        int rc = async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     120                        if (rc != EOK) {
     121                                async_hangup(irc_phone);
     122                                return false;
     123                        }
     124                }
     125        }
     126
     127        async_hangup(irc_phone);
     128        return true;
     129}
     130
     131static int pci_config_space_write_32(
     132    ddf_fun_t *fun, uint32_t address, 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;
    88183}
    89184
     
    93188};
    94189
    95 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};
    96203
    97204static int pci_add_device(ddf_dev_t *);
     
    287394        /* Get the value of the BAR. */
    288395        val = pci_conf_read_32(fun, addr);
     396
     397#define IO_MASK  (~0x3)
     398#define MEM_MASK (~0xf)
    289399       
    290400        io = (bool) (val & 1);
    291401        if (io) {
    292402                addrw64 = false;
     403                mask = IO_MASK;
    293404        } else {
     405                mask = MEM_MASK;
    294406                switch ((val >> 1) & 3) {
    295407                case 0:
     
    307419        /* Get the address mask. */
    308420        pci_conf_write_32(fun, addr, 0xffffffff);
    309         mask = pci_conf_read_32(fun, addr);
     421        mask &= pci_conf_read_32(fun, addr);
    310422       
    311423        /* Restore the original value. */
     
    555667{
    556668        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     669        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
    557670}
    558671
     
    626739size_t pci_bar_mask_to_size(uint32_t mask)
    627740{
    628         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     741        size_t size = mask & ~(mask - 1);
     742        return size;
    629743}
    630744
Note: See TracChangeset for help on using the changeset viewer.