drivers/pcie: Even single MSI based interrupt needs to be remapped

Refactor to handle this case. This is valid only when MSI multi-vector
feature is enabled.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c
index cecdcb7..cf1e9b7 100644
--- a/arch/x86/core/pcie.c
+++ b/arch/x86/core/pcie.c
@@ -213,48 +213,66 @@
 				       msi_vector_t *vectors,
 				       uint8_t n_vector)
 {
-	if (n_vector > 1) {
-		int prev_vector = -1;
-		int i;
+	int prev_vector = -1;
+	int i, irq, vector;
+
+	if (vectors == NULL || n_vector == 0) {
+		return 0;
+	}
+
+
 #ifdef CONFIG_INTEL_VTD_ICTL
-		{
-			int irte;
+	{
+		int irte;
 
-			if (!get_vtd()) {
-				return 0;
-			}
-
-			irte = vtd_allocate_entries(vtd, n_vector);
-			if (irte < 0) {
-				return 0;
-			}
-
-			for (i = 0; i < n_vector; i++, irte++) {
-				vectors[i].arch.irte = irte;
-				vectors[i].arch.remap = true;
-			}
+		if (!get_vtd()) {
+			return 0;
 		}
+
+		irte = vtd_allocate_entries(vtd, n_vector);
+		if (irte < 0) {
+			return 0;
+		}
+
+		for (i = 0; i < n_vector; i++, irte++) {
+			vectors[i].arch.irte = irte;
+			vectors[i].arch.remap = true;
+		}
+	}
 #endif /* CONFIG_INTEL_VTD_ICTL */
 
-		for (i = 0; i < n_vector; i++) {
-			vectors[i].arch.irq = arch_irq_allocate();
-			vectors[i].arch.vector =
-				z_x86_allocate_vector(priority, prev_vector);
-			if (vectors[i].arch.vector < 0) {
-				return 0;
-			}
+	for (i = 0; i < n_vector; i++) {
+		if (n_vector == 1) {
+			/* This path is taken by PCIE device with fixed
+			 * or single MSI: IRQ has been already allocated
+			 * and/or set on the PCIe bus. Thus we only require
+			 * to get it.
+			 */
+			irq = pcie_get_irq(vectors->bdf);
+		} else {
+			irq = arch_irq_allocate();
+		}
+
+		if ((irq == PCIE_CONF_INTR_IRQ_NONE) || (irq == -1)) {
+			return -1;
+		}
+
+		vector = z_x86_allocate_vector(priority, prev_vector);
+		if (vector < 0) {
+			return 0;
+		}
+
+		vectors[i].arch.irq = irq;
+		vectors[i].arch.vector = vector;
 
 #ifdef CONFIG_INTEL_VTD_ICTL
-			vtd_set_irte_vector(vtd, vectors[i].arch.irte,
-					    vectors[i].arch.vector);
-			vtd_set_irte_irq(vtd, vectors[i].arch.irte,
-					 vectors[i].arch.irq);
-			vtd_set_irte_msi(vtd, vectors[i].arch.irte, true);
+		vtd_set_irte_vector(vtd, vectors[i].arch.irte,
+				    vectors[i].arch.vector);
+		vtd_set_irte_irq(vtd, vectors[i].arch.irte,
+				 vectors[i].arch.irq);
+		vtd_set_irte_msi(vtd, vectors[i].arch.irte, true);
 #endif
-			prev_vector = vectors[i].arch.vector;
-		}
-	} else {
-		vectors[0].arch.vector = z_x86_allocate_vector(priority, -1);
+		prev_vector = vectors[i].arch.vector;
 	}
 
 	return n_vector;
diff --git a/drivers/pcie/host/msi.c b/drivers/pcie/host/msi.c
index 303461e..bcbf3e4 100644
--- a/drivers/pcie/host/msi.c
+++ b/drivers/pcie/host/msi.c
@@ -167,6 +167,10 @@
 		n_vector = req_vectors;
 	}
 
+	for (req_vectors = 0; req_vectors < n_vector; req_vectors++) {
+		vectors[req_vectors].bdf = bdf;
+	}
+
 	return arch_pcie_msi_vectors_allocate(priority, vectors, n_vector);
 }
 
@@ -183,8 +187,6 @@
 		return false;
 	}
 
-	vector->bdf = bdf;
-
 	return arch_pcie_msi_vector_connect(vector, routine, parameter, flags);
 }