--- a/usr/src/uts/common/Makefile.files Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/common/Makefile.files Fri Apr 24 13:17:47 2009 -0700
@@ -1717,7 +1717,7 @@
INCLUDE_PATH += $(INC_PATH) $(CCYFLAG)$(UTSBASE)/common
#
-PCIE_OBJS += pcie.o pcie_fault.o
+PCIE_MISC_OBJS += pcie.o pcie_fault.o
# Chelsio N110 10G NIC driver module
#
--- a/usr/src/uts/common/io/pcie.c Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/common/io/pcie.c Fri Apr 24 13:17:47 2009 -0700
@@ -45,36 +45,10 @@
static void pcie_check_io_mem_range(ddi_acc_handle_t, boolean_t *, boolean_t *);
#endif /* defined(__i386) || defined(__amd64) */
-#ifdef DEBUG
+#ifdef DEBUG
uint_t pcie_debug_flags = 0;
-
static void pcie_print_bus(pcie_bus_t *bus_p);
-
-#define PCIE_DBG pcie_dbg
-/* Common Debugging shortcuts */
-#define PCIE_DBG_CFG(dip, bus_p, name, sz, off, org) \
- PCIE_DBG("%s:%d:(0x%x) %s(0x%x) 0x%x -> 0x%x\n", ddi_node_name(dip), \
- ddi_get_instance(dip), bus_p->bus_bdf, name, off, org, \
- PCIE_GET(sz, bus_p, off))
-#define PCIE_DBG_CAP(dip, bus_p, name, sz, off, org) \
- PCIE_DBG("%s:%d:(0x%x) %s(0x%x) 0x%x -> 0x%x\n", ddi_node_name(dip), \
- ddi_get_instance(dip), bus_p->bus_bdf, name, off, org, \
- PCIE_CAP_GET(sz, bus_p, off))
-#define PCIE_DBG_AER(dip, bus_p, name, sz, off, org) \
- PCIE_DBG("%s:%d:(0x%x) %s(0x%x) 0x%x -> 0x%x\n", ddi_node_name(dip), \
- ddi_get_instance(dip), bus_p->bus_bdf, name, off, org, \
- PCIE_AER_GET(sz, bus_p, off))
-
-static void pcie_dbg(char *fmt, ...);
-
-#else /* DEBUG */
-
-#define PCIE_DBG_CFG 0 &&
-#define PCIE_DBG 0 &&
-#define PCIE_DBG_CAP 0 &&
-#define PCIE_DBG_AER 0 &&
-
-#endif /* DEBUG */
+#endif /* DEBUG */
/* Variable to control default PCI-Express config settings */
ushort_t pcie_command_default =
@@ -676,6 +650,8 @@
bus_p->bus_mps = 0;
+ pcie_init_plat(cdip);
+
PCIE_DBG("Add %s(dip 0x%p, bdf 0x%x, secbus 0x%x)\n",
ddi_driver_name(cdip), (void *)cdip, bus_p->bus_bdf,
bus_p->bus_bdg_secbus);
@@ -721,6 +697,7 @@
{
pcie_bus_t *bus_p;
+ pcie_fini_plat(cdip);
pcie_fini_pfd(cdip);
bus_p = PCIE_DIP2UPBUS(cdip);
@@ -1510,7 +1487,7 @@
* o taskq to print at lower pil
*/
int pcie_dbg_print = 0;
-static void
+void
pcie_dbg(char *fmt, ...)
{
va_list ap;
--- a/usr/src/uts/common/sys/pcie_impl.h Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/common/sys/pcie_impl.h Fri Apr 24 13:17:47 2009 -0700
@@ -270,6 +270,8 @@
pf_data_t *bus_pfd;
int bus_mps; /* Maximum Payload Size */
+
+ void *bus_plat_private; /* Platform specific */
} pcie_bus_t;
struct pf_data {
@@ -342,6 +344,34 @@
int highest_common_mps;
} pcie_max_supported_t;
+#ifdef DEBUG
+extern uint_t pcie_debug_flags;
+#define PCIE_DBG pcie_dbg
+/* Common Debugging shortcuts */
+#define PCIE_DBG_CFG(dip, bus_p, name, sz, off, org) \
+ PCIE_DBG("%s:%d:(0x%x) %s(0x%x) 0x%x -> 0x%x\n", ddi_node_name(dip), \
+ ddi_get_instance(dip), bus_p->bus_bdf, name, off, org, \
+ PCIE_GET(sz, bus_p, off))
+#define PCIE_DBG_CAP(dip, bus_p, name, sz, off, org) \
+ PCIE_DBG("%s:%d:(0x%x) %s(0x%x) 0x%x -> 0x%x\n", ddi_node_name(dip), \
+ ddi_get_instance(dip), bus_p->bus_bdf, name, off, org, \
+ PCIE_CAP_GET(sz, bus_p, off))
+#define PCIE_DBG_AER(dip, bus_p, name, sz, off, org) \
+ PCIE_DBG("%s:%d:(0x%x) %s(0x%x) 0x%x -> 0x%x\n", ddi_node_name(dip), \
+ ddi_get_instance(dip), bus_p->bus_bdf, name, off, org, \
+ PCIE_AER_GET(sz, bus_p, off))
+
+extern void pcie_dbg(char *fmt, ...);
+
+#else /* DEBUG */
+
+#define PCIE_DBG_CFG 0 &&
+#define PCIE_DBG 0 &&
+#define PCIE_DBG_CAP 0 &&
+#define PCIE_DBG_AER 0 &&
+
+#endif /* DEBUG */
+
/* PCIe Friendly Functions */
extern void pcie_init_root_port_mps(dev_info_t *dip);
extern int pcie_initchild(dev_info_t *dip);
@@ -379,6 +409,8 @@
extern void pcie_set_aer_ce_mask(uint32_t mask);
extern void pcie_set_aer_suce_mask(uint32_t mask);
extern void pcie_set_serr_mask(uint32_t mask);
+extern void pcie_init_plat(dev_info_t *dip);
+extern void pcie_fini_plat(dev_info_t *dip);
/* PCIe error handling functions */
extern int pf_scan_fabric(dev_info_t *rpdip, ddi_fm_error_t *derr,
--- a/usr/src/uts/i86pc/Makefile.files Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/i86pc/Makefile.files Fri Apr 24 13:17:47 2009 -0700
@@ -173,7 +173,7 @@
gfxp_devmap.o gfxp_vgatext.o gfxp_vm.o vgasubr.o
IOAT_OBJS += ioat.o ioat_rs.o ioat_ioctl.o ioat_chan.o
ISANEXUS_OBJS += isa.o dma_engine.o i8237A.o
-PCI_E_MISC_OBJS += pcie.o pcie_fault.o
+PCIE_MISC_OBJS += pcie_acpi.o
PCI_E_NEXUS_OBJS += npe.o npe_misc.o
PCI_E_NEXUS_OBJS += pci_common.o pci_kstats.o pci_tools.o
PCINEXUS_OBJS += pci.o pci_common.o pci_kstats.o pci_tools.o
--- a/usr/src/uts/i86pc/pcie/Makefile Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/i86pc/pcie/Makefile Fri Apr 24 13:17:47 2009 -0700
@@ -21,10 +21,9 @@
#
# uts/i86pc/pcie/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
#
# This makefile drives the production of the kernel/misc/pcie module
# for PCI-E Error handling support in PCI-E nexus drivers.
@@ -41,8 +40,8 @@
# Define the module and object file sets.
#
MODULE = pcie
-OBJECTS = $(PCI_E_MISC_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(PCI_E_MISC_OBJS:%.o=$(LINTS_DIR)/%.ln)
+OBJECTS = $(PCIE_MISC_OBJS:%=$(OBJS_DIR)/%)
+LINTS = $(PCIE_MISC_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_PSM_MISC_DIR)/$(MODULE)
#
@@ -50,6 +49,8 @@
#
include $(UTSBASE)/i86pc/Makefile.i86pc
+LDFLAGS += -dy -Nmisc/acpica
+
#
# Define targets
#
--- a/usr/src/uts/intel/Makefile.files Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/intel/Makefile.files Fri Apr 24 13:17:47 2009 -0700
@@ -153,7 +153,7 @@
PCICFG_OBJS += pcicfg.o
PCI_E_PCINEXUS_OBJS += pcie_pci.o
PCI_PCINEXUS_OBJS += pci_pci.o
-PCIEHPCNEXUS_OBJS += pciehpc_x86.o pciehpc_acpi.o
+PCIEHPCNEXUS_OBJS += pciehpc_acpi.o
PCN_OBJS += mii.o
PIT_BEEP_OBJS += pit_beep.o
POWER_OBJS += power.o
--- a/usr/src/uts/intel/ia32/ml/modstubs.s Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/intel/ia32/ml/modstubs.s Fri Apr 24 13:17:47 2009 -0700
@@ -1049,7 +1049,6 @@
MODULE(pciehpc,misc);
STUB(pciehpc, pciehpc_init, 0);
STUB(pciehpc, pciehpc_uninit, 0);
- STUB(pciehpc, pciehpc_acpi_eval_osc, 0);
WSTUB(pciehpc, pciehpc_intr, nomod_zero);
END_MODULE(pciehpc);
#endif
--- a/usr/src/uts/intel/io/hotplug/pciehpc/pciehpc_acpi.c Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/intel/io/hotplug/pciehpc/pciehpc_acpi.c Fri Apr 24 13:17:47 2009 -0700
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +38,7 @@
#include <sys/pci.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
+#include <sys/pcie_acpi.h>
#include "pciehpc_acpi.h"
/* local static functions */
@@ -51,6 +52,7 @@
void *data, uint_t flags);
static int pciehpc_acpi_slot_disconnect(caddr_t ops_arg, hpc_slot_t slot_hdl,
void *data, uint_t flags);
+static void pciehpc_acpi_setup_ops(pciehpc_t *ctrl_p);
static ACPI_STATUS pciehpc_acpi_install_event_handler(pciehpc_t *ctrl_p);
static void pciehpc_acpi_uninstall_event_handler(pciehpc_t *ctrl_p);
@@ -60,127 +62,39 @@
void *context);
static ACPI_STATUS pciehpc_acpi_ej0_present(ACPI_HANDLE pcibus_obj);
static ACPI_STATUS pciehpc_acpi_get_dev_state(ACPI_HANDLE obj, int *statusp);
-ACPI_STATUS pciehpc_acpi_eval_osc(ACPI_HANDLE osc_hdl, uint32_t *hp_mode);
-static ACPI_STATUS pciehpc_acpi_find_osc(ACPI_HANDLE busobj,
- ACPI_HANDLE *osc_hdlp);
-#ifdef DEBUG
-static void pciehpc_dump_acpi_obj(ACPI_HANDLE pcibus_obj);
-static ACPI_STATUS pciehpc_walk_obj_namespace(ACPI_HANDLE hdl, uint32_t nl,
- void *context, void **ret);
-static ACPI_STATUS pciehpc_print_acpi_name(ACPI_HANDLE hdl, uint32_t nl,
- void *context, void **ret);
-static void print_acpi_pathname(ACPI_HANDLE hdl);
-#endif
-
-/* UUID for for PCI/PCI-X/PCI-Exp hierarchy as defined in PCI fw ver 3.0 */
-static uint8_t pcie_uuid[16] =
- {0x5b, 0x4d, 0xdb, 0x33, 0xf7, 0x1f, 0x1c, 0x40,
- 0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66};
/*
- * Function to check if ACPI hot plug is enabled on this bridge device.
- * Since there is no absolute way to figure out if ACPI BIOS has hot plug
- * control, the following approach is necessary:
- *
- * 1) If _OSC method is present then it is straight forward.
- * 2) Otherwise, we need platform specific way to determine
- * whether ACPI BIOS has hot plug control or not.
- * (e.g: using .conf file property)
- *
- * NOTE: As per the PCI FW 3.0 spec, in the absence of _OSC method OS
- * should not try to do native hot plug control.
- *
- * Returns 0 if the current mode is not ACPI hot plug.
+ * Update ops vector with platform specific (ACPI, CK8-04,...) functions.
*/
-int
-pciehpc_acpi_hotplug_enabled(dev_info_t *dip)
+void
+pciehpc_update_ops(pciehpc_t *ctrl_p)
{
- int *hotplug_mode;
- uint_t count;
- ACPI_HANDLE pcibus_obj;
- int status = AE_ERROR;
- ACPI_HANDLE osc_hdl;
- int use_native_hotplug = 0;
- uint32_t hp_mode;
-
- /*
- * (1) Find the ACPI device node for this bus node.
- */
- status = acpica_get_handle(dip, &pcibus_obj);
- if (status != AE_OK) {
- /*
- * No ACPI device for this bus node. Assume there is
- * no ACPI hot plug support on this bus.
- */
- PCIEHPC_DEBUG((CE_CONT, "No ACPI device found (dip %p)\n",
- (void *)dip));
- PCIEHPC_DEBUG((CE_CONT, "Assuming native Hot-Plug mode\n"));
- return (0);
- }
-
+ boolean_t hp_native_mode = B_FALSE;
+ uint32_t osc_flags = OSC_CONTROL_PCIE_NAT_HP;
/*
- * NOTE: Without _OSC method there is no reliable way to know if the
- * platform implements ACPI hot plug or native hot plug. But, if it is
- * present then it may be possible to use either mode (i.e ACPI or
- * native-hotplug) if the platform supports both.
+ * Call _OSC method to determine if hotplug mode is native or ACPI.
+ * If _OSC method succeeds hp_native_mode below will be set according to
+ * if native hotplug control was granted or not by BIOS.
+ *
+ * If _OSC method fails for any reason or if native hotplug control was
+ * not granted assume it's ACPI mode and update platform specific
+ * (ACPI, CK8-04,...) impl. ops
*/
- /*
- * (2) Check if _OSC method is present.
- */
- if (pciehpc_acpi_find_osc(pcibus_obj, &osc_hdl) != AE_OK) {
- /* no _OSC method present; we need to guess here! */
- PCIEHPC_DEBUG((CE_NOTE, "no _OSC method present\n"));
- /*
- * If "use-native-hotplug-mode" property set then it means
- * the platform supports only native hot-plug mode.
- */
- if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "use-native-hotplug-mode",
- &hotplug_mode, &count) == DDI_PROP_SUCCESS) {
- if (hotplug_mode[0] == 1)
- use_native_hotplug = 1;
- ddi_prop_free(hotplug_mode);
- }
- if (use_native_hotplug) {
- PCIEHPC_DEBUG((CE_NOTE,
- "Assuming native Hot-Plug mode\n"));
- return (0); /* assume native hot plug mode */
- } else {
- PCIEHPC_DEBUG((CE_NOTE,
- "Assuming legacy ACPI Hot-Plug mode\n"));
- return (1); /* assume ACPI hot plug mode */
- }
+ if (pcie_acpi_osc(ctrl_p->dip, &osc_flags) == DDI_SUCCESS) {
+ hp_native_mode = (osc_flags & OSC_CONTROL_PCIE_NAT_HP) ?
+ B_TRUE : B_FALSE;
}
- /*
- * (3) _OSC method exists; evaluate _OSC to use native hot-plug mode.
- *
- * Note: The default policy is to use native hot-plug mode if the
- * platform supports it.
- */
- if (pciehpc_acpi_eval_osc(osc_hdl, &hp_mode) != AE_OK) {
- /* failed to evaluate _OSC method; assume ACPI hot plug */
- PCIEHPC_DEBUG((CE_NOTE, "Failed to evaluate _OSC; "
- "Assuming legacy ACPI Hot-Plug mode\n"));
- return (1);
+ if (!hp_native_mode) {
+ /* update ops vector for ACPI mode */
+ pciehpc_acpi_setup_ops(ctrl_p);
+ ctrl_p->hp_mode = PCIEHPC_ACPI_HP_MODE;
}
-
-#ifdef DEBUG
- if (pciehpc_debug > 1)
- pciehpc_dump_acpi_obj(pcibus_obj);
-#endif
- if (hp_mode == NATIVE_HP_MODE) {
- PCIEHPC_DEBUG((CE_NOTE, "Native Hot-Plug mode enabled\n"));
- return (0); /* it is in native hp mode! */
- }
-
- PCIEHPC_DEBUG((CE_NOTE, "ACPI Hot-Plug mode enabled\n"));
- return (1); /* use ACPI mode */
}
-void
+static void
pciehpc_acpi_setup_ops(pciehpc_t *ctrl_p)
{
ctrl_p->ops.init_hpc_hw = pciehpc_acpi_hpc_init;
@@ -752,196 +666,3 @@
return (ret);
}
-
-/*
- * Evaluate _OSC method to use native hot-plug mode if platform supports it.
- * If platform doesn't support native hot-plug then hp_mode will be set
- * to ACPI_HP_MODE.
- */
-ACPI_STATUS
-pciehpc_acpi_eval_osc(ACPI_HANDLE osc_hdl, uint32_t *hp_mode)
-{
- ACPI_STATUS status;
- ACPI_OBJECT_LIST arglist;
- ACPI_OBJECT args[4];
- UINT32 caps_buffer[3];
- ACPI_BUFFER rb;
- UINT32 *rbuf;
-
- /* construct argument list */
- arglist.Count = 4;
- arglist.Pointer = args;
-
- /* arg0 - UUID */
- args[0].Type = ACPI_TYPE_BUFFER;
- args[0].Buffer.Length = 16; /* size of UUID string */
- args[0].Buffer.Pointer = pcie_uuid;
-
- /* arg1 - Revision ID */
- args[1].Type = ACPI_TYPE_INTEGER;
- args[1].Integer.Value = PCIE_OSC_REVISION_ID;
-
- /* arg2 - Count */
- args[2].Type = ACPI_TYPE_INTEGER;
- args[2].Integer.Value = 3; /* no. of DWORDS in caps_buffer */
-
- /* arg3 - Capabilities Buffer */
- args[3].Type = ACPI_TYPE_BUFFER;
- args[3].Buffer.Length = 12;
- args[3].Buffer.Pointer = (void *)caps_buffer;
-
- /* Initialize Capabilities Buffer */
-
- /* DWORD1: no query flag set */
- caps_buffer[0] = 0;
- /* DWORD2: Support Field */
- caps_buffer[1] = OSC_SUPPORT_FIELD_INIT;
- /* DWORD3: Control Field */
- caps_buffer[2] = OSC_CONTROL_FIELD_INIT;
-
- rb.Length = ACPI_ALLOCATE_BUFFER;
- rb.Pointer = NULL;
-
- status = AcpiEvaluateObjectTyped(osc_hdl, NULL, &arglist, &rb,
- ACPI_TYPE_BUFFER);
- if (status != AE_OK) {
- PCIEHPC_DEBUG((CE_CONT,
- "Failed to execute _OSC method (status %d)\n", status));
- return (status);
- }
-
- rbuf = (UINT32 *)((ACPI_OBJECT *)rb.Pointer)->Buffer.Pointer;
-
- /* check the STATUS word in the capability buffer */
- if (rbuf[0] & OSC_STATUS_ERRORS) {
- PCIEHPC_DEBUG((CE_CONT, "_OSC method failed (STATUS %d)\n",
- rbuf[0]));
- AcpiOsFree(rb.Pointer);
- return (AE_ERROR);
- }
-
- PCIEHPC_DEBUG((CE_CONT, "_OSC method evaluation completed: "
- "STATUS 0x%x SUPPORT 0x%x CONTROL 0x%x\n",
- rbuf[0], rbuf[1], rbuf[2]));
-
- /* check if the Native Hot-Plug Control is granted */
- if (rbuf[2] & OSC_CONTROL_PCIE_NAT_HP)
- *hp_mode = NATIVE_HP_MODE;
- else
- *hp_mode = ACPI_HP_MODE;
-
- AcpiOsFree(rb.Pointer);
-
- return (AE_OK);
-}
-
-#ifdef DEBUG
-static void
-pciehpc_dump_acpi_obj(ACPI_HANDLE pcibus_obj)
-{
- int status;
- ACPI_BUFFER retbuf;
-
- if (pcibus_obj == NULL)
- return;
-
- /* print the full path name */
- retbuf.Pointer = NULL;
- retbuf.Length = ACPI_ALLOCATE_BUFFER;
- status = AcpiGetName(pcibus_obj, ACPI_FULL_PATHNAME, &retbuf);
- if (status != AE_OK)
- return;
- cmn_err(CE_CONT, "PCIE BUS PATHNAME: %s\n", (char *)retbuf.Pointer);
- AcpiOsFree(retbuf.Pointer);
-
- /* dump all the methods for this bus node */
- cmn_err(CE_CONT, " METHODS: \n");
- status = AcpiWalkNamespace(ACPI_TYPE_METHOD, pcibus_obj, 1,
- pciehpc_print_acpi_name, " ", NULL);
- /* dump all the child devices */
- status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, pcibus_obj, 1,
- pciehpc_walk_obj_namespace, NULL, NULL);
-}
-
-/*ARGSUSED*/
-static ACPI_STATUS
-pciehpc_walk_obj_namespace(ACPI_HANDLE hdl, uint32_t nl, void *context,
- void **ret)
-{
- int status;
- ACPI_BUFFER retbuf;
- char buf[32];
-
- /* print the full path name */
- retbuf.Pointer = NULL;
- retbuf.Length = ACPI_ALLOCATE_BUFFER;
- status = AcpiGetName(hdl, ACPI_FULL_PATHNAME, &retbuf);
- if (status != AE_OK)
- return (status);
- buf[0] = 0;
- while (nl--)
- (void) strcat(buf, " ");
- cmn_err(CE_CONT, "%sDEVICE: %s\n", buf, (char *)retbuf.Pointer);
- AcpiOsFree(retbuf.Pointer);
-
- /* dump all the methods for this device */
- cmn_err(CE_CONT, "%s METHODS: \n", buf);
- status = AcpiWalkNamespace(ACPI_TYPE_METHOD, hdl, 1,
- pciehpc_print_acpi_name, (void *)buf, NULL);
- return (status);
-}
-
-/*ARGSUSED*/
-static ACPI_STATUS
-pciehpc_print_acpi_name(ACPI_HANDLE hdl, uint32_t nl, void *context, void **ret)
-{
- int status;
- ACPI_BUFFER retbuf;
- char name[16];
-
- retbuf.Pointer = name;
- retbuf.Length = 16;
- status = AcpiGetName(hdl, ACPI_SINGLE_NAME, &retbuf);
- if (status == AE_OK)
- cmn_err(CE_CONT, "%s %s \n", (char *)context, name);
- return (AE_OK);
-}
-
-static void
-print_acpi_pathname(ACPI_HANDLE hdl)
-{
- int status;
- ACPI_BUFFER retbuf;
-
- retbuf.Pointer = NULL;
- retbuf.Length = ACPI_ALLOCATE_BUFFER;
- status = AcpiGetName(hdl, ACPI_FULL_PATHNAME, &retbuf);
- if (status == AE_OK) {
- cmn_err(CE_CONT, "%s \n", (char *)retbuf.Pointer);
- AcpiOsFree(retbuf.Pointer);
- }
-}
-#endif
-
-static ACPI_STATUS
-pciehpc_acpi_find_osc(ACPI_HANDLE busobj, ACPI_HANDLE *osc_hdlp)
-{
- ACPI_HANDLE parentobj = busobj;
- ACPI_STATUS status = AE_NOT_FOUND;
-
- *osc_hdlp = NULL;
-
- /*
- * Walk up the ACPI device tree looking for _OSC method.
- */
- do {
- busobj = parentobj;
- if ((status = AcpiGetHandle(busobj, "_OSC", osc_hdlp)) == AE_OK)
- break;
- } while (AcpiGetParent(busobj, &parentobj) == AE_OK);
-
- if (*osc_hdlp == NULL)
- status = AE_NOT_FOUND;
-
- return (status);
-}
--- a/usr/src/uts/intel/io/hotplug/pciehpc/pciehpc_acpi.h Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/intel/io/hotplug/pciehpc/pciehpc_acpi.h Fri Apr 24 13:17:47 2009 -0700
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _PCIEHPC_ACPI_H
#define _PCIEHPC_ACPI_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -64,48 +62,6 @@
#define PCIEHPC_ACPI_DSM_PRESENT 0x0080
#define PCIEHPC_ACPI_STR_PRESENT 0x0100
-/* revision id of _OSC for PCI/PCI-X/PCI-Exp hierarchy */
-#define PCIE_OSC_REVISION_ID 1 /* defined in PCI fw ver 3.0 */
-
-/*
- * _OSC method Capabilities buffer bit definitions (from PCI FW 3.0)
- */
-/* first DWORD: status from _OSC invocation (except bit 0) */
-#define OSC_STATUS_QUERY_ENABLE 0x1 /* Query Support Flag */
-#define OSC_STATUS_FAILED 0x2 /* _OSC failure */
-#define OSC_STATUS_INV_UUID 0x4 /* invalid UUID */
-#define OSC_STATUS_INV_REVID 0x8 /* invalid revision ID */
-#define OSC_STATUS_CAPS_MASKED 0x10 /* capabilities masked */
-
-#define OSC_STATUS_ERRORS \
- (OSC_STATUS_FAILED | OSC_STATUS_INV_UUID | OSC_STATUS_INV_REVID)
-
-/* second DWORD: Support Field (set by OS) */
-#define OSC_SUPPORT_EXT_PCI_CFG 0x1 /* Extended PCI Config Ops supported */
-#define OSC_SUPPORT_ACT_PM 0x2 /* Active State PM supported */
-#define OSC_SUPPORT_CLK_PM_CAP 0x4 /* Clock PM Capability supported */
-#define OSC_SUPPORT_PCI_SEGS 0x8 /* PCI Segment Groups supported */
-#define OSC_SUPPORT_MSI 0x10 /* MSI supported */
-
-/* third DWORD: Control Field (set by OS/BIOS) */
-#define OSC_CONTROL_PCIE_NAT_HP 0x1 /* PCI Exp Native Hot Plug control */
-#define OSC_CONTROL_SHPC_NAT_HP 0x2 /* SHPC Native Hot Plug control */
-#define OSC_CONTROL_PCIE_NAT_PM 0x4 /* PCI Exp Native Power Mgmt. control */
-#define OSC_CONTROL_PCIE_ADV_ERR 0x8 /* PCIE Advanced Err. rep. control */
-#define OSC_CONTROL_PCIE_CAPS 0x10 /* PCIE Caps Structure control */
-
-#define OSC_CONTROL_FIELD_INIT \
- (OSC_CONTROL_PCIE_NAT_PM | OSC_CONTROL_PCIE_NAT_HP | \
- OSC_CONTROL_PCIE_CAPS | OSC_CONTROL_PCIE_ADV_ERR)
-
-#define OSC_SUPPORT_FIELD_INIT \
- (OSC_SUPPORT_EXT_PCI_CFG | \
- OSC_SUPPORT_ACT_PM | OSC_SUPPORT_CLK_PM_CAP | \
- OSC_SUPPORT_MSI | OSC_SUPPORT_PCI_SEGS)
-
-#define ACPI_HP_MODE 1
-#define NATIVE_HP_MODE 2
-
/* Device status bit as returned by _STA method (see 6.3.7 of ACPI 3.0) */
#define DEV_STS_PRESENT 0x1 /* device is present */
#define DEV_STS_ENABLED 0x2 /* device is enabled */
--- a/usr/src/uts/intel/io/hotplug/pciehpc/pciehpc_x86.c Fri Apr 24 10:24:29 2009 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-#include <sys/note.h>
-#include <sys/kmem.h>
-#include <sys/debug.h>
-#include <sys/vtrace.h>
-#include <sys/autoconf.h>
-#include <sys/varargs.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/pci.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/time.h>
-#include <sys/callb.h>
-#include <sys/hotplug/pci/pciehpc_impl.h>
-
-extern int pciehpc_acpi_hotplug_enabled(dev_info_t *dip);
-extern void pciehpc_acpi_setup_ops(pciehpc_t *ctrl_p);
-
-/*
- * Update ops vector with platform specific (ACPI, CK8-04,...) functions.
- */
-void
-pciehpc_update_ops(pciehpc_t *ctrl_p)
-{
- /* update platform specific (ACPI, CK8-04,...) impl. ops */
- if (pciehpc_acpi_hotplug_enabled(ctrl_p->dip)) {
- /* update ops vector for ACPI mode */
- pciehpc_acpi_setup_ops(ctrl_p);
- ctrl_p->hp_mode = PCIEHPC_ACPI_HP_MODE;
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/intel/io/pciex/pcie_acpi.c Fri Apr 24 13:17:47 2009 -0700
@@ -0,0 +1,314 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+#include <sys/kmem.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sunndi.h>
+#include <sys/promif.h>
+#include <sys/pcie.h>
+#include <sys/pci_cap.h>
+#include <sys/pcie_impl.h>
+#include <sys/pcie_acpi.h>
+#include <sys/acpi/acpi.h>
+#include <sys/acpica.h>
+
+ACPI_STATUS pcie_acpi_eval_osc(dev_info_t *dip, ACPI_HANDLE osc_hdl,
+ uint32_t *osc_flags);
+static ACPI_STATUS pcie_acpi_find_osc(ACPI_HANDLE busobj,
+ ACPI_HANDLE *osc_hdlp);
+
+#ifdef DEBUG
+static void pcie_dump_acpi_obj(ACPI_HANDLE pcibus_obj);
+static ACPI_STATUS pcie_walk_obj_namespace(ACPI_HANDLE hdl, uint32_t nl,
+ void *context, void **ret);
+static ACPI_STATUS pcie_print_acpi_name(ACPI_HANDLE hdl, uint32_t nl,
+ void *context, void **ret);
+#endif /* DEBUG */
+
+void
+pcie_init_plat(dev_info_t *dip)
+{
+ pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
+ bus_p->bus_plat_private =
+ (pcie_x86_priv_t *)kmem_zalloc(sizeof (pcie_x86_priv_t), KM_SLEEP);
+}
+
+void
+pcie_fini_plat(dev_info_t *dip)
+{
+ pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
+
+ kmem_free(bus_p->bus_plat_private, sizeof (pcie_x86_priv_t));
+}
+
+int
+pcie_acpi_osc(dev_info_t *dip, uint32_t *osc_flags)
+{
+ ACPI_HANDLE pcibus_obj;
+ int status = AE_ERROR;
+ ACPI_HANDLE osc_hdl;
+ pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
+ pcie_x86_priv_t *osc_p = (pcie_x86_priv_t *)bus_p->bus_plat_private;
+
+ /* Mark this so we know _OSC has been called for this device */
+ osc_p->bus_osc = B_TRUE;
+
+ /*
+ * (1) Find the ACPI device node for this bus node.
+ */
+ status = acpica_get_handle(dip, &pcibus_obj);
+ if (status != AE_OK) {
+ PCIE_DBG("No ACPI device found (dip %p)\n", (void *)dip);
+ return (DDI_FAILURE);
+ }
+
+ /*
+ * (2) Check if _OSC method is present.
+ */
+ if (pcie_acpi_find_osc(pcibus_obj, &osc_hdl) != AE_OK) {
+ /* no _OSC method present */
+ PCIE_DBG("no _OSC method present for dip %p\n",
+ (void *)dip);
+ return (DDI_FAILURE);
+ }
+
+ /*
+ * (3) _OSC method exists; evaluate _OSC.
+ */
+ if (pcie_acpi_eval_osc(dip, osc_hdl, osc_flags) != AE_OK) {
+ PCIE_DBG("Failed to evaluate _OSC method for dip 0x%p\n",
+ (void *)dip);
+ return (DDI_FAILURE);
+ }
+
+ osc_p->bus_osc_hp = (*osc_flags & OSC_CONTROL_PCIE_NAT_HP) ?
+ B_TRUE : B_FALSE;
+ osc_p->bus_osc_aer = (*osc_flags & OSC_CONTROL_PCIE_ADV_ERR) ?
+ B_TRUE : B_FALSE;
+
+#ifdef DEBUG
+ if (pcie_debug_flags > 1)
+ pcie_dump_acpi_obj(pcibus_obj);
+#endif /* DEBUG */
+
+ return (DDI_SUCCESS);
+}
+
+static ACPI_STATUS
+pcie_acpi_find_osc(ACPI_HANDLE busobj, ACPI_HANDLE *osc_hdlp)
+{
+ ACPI_HANDLE parentobj = busobj;
+ ACPI_STATUS status = AE_NOT_FOUND;
+
+ *osc_hdlp = NULL;
+
+ /*
+ * Walk up the ACPI device tree looking for _OSC method.
+ */
+ do {
+ busobj = parentobj;
+ if ((status = AcpiGetHandle(busobj, "_OSC", osc_hdlp)) == AE_OK)
+ break;
+ } while (AcpiGetParent(busobj, &parentobj) == AE_OK);
+
+ if (*osc_hdlp == NULL)
+ status = AE_NOT_FOUND;
+
+ return (status);
+}
+
+/* UUID for for PCI/PCI-X/PCI-Exp hierarchy as defined in PCI fw ver 3.0 */
+static uint8_t pcie_uuid[16] =
+ {0x5b, 0x4d, 0xdb, 0x33, 0xf7, 0x1f, 0x1c, 0x40,
+ 0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66};
+
+/*
+ * Evaluate _OSC method.
+ */
+ACPI_STATUS
+pcie_acpi_eval_osc(dev_info_t *dip, ACPI_HANDLE osc_hdl, uint32_t *osc_flags)
+{
+ ACPI_STATUS status;
+ ACPI_OBJECT_LIST arglist;
+ ACPI_OBJECT args[4];
+ UINT32 caps_buffer[3];
+ ACPI_BUFFER rb;
+ UINT32 *rbuf;
+ UINT32 tmp_ctrl;
+
+ /* construct argument list */
+ arglist.Count = 4;
+ arglist.Pointer = args;
+
+ /* arg0 - UUID */
+ args[0].Type = ACPI_TYPE_BUFFER;
+ args[0].Buffer.Length = 16; /* size of UUID string */
+ args[0].Buffer.Pointer = pcie_uuid;
+
+ /* arg1 - Revision ID */
+ args[1].Type = ACPI_TYPE_INTEGER;
+ args[1].Integer.Value = PCIE_OSC_REVISION_ID;
+
+ /* arg2 - Count */
+ args[2].Type = ACPI_TYPE_INTEGER;
+ args[2].Integer.Value = 3; /* no. of DWORDS in caps_buffer */
+
+ /* arg3 - Capabilities Buffer */
+ args[3].Type = ACPI_TYPE_BUFFER;
+ args[3].Buffer.Length = 12;
+ args[3].Buffer.Pointer = (void *)caps_buffer;
+
+ /* Initialize Capabilities Buffer */
+
+ /* DWORD1: no query flag set */
+ caps_buffer[0] = 0;
+ /* DWORD2: Support Field */
+ caps_buffer[1] = OSC_SUPPORT_FIELD_INIT;
+ /* DWORD3: Control Field */
+ caps_buffer[2] = OSC_CONTROL_FIELD_INIT;
+
+ /* If hotplug is supported add the corresponding control fields */
+ if (*osc_flags & OSC_CONTROL_PCIE_NAT_HP)
+ caps_buffer[2] |= (OSC_CONTROL_PCIE_NAT_HP |
+ OSC_CONTROL_PCIE_NAT_PM);
+
+ tmp_ctrl = caps_buffer[2];
+ rb.Length = ACPI_ALLOCATE_BUFFER;
+ rb.Pointer = NULL;
+
+ status = AcpiEvaluateObjectTyped(osc_hdl, NULL, &arglist, &rb,
+ ACPI_TYPE_BUFFER);
+ if (status != AE_OK) {
+ PCIE_DBG("Failed to execute _OSC method (status %d)\n",
+ status);
+ return (status);
+ }
+
+ /* LINTED pointer alignment */
+ rbuf = (UINT32 *)((ACPI_OBJECT *)rb.Pointer)->Buffer.Pointer;
+
+ /* check the STATUS word in the capability buffer */
+ if (rbuf[0] & OSC_STATUS_ERRORS) {
+ PCIE_DBG("_OSC method failed (STATUS %d)\n", rbuf[0]);
+ AcpiOsFree(rb.Pointer);
+ return (AE_ERROR);
+ }
+
+ *osc_flags = rbuf[2];
+
+ PCIE_DBG("_OSC method evaluation completed for 0x%p: "
+ "STATUS 0x%x SUPPORT 0x%x CONTROL req 0x%x, CONTROL ret 0x%x\n",
+ (void *)dip, rbuf[0], rbuf[1], tmp_ctrl, rbuf[2]);
+
+ AcpiOsFree(rb.Pointer);
+
+ return (AE_OK);
+}
+
+/*
+ * Checks if _OSC method has been called for this device.
+ */
+boolean_t
+pcie_is_osc(dev_info_t *dip)
+{
+ pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
+ pcie_x86_priv_t *osc_p = (pcie_x86_priv_t *)bus_p->bus_plat_private;
+ return (osc_p->bus_osc);
+}
+
+#ifdef DEBUG
+static void
+pcie_dump_acpi_obj(ACPI_HANDLE pcibus_obj)
+{
+ int status;
+ ACPI_BUFFER retbuf;
+
+ if (pcibus_obj == NULL)
+ return;
+
+ /* print the full path name */
+ retbuf.Pointer = NULL;
+ retbuf.Length = ACPI_ALLOCATE_BUFFER;
+ status = AcpiGetName(pcibus_obj, ACPI_FULL_PATHNAME, &retbuf);
+ if (status != AE_OK)
+ return;
+ PCIE_DBG("PCIE BUS PATHNAME: %s\n", (char *)retbuf.Pointer);
+ AcpiOsFree(retbuf.Pointer);
+
+ /* dump all the methods for this bus node */
+ PCIE_DBG(" METHODS: \n");
+ status = AcpiWalkNamespace(ACPI_TYPE_METHOD, pcibus_obj, 1,
+ pcie_print_acpi_name, " ", NULL);
+ /* dump all the child devices */
+ status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, pcibus_obj, 1,
+ pcie_walk_obj_namespace, NULL, NULL);
+}
+
+/*ARGSUSED*/
+static ACPI_STATUS
+pcie_walk_obj_namespace(ACPI_HANDLE hdl, uint32_t nl, void *context,
+ void **ret)
+{
+ int status;
+ ACPI_BUFFER retbuf;
+ char buf[32];
+
+ /* print the full path name */
+ retbuf.Pointer = NULL;
+ retbuf.Length = ACPI_ALLOCATE_BUFFER;
+ status = AcpiGetName(hdl, ACPI_FULL_PATHNAME, &retbuf);
+ if (status != AE_OK)
+ return (status);
+ buf[0] = 0;
+ while (nl--)
+ (void) strcat(buf, " ");
+ PCIE_DBG("%sDEVICE: %s\n", buf, (char *)retbuf.Pointer);
+ AcpiOsFree(retbuf.Pointer);
+
+ /* dump all the methods for this device */
+ PCIE_DBG("%s METHODS: \n", buf);
+ status = AcpiWalkNamespace(ACPI_TYPE_METHOD, hdl, 1,
+ pcie_print_acpi_name, (void *)buf, NULL);
+ return (status);
+}
+
+/*ARGSUSED*/
+static ACPI_STATUS
+pcie_print_acpi_name(ACPI_HANDLE hdl, uint32_t nl, void *context, void **ret)
+{
+ int status;
+ ACPI_BUFFER retbuf;
+ char name[16];
+
+ retbuf.Pointer = name;
+ retbuf.Length = 16;
+ status = AcpiGetName(hdl, ACPI_SINGLE_NAME, &retbuf);
+ if (status == AE_OK)
+ PCIE_DBG("%s %s \n", (char *)context, name);
+ return (AE_OK);
+}
+#endif /* DEBUG */
--- a/usr/src/uts/intel/io/pciex/pcie_pci.c Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/intel/io/pciex/pcie_pci.c Fri Apr 24 13:17:47 2009 -0700
@@ -44,6 +44,7 @@
#include <sys/pcie.h>
#include <sys/pci_cap.h>
#include <sys/pcie_impl.h>
+#include <sys/pcie_acpi.h>
#include <sys/hotplug/pci/pcihp.h>
#include <sys/hotplug/pci/pciehpc.h>
#include <sys/hotplug/hpctrl.h>
@@ -305,8 +306,8 @@
int instance, intr_types, fmcap;
char device_type[8];
pepb_devstate_t *pepb;
- ddi_acc_handle_t config_handle;
pcie_bus_t *bus_p = PCIE_DIP2UPBUS(devi);
+ ddi_acc_handle_t config_handle = bus_p->bus_cfg_hdl;
switch (cmd) {
case DDI_RESUME:
@@ -370,54 +371,6 @@
DDI_PROP_DONTPASS, "pci-hotplug-type", INBAND_HPC_NONE);
/*
- * Initialize interrupt handlers.
- */
- if (ddi_intr_get_supported_types(devi, &intr_types) != DDI_SUCCESS)
- goto next_step;
-
- PEPB_DEBUG((CE_NOTE, "%s#%d: intr_types = 0x%x\n",
- ddi_driver_name(devi), ddi_get_instance(devi), intr_types));
-
- if (pepb_msi_intr_supported(devi, intr_types) == DDI_SUCCESS) {
- if (pepb_intr_init(pepb, DDI_INTR_TYPE_MSI) == DDI_SUCCESS)
- goto next_step;
- else
- PEPB_DEBUG((CE_WARN,
- "%s#%d: Unable to attach MSI handler",
- ddi_driver_name(devi), ddi_get_instance(devi)));
- }
-
- /*
- * If we are here that means MSIs were not enabled. For errors fall back
- * to the SERR+Machinecheck approach on Intel chipsets.
- */
- if (PCIE_IS_RP(bus_p))
- pepb->pepb_no_aer_msi = B_TRUE;
-
- /*
- * Only register hotplug interrupts for now.
- * Check if device supports PCIe hotplug or not?
- * If yes, register fixed interrupts if ILINE is valid.
- * Fix error handling for INTx.
- */
- if (pepb->inband_hpc == INBAND_HPC_PCIE) {
- uint8_t iline;
-
- (void) pci_config_setup(devi, &config_handle);
- iline = pci_config_get8(config_handle, PCI_CONF_ILINE);
- pci_config_teardown(&config_handle);
-
- if (iline == 0 || iline > 15)
- goto next_step;
-
- if (pepb_intr_init(pepb, DDI_INTR_TYPE_FIXED) != DDI_SUCCESS)
- PEPB_DEBUG((CE_WARN,
- "%s#%d: Unable to attach INTx handler",
- ddi_driver_name(devi), ddi_get_instance(devi)));
- }
-
-next_step:
- /*
* Initialize hotplug support on this bus. At minimum
* (for non hotplug bus) this would create ":devctl" minor
* node to support DEVCTL_DEVICE_* and DEVCTL_BUS_* ioctls
@@ -439,6 +392,71 @@
}
}
+ /*
+ * Call _OSC method for 2 reasons:
+ * 1. Hotplug: To determine if it is native or ACPI mode.
+ *
+ * 2. Error handling: Inform firmware that OS can support AER error
+ * handling. Currently we don't care for what the BIOS response was
+ * and instead setup interrupts for error handling as if it were
+ * supported.
+ *
+ * For hotpluggable slots the _OSC method has already been called as
+ * part of the hotplug initialization above.
+ * For non-hotpluggable slots we need to call the _OSC method only for
+ * Root Ports (for AER support).
+ */
+ if (!pcie_is_osc(devi) && PCIE_IS_RP(bus_p) && PCIE_HAS_AER(bus_p)) {
+ uint32_t osc_flags = OSC_CONTROL_PCIE_ADV_ERR;
+ (void) pcie_acpi_osc(devi, &osc_flags);
+ }
+
+ /*
+ * Initialize interrupt handlers.
+ */
+ if (ddi_intr_get_supported_types(devi, &intr_types) != DDI_SUCCESS)
+ goto next_step;
+
+ PEPB_DEBUG((CE_NOTE, "%s#%d: intr_types = 0x%x\n",
+ ddi_driver_name(devi), ddi_get_instance(devi), intr_types));
+
+ if (pepb_msi_intr_supported(devi, intr_types) == DDI_SUCCESS) {
+ if (pepb_intr_init(pepb, DDI_INTR_TYPE_MSI) == DDI_SUCCESS)
+ goto next_step;
+ else
+ PEPB_DEBUG((CE_WARN,
+ "%s#%d: Unable to attach MSI handler",
+ ddi_driver_name(devi), ddi_get_instance(devi)));
+ }
+
+ /*
+ * If we are here that means MSIs were not enabled. For errors fall back
+ * to the SERR+Machinecheck approach on certain Intel chipsets.
+ */
+ if (PCIE_IS_RP(bus_p))
+ pepb->pepb_no_aer_msi = B_TRUE;
+
+ /*
+ * Only register hotplug interrupts for now.
+ * Check if device supports PCIe hotplug or not?
+ * If yes, register fixed interrupts if ILINE is valid.
+ * Fix error handling for INTx.
+ */
+ if (pepb->inband_hpc == INBAND_HPC_PCIE) {
+ uint8_t iline;
+
+ iline = pci_config_get8(config_handle, PCI_CONF_ILINE);
+
+ if (iline == 0 || iline > 15)
+ goto next_step;
+
+ if (pepb_intr_init(pepb, DDI_INTR_TYPE_FIXED) != DDI_SUCCESS)
+ PEPB_DEBUG((CE_WARN,
+ "%s#%d: Unable to attach INTx handler",
+ ddi_driver_name(devi), ddi_get_instance(devi)));
+ }
+
+next_step:
/* Must apply workaround only after all initialization is done */
pepb_intel_serr_workaround(devi, pepb->pepb_no_aer_msi);
pepb_intel_rber_workaround(devi);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/intel/sys/pcie_acpi.h Fri Apr 24 13:17:47 2009 -0700
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_PCIE_ACPI_H
+#define _SYS_PCIE_ACPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* revision id of _OSC for PCI/PCI-X/PCI-Exp hierarchy */
+#define PCIE_OSC_REVISION_ID 1 /* defined in PCI fw ver 3.0 */
+
+/*
+ * _OSC method Capabilities buffer bit definitions (from PCI FW 3.0)
+ */
+/* first DWORD: status from _OSC invocation (except bit 0) */
+#define OSC_STATUS_QUERY_ENABLE 0x1 /* Query Support Flag */
+#define OSC_STATUS_FAILED 0x2 /* _OSC failure */
+#define OSC_STATUS_INV_UUID 0x4 /* invalid UUID */
+#define OSC_STATUS_INV_REVID 0x8 /* invalid revision ID */
+#define OSC_STATUS_CAPS_MASKED 0x10 /* capabilities masked */
+
+#define OSC_STATUS_ERRORS \
+ (OSC_STATUS_FAILED | OSC_STATUS_INV_UUID | OSC_STATUS_INV_REVID)
+
+/* second DWORD: Support Field (set by OS) */
+#define OSC_SUPPORT_EXT_PCI_CFG 0x1 /* Extended PCI Config Ops supported */
+#define OSC_SUPPORT_ACT_PM 0x2 /* Active State PM supported */
+#define OSC_SUPPORT_CLK_PM_CAP 0x4 /* Clock PM Capability supported */
+#define OSC_SUPPORT_PCI_SEGS 0x8 /* PCI Segment Groups supported */
+#define OSC_SUPPORT_MSI 0x10 /* MSI supported */
+
+/* third DWORD: Control Field (set by OS/BIOS) */
+#define OSC_CONTROL_PCIE_NAT_HP 0x1 /* PCI Exp Native Hot Plug control */
+#define OSC_CONTROL_SHPC_NAT_HP 0x2 /* SHPC Native Hot Plug control */
+#define OSC_CONTROL_PCIE_NAT_PM 0x4 /* PCI Exp Native Power Mgmt. control */
+#define OSC_CONTROL_PCIE_ADV_ERR 0x8 /* PCIE Advanced Err. rep. control */
+#define OSC_CONTROL_PCIE_CAPS 0x10 /* PCIE Caps Structure control */
+
+#define OSC_CONTROL_FIELD_INIT \
+ (OSC_CONTROL_PCIE_CAPS | OSC_CONTROL_PCIE_ADV_ERR)
+
+#define OSC_SUPPORT_FIELD_INIT \
+ (OSC_SUPPORT_EXT_PCI_CFG | \
+ OSC_SUPPORT_ACT_PM | OSC_SUPPORT_CLK_PM_CAP | \
+ OSC_SUPPORT_MSI | OSC_SUPPORT_PCI_SEGS)
+
+typedef struct pcie_x86_priv {
+ /* _OSC related */
+ boolean_t bus_osc; /* Has _OSC method been called */
+ boolean_t bus_osc_hp; /* Was native HP control granted */
+ boolean_t bus_osc_aer; /* Was AER control granted */
+} pcie_x86_priv_t;
+
+extern int pcie_acpi_osc(dev_info_t *dip, uint32_t *osc_flags);
+extern boolean_t pcie_is_osc(dev_info_t *dip);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_PCIE_ACPI_H */
--- a/usr/src/uts/sparc/Makefile.files Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/sparc/Makefile.files Fri Apr 24 13:17:47 2009 -0700
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# This Makefile defines all file modules and build rules for the
@@ -65,6 +65,7 @@
CPR_SPARC_OBJS += cpr_sparc.o
PCI_PCI_OBJS += pci_pci.o pci_debug.o pci_pwr.o pcix.o
PX_PCI_OBJS += px_pci.o pcie_pwr.o
+PCIE_MISC_OBJS += pcie_plat.o
FCODE_OBJS += fcode.o
NSKERN_OBJS += nsc_asm.o
--- a/usr/src/uts/sparc/Makefile.rules Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/sparc/Makefile.rules Fri Apr 24 13:17:47 2009 -0700
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# This Makefile defines all file modules and build rules for the
@@ -48,6 +48,10 @@
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(UTSBASE)/sparc/io/pciex/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
$(OBJS_DIR)/%.o: $(UTSBASE)/sparc/fpu/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -101,6 +105,9 @@
$(LINTS_DIR)/%.ln: $(UTSBASE)/sparc/io/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(LINTS_DIR)/%.ln: $(UTSBASE)/sparc/io/pciex/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
$(LINTS_DIR)/%.ln: $(UTSBASE)/sparc/fpu/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sparc/io/pciex/pcie_plat.c Fri Apr 24 13:17:47 2009 -0700
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/types.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sunndi.h>
+#include <sys/pcie_impl.h>
+
+/* ARGSUSED */
+void
+pcie_init_plat(dev_info_t *dip)
+{
+}
+
+/* ARGSUSED */
+void
+pcie_fini_plat(dev_info_t *dip)
+{
+}
--- a/usr/src/uts/sparc/pcie/Makefile Fri Apr 24 10:24:29 2009 -0700
+++ b/usr/src/uts/sparc/pcie/Makefile Fri Apr 24 13:17:47 2009 -0700
@@ -20,10 +20,9 @@
#
#
# uts/sparc/pcie/Makefile
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
#
# This makefile drives the production of the PCIE driver kernel module.
#
@@ -39,8 +38,8 @@
# Define the module and object file sets.
#
MODULE = pcie
-OBJECTS = $(PCIE_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(PCIE_OBJS:%.o=$(LINTS_DIR)/%.ln)
+OBJECTS = $(PCIE_MISC_OBJS:%=$(OBJS_DIR)/%)
+LINTS = $(PCIE_MISC_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE)
#