px_pci.c revision c333dd99c762d509c7eb6cce222221958e23b4c8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER START
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The contents of this file are subject to the terms of the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Common Development and Distribution License (the "License").
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You may not use this file except in compliance with the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * See the License for the specific language governing permissions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and limitations under the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * When distributing Covered Code, include this CDDL HEADER in each
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If applicable, add the following below this CDDL HEADER, with the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fields enclosed by brackets "[]" replaced with your own identifying
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * information: Portions Copyright [yyyy] [name of copyright owner]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER END
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Use is subject to license terms.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma ident "%Z%%M% %I% %E% SMI"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Sun4 PCI Express to PCI bus bridge nexus driver
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* PX_PLX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(DEBUG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void pxb_dbg(uint_t bit, dev_info_t *dip, char *fmt, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else /* DEBUG */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DBG 0 &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* DEBUG */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef enum { /* same sequence as px_debug_sym[] */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *pxb_debug_sym [] = { /* same sequence as px_debug_bit */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Tunables. Beware: Some are for debug purpose only. */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * PXB MSI tunable:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * By default MSI is enabled on all supported platforms.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic boolean_t pxb_enable_msi = B_TRUE; /* MSI enabled if TRUE, else INTX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pxb_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pxb_dma_allochdl(dev_info_t *dip, dev_info_t *rdip,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ddi_dma_attr_t *attr_p, int (*waitfp)(caddr_t), caddr_t arg,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pxb_dma_mctl(dev_info_t *dip, dev_info_t *rdip,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ddi_dma_handle_t handle, enum ddi_dma_ctlops cmd, off_t *offp,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pxb_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *, void *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pxb_intr_ops(dev_info_t *dip, dev_info_t *rdip,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FMA functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pxb_fm_init_child(dev_info_t *dip, dev_info_t *cdip, int cap,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pxb_fm_err_callback(dev_info_t *dip, ddi_fm_error_t *derr,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const void *impl_data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void pxb_set_pci_perf_parameters(dev_info_t *dip,
#ifdef PRINT_PLX_SEEPROM_CRC
#ifdef PX_PLX
(void *)&modldrv,
void *pxb_state;
_init(void)
_fini(void)
instance);
switch (infocmd) {
return (DDI_FAILURE);
case DDI_INFO_DEVT2INSTANCE:
return (DDI_SUCCESS);
case DDI_INFO_DEVT2DEVINFO:
return (DDI_FAILURE);
return (DDI_SUCCESS);
return (DDI_PROBE_SUCCESS);
int instance;
#ifdef PX_PLX
switch (cmd) {
case DDI_RESUME:
return (DDI_SUCCESS);
case DDI_ATTACH:
return (DDI_FAILURE);
return (DDI_FAILURE);
goto fail;
goto fail;
#ifdef PX_PLX
goto fail;
goto fail;
goto fail;
#ifdef PX_PLX
goto hotplug_done;
#ifdef PX_PLX
goto fail;
#ifdef PRINT_PLX_SEEPROM_CRC
goto fail;
goto fail;
return (DDI_SUCCESS);
fail:
return (DDI_FAILURE);
switch (cmd) {
case DDI_DETACH:
#ifdef PX_PLX
return (error);
case DDI_SUSPEND:
return (error);
return (DDI_FAILURE);
int reglen;
int rn;
int totreg;
switch (ctlop) {
case DDI_CTLOPS_REPORTDEV:
return (DDI_FAILURE);
return (DDI_SUCCESS);
case DDI_CTLOPS_INITCHILD:
case DDI_CTLOPS_UNINITCHILD:
return (DDI_SUCCESS);
case DDI_CTLOPS_SIDDEV:
return (DDI_SUCCESS);
case DDI_CTLOPS_REGSIZE:
case DDI_CTLOPS_NREGS:
return (DDI_FAILURE);
case DDI_CTLOPS_ATTACH:
return (DDI_SUCCESS);
case DDI_PRE:
DDI_SUCCESS) {
return (DDI_SUCCESS);
case DDI_POST: {
return (DDI_SUCCESS);
DDI_SUCCESS) {
return (DDI_SUCCESS);
case DDI_CTLOPS_DETACH:
return (DDI_SUCCESS);
case DDI_PRE:
return (DDI_SUCCESS);
case DDI_POST:
return (DDI_SUCCESS);
*(int *)result = 0;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
goto done;
goto done;
return (DDI_FAILURE);
done:
char **unit_addr;
uint_t n;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
return (DDI_FAILURE);
if (func != 0)
return (DDI_SUCCESS);
#ifdef PX_PLX
goto done;
extern int pci_allow_pseudo_children;
goto done;
if (pci_allow_pseudo_children) {
goto done;
goto done;
goto done;
goto cleanup;
goto cleanup;
#ifdef PX_PLX
if (!pxb_tlp_count) {
goto cleanup;
goto cleanup;
done:
return (result);
int intr_types;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
int ret;
int intr_cap = 0;
return (DDI_SUCCESS);
goto fail;
goto fail;
goto fail;
ret);
goto fail;
ret);
for (x = 0; x < count; x++) {
goto fail;
return (DDI_SUCCESS);
fail:
return (DDI_FAILURE);
for (x = 0; x < count; x++) {
static uint_t
return (rval);
return (DDI_SUCCESS);
goto fail;
goto fail;
goto fail;
return (DDI_SUCCESS);
fail:
return (DDI_FAILURE);
return (EINVAL);
instance);
return (ENXIO);
return (EBUSY);
return (EBUSY);
return (EINVAL);
instance);
return (ENXIO);
int *rvalp)
int rv = 0;
instance);
return (ENXIO);
switch (cmd) {
case DEVCTL_DEVICE_GETSTATE:
case DEVCTL_DEVICE_ONLINE:
case DEVCTL_DEVICE_OFFLINE:
case DEVCTL_BUS_GETSTATE:
return (EFAULT);
switch (cmd) {
case DEVCTL_DEVICE_RESET:
case DEVCTL_BUS_QUIESCE:
case DEVCTL_BUS_UNQUIESCE:
case DEVCTL_BUS_RESET:
case DEVCTL_BUS_RESETALL:
return (rv);
instance);
return (ENXIO);
#ifdef PX_PLX
return (DDI_SUCCESS);
return (DDI_FAILURE);
== DDI_FAILURE) {
return (DDI_SUCCESS);
return (DDI_FAILURE);
switch (pmcsr) {
case PCI_PMCSR_D0:
case PCI_PMCSR_D1:
case PCI_PMCSR_D2:
case PCI_PMCSR_D3HOT:
return (ret);
return (DDI_SUCCESS);
const void *impl_data)
return (DDI_FM_OK);
!= DDI_FAILURE) {
if (slotimpl)
return (DDI_SUCCESS);
return (DDI_FAILURE);
!= DDI_FAILURE) {
return (DDI_SUCCESS);
return (DDI_FAILURE);
if (port_type < 0)
return (DDI_FAILURE);
return (DDI_SUCCESS);
return (DDI_FAILURE);
uint_t n;
#ifdef PRINT_PLX_SEEPROM_CRC
int nregs;
#ifdef PLX_HOT_RESET_DISABLE
ddi_regs_map_free(&h);
#ifdef PX_PLX
if (fic)
if (serialid)
int ret;
#ifdef BCM_SW_WORKAROUNDS
#ifdef BCM_SW_WORKAROUNDS
return (ret);
int ret;
#ifdef BCM_SW_WORKAROUNDS
return (DDI_FAILURE);
return (ret);
#ifdef DEBUG
if (dip)
body:
if (ap)
#ifdef PX_PLX
case PXB_DEVICE_PLX_8533:
case PXB_DEVICE_PLX_8548: