pcicmu.c revision 193974072f41a843678abf5f61979c748687e66b
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * CDDL HEADER START
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Common Development and Distribution License (the "License").
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You may not use this file except in compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing permissions
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL HEADER in each
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below this CDDL HEADER, with the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * fields enclosed by brackets "[]" replaced with your own identifying
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * information: Portions Copyright [yyyy] [name of copyright owner]
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * CDDL HEADER END
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Use is subject to license terms.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * OPL CMU-CH PCI nexus driver.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosteruint32_t pcmu_spurintr_duration = 60000000; /* One minute */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The variable controls the default setting of the command register
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * for pci devices. See pcmu_init_child() for details.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This flags also controls the setting of bits in the bridge control
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * register pci to pci bridges. See pcmu_init_child() for details.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterushort_t pcmu_command_default = PCI_COMM_SERR_ENABLE |
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The following driver parameters are defined as variables to allow
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * patching for debugging and tuning. Flags that can be set on a per
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * PBM basis are bit fields where the PBM device instance number maps
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * to the bit position.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosteruint_t pcmu_ecc_afsr_retries = 100; /* XXX - what's a good value? */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosteruint_t pcmu_intr_retry_intv = 5; /* for interrupt retry reg */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosteruint_t pcmu_panic_on_fatal_errors = 1; /* should be 1 at beta */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterhrtime_t pcmu_intrpend_timeout = 5ll * NANOSEC; /* 5 seconds in nanoseconds */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The following value is the number of consecutive unclaimed interrupts that
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * will be tolerated for a particular ino_p before the interrupt is deemed to
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * be jabbering and is blocked.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * function prototypes for dev ops routines:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_open(dev_t *devp, int flags, int otyp, cred_t *credp);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_close(dev_t dev, int flags, int otyp, cred_t *credp);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int flags, char *name, caddr_t valuep, int *lengthp);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_ctlops_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_ctlops_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int map_pcmu_registers(pcmu_t *, dev_info_t *);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster void *, void *);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic uint32_t pcmu_identity_init(pcmu_t *pcmu_p);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic void pcmu_pbm_errstate_get(pcmu_t *pcmu_p,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic void u2u_ittrans_init(pcmu_t *, u2u_ittrans_data_t **);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic void u2u_ittrans_resume(u2u_ittrans_data_t **);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic void u2u_ittrans_uninit(u2u_ittrans_data_t *);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * bus ops and dev ops structures:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ndi_busop_get_eventcookie, /* (*bus_get_eventcookie)(); */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ndi_busop_add_eventcall, /* (*bus_add_eventcall)(); */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ndi_busop_remove_eventcall, /* (*bus_remove_eventcall)(); */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * module definitions:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "OPL CMU-CH PCI Nexus driver", /* Name of module. */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * driver global data:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid *per_pcmu_state; /* per-pbm soft state pointer */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterkmutex_t pcmu_global_mutex; /* attach/detach common struct lock */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostererrorq_t *pcmu_ecc_queue = NULL; /* per-system ecc handling queue */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterextern void pcmu_child_cfg_save(dev_info_t *dip);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterextern void pcmu_child_cfg_restore(dev_info_t *dip);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Initialize per-pci bus soft state pointer.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster e = ddi_soft_state_init(&per_pcmu_state, sizeof (pcmu_t), 1);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Initialize global mutexes.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster mutex_init(&pcmu_global_mutex, NULL, MUTEX_DRIVER, NULL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Create the performance kstats.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Install the module.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (e != 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Remove the module.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (e != 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Destroy pcmu_ecc_queue, and set it to NULL.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Destroy the performance kstats.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Free the per-pci and per-CMU-CH soft state info and destroy
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * mutex for per-CMU-CH soft state.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_t *pcmu_p = get_pcmu_soft_state(instance);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/* device driver entry points */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * attach entry point:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_ATTACH, dip, "DDI_ATTACH\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Allocate and get the per-pci soft state structure.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (alloc_pcmu_soft_state(instance) != DDI_SUCCESS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster cmn_err(CE_WARN, "%s%d: can't allocate pci state",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster mutex_init(&pcmu_p->pcmu_mutex, NULL, MUTEX_DRIVER, NULL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_CLOSED;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Get key properties of the pci bridge node.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (get_pcmu_properties(pcmu_p, dip) == DDI_FAILURE) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Map in the registers.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (map_pcmu_registers(pcmu_p, dip) == DDI_FAILURE) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Due to unresolved hardware issues, disable PCIPM until
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the problem is fully understood.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * pcmu_pwr_setup(pcmu_p, dip);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_ATTACH, dip, "attach success\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_ATTACH, dip, "DDI_RESUME\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Make sure the CMU-CH control registers
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * are configured properly.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Make sure this instance has been suspended.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "instance NOT suspended\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_ATTACH, dip, "unsupported attach op\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * detach entry point:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_t *pcmu_p = get_pcmu_soft_state(instance);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Make sure we are currently attached
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "failed - instance not attached\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_DETACH, dip, "DDI_DETACH\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Free the pci soft state structure and the rest of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * resources it's using.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* Free the interrupt-priorities prop if we created it. */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "interrupt-priorities", &len) == DDI_PROP_SUCCESS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "interrupt-priorities");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_DETACH, dip, "unsupported detach op\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/* ARGSUSED3 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_open(dev_t *devp, int flags, int otyp, cred_t *credp)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Get the soft state structure for the device.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Handle the open by tracking the device state.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (pcmu_p->pcmu_soft_state != PCMU_SOFT_STATE_CLOSED) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, "busy\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_OPEN_EXCL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (pcmu_p->pcmu_soft_state == PCMU_SOFT_STATE_OPEN_EXCL) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, "busy\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_OPEN;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/* ARGSUSED */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_close(dev_t dev, int flags, int otyp, cred_t *credp)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_CLOSED;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/* ARGSUSED */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG2(PCMU_DBG_IOCTL, dip, "dev=%x: cmd=%x\n", dev, cmd);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * We can use the generic implementation for these ioctls
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * read devctl ioctl data
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_DEVICE_RESET\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_QUIESCE\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_UNQUIESCE\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_RESET\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_RESETALL\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int pcmu_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int flags, char *name, caddr_t valuep, int *lengthp)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/* bus driver entry points */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * bus map entry point:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * if map request is for an rnumber
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * get the corresponding regspec from device node
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * build a new regspec in our parent's format
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * build a new map_req with the new regspec
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * call up the tree to complete the mapping
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ddi_driver_name(rdip), ddi_get_instance(rdip));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster reloc_reg = *(pci_regspec_t *)mp->map_obj.rp; /* dup whole */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG1(PCMU_DBG_MAP | PCMU_DBG_CONT, dip, " r#=%x", r_no);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (ddi_getlongprop(DDI_DEV_T_NONE, rdip, DDI_PROP_DONTPASS,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "reg", (caddr_t)&rp, ®len) != DDI_SUCCESS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (r_no < 0 || r_no >= reglen / sizeof (pci_regspec_t)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster PCMU_DBG0(PCMU_DBG_MAP | PCMU_DBG_CONT, dip, "\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* use "assigned-addresses" to relocate regspec within pci space */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (rval = pcmu_reloc_reg(dip, rdip, pcmu_p, rp)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* adjust regspec according to mapping request */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* use "ranges" to translate relocated pci regspec into parent space */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (rval = pcmu_xlate_reg(pcmu_p, rp, &p_regspec)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#endif /* DEBUG */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_do_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* Set up protected environment. */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster err = do_poke(in_args->size, (void *)in_args->dev_addr,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Read the async fault register for the PBM to see it sees
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * a master-abort.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* Take down protected environment. */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_ctlops_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/* ARGSUSED */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_do_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster err = do_peek(in_args->size, (void *)in_args->dev_addr,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_ctlops_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args, void *result)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * control ops entry point:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Requests handled completely:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_INITCHILD see pcmu_init_child() for details
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_UNINITCHILD
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_REPORTDEV see report_dev() for details
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_XLATE_INTRS nothing to do
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_IOMIN cache line size if streaming otherwise 1
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_REGSIZE
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_NREGS
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_NINTRS
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_DVMAPAGESIZE
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_POKE
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_PEEK
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_QUIESCE
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DDI_CTLOPS_UNQUIESCE
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * All others passed to parent.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return (pcmu_init_child(pcmu_p, (dev_info_t *)arg));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return (pcmu_uninit_child(pcmu_p, (dev_info_t *)arg));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If we are using the streaming cache, align at
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * least on a cache line boundary. Otherwise use
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * whatever alignment is passed in.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *((off_t *)result) = pcmu_get_reg_set_size(rdip, *((int *)arg));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return (pcmu_ctlops_poke(pcmu_p, (peekpoke_ctlops_t *)arg));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return (pcmu_ctlops_peek(pcmu_p, (peekpoke_ctlops_t *)arg,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Now pass the request up to our parent.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "passing request to parent: rdip=%s%d\n",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ddi_driver_name(rdip), ddi_get_instance(rdip));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return (ddi_ctlops(dip, rdip, op, arg, result));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/* ARGSUSED */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpcmu_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* GetCap will always fail for all non PCI devices */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *(int *)result = hdlp->ih_pri ? hdlp->ih_pri : 0;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ret = pcmu_ib_update_intr_state(pcmu_p, rdip, hdlp,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ret = pcmu_ib_update_intr_state(pcmu_p, rdip, hdlp,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ret = pci_intx_get_pending(rdip, (int *)result);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* PCI nexus driver supports only fixed interrupts */
return (ret);
int ret;
goto done;
done:
ret);
return (ret);
int i, no_of_intrs;
i = CELLS_1275_TO_BYTES(i);
for (i = 0; i < no_of_intrs; i++) {
goto teardown;
goto teardown;
return (DDI_SUCCESS);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
static uintptr_t
static uintptr_t
uint64_t *
return (addr);
uint64_t *
return (addr);
int l2;
int cpu_id;
goto newcpu;
goto newcpu;
if (s1) {
extern int intr_dist_debug;
if (intr_dist_debug) {
if (sino_p) {
goto out;
if (buf2)
return (cpu_id);
return (BF_NONE);
static uintptr_t
static pcmu_kev_mask_t
pcicmu_pcmu_events[] = {
* u2u_ittrans_init() is caled from in pci.c's pcmu_cb_setup() per CMU.
int ret;
int board;
int ix;
int ix;
return (cpu_id);
if (panicstr) {
return (cpu_id);
if (!panicstr) {
return (index);
int ix;
switch (err) {
case PCMU_ECC_UE_AFSR_E_PIO:
uint32_t e;
int nerr = 0;
char **tmp_class;
if (e & PCMU_PCI_AFSR_E_MA) {
nerr++;
return (nerr);
int fatal = 0;
int nonfatal = 0;
int unknown = 0;
int ret = 0;
nonfatal++;
goto done;
nonfatal++;
goto done;
fatal++;
nonfatal++;
fatal++;
nonfatal++;
done:
fatal++;
nonfatal++;
unknown++;
(void *)NULL,
char *aux_msg;
if (prierr)
else if (secerr)