Merge branch 'master' into isa/arm64
[lunaix-os.git] / lunaix-os / hal / ahci / ahci_pci.c
index 0ecde58061af4ed37a1e78ab8e7c706355d57cf7..7c9288fa3b5b37b0677e6d1ae0005d76f8302a97 100644 (file)
@@ -2,33 +2,37 @@
 
 #include <hal/ahci/ahci.h>
 #include <hal/pci.h>
-#include <sys/pci_hba.h>
 
 static int
 ahci_pci_bind(struct device_def* def, struct device* dev)
 {
-    struct pci_device* ahci_dev = container_of(dev, struct pci_device, dev);
-
-    struct pci_base_addr* bar6 = &ahci_dev->bar[5];
-    assert_msg(bar6->type & BAR_TYPE_MMIO, "AHCI: BAR#6 is not MMIO.");
-
-    pci_reg_t cmd = pci_read_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD);
-
-    // 禁用传统中断(因为我们使用MSI),启用MMIO访问,允许PCI设备间访问
-    cmd |= (PCI_RCMD_MM_ACCESS | PCI_RCMD_DISABLE_INTR | PCI_RCMD_BUS_MASTER);
-
-    pci_write_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD, cmd);
-
-    int iv = isrm_ivexalloc(ahci_hba_isr);
-    pci_setup_msi(ahci_dev, iv);
+    struct pci_device* ahci_dev;
+    struct pci_base_addr* bar6;
+    struct ahci_driver* ahci_drv;
+    msi_vector_t msiv;
+
+    ahci_dev = PCI_DEVICE(dev);
+    bar6 = pci_device_bar(ahci_dev, 5);
+    assert_msg(pci_bar_mmio_space(bar6), "AHCI: BAR#6 is not MMIO.");
+
+    pci_reg_t cmd = 0;
+    pci_cmd_set_bus_master(&cmd);
+    pci_cmd_set_mmio(&cmd);
+    pci_cmd_set_msi(&cmd);
+    pci_apply_command(ahci_dev, cmd);
+    
+    assert(pci_capability_msi(ahci_dev));
+
+    msiv = isrm_msialloc(ahci_hba_isr);
+    pci_setup_msi(ahci_dev, msiv);
 
     struct ahci_driver_param param = {
         .mmio_base = bar6->start,
         .mmio_size = bar6->size,
-        .ahci_iv = iv,
+        .ahci_iv = msi_vect(msiv),
     };
 
-    struct ahci_driver* ahci_drv = ahci_driver_init(&param);
+    ahci_drv = ahci_driver_init(&param);
     pci_bind_instance(ahci_dev, ahci_drv);
 
     return 0;
@@ -40,12 +44,19 @@ ahci_pci_init(struct device_def* def)
     return pci_bind_definition_all(pcidev_def(def));
 }
 
+static bool
+ahci_pci_compat(struct pci_device_def* def, 
+                struct pci_device* pcidev)
+{
+    return pci_device_class(pcidev) == AHCI_HBA_CLASS;
+}
+
+
 static struct pci_device_def ahcidef = {
-    .dev_class = AHCI_HBA_CLASS,
-    .ident_mask = PCI_MATCH_ANY,
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA),
-                .name = "Generic SATA",
+                .name = "Generic AHCI",
                 .init = ahci_pci_init,
-                .bind = ahci_pci_bind }
+                .bind = ahci_pci_bind },
+    .test_compatibility = ahci_pci_compat
 };
 EXPORT_PCI_DEVICE(ahci, &ahcidef, load_postboot);
\ No newline at end of file