When we fail to enable io ports via x86 method, this means we are a client/nested arbiter. But we still need to enable io ports that are not in PCI CONF1 range. --- src/hurd_pci.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-)
diff --git a/src/hurd_pci.c b/src/hurd_pci.c index 2d10c5c..e4975ea 100644 --- a/src/hurd_pci.c +++ b/src/hurd_pci.c @@ -39,6 +39,7 @@ #include <hurd/paths.h> #include <hurd/fs.h> #include <device/device.h> +#include <sys/io.h> #include "x86_pci.h" #include "pciaccess.h" @@ -58,6 +59,10 @@ #define FILE_REGION_NAME "region" #define FILE_ROM_NAME "rom" +/* IO hole for PCI conf1 */ +#define PCI_CFG1_START 0xcf8 +#define PCI_CFG1_END 0xcff + /* Level in the fs tree */ typedef enum { LEVEL_NONE, @@ -72,6 +77,34 @@ struct pci_system_hurd { mach_port_t root; }; +static int +hurd_enable_io(void) +{ + /* 0-0xcf7 */ + if (ioperm(0, PCI_CFG1_START, 1)) + return errno; + + /* 0xd00-0xffff */ + if (ioperm(PCI_CFG1_END+1, 0x10000 - (PCI_CFG1_END+1), 1)) + return errno; + + return 0; +} + +static int +hurd_disable_io(void) +{ + /* 0-0xcf7 */ + if (ioperm(0, PCI_CFG1_START, 0)) + return errno; + + /* 0xd00-0xffff */ + if (ioperm(PCI_CFG1_END+1, 0x10000 - (PCI_CFG1_END+1), 0)) + return errno; + + return 0; +} + static int pci_device_hurd_probe(struct pci_device *dev) { @@ -151,12 +184,25 @@ pci_device_hurd_probe(struct pci_device *dev) return 0; } +static struct pci_io_handle * +pci_device_hurd_open_legacy_io(struct pci_io_handle *ret, + struct pci_device *dev, pciaddr_t base, pciaddr_t size) +{ + hurd_enable_io(); + + ret->base = base; + ret->size = size; + ret->is_legacy = 1; + + return ret; +} + static void pci_system_hurd_destroy(void) { struct pci_system_hurd *pci_sys_hurd = (struct pci_system_hurd *)pci_sys; - x86_disable_io(); + hurd_disable_io(); mach_port_deallocate(mach_task_self(), pci_sys_hurd->root); } @@ -600,8 +646,8 @@ static const struct pci_system_methods hurd_pci_methods = { .read = pci_device_hurd_read, .write = pci_device_hurd_write, .fill_capabilities = pci_fill_capabilities_generic, - .open_legacy_io = pci_device_x86_open_legacy_io, - .close_io = pci_device_x86_close_io, + .open_legacy_io = pci_device_hurd_open_legacy_io, + .close_io = NULL, .read32 = pci_device_x86_read32, .read16 = pci_device_x86_read16, .read8 = pci_device_x86_read8, @@ -638,9 +684,12 @@ pci_system_hurd_create(void) * Both will connect to a master arbiter. */ + /* Our io ports failed to open before so open them without pci conf1 */ + hurd_enable_io(); + pci_sys_hurd = calloc(1, sizeof(struct pci_system_hurd)); if (pci_sys_hurd == NULL) { - x86_disable_io(); + hurd_disable_io(); return ENOMEM; } pci_sys = &pci_sys_hurd->system; -- 2.34.1