From 826c0d1d61fdbb1e3a35b1ed2f5ec3f77c29949b Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Thu, 9 Mar 2017 21:51:52 +0000 Subject: [PATCH] 8343 PCIe serial cap should be automatically added to device properties Reviewed by: Jerry Jelinek Reviewed by: Patrick Mooney Reviewed by: Toomas Soome Reviewed by: Gordon Ross Approved by: Dan McDonald --- usr/src/uts/common/io/pciex/pcie.c | 73 +++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/usr/src/uts/common/io/pciex/pcie.c b/usr/src/uts/common/io/pciex/pcie.c index 347f4699a3..95eaa5837f 100644 --- a/usr/src/uts/common/io/pciex/pcie.c +++ b/usr/src/uts/common/io/pciex/pcie.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. */ #include @@ -466,6 +467,52 @@ pcie_fini_cfghdl(dev_info_t *cdip) pci_config_teardown(&bus_p->bus_cfg_hdl); } +void +pcie_determine_serial(dev_info_t *dip) +{ + pcie_bus_t *bus_p = PCIE_DIP2BUS(dip); + ddi_acc_handle_t h; + uint16_t cap; + uchar_t serial[8]; + uint32_t low, high; + + if (!PCIE_IS_PCIE(bus_p)) + return; + + h = bus_p->bus_cfg_hdl; + + if ((PCI_CAP_LOCATE(h, PCI_CAP_XCFG_SPC(PCIE_EXT_CAP_ID_SER), &cap)) == + DDI_FAILURE) + return; + + high = PCI_XCAP_GET32(h, 0, cap, PCIE_SER_SID_UPPER_DW); + low = PCI_XCAP_GET32(h, 0, cap, PCIE_SER_SID_LOWER_DW); + + /* + * Here, we're trying to figure out if we had an invalid PCIe read. From + * looking at the contents of the value, it can be hard to tell the + * difference between a value that has all 1s correctly versus if we had + * an error. In this case, we only assume it's invalid if both register + * reads are invalid. We also only use 32-bit reads as we're not sure if + * all devices will support these as 64-bit reads, while we know that + * they'll support these as 32-bit reads. + */ + if (high == PCI_EINVAL32 && low == PCI_EINVAL32) + return; + + serial[0] = low & 0xff; + serial[1] = (low >> 8) & 0xff; + serial[2] = (low >> 16) & 0xff; + serial[3] = (low >> 24) & 0xff; + serial[4] = high & 0xff; + serial[5] = (high >> 8) & 0xff; + serial[6] = (high >> 16) & 0xff; + serial[7] = (high >> 24) & 0xff; + + (void) ndi_prop_update_byte_array(DDI_DEV_T_NONE, dip, "pcie-serial", + serial, sizeof (serial)); +} + /* * PCI-Express child device initialization. * This function enables generic pci-express interrupts and error @@ -608,6 +655,8 @@ pcie_initchild(dev_info_t *cdip) /* Enable PCIe errors */ pcie_enable_errors(cdip); + + pcie_determine_serial(cdip); } bus_p->bus_ari = B_FALSE; @@ -1659,24 +1708,29 @@ pcie_get_bdf_for_dma_xfer(dev_info_t *dip, dev_info_t *rdip) } uint32_t -pcie_get_aer_uce_mask() { +pcie_get_aer_uce_mask() +{ return (pcie_aer_uce_mask); } uint32_t -pcie_get_aer_ce_mask() { +pcie_get_aer_ce_mask() +{ return (pcie_aer_ce_mask); } uint32_t -pcie_get_aer_suce_mask() { +pcie_get_aer_suce_mask() +{ return (pcie_aer_suce_mask); } uint32_t -pcie_get_serr_mask() { +pcie_get_serr_mask() +{ return (pcie_serr_disable_flag); } void -pcie_set_aer_uce_mask(uint32_t mask) { +pcie_set_aer_uce_mask(uint32_t mask) +{ pcie_aer_uce_mask = mask; if (mask & PCIE_AER_UCE_UR) pcie_base_err_default &= ~PCIE_DEVCTL_UR_REPORTING_EN; @@ -1688,15 +1742,18 @@ pcie_set_aer_uce_mask(uint32_t mask) { } void -pcie_set_aer_ce_mask(uint32_t mask) { +pcie_set_aer_ce_mask(uint32_t mask) +{ pcie_aer_ce_mask = mask; } void -pcie_set_aer_suce_mask(uint32_t mask) { +pcie_set_aer_suce_mask(uint32_t mask) +{ pcie_aer_suce_mask = mask; } void -pcie_set_serr_mask(uint32_t mask) { +pcie_set_serr_mask(uint32_t mask) +{ pcie_serr_disable_flag = mask; } -- 2.11.4.GIT