#include #include #include #include #include #include #include #include #include #include #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);