diff options
Diffstat (limited to 'usr/src/uts/intel/io')
-rw-r--r-- | usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c | 77 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_boot.c | 49 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pciex/pcie_nvidia.c | 30 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pciex/pcie_pci.c | 74 |
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); |