Ignore:
File:
1 edited

Legend:

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

    rebcb05a r5857be2  
    5252#include <ipc/devman.h>
    5353#include <ipc/dev_iface.h>
     54#include <ipc/irc.h>
     55#include <ipc/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        int irc_phone = ENOTSUP;
     99
     100        if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
     101            || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
     102                irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
     103        }
     104
     105        if (irc_phone < 0) {
     106                return false;
     107        }
     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                        const int rc =
     115                            async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     116                        if (rc != EOK) {
     117                                async_hangup(irc_phone);
     118                                return false;
     119                        }
     120                }
     121        }
     122
     123        async_hangup(irc_phone);
     124        return true;
     125}
     126
     127static int pci_config_space_write_32(
     128    ddf_fun_t *fun, uint32_t address, uint32_t data)
     129{
     130        if (address > 252)
     131                return EINVAL;
     132        pci_conf_write_32(PCI_FUN(fun), address, data);
     133        return EOK;
     134}
     135
     136static int pci_config_space_write_16(
     137    ddf_fun_t *fun, uint32_t address, uint16_t data)
     138{
     139        if (address > 254)
     140                return EINVAL;
     141        pci_conf_write_16(PCI_FUN(fun), address, data);
     142        return EOK;
     143}
     144
     145static int pci_config_space_write_8(
     146    ddf_fun_t *fun, uint32_t address, uint8_t data)
     147{
     148        if (address > 255)
     149                return EINVAL;
     150        pci_conf_write_8(PCI_FUN(fun), address, data);
     151        return EOK;
     152}
     153
     154static int pci_config_space_read_32(
     155    ddf_fun_t *fun, uint32_t address, uint32_t *data)
     156{
     157        if (address > 252)
     158                return EINVAL;
     159        *data = pci_conf_read_32(PCI_FUN(fun), address);
     160        return EOK;
     161}
     162
     163static int pci_config_space_read_16(
     164    ddf_fun_t *fun, uint32_t address, uint16_t *data)
     165{
     166        if (address > 254)
     167                return EINVAL;
     168        *data = pci_conf_read_16(PCI_FUN(fun), address);
     169        return EOK;
     170}
     171
     172static int pci_config_space_read_8(
     173    ddf_fun_t *fun, uint32_t address, uint8_t *data)
     174{
     175        if (address > 255)
     176                return EINVAL;
     177        *data = pci_conf_read_8(PCI_FUN(fun), address);
     178        return EOK;
    89179}
    90180
     
    94184};
    95185
    96 static ddf_dev_ops_t pci_fun_ops;
     186static pci_dev_iface_t pci_dev_ops = {
     187        .config_space_read_8 = &pci_config_space_read_8,
     188        .config_space_read_16 = &pci_config_space_read_16,
     189        .config_space_read_32 = &pci_config_space_read_32,
     190        .config_space_write_8 = &pci_config_space_write_8,
     191        .config_space_write_16 = &pci_config_space_write_16,
     192        .config_space_write_32 = &pci_config_space_write_32
     193};
     194
     195static ddf_dev_ops_t pci_fun_ops = {
     196        .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops,
     197        .interfaces[PCI_DEV_IFACE] = &pci_dev_ops
     198};
    97199
    98200static int pci_add_device(ddf_dev_t *);
     
    288390        /* Get the value of the BAR. */
    289391        val = pci_conf_read_32(fun, addr);
     392
     393#define IO_MASK  (~0x3)
     394#define MEM_MASK (~0xf)
    290395       
    291396        io = (bool) (val & 1);
    292397        if (io) {
    293398                addrw64 = false;
     399                mask = IO_MASK;
    294400        } else {
     401                mask = MEM_MASK;
    295402                switch ((val >> 1) & 3) {
    296403                case 0:
     
    308415        /* Get the address mask. */
    309416        pci_conf_write_32(fun, addr, 0xffffffff);
    310         mask = pci_conf_read_32(fun, addr);
     417        mask &= pci_conf_read_32(fun, addr);
    311418       
    312419        /* Restore the original value. */
     
    558665        ddf_log_init(NAME, LVL_ERROR);
    559666        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     667        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
    560668}
    561669
     
    629737size_t pci_bar_mask_to_size(uint32_t mask)
    630738{
    631         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     739        size_t size = mask & ~(mask - 1);
     740        return size;
    632741}
    633742
Note: See TracChangeset for help on using the changeset viewer.