mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Fix drivers not detecting PCI devices without an interrupt line.
This commit is contained in:
parent
da89dec2e2
commit
2b6463aa95
6 changed files with 44 additions and 13 deletions
|
@ -126,6 +126,13 @@ void HBA__OnInterrupt(struct interrupt_context*, void* context)
|
|||
|
||||
bool HBA::Initialize(Ref<Descriptor> dev, const char* devpath)
|
||||
{
|
||||
interrupt_index = PCI::SetupInterruptLine(devaddr);
|
||||
if ( !interrupt_index )
|
||||
{
|
||||
LogF("error: cannot determine interrupt line");
|
||||
return errno = EINVAL, false;
|
||||
}
|
||||
|
||||
pcibar_t mmio_bar = PCI::GetBAR(devaddr, 5);
|
||||
if ( mmio_bar.size() < sizeof(struct hba_regs) && /* or || ? */
|
||||
mmio_bar.size() < 1024 )
|
||||
|
@ -228,8 +235,6 @@ bool HBA::Initialize(Ref<Descriptor> dev, const char* devpath)
|
|||
}
|
||||
}
|
||||
|
||||
interrupt_index =
|
||||
Interrupt::IRQ0 + PCI::Read8(devaddr, PCIFIELD_INTERRUPT_LINE);
|
||||
interrupt_registration.handler = HBA__OnInterrupt;
|
||||
interrupt_registration.context = this;
|
||||
Interrupt::RegisterHandler(interrupt_index, &interrupt_registration);
|
||||
|
|
|
@ -56,7 +56,7 @@ private:
|
|||
addralloc_t mmio_alloc;
|
||||
volatile struct hba_regs* regs;
|
||||
uint32_t devaddr;
|
||||
unsigned int interrupt_index;
|
||||
uint8_t interrupt_index;
|
||||
bool interrupt_registered;
|
||||
bool mmio_alloced;
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ void FixDefaultDeviceBars(pcibar_t* basebar, pcibar_t* ctrlbar, uint8_t* irq,
|
|||
bool compatibility = interface == 0x00 || interface == 0x02;
|
||||
|
||||
if ( compatibility )
|
||||
*irq = channel_index == 0 ? 14 : 15;
|
||||
*irq = channel_index == 0 ? Interrupt::IRQ14 : Interrupt::IRQ15;
|
||||
|
||||
if ( compatibility ||
|
||||
basebar->addr_raw == 0 ||
|
||||
|
@ -175,8 +175,14 @@ bool Channel::Initialize(Ref<Descriptor> dev, const char* devpath)
|
|||
pcibar_t basebar = PCI::GetBAR(devaddr, 2 * channel_index + 0);
|
||||
pcibar_t ctrlbar = PCI::GetBAR(devaddr, 2 * channel_index + 1);
|
||||
pcibar_t busmasterbar = PCI::GetBAR(devaddr, 4);
|
||||
uint8_t irq = PCI::Read8(devaddr, PCIFIELD_INTERRUPT_LINE);
|
||||
FixDefaultDeviceBars(&basebar, &ctrlbar, &irq, channel_index, interface);
|
||||
interrupt_index = PCI::SetupInterruptLine(devaddr);
|
||||
FixDefaultDeviceBars(&basebar, &ctrlbar, &interrupt_index, channel_index, interface);
|
||||
|
||||
if ( !interrupt_index )
|
||||
{
|
||||
LogF("error: cannot determine interrupt line");
|
||||
return errno = EINVAL, false;
|
||||
}
|
||||
|
||||
if ( !basebar.is_iospace() )
|
||||
{
|
||||
|
@ -255,8 +261,6 @@ bool Channel::Initialize(Ref<Descriptor> dev, const char* devpath)
|
|||
}
|
||||
}
|
||||
|
||||
interrupt_index = Interrupt::IRQ0 + irq;
|
||||
|
||||
interrupt_registration.handler = Channel__OnInterrupt;
|
||||
interrupt_registration.context = this;
|
||||
Interrupt::RegisterHandler(interrupt_index, &interrupt_registration);
|
||||
|
|
|
@ -61,7 +61,7 @@ private:
|
|||
uint16_t port_control;
|
||||
uint16_t busmaster_base;
|
||||
Port* drives[2];
|
||||
unsigned int interrupt_index;
|
||||
uint8_t interrupt_index;
|
||||
bool interrupt_registered;
|
||||
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -152,6 +152,7 @@ pcibar_t GetExpansionROM(uint32_t devaddr);
|
|||
void EnableExpansionROM(uint32_t devaddr);
|
||||
void DisableExpansionROM(uint32_t devaddr);
|
||||
bool IsExpansionROMEnabled(uint32_t devaddr);
|
||||
uint8_t SetupInterruptLine(uint32_t devaddr);
|
||||
|
||||
} // namespace PCI
|
||||
} // namespace Sortix
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2012, 2013, 2014 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include <endian.h>
|
||||
|
||||
#include <sortix/kernel/cpu.h>
|
||||
#include <sortix/kernel/interrupt.h>
|
||||
#include <sortix/kernel/ioport.h>
|
||||
#include <sortix/kernel/kernel.h>
|
||||
#include <sortix/kernel/kthread.h>
|
||||
|
@ -31,8 +32,8 @@ namespace PCI {
|
|||
|
||||
static kthread_mutex_t pci_lock = KTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
const uint16_t CONFIG_ADDRESS = 0xCF8;
|
||||
const uint16_t CONFIG_DATA = 0xCFC;
|
||||
static const uint16_t CONFIG_ADDRESS = 0xCF8;
|
||||
static const uint16_t CONFIG_DATA = 0xCFC;
|
||||
|
||||
uint32_t MakeDevAddr(uint8_t bus, uint8_t slot, uint8_t func)
|
||||
{
|
||||
|
@ -279,6 +280,26 @@ bool IsExpansionROMEnabled(uint32_t devaddr)
|
|||
return PCI::Read32(devaddr, 0x30) & 0x1;
|
||||
}
|
||||
|
||||
static bool IsOkayInterruptLine(uint8_t line)
|
||||
{
|
||||
if ( line == 0 )
|
||||
return false; // Conflict with PIT.
|
||||
if ( line == 2 )
|
||||
return false; // Cascade, can't be received.
|
||||
if ( 16 <= line )
|
||||
return false; // Not in set of valid IRQs.
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t SetupInterruptLine(uint32_t devaddr)
|
||||
{
|
||||
ScopedLock lock(&pci_lock);
|
||||
uint8_t line = Read8(devaddr, PCIFIELD_INTERRUPT_LINE);
|
||||
if ( !IsOkayInterruptLine(line) )
|
||||
return 0;
|
||||
return Interrupt::IRQ0 + line;
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue