diff --git a/headers/os/drivers/PCI_x86.h b/headers/os/drivers/PCI_x86.h index d20961fb08..d1bfb1704c 100644 --- a/headers/os/drivers/PCI_x86.h +++ b/headers/os/drivers/PCI_x86.h @@ -47,21 +47,11 @@ typedef struct pci_x86_module_info { uint8 function, /* function # in device */ uint8 count, /* count of vectors desired */ uint8 *startVector); /* first configured vector */ - status_t (*unconfigure_msix)( - uint8 bus, /* bus number */ - uint8 device, /* device # on bus */ - uint8 function); /* function # in device */ - status_t (*enable_msix)( uint8 bus, /* bus number */ uint8 device, /* device # on bus */ uint8 function); /* function # in device */ - status_t (*disable_msix)( - uint8 bus, /* bus number */ - uint8 device, /* device # on bus */ - uint8 function); /* function # in device */ - } pci_x86_module_info; #define B_PCI_X86_MODULE_NAME "bus_managers/pci/x86/v1" diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_module.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_module.cpp index 0220bf7677..b0f8952371 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_module.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_module.cpp @@ -45,7 +45,5 @@ pci_x86_module_info gPCIArchModule = { &pci_disable_msi, &pci_get_msix_count, &pci_configure_msix, - &pci_unconfigure_msix, - &pci_enable_msix, - &pci_disable_msix + &pci_enable_msix }; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp index e87e852270..c175f5d7b4 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp @@ -15,6 +15,10 @@ extern PCI *gPCI; +static status_t pci_unconfigure_msix(PCIDev *device); +static status_t pci_disable_msix(PCIDev *device); + + static void pci_ht_msi_map(PCIDev *device, uint64 address) { @@ -33,7 +37,7 @@ pci_ht_msi_map(PCIDev *device, uint64 address) info->control_value |= PCI_ht_command_msi_enable; } gPCI->WriteConfig(device, info->capability_offset + PCI_ht_command, - info->control_value, 2); + info->control_value, 2); } } @@ -166,6 +170,11 @@ pci_unconfigure_msi(uint8 virtualBus, uint8 _device, uint8 function) if (device == NULL) return B_ERROR; + // try MSI-X + result = pci_unconfigure_msix(device); + if (result != B_UNSUPPORTED && result != B_NO_INIT) + return result; + msi_info *info = &device->arch_info.msi; if (!info->msi_capable) return B_UNSUPPORTED; @@ -243,6 +252,11 @@ pci_disable_msi(uint8 virtualBus, uint8 _device, uint8 function) if (device == NULL) return B_ERROR; + // try MSI-X + result = pci_disable_msix(device); + if (result != B_UNSUPPORTED && result != B_NO_INIT) + return result; + msi_info *info = &device->arch_info.msi; if (!info->msi_capable) return B_UNSUPPORTED; @@ -345,7 +359,7 @@ pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, // map the table bar size_t tableSize = info->message_count * 16; addr_t address; - area_id area = map_physical_memory("msi table map", + area_id area = map_physical_memory("msi table map", device->info.u.h0.base_registers[info->table_bar], tableSize + info->table_offset, B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, (void**)&address); @@ -356,7 +370,7 @@ pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, // and the pba bar if necessary if (info->table_bar != info->pba_bar) { - area = map_physical_memory("msi pba map", + area = map_physical_memory("msi pba map", device->info.u.h0.base_registers[info->pba_bar], tableSize + info->pba_offset, B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, @@ -366,7 +380,7 @@ pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, info->table_area_id = -1; return area; } - info->pba_area_id = area; + info->pba_area_id = area; } else info->pba_area_id = -1; info->pba_address = address + info->pba_offset; @@ -402,22 +416,9 @@ pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, } -status_t -pci_unconfigure_msix(uint8 virtualBus, uint8 _device, uint8 function) +static status_t +pci_unconfigure_msix(PCIDev *device) { - if (!msi_supported()) - return B_UNSUPPORTED; - - uint8 bus; - uint8 domain; - status_t result = gPCI->ResolveVirtualBus(virtualBus, &domain, &bus); - if (result != B_OK) - return result; - - PCIDev *device = gPCI->FindDevice(domain, bus, _device, function); - if (device == NULL) - return B_ERROR; - msix_info *info = &device->arch_info.msix; if (!info->msix_capable) return B_UNSUPPORTED; @@ -493,21 +494,8 @@ pci_enable_msix(uint8 virtualBus, uint8 _device, uint8 function) status_t -pci_disable_msix(uint8 virtualBus, uint8 _device, uint8 function) +pci_disable_msix(PCIDev *device) { - if (!msi_supported()) - return B_UNSUPPORTED; - - uint8 bus; - uint8 domain; - status_t result = gPCI->ResolveVirtualBus(virtualBus, &domain, &bus); - if (result != B_OK) - return result; - - PCIDev *device = gPCI->FindDevice(domain, bus, _device, function); - if (device == NULL) - return B_ERROR; - msix_info *info = &device->arch_info.msix; if (!info->msix_capable) return B_UNSUPPORTED; @@ -558,10 +546,9 @@ pci_read_msix_info(PCIDev *device) uint32 pba_value = gPCI->ReadConfig(device->domain, device->bus, device->device, device->function, info->capability_offset + PCI_msix_pba, 4); - + info->table_bar = table_value & PCI_msix_bir_mask; info->table_offset = table_value & PCI_msix_offset_mask; info->pba_bar = pba_value & PCI_msix_bir_mask; info->pba_offset = pba_value & PCI_msix_offset_mask; } - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.h b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.h index 52fa47a67d..28ed8f63b4 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.h +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.h @@ -61,9 +61,7 @@ typedef struct msix_info { uint8 pci_get_msix_count(uint8 virtualBus, uint8 _device, uint8 function); status_t pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, uint8 count, uint8 *startVector); -status_t pci_unconfigure_msix(uint8 virtualBus, uint8 device, uint8 function); status_t pci_enable_msix(uint8 virtualBus, uint8 _device, uint8 function); -status_t pci_disable_msix(uint8 virtualBus, uint8 _device, uint8 function); void pci_read_msix_info(PCIDev *device); // HyperTransport MSI mapping diff --git a/src/add-ons/kernel/busses/virtio/virtio_pci.cpp b/src/add-ons/kernel/busses/virtio/virtio_pci.cpp index 2409bc0a7a..ae6da94c17 100644 --- a/src/add-ons/kernel/busses/virtio/virtio_pci.cpp +++ b/src/add-ons/kernel/busses/virtio/virtio_pci.cpp @@ -466,10 +466,7 @@ uninit_bus(void* bus_cookie) if (bus->irq_type != VIRTIO_IRQ_LEGACY) { if (bus->irq_type == VIRTIO_IRQ_MSI) { remove_io_interrupt_handler(bus->irq, virtio_pci_interrupt, bus); - sPCIx86Module->disable_msi(bus->info.bus, - bus->info.device, bus->info.function); - sPCIx86Module->unconfigure_msi(bus->info.bus, - bus->info.device, bus->info.function); + } else { int32 irq = bus->irq + 1; for (uint16 queue = 0; queue < bus->queue_count; queue++, irq++) { @@ -478,11 +475,11 @@ uninit_bus(void* bus_cookie) } remove_io_interrupt_handler(bus->irq, virtio_pci_config_interrupt, bus); - sPCIx86Module->disable_msix(bus->info.bus, - bus->info.device, bus->info.function); - sPCIx86Module->unconfigure_msix(bus->info.bus, - bus->info.device, bus->info.function); } + sPCIx86Module->disable_msi(bus->info.bus, + bus->info.device, bus->info.function); + sPCIx86Module->unconfigure_msi(bus->info.bus, + bus->info.device, bus->info.function); } else remove_io_interrupt_handler(bus->irq, virtio_pci_interrupt, bus); if (sPCIx86Module != NULL) { @@ -668,4 +665,3 @@ module_info* modules[] = { (module_info* )&gVirtioPCIDeviceModule, NULL }; -