px_pci.c revision c9f965e38407a1b2c59e93790806289c7e090cf0
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * CDDL HEADER START
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * The contents of this file are subject to the terms of the
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * Common Development and Distribution License, Version 1.0 only
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * (the "License"). You may not use this file except in compliance
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * with the License.
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * See the License for the specific language governing permissions
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * and limitations under the License.
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * When distributing Covered Code, include this CDDL HEADER in each
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * If applicable, add the following below this CDDL HEADER, with the
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * fields enclosed by brackets "[]" replaced with your own identifying
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * information: Portions Copyright [yyyy] [name of copyright owner]
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * CDDL HEADER END
a585e5e48b946aa1de0f69a97853291aa519b8c7ludo * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
d5af1880773b35da2da505be54be517b746e7410ludovicp * Use is subject to license terms.
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn#pragma ident "%Z%%M% %I% %E% SMI"
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * Sun4 PCI Express to PCI bus bridge nexus driver
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbnstatic int pxb_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbnstatic int pxb_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn void *, void *);
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbnstatic int pxb_intr_ops(dev_info_t *dip, dev_info_t *rdip,
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result);
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * FMA functions
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_fm_init_child(dev_info_t *dip, dev_info_t *cdip, int cap,
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbnstatic int pxb_fm_err_callback(dev_info_t *dip, ddi_fm_error_t *derr,
d5af1880773b35da2da505be54be517b746e7410ludovicp const void *impl_data);
d5af1880773b35da2da505be54be517b746e7410ludovicp ndi_busop_get_eventcookie, /* (*bus_get_eventcookie)(); */
d5af1880773b35da2da505be54be517b746e7410ludovicp ndi_busop_add_eventcall, /* (*bus_add_eventcall)(); */
d5af1880773b35da2da505be54be517b746e7410ludovicp ndi_busop_remove_eventcall, /* (*bus_remove_eventcall)(); */
d5af1880773b35da2da505be54be517b746e7410ludovicp i_ndi_busop_access_enter, /* (*bus_fm_access_enter)(); */
d5af1880773b35da2da505be54be517b746e7410ludovicp i_ndi_busop_access_exit, /* (*bus_fm_access_fini)(); */
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_open(dev_t *devp, int flags, int otyp, cred_t *credp);
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_close(dev_t dev, int flags, int otyp, cred_t *credp);
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
d5af1880773b35da2da505be54be517b746e7410ludovicp int flags, char *name, caddr_t valuep, int *lengthp);
d5af1880773b35da2da505be54be517b746e7410ludovicp D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic int pxb_pwr_init_and_raise(dev_info_t *dip, pcie_pwr_t *pwr_p);
d5af1880773b35da2da505be54be517b746e7410ludovicp 0, /* refcnt */
d5af1880773b35da2da505be54be517b746e7410ludovicp * Module linkage information for the kernel.
d5af1880773b35da2da505be54be517b746e7410ludovicp "Standard PCI to PCI bridge nexus driver 1.5",
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * soft state pointer and structure template:
d5af1880773b35da2da505be54be517b746e7410ludovicp * SW workaround for PLX HW bug Flag
a585e5e48b946aa1de0f69a97853291aa519b8c7ludo * forward function declarations:
a585e5e48b946aa1de0f69a97853291aa519b8c7ludostatic int pxb_intr_init(pxb_devstate_t *pxb, int intr_type);
a585e5e48b946aa1de0f69a97853291aa519b8c7ludostatic int pxb_get_port_type(dev_info_t *dip, ddi_acc_handle_t config_handle);
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic dev_info_t *get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip);
d5af1880773b35da2da505be54be517b746e7410ludovicpstatic void pxb_create_ranges_prop(dev_info_t *, ddi_acc_handle_t);
a585e5e48b946aa1de0f69a97853291aa519b8c7ludo if ((e = ddi_soft_state_init(&pxb_state, sizeof (pxb_devstate_t),
d5af1880773b35da2da505be54be517b746e7410ludovicp return (e);
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbnpxb_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn pxb_devstate_t *pxb_p; /* per pxb state pointer */
d5af1880773b35da2da505be54be517b746e7410ludovicp int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
d5af1880773b35da2da505be54be517b746e7410ludovicp pxb_p = (pxb_devstate_t *)ddi_get_soft_state(pxb_state,
a585e5e48b946aa1de0f69a97853291aa519b8c7ludo/*ARGSUSED*/
d5af1880773b35da2da505be54be517b746e7410ludovicp/*ARGSUSED*/
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbnpxb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
a585e5e48b946aa1de0f69a97853291aa519b8c7ludo * Get the soft state structure for the bridge.
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn /* Follow through to below the switch statement */
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn * Allocate and get soft state structure.
a585e5e48b946aa1de0f69a97853291aa519b8c7ludo if (ddi_soft_state_zalloc(pxb_state, instance) != DDI_SUCCESS) {
a585e5e48b946aa1de0f69a97853291aa519b8c7ludo DBG(DBG_ATTACH, devi, "Unable to allocate soft state.\n");
9def8137e705ec92bc3a2881a8457795c860fdb1shankar_mbn pxb = (pxb_devstate_t *)ddi_get_soft_state(pxb_state, instance);
b3d0736ce9ff54f95fc06741c7279172f961363fshankar_mbn /* Create Mutex */
3e8ebc69e18e02f0935b37e8f5837aab18557f50ludovicp mutex_init(&pxb->pxb_mutex, NULL, MUTEX_DRIVER, NULL);
d5af1880773b35da2da505be54be517b746e7410ludovicp /* Setup and save the config space pointer */
d5af1880773b35da2da505be54be517b746e7410ludovicp if (pci_config_setup(devi, &config_handle) != DDI_SUCCESS) {
d5af1880773b35da2da505be54be517b746e7410ludovicp DBG(DBG_ATTACH, devi, "Failed in pci_config_setup call\n");
d5af1880773b35da2da505be54be517b746e7410ludovicp * Power management setup. This also makes sure that switch/bridge
d5af1880773b35da2da505be54be517b746e7410ludovicp * is at D0 during attach.
d5af1880773b35da2da505be54be517b746e7410ludovicp DBG(DBG_ATTACH, devi, "Failed in px_pci_fm_attach\n");
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
return (DDI_SUCCESS);
fail:
return (DDI_FAILURE);
switch (cmd) {
case DDI_DETACH:
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:
case DDI_PRE:
return (DDI_SUCCESS);
case DDI_POST:
return (DDI_SUCCESS);
case DDI_CTLOPS_DETACH:
case DDI_POST:
return (DDI_SUCCESS);
*(int *)result = 0;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
static dev_info_t *
return (cdip);
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);
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;
if ((!pxb_tlp_count) ||
goto cleanup;
goto cleanup;
done:
return (result);
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 (DDI_INTR_UNCLAIMED);
& PCI_STAT_CAP)
caps_ptr);
return (port_type);
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);
return (DDI_FAILURE);
if (cap_ptr == 0) {
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)
#ifdef FMA
return (DDI_FM_OK);