Index: uspace/drv/pciintel/pci.c
===================================================================
--- uspace/drv/pciintel/pci.c	(revision ebcb05a569ef3a706553a41bd6a44277cc63277f)
+++ uspace/drv/pciintel/pci.c	(revision f9c03b5741ded16234379e99ce809ea66a8b9f6c)
@@ -52,8 +52,13 @@
 #include <ipc/devman.h>
 #include <ipc/dev_iface.h>
+#include <ipc/irc.h>
+#include <ipc/ns.h>
+#include <ipc/services.h>
+#include <sysinfo.h>
 #include <ops/hw_res.h>
 #include <device/hw_res.h>
 #include <ddi.h>
 #include <libarch/ddi.h>
+#include <pci_dev_iface.h>
 
 #include "pci.h"
@@ -84,7 +89,90 @@
 static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
 {
-	/* TODO */
-	
-	return false;
+	/* This is an old ugly way, copied from ne2000 driver */
+	assert(fnode);
+	pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
+
+	sysarg_t apic;
+	sysarg_t i8259;
+
+	int irc_phone = ENOTSUP;
+
+	if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
+	    || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
+		irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
+	}
+
+	if (irc_phone < 0) {
+		return false;
+	}
+
+	size_t i;
+	for (i = 0; i < dev_data->hw_resources.count; i++) {
+		if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
+			int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
+			int rc = async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
+			if (rc != EOK) {
+				async_hangup(irc_phone);
+				return false;
+			}
+		}
+	}
+
+	async_hangup(irc_phone);
+	return true;
+}
+
+static int pci_config_space_write_32(
+    ddf_fun_t *fun, uint32_t address, uint32_t data)
+{
+	if (address > 252)
+		return EINVAL;
+	pci_conf_write_32(PCI_FUN(fun), address, data);
+	return EOK;
+}
+
+static int pci_config_space_write_16(
+    ddf_fun_t *fun, uint32_t address, uint16_t data)
+{
+	if (address > 254)
+		return EINVAL;
+	pci_conf_write_16(PCI_FUN(fun), address, data);
+	return EOK;
+}
+
+static int pci_config_space_write_8(
+    ddf_fun_t *fun, uint32_t address, uint8_t data)
+{
+	if (address > 255)
+		return EINVAL;
+	pci_conf_write_8(PCI_FUN(fun), address, data);
+	return EOK;
+}
+
+static int pci_config_space_read_32(
+    ddf_fun_t *fun, uint32_t address, uint32_t *data)
+{
+	if (address > 252)
+		return EINVAL;
+	*data = pci_conf_read_32(PCI_FUN(fun), address);
+	return EOK;
+}
+
+static int pci_config_space_read_16(
+    ddf_fun_t *fun, uint32_t address, uint16_t *data)
+{
+	if (address > 254)
+		return EINVAL;
+	*data = pci_conf_read_16(PCI_FUN(fun), address);
+	return EOK;
+}
+
+static int pci_config_space_read_8(
+    ddf_fun_t *fun, uint32_t address, uint8_t *data)
+{
+	if (address > 255)
+		return EINVAL;
+	*data = pci_conf_read_8(PCI_FUN(fun), address);
+	return EOK;
 }
 
@@ -94,5 +182,17 @@
 };
 
-static ddf_dev_ops_t pci_fun_ops;
+static pci_dev_iface_t pci_dev_ops = {
+	.config_space_read_8 = &pci_config_space_read_8,
+	.config_space_read_16 = &pci_config_space_read_16,
+	.config_space_read_32 = &pci_config_space_read_32,
+	.config_space_write_8 = &pci_config_space_write_8,
+	.config_space_write_16 = &pci_config_space_write_16,
+	.config_space_write_32 = &pci_config_space_write_32
+};
+
+static ddf_dev_ops_t pci_fun_ops = {
+	.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops,
+	.interfaces[PCI_DEV_IFACE] = &pci_dev_ops
+};
 
 static int pci_add_device(ddf_dev_t *);
@@ -288,9 +388,14 @@
 	/* Get the value of the BAR. */
 	val = pci_conf_read_32(fun, addr);
+
+#define IO_MASK  (~0x3)
+#define MEM_MASK (~0xf)
 	
 	io = (bool) (val & 1);
 	if (io) {
 		addrw64 = false;
+		mask = IO_MASK;
 	} else {
+		mask = MEM_MASK;
 		switch ((val >> 1) & 3) {
 		case 0:
@@ -308,5 +413,5 @@
 	/* Get the address mask. */
 	pci_conf_write_32(fun, addr, 0xffffffff);
-	mask = pci_conf_read_32(fun, addr);
+	mask &= pci_conf_read_32(fun, addr);
 	
 	/* Restore the original value. */
@@ -558,4 +663,5 @@
 	ddf_log_init(NAME, LVL_ERROR);
 	pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
+	pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
 }
 
@@ -629,5 +735,6 @@
 size_t pci_bar_mask_to_size(uint32_t mask)
 {
-	return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
+	size_t size = mask & ~(mask - 1);
+	return size;
 }
 
