Files
mango/kexts/drivers/block/ahci/main.c
2023-07-09 09:07:15 +01:00

81 lines
2.0 KiB
C

#include <socks/printk.h>
#include <socks/pci.h>
#include <socks/device.h>
#include <socks/kext.h>
#include <socks/pci.h>
#include <socks/util.h>
#include <socks/machine/init.h>
#include <socks/libc/stdio.h>
#include <socks/libc/ctype.h>
#include <arch/irq.h>
#include "ahci.h"
static struct pci_driver *__ahci_driver = NULL;
static volatile struct hba_config *hba_config = NULL;
static int irq_callback(void);
static struct irq_hook irq_hook = {
.irq_callback = irq_callback,
};
static struct pci_device_id ahci_device_ids[] = {
PCI_CLASS_ID(0x01, 0x06),
PCI_DEVICE_ID_INVALID,
};
struct driver *ahci_driver(void)
{
return pci_driver_base(__ahci_driver);
}
static kern_status_t ahci_scan(struct device *ahci_bus)
{
struct pci_device *pci_dev = device_get_pci_info(ahci_bus);
printk("ahci: probing ports on ahci controller at pci%04x:%02x.%02u", pci_dev->pci_bus, pci_dev->pci_slot, pci_dev->pci_func);
uint32_t abar = pci_device_read_field(ahci_bus, PCI_REG_BAR5, 4);
hba_config = vm_phys_to_virt(abar);
probe_ahci_ports(pci_driver_base(__ahci_driver), ahci_bus, hba_config, create_device_from_ahci_port);
return KERN_OK;
}
static struct bus_device_ops ahci_bus_ops = {
.scan = ahci_scan,
};
static int irq_callback(void)
{
printk("ahci: received IRQ");
return 0;
}
static kern_status_t ahci_probe(struct pci_driver *driver, struct device *dev)
{
struct bus_device *ahci_bus = bus_device_from_generic(dev);
ahci_bus->b_ops = &ahci_bus_ops;
snprintf(dev->dev_name, sizeof dev->dev_name, "ahci");
uint8_t irq_vec = pci_device_read_field(dev, PCI_REG_INTERRUPT_LINE, 1);
hook_irq(IRQ0 + irq_vec, &irq_hook);
return device_register(dev, pci_driver_base(__ahci_driver), NULL);
}
static kern_status_t online(struct kext *self)
{
printk("ahci: registering AHCI driver");
__ahci_driver = pci_driver_create(self, "ahci", ahci_device_ids);
if (!__ahci_driver) {
return KERN_NO_MEMORY;
}
__ahci_driver->probe = ahci_probe;
pci_driver_register(__ahci_driver);
return KERN_OK;
}
DEFINE_KEXT("net.doorstuck.socks.ahci",
online, NULL,
PCI_SUBSYSTEM_KEXT_ID);