summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel/io')
-rw-r--r--usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c77
-rw-r--r--usr/src/uts/intel/io/pci/pci_boot.c49
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_nvidia.c30
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_pci.c74
4 files changed, 70 insertions, 160 deletions
diff --git a/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c b/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c
index 08ab16924b..7ca5da0bb4 100644
--- a/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c
+++ b/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c
@@ -35,6 +35,7 @@
#include <sys/autoconf.h>
#include <sys/hwconf.h>
#include <sys/pcie.h>
+#include <sys/pci_cap.h>
#include <sys/ddi.h>
#include <sys/sunndi.h>
#include <sys/hotplug/pci/pcicfg.h>
@@ -2859,8 +2860,8 @@ static int
pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
uint8_t pcie_dev)
{
- int ret, cap_id_loc;
- uint16_t val;
+ int ret;
+ uint16_t cap_id_loc, val;
uint32_t wordval;
uint8_t byteval;
@@ -2985,28 +2986,14 @@ pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
return (ret);
}
}
- if ((cap_id_loc = pcicfg_get_cap(config_handle, PCI_CAP_ID_PCIX)) > 0) {
- /* create the pcix-capid-pointer property */
- if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcix-capid-pointer", cap_id_loc)) != DDI_SUCCESS)
- return (ret);
- }
- if (pcie_dev && (cap_id_loc = pcicfg_get_cap(config_handle,
- PCI_CAP_ID_PCI_E)) > 0) {
- /* create the pcie-capid-pointer property */
- if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcie-capid-pointer", cap_id_loc)) != DDI_SUCCESS)
- return (ret);
+ (void) PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E, &cap_id_loc);
+ if (pcie_dev && cap_id_loc != PCI_CAP_NEXT_PTR_NULL) {
val = pci_config_get16(config_handle, cap_id_loc +
PCIE_PCIECAP) & PCIE_PCIECAP_SLOT_IMPL;
/* if slot implemented, get physical slot number */
if (val) {
wordval = pci_config_get32(config_handle, cap_id_loc +
PCIE_SLOTCAP);
- /* create the slotcap-reg property */
- if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE,
- dip, "pcie-slotcap-reg", wordval)) != DDI_SUCCESS)
- return (ret);
/* create the property only if slotnum set correctly? */
if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
"physical-slot#", PCIE_SLOTCAP_PHY_SLOT_NUM(
@@ -4496,61 +4483,24 @@ debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3,
}
#endif
-/*
- * given a cap_id, return its cap_id location in config space
- */
-static int
-pcicfg_get_cap(ddi_acc_handle_t config_handle, uint8_t cap_id)
-{
- uint8_t curcap;
- uint_t cap_id_loc;
- uint16_t status;
- int location = -1;
-
- /*
- * Need to check the Status register for ECP support first.
- * Also please note that for type 1 devices, the
- * offset could change. Should support type 1 next.
- */
- status = pci_config_get16(config_handle, PCI_CONF_STAT);
- if (!(status & PCI_STAT_CAP)) {
- return (-1);
- }
- cap_id_loc = pci_config_get8(config_handle, PCI_CONF_CAP_PTR);
-
- /* Walk the list of capabilities */
- while (cap_id_loc) {
-
- curcap = pci_config_get8(config_handle, cap_id_loc);
-
- if (curcap == cap_id) {
- location = cap_id_loc;
- break;
- }
- cap_id_loc = pci_config_get8(config_handle,
- cap_id_loc + 1);
- }
- return (location);
-}
-
/*ARGSUSED*/
static uint8_t
pcicfg_get_nslots(dev_info_t *dip, ddi_acc_handle_t handle)
{
- int cap_id_loc;
+ uint16_t cap_id_loc, slot_id_loc;
uint8_t num_slots = 0;
/* just depend on the pcie_cap for now. */
- if ((cap_id_loc = pcicfg_get_cap(handle, PCI_CAP_ID_PCI_E))
- > 0) {
+ (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_id_loc);
+ (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &slot_id_loc);
+ if (cap_id_loc != PCI_CAP_NEXT_PTR_NULL) {
if (pci_config_get8(handle, cap_id_loc +
PCI_CAP_ID_REGS_OFF) &
PCIE_PCIECAP_SLOT_IMPL)
num_slots = 1;
} else /* not a PCIe switch/bridge. Must be a PCI-PCI[-X] bridge */
- if ((cap_id_loc = pcicfg_get_cap(handle, PCI_CAP_ID_SLOT_ID))
- > 0) {
- uint8_t esr_reg = pci_config_get8(handle, cap_id_loc + 2);
+ if (slot_id_loc != PCI_CAP_NEXT_PTR_NULL) {
+ uint8_t esr_reg = pci_config_get8(handle, slot_id_loc + 2);
num_slots = PCI_CAPSLOT_NSLOTS(esr_reg);
}
/* XXX - need to cover PCI-PCIe bridge with n slots */
@@ -4608,10 +4558,11 @@ static int
pcicfg_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
{
int port_type = -1;
- int cap_loc;
+ uint16_t cap_loc;
/* Note: need to look at the port type information here */
- if ((cap_loc = pcicfg_get_cap(handle, PCI_CAP_ID_PCI_E)) > 0)
+ (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_loc);
+ if (cap_loc != PCI_CAP_NEXT_PTR_NULL)
port_type = pci_config_get16(handle,
cap_loc + PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
diff --git a/usr/src/uts/intel/io/pci/pci_boot.c b/usr/src/uts/intel/io/pci/pci_boot.c
index 761c8f9499..05cf1aecdd 100644
--- a/usr/src/uts/intel/io/pci/pci_boot.c
+++ b/usr/src/uts/intel/io/pci/pci_boot.c
@@ -98,12 +98,14 @@ static void process_devfunc(uchar_t, uchar_t, uchar_t, uchar_t,
static void add_compatible(dev_info_t *, ushort_t, ushort_t,
ushort_t, ushort_t, uchar_t, uint_t, int);
static int add_reg_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int, int);
-static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int);
+static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int,
+ ushort_t);
static void add_model_prop(dev_info_t *, uint_t);
static void add_bus_range_prop(int);
static void add_bus_slot_names_prop(int);
static void add_ppb_ranges_prop(int);
static void add_bus_available_prop(int);
+static int get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id);
static void fix_ppb_res(uchar_t, boolean_t);
static void alloc_res_array();
static void create_ioapic_node(int bus, int dev, int fn, ushort_t vendorid,
@@ -591,6 +593,40 @@ get_parbus_mem_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align)
}
/*
+ * given a cap_id, return its cap_id location in config space
+ */
+static int
+get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id)
+{
+ uint8_t curcap, cap_id_loc;
+ uint16_t status;
+ int location = -1;
+
+ /*
+ * Need to check the Status register for ECP support first.
+ * Also please note that for type 1 devices, the
+ * offset could change. Should support type 1 next.
+ */
+ status = pci_getw(bus, dev, func, PCI_CONF_STAT);
+ if (!(status & PCI_STAT_CAP)) {
+ return (-1);
+ }
+ cap_id_loc = pci_getb(bus, dev, func, PCI_CONF_CAP_PTR);
+
+ /* Walk the list of capabilities */
+ while (cap_id_loc && cap_id_loc != (uint8_t)-1) {
+ curcap = pci_getb(bus, dev, func, cap_id_loc);
+
+ if (curcap == cap_id) {
+ location = cap_id_loc;
+ break;
+ }
+ cap_id_loc = pci_getb(bus, dev, func, cap_id_loc + 1);
+ }
+ return (location);
+}
+
+/*
* Assign valid resources to unconfigured pci(e) bridges. We are trying
* to reprogram the bridge when its
* i) SECBUS == SUBBUS ||
@@ -641,9 +677,8 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
/*
* If pcie bridge, check to see if link is enabled
*/
- cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
- if (cap_ptr != PCI_CAP_NEXT_PTR_NULL) {
+ cap_ptr = get_pci_cap(bus, dev, func, PCI_CAP_ID_PCI_E);
+ if (cap_ptr != -1) {
cmd_reg = pci_getw(bus, dev, func,
(uint16_t)cap_ptr + PCIE_LINKCTL);
if (cmd_reg & PCIE_LINKCTL_LINK_DISABLE) {
@@ -1505,7 +1540,7 @@ process_devfunc(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header,
set_devpm_d0(bus, dev, func);
if ((basecl == PCI_CLASS_BRIDGE) && (subcl == PCI_BRIDGE_PCI))
- add_ppb_props(dip, bus, dev, func, pciex);
+ add_ppb_props(dip, bus, dev, func, pciex, is_pci_bridge);
else {
/*
* Record the non-PPB devices on the bus for possible
@@ -2175,7 +2210,7 @@ done:
static void
add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
- int pciex)
+ int pciex, ushort_t is_pci_bridge)
{
char *dev_type;
int i;
@@ -2206,7 +2241,7 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
pci_bus_res[secbus].dip = dip;
pci_bus_res[secbus].par_bus = bus;
- dev_type = pciex ? "pciex" : "pci";
+ dev_type = (pciex && !is_pci_bridge) ? "pciex" : "pci";
/* setup bus number hierarchy */
pci_bus_res[secbus].sub_bus = subbus;
diff --git a/usr/src/uts/intel/io/pciex/pcie_nvidia.c b/usr/src/uts/intel/io/pciex/pcie_nvidia.c
index 23f3993b9f..b419d2dd81 100644
--- a/usr/src/uts/intel/io/pciex/pcie_nvidia.c
+++ b/usr/src/uts/intel/io/pciex/pcie_nvidia.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Library file that has code for PCIe booting
*/
@@ -67,10 +65,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
capsp &= PCI_CAP_PTR_MASK;
cap = (*pci_getb_func)(bus, dev, func, capsp);
- if (cap == PCI_CAP_ID_PCIX && cdip)
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
- "pcix-capid-pointer", capsp);
-
if (cap == PCI_CAP_ID_PCI_E) {
#ifdef DEBUG
if (pci_boot_debug)
@@ -86,7 +80,7 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
* device is a PCIe2PCI bridge
*/
*is_pci_bridge =
- ((status & PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) ==
+ ((status & PCIE_PCIECAP_DEV_TYPE_MASK) ==
PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) ? 1 : 0;
/*
@@ -100,11 +94,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
*slot_number =
PCIE_SLOTCAP_PHY_SLOT_NUM(slot_cap);
- if (cdip)
- (void) ndi_prop_update_int(
- DDI_DEV_T_NONE, cdip,
- "pcie-slotcap-reg", slot_cap);
-
/* Is PCI Express HotPlug capability set? */
if (cdip &&
(slot_cap & PCIE_SLOTCAP_HP_CAPABLE)) {
@@ -115,21 +104,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
}
}
- /*
- * Can only do I/O based config space access at
- * this early stage. Meaning, one cannot access
- * extended config space i.e. > 256 bytes.
- * So, AER cap_id property will be created much later.
- */
- if (cdip) {
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
- "pcie-capid-reg",
- (*pci_getw_func)(bus, dev, func,
- capsp + PCIE_PCIECAP));
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
- "pcie-capid-pointer", capsp);
- }
-
found_pciex = B_TRUE;
}
diff --git a/usr/src/uts/intel/io/pciex/pcie_pci.c b/usr/src/uts/intel/io/pciex/pcie_pci.c
index 918460302d..0da90e8b76 100644
--- a/usr/src/uts/intel/io/pciex/pcie_pci.c
+++ b/usr/src/uts/intel/io/pciex/pcie_pci.c
@@ -211,7 +211,6 @@ typedef struct {
kmutex_t pepb_peek_poke_mutex;
boolean_t pepb_no_aer_msi;
ddi_iblock_cookie_t pepb_fm_ibc;
- int port_type;
} pepb_devstate_t;
/* soft state flags */
@@ -245,9 +244,7 @@ static void pepb_uninitchild(dev_info_t *);
static int pepb_initchild(dev_info_t *child);
static void pepb_save_config_regs(pepb_devstate_t *pepb_p);
static void pepb_restore_config_regs(pepb_devstate_t *pepb_p);
-static int pepb_pcie_device_type(dev_info_t *dip, int *port_type);
-static int pepb_pcie_port_type(dev_info_t *dip,
- ddi_acc_handle_t config_handle);
+static boolean_t pepb_is_pcie_device_type(dev_info_t *dip);
/* interrupt related declarations */
static int pepb_msi_intr_supported(dev_info_t *, int intr_type);
@@ -360,7 +357,7 @@ pepb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
/*
* Make sure the "device_type" property exists.
*/
- if (pepb_pcie_device_type(devi, &pepb->port_type) == DDI_SUCCESS)
+ if (pepb_is_pcie_device_type(devi))
(void) strcpy(device_type, "pciex");
else
(void) strcpy(device_type, "pci");
@@ -547,7 +544,7 @@ pepb_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
case DDI_CTLOPS_PEEK:
case DDI_CTLOPS_POKE:
- if (pepb->port_type != PCIE_PCIECAP_DEV_TYPE_ROOT)
+ if (!PCIE_IS_RP(PCIE_DIP2BUS(dip)))
return (ddi_ctlops(dip, rdip, ctlop, arg, result));
return (pci_peekpoke_check(dip, rdip, ctlop, arg, result,
ddi_ctlops, &pepb->pepb_err_mutex,
@@ -865,29 +862,15 @@ pepb_restore_config_regs(pepb_devstate_t *pepb_p)
}
}
-static int
-pepb_pcie_device_type(dev_info_t *dip, int *port_type)
+static boolean_t
+pepb_is_pcie_device_type(dev_info_t *dip)
{
- ddi_acc_handle_t handle;
-
- if (pci_config_setup(dip, &handle) != DDI_SUCCESS)
- return (DDI_FAILURE);
- *port_type = pepb_pcie_port_type(dip, handle);
- pci_config_teardown(&handle);
-
- /* No PCIe CAP regs, we are not PCIe device_type */
- if (*port_type < 0)
- return (DDI_FAILURE);
+ pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
- /* check for all PCIe device_types */
- if ((*port_type == PCIE_PCIECAP_DEV_TYPE_UP) ||
- (*port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) ||
- (*port_type == PCIE_PCIECAP_DEV_TYPE_ROOT) ||
- (*port_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE))
- return (DDI_SUCCESS);
-
- return (DDI_FAILURE);
+ if (PCIE_IS_SW(bus_p) || PCIE_IS_RP(bus_p) || PCIE_IS_PCI2PCIE(bus_p))
+ return (B_TRUE);
+ return (B_FALSE);
}
/*
@@ -1183,20 +1166,6 @@ pepb_msi_intr_supported(dev_info_t *dip, int intr_type)
return (DDI_SUCCESS);
}
-static int
-pepb_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
-{
- uint_t cap_loc;
-
- /* Need to look at the port type information here */
- cap_loc = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
-
- return (cap_loc == PCI_CAP_NEXT_PTR_NULL ? -1 :
- pci_config_get16(handle, cap_loc + PCIE_PCIECAP) &
- PCIE_PCIECAP_DEV_TYPE_MASK);
-}
-
/*ARGSUSED*/
int
pepb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
@@ -1214,24 +1183,8 @@ pepb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
static int
pepb_check_slot_disabled(dev_info_t *dip)
{
- int rval = 0;
- uint8_t pcie_cap_ptr;
- ddi_acc_handle_t config_handle;
-
- if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS)
- return (rval);
-
- pcie_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
-
- if (pcie_cap_ptr != PCI_CAP_NEXT_PTR_NULL) {
- if (pci_config_get16(config_handle,
- pcie_cap_ptr + PCIE_LINKCTL) & PCIE_LINKCTL_LINK_DISABLE)
- rval = 1;
- }
-
- pci_config_teardown(&config_handle);
- return (rval);
+ return ((PCIE_CAP_GET(16, PCIE_DIP2BUS(dip), PCIE_LINKCTL) &
+ PCIE_LINKCTL_LINK_DISABLE) ? 1 : 0);
}
static int
@@ -1682,15 +1635,12 @@ static void
pepb_intel_sw_workaround(dev_info_t *dip)
{
uint16_t vid, regw;
- int port_type;
ddi_acc_handle_t cfg_hdl;
if (pepb_intel_workaround_disable)
return;
- (void) pepb_pcie_device_type(dip, &port_type);
- if (!((port_type == PCIE_PCIECAP_DEV_TYPE_UP) ||
- (port_type == PCIE_PCIECAP_DEV_TYPE_DOWN)))
+ if (!PCIE_IS_SW(PCIE_DIP2BUS(dip)))
return;
(void) pci_config_setup(dip, &cfg_hdl);