PCI 16x50 UART Controller, O2 Enablement (#39)
[lunaix-os.git] / lunaix-os / hal / bus / pci.c
index af7a256f50b47614298cc213eb8821a83f40059d..6d26d09d7d4c4e789267c6f934ed8a31403cd487 100644 (file)
@@ -9,7 +9,6 @@
  *
  */
 #include <hal/pci.h>
  *
  */
 #include <hal/pci.h>
-#include <sys/pci_hba.h>
 
 #include <klibc/string.h>
 #include <lunaix/fs/twifs.h>
 
 #include <klibc/string.h>
 #include <lunaix/fs/twifs.h>
@@ -71,23 +70,19 @@ pci_create_device(pciaddr_t loc, ptr_t pci_base, int devinfo)
 }
 
 int
 }
 
 int
-pci_bind_definition(struct pci_device_def* pcidev_def, int* more)
+pci_bind_definition(struct pci_device_def* pcidef, bool* more)
 {
 {
-    u32_t class = pcidev_def->dev_class;
-    u32_t devid_mask = pcidev_def->ident_mask;
-    u32_t devid = pcidev_def->dev_ident & devid_mask;
-
-    if (!pcidev_def->devdef.bind) {
+    if (!pcidef->devdef.bind) {
         ERROR("pcidev %xh:%xh.%d is unbindable",
         ERROR("pcidev %xh:%xh.%d is unbindable",
-              pcidev_def->devdef.class.fn_grp,
-              pcidev_def->devdef.class.device,
-              pcidev_def->devdef.class.variant);
+              pcidef->devdef.class.fn_grp,
+              pcidef->devdef.class.device,
+              pcidef->devdef.class.variant);
         return EINVAL;
     }
 
         return EINVAL;
     }
 
-    *more = 0;
+    *more = false;
 
 
-    int bind_attempted = 0;
+    bool bind_attempted = 0;
     int errno = 0;
 
     struct device_def* devdef;
     int errno = 0;
 
     struct device_def* devdef;
@@ -98,23 +93,22 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more)
             continue;
         }
 
             continue;
         }
 
-        if (class != PCI_DEV_CLASS(pos->class_info)) {
-            continue;
-        }
+        bool matched;
 
 
-        int matched = (pos->device_info & devid_mask) == devid;
+        assert(pcidef->test_compatibility);
+        matched = pcidef->test_compatibility(pcidef, pos);
 
         if (!matched) {
             continue;
         }
 
         if (bind_attempted) {
 
         if (!matched) {
             continue;
         }
 
         if (bind_attempted) {
-            *more = 1;
+            *more = true;
             break;
         }
 
             break;
         }
 
-        bind_attempted = 1;
-        devdef = &pcidev_def->devdef;
+        bind_attempted = true;
+        devdef = &pcidef->devdef;
         errno = devdef->bind(devdef, &pos->dev);
 
         if (errno) {
         errno = devdef->bind(devdef, &pos->dev);
 
         if (errno) {
@@ -127,7 +121,7 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more)
             continue;
         }
 
             continue;
         }
 
-        pos->binding.def = &pcidev_def->devdef;
+        pos->binding.def = &pcidef->devdef;
     }
 
     return errno;
     }
 
     return errno;
@@ -136,9 +130,10 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more)
 int
 pci_bind_definition_all(struct pci_device_def* pcidef)
 {
 int
 pci_bind_definition_all(struct pci_device_def* pcidef)
 {
-    int more = 0, e = 0;
+    int e = 0;
+    bool more = false;
     do {
     do {
-        if (!(e = pci_bind_definition(pcidef, &more))) {
+        if ((e = pci_bind_definition(pcidef, &more))) {
             break;
         }
     } while (more);
             break;
         }
     } while (more);
@@ -201,7 +196,7 @@ pci_probe_bar_info(struct pci_device* device)
 {
     u32_t bar;
     struct pci_base_addr* ba;
 {
     u32_t bar;
     struct pci_base_addr* ba;
-    for (size_t i = 0; i < 6; i++) {
+    for (size_t i = 0; i < PCI_BAR_COUNT; i++) {
         ba = &device->bar[i];
         ba->size = pci_bar_sizing(device, &bar, i + 1);
         if (PCI_BAR_MMIO(bar)) {
         ba = &device->bar[i];
         ba->size = pci_bar_sizing(device, &bar, i + 1);
         if (PCI_BAR_MMIO(bar)) {
@@ -327,6 +322,21 @@ pci_get_device_by_class(u32_t class)
     return NULL;
 }
 
     return NULL;
 }
 
+void
+pci_apply_command(struct pci_device* pcidev, pci_reg_t cmd)
+{
+    pci_reg_t rcmd;
+    ptr_t base;
+
+    base = pcidev->cspace_base;
+    rcmd = pci_read_cspace(base, PCI_REG_STATUS_CMD);
+
+    cmd  = cmd & 0xffff;
+    rcmd = (rcmd & 0xffff0000) | cmd;
+
+    pci_write_cspace(base, PCI_REG_STATUS_CMD, rcmd);
+}
+
 static void
 __pci_read_cspace(struct twimap* map)
 {
 static void
 __pci_read_cspace(struct twimap* map)
 {