--- a/usr/src/uts/common/sys/pcie_impl.h Mon Apr 26 16:32:21 2010 -0700
+++ b/usr/src/uts/common/sys/pcie_impl.h Mon Apr 26 16:41:00 2010 -0700
@@ -37,7 +37,7 @@
#define PCI_GET_SEC_BUS(dip) \
PCIE_DIP2BUS(dip)->bus_bdg_secbus
#define PCI_GET_PCIE2PCI_SECBUS(dip) \
- PCIE_DIP2BUS(dip)->bus_bdg_secbus
+ PCIE_DIP2BUS(dip)->bus_pcie2pci_secbus
#define DEVI_PORT_TYPE_PCI \
((PCI_CLASS_BRIDGE << 16) | (PCI_BRIDGE_PCI << 8) | \
@@ -332,6 +332,9 @@
int bus_ari; /* ARI device */
uint64_t bus_cfgacc_base; /* config space base address */
+
+ /* workaround for PCI/PCI-X devs behind PCIe2PCI Bridge */
+ pcie_req_id_t bus_pcie2pci_secbus;
} pcie_bus_t;
/*
--- a/usr/src/uts/sparc/io/pciex/pcie_sparc.c Mon Apr 26 16:32:21 2010 -0700
+++ b/usr/src/uts/sparc/io/pciex/pcie_sparc.c Mon Apr 26 16:41:00 2010 -0700
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/types.h>
@@ -30,16 +29,38 @@
#include <sys/pcie_impl.h>
#include <sys/pcie_pwr.h>
-/* ARGSUSED */
void
pcie_init_plat(dev_info_t *dip)
{
+ pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
+
+ if (PCIE_IS_PCIE_BDG(bus_p)) {
+ bus_p->bus_pcie2pci_secbus = bus_p->bus_bdg_secbus;
+ } else {
+ dev_info_t *pdip;
+
+ for (pdip = ddi_get_parent(dip); pdip;
+ pdip = ddi_get_parent(pdip)) {
+ pcie_bus_t *parent_bus_p = PCIE_DIP2BUS(pdip);
+
+ if (parent_bus_p->bus_pcie2pci_secbus) {
+ bus_p->bus_pcie2pci_secbus =
+ parent_bus_p->bus_pcie2pci_secbus;
+ break;
+ }
+ if (PCIE_IS_ROOT(parent_bus_p))
+ break;
+ }
+ }
}
-/* ARGSUSED */
void
pcie_fini_plat(dev_info_t *dip)
{
+ pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
+
+ if (PCIE_IS_PCIE_BDG(bus_p))
+ bus_p->bus_pcie2pci_secbus = 0;
}
int
--- a/usr/src/uts/sun4v/io/px/px_lib4v.c Mon Apr 26 16:32:21 2010 -0700
+++ b/usr/src/uts/sun4v/io/px/px_lib4v.c Mon Apr 26 16:41:00 2010 -0700
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/types.h>
@@ -52,6 +51,7 @@
/*
* Hypervisor VPCI services information for the px nexus driver.
*/
+static uint64_t px_vpci_maj_ver; /* Negotiated VPCI API major version */
static uint64_t px_vpci_min_ver; /* Negotiated VPCI API minor version */
static uint_t px_vpci_users = 0; /* VPCI API users */
static hsvc_info_t px_hsvc_vpci = {
@@ -149,17 +149,38 @@
/*
* Negotiate the API version for VPCI hypervisor services.
*/
- if ((px_vpci_users == 0) &&
- ((ret = hsvc_register(&px_hsvc_vpci, &px_vpci_min_ver)) != 0)) {
+ if (px_vpci_users == 0) {
+ if ((ret = hsvc_register(&px_hsvc_vpci, &px_vpci_min_ver))
+ == 0) {
+ px_vpci_maj_ver = px_hsvc_vpci.hsvc_major;
+ goto hv_negotiation_complete;
+ }
+ /*
+ * Negotiation with the latest known VPCI hypervisor services
+ * failed. Fallback to version 1.0.
+ */
+ px_hsvc_vpci.hsvc_major = PX_HSVC_MAJOR_VER_1;
+ px_hsvc_vpci.hsvc_minor = PX_HSVC_MINOR_VER_0;
+
+ if ((ret = hsvc_register(&px_hsvc_vpci, &px_vpci_min_ver))
+ == 0) {
+ px_vpci_maj_ver = px_hsvc_vpci.hsvc_major;
+ goto hv_negotiation_complete;
+ }
+
cmn_err(CE_WARN, "%s: cannot negotiate hypervisor services "
"group: 0x%lx major: 0x%lx minor: 0x%lx errno: %d\n",
px_hsvc_vpci.hsvc_modname, px_hsvc_vpci.hsvc_group,
px_hsvc_vpci.hsvc_major, px_hsvc_vpci.hsvc_minor, ret);
+
return (DDI_FAILURE);
}
+hv_negotiation_complete:
+
px_vpci_users++;
+
DBG(DBG_ATTACH, dip, "px_lib_dev_init: negotiated VPCI API version, "
- "major 0x%lx minor 0x%lx\n", px_hsvc_vpci.hsvc_major,
+ "major 0x%lx minor 0x%lx\n", px_vpci_maj_ver,
px_vpci_min_ver);
/*
@@ -428,11 +449,12 @@
pfns[i] = MMU_PTOB(PX_ADDR2PFN(addr, pfn_index, flags, i));
/*
- * If HV VPCI version is 1.1 and higher, pass BDF, phantom function,
+ * If HV VPCI version is 2.0 and higher, pass BDF, phantom function,
* and relaxed ordering attributes. Otherwise, pass only read or write
* attribute.
*/
- if (px_vpci_min_ver == PX_HSVC_MINOR_VER_0)
+ if ((px_vpci_maj_ver == PX_HSVC_MAJOR_VER_1) &&
+ (px_vpci_min_ver == PX_HSVC_MINOR_VER_0))
attr = attr & (PCI_MAP_ATTR_READ | PCI_MAP_ATTR_WRITE);
while ((ttes_mapped = pfn_p - pfns) < pages) {
@@ -572,11 +594,12 @@
DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getbypass: dip 0x%p ra 0x%llx "
"attr 0x%llx\n", dip, ra, attr);
/*
- * If HV VPCI version is 1.1 and higher, pass BDF, phantom function,
+ * If HV VPCI version is 2.0 and higher, pass BDF, phantom function,
* and relaxed ordering attributes. Otherwise, pass only read or write
* attribute.
*/
- if (px_vpci_min_ver == PX_HSVC_MINOR_VER_0)
+ if ((px_vpci_maj_ver == PX_HSVC_MAJOR_VER_1) &&
+ (px_vpci_min_ver == PX_HSVC_MINOR_VER_0))
attr &= PCI_MAP_ATTR_READ | PCI_MAP_ATTR_WRITE;
if ((ret = hvio_iommu_getbypass(DIP_TO_HANDLE(dip), ra,
--- a/usr/src/uts/sun4v/io/px/px_lib4v.h Mon Apr 26 16:32:21 2010 -0700
+++ b/usr/src/uts/sun4v/io/px/px_lib4v.h Mon Apr 26 16:41:00 2010 -0700
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _SYS_PX_LIB4V_H
@@ -98,16 +97,20 @@
* Hypercall service versioning
*/
#define PX_HSVC_MAJOR_VER_1 0x1ull
+#define PX_HSVC_MAJOR_VER_2 0x2ull
#define PX_HSVC_MINOR_VER_0 0x0ull
#define PX_HSVC_MINOR_VER_1 0x1ull
#define PX_HSVC_MINOR_VER_2 0x2ull
/*
* VPCI API versioning.
- * Currently PX nexus driver supports VPCI API version 1.2
+ * Currently PX nexus driver supports VPCI API version 2.0
+ * 1.0 - Negotiated/supported.
+ * 1.1/1.2 - Deprecated.
+ * 2.0 - Negotiated/supported.
*/
-#define PX_VPCI_MAJOR_VER PX_HSVC_MAJOR_VER_1
-#define PX_VPCI_MINOR_VER PX_HSVC_MINOR_VER_2
+#define PX_VPCI_MAJOR_VER PX_HSVC_MAJOR_VER_2
+#define PX_VPCI_MINOR_VER PX_HSVC_MINOR_VER_0
/*
* SDIO API versioning.