pcie.c revision 4496171313bed39e96f21bc2f9faf2868e267ae3
/*
* 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
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sysmacros.h>
#include <sys/pcie_impl.h>
#include <sys/pci_impl.h>
#ifdef DEBUG
uint_t pcie_debug_flags = 0;
#else /* DEBUG */
#define PCIE_DBG 0 &&
#endif /* DEBUG */
/* Variable to control default PCI-Express config settings */
uint32_t pcie_aer_ce_mask = 0;
/*
* modload support
*/
extern struct mod_ops mod_miscops;
&mod_miscops, /* Type of module */
"PCIE: PCI Express Architecture %I%"
};
struct modlinkage modlinkage = {
(void *)&modlmisc,
};
int
_init(void)
{
int rval;
return (rval);
}
int
_fini()
{
int rval;
return (rval);
}
int
{
}
/*
* PCI-Express child device initialization.
* This function enables generic pci-express interrupts and error
* handling.
*
* @param pdip root dip (root nexus's dip)
* @param cdip child's dip (device's dip)
* @return DDI_SUCCESS or DDI_FAILURE
*/
/* ARGSUSED */
int
{
return (DDI_FAILURE);
/* Allocate memory for pci parent data */
/*
* Retrieve and save BDF and PCIE2PCI bridge's secondary bus
* information in the parent private data structure.
*/
goto fail;
"pcie2pci-sec-bus", 0);
/*
* Determine the configuration header type.
*/
/*
* Setup the device's command register
*/
/*
* If the device has a bus control register then program it
* based on the settings in the command register.
*/
}
!= DDI_FAILURE) {
}
return (DDI_SUCCESS);
fail:
return (DDI_FAILURE);
}
int
{
int rval = DDI_FAILURE;
return (DDI_FAILURE);
return (rval);
}
/*
* PCI-Express child device de-initialization.
* This function disables generic pci-express interrupts and error
* handling.
*
* @param pdip parent dip (root nexus's dip)
* @param cdip child's dip (device's dip)
* @param arg pcie private data
*/
/* ARGSUSED */
void
{
}
return;
}
/* ARGSUSED */
void
{
int rval = DDI_FAILURE;
/* 1. clear the Legacy PCI Errors */
== DDI_FAILURE)
return;
(PCIE_EXT_CAP_ID_AER), &aer_ptr);
/*
* Clear any pending errors
*/
/* 2. clear the Advanced PCIe Errors */
if (rval != DDI_FAILURE) {
-1);
-1);
if (dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
PCIE_AER_SUCE_STS, -1);
}
}
/* 3. clear the PCIe Errors */
PCIE_DEVSTS)) != PCI_CAP_EINVAL16)
if (dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
}
}
void
{
int rval = DDI_FAILURE;
/*
* Clear any pending errors
*/
== DDI_FAILURE)
return;
(PCIE_EXT_CAP_ID_AER), &aer_ptr);
/*
* Enable Baseline Error Handling but leave CE reporting off (poweron
* default).
*/
PCIE_DEVCTL)) != PCI_CAP_EINVAL16) {
PCIE_DEVCTL));
}
/*
* Enable PCI-Express Advanced Error Handling if Exists
*/
if (rval == DDI_FAILURE) {
return;
}
/* Enable Uncorrectable errors */
PCIE_AER_UCE_MASK)) != PCI_CAP_EINVAL32) {
}
/* Enable ECRC generation and checking */
PCIE_AER_CTL)) != PCI_CAP_EINVAL32) {
aer_reg);
}
/*
* Enable Secondary Uncorrectable errors if this is a bridge
*/
if (!(dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI))
return;
/*
* Enable secondary bus errors
*/
PCIE_AER_SUCE_MASK)) != PCI_CAP_EINVAL32) {
}
}
/*
* This function is used for enabling CE reporting and setting the AER CE mask.
* When called from outside the pcie module it should always be preceded by
* a call to pcie_enable_errors.
*/
int
{
== DDI_FAILURE)
return (DDI_FAILURE);
/*
* The "pcie_ce_mask" property is used to control both the CE reporting
* enable field in the device control register and the AER CE mask. We
* leave CE reporting disabled if pcie_ce_mask is set to -1.
*/
if (tmp_pcie_aer_ce_mask == -1) {
/*
* Nothing to do since CE reporting has already been disabled.
*/
return (DDI_SUCCESS);
}
/* Enable AER CE */
PCIE_DBG("%s: AER CE set to 0x%x\n",
/* Clear any pending AER CE errors */
-1);
}
/* clear any pending CE errors */
PCIE_DEVSTS)) != PCI_CAP_EINVAL16)
/* Enable CE reporting */
return (DDI_SUCCESS);
}
/* ARGSUSED */
void
{
int rval = DDI_FAILURE;
== DDI_FAILURE)
return;
(PCIE_EXT_CAP_ID_AER), &aer_ptr);
/*
* Disable PCI-Express Baseline Error Handling
*/
/*
* Disable PCI-Express Advanced Error Handling if Exists
*/
if (rval == DDI_FAILURE) {
return;
}
/* Disable Uncorrectable errors */
/* Disable Correctable errors */
/* Disable ECRC generation and checking */
PCIE_AER_CTL)) != PCI_CAP_EINVAL32) {
aer_reg &= ~(PCIE_AER_CTL_ECRC_GEN_ENA |
aer_reg);
}
/*
* Disable Secondary Uncorrectable errors if this is a bridge
*/
if (!(dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI))
return;
/*
* Disable secondary bus errors
*/
}
static int
{
int reglen;
return (DDI_FAILURE);
if (reglen < (sizeof (pci_regspec_t) / sizeof (int))) {
return (DDI_FAILURE);
}
/* Get phys_hi from first element. All have same bdf. */
return (DDI_SUCCESS);
}
{
;
return (cdip);
}
#ifdef DEBUG
/*
* This is a temporary stop gap measure.
* PX runs at PIL 14, which is higher than the clock's PIL.
* As a results we cannot safely print while servicing interrupts using
* cmn_err or prom_printf.
*
* For debugging purposes set px_dbg_print != 0 to see printf messages
* during interrupt.
*
* When a proper solution is in place this code will disappear.
* Potential solutions are:
* o circular buffers
* o taskq to print at lower pil
*/
int pcie_dbg_print = 0;
static void
{
if (!pcie_debug_flags) {
return;
}
if (servicing_interrupt()) {
if (pcie_dbg_print) {
}
} else {
}
}
#endif /* DEBUG */