17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57aadd8d4Skini * Common Development and Distribution License (the "License"). 67aadd8d4Skini * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 223d78e6abSAlan Adamson, SD OSSD * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #include <sys/types.h> 267c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 277c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 289c75c6bfSgovinda #include <sys/async.h> 297c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 307c478bd9Sstevel@tonic-gate #include <sys/ddifm.h> 317c478bd9Sstevel@tonic-gate #include <sys/fm/protocol.h> 327c478bd9Sstevel@tonic-gate #include <sys/vmem.h> 33f8d2de6bSjchu #include <sys/intr.h> 34f8d2de6bSjchu #include <sys/ivintr.h> 35f8d2de6bSjchu #include <sys/errno.h> 367c478bd9Sstevel@tonic-gate #include <sys/hypervisor_api.h> 3744bb982bSgovinda #include <sys/hsvc.h> 387c478bd9Sstevel@tonic-gate #include <px_obj.h> 39f8d2de6bSjchu #include <sys/machsystm.h> 40fc256490SJason Beloro #include <sys/sunndi.h> 41fc256490SJason Beloro #include <sys/pcie_impl.h> 427c478bd9Sstevel@tonic-gate #include "px_lib4v.h" 43f8d2de6bSjchu #include "px_err.h" 44c0da6274SZhi-Jun Robin Fu #include <sys/pci_cfgacc.h> 45c0da6274SZhi-Jun Robin Fu #include <sys/pci_cfgacc_4v.h> 46c0da6274SZhi-Jun Robin Fu 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate /* mask for the ranges property in calculating the real PFN range */ 497c478bd9Sstevel@tonic-gate uint_t px_ranges_phi_mask = ((1 << 28) -1); 507c478bd9Sstevel@tonic-gate 5144bb982bSgovinda /* 5244bb982bSgovinda * Hypervisor VPCI services information for the px nexus driver. 5344bb982bSgovinda */ 543d78e6abSAlan Adamson, SD OSSD static uint64_t px_vpci_maj_ver; /* Negotiated VPCI API major version */ 5544bb982bSgovinda static uint64_t px_vpci_min_ver; /* Negotiated VPCI API minor version */ 5644bb982bSgovinda static uint_t px_vpci_users = 0; /* VPCI API users */ 57fc256490SJason Beloro static hsvc_info_t px_hsvc_vpci = { 5844bb982bSgovinda HSVC_REV_1, NULL, HSVC_GROUP_VPCI, PX_VPCI_MAJOR_VER, 5944bb982bSgovinda PX_VPCI_MINOR_VER, "PX" 6044bb982bSgovinda }; 6144bb982bSgovinda 62fc256490SJason Beloro /* 63fc256490SJason Beloro * Hypervisor SDIO services information for the px nexus driver. 64fc256490SJason Beloro */ 65fc256490SJason Beloro static uint64_t px_sdio_min_ver; /* Negotiated SDIO API minor version */ 66fc256490SJason Beloro static uint_t px_sdio_users = 0; /* SDIO API users */ 67fc256490SJason Beloro static hsvc_info_t px_hsvc_sdio = { 68fc256490SJason Beloro HSVC_REV_1, NULL, HSVC_GROUP_SDIO, PX_SDIO_MAJOR_VER, 69fc256490SJason Beloro PX_SDIO_MINOR_VER, "PX" 70fc256490SJason Beloro }; 71fc256490SJason Beloro 72fc256490SJason Beloro /* 73fc256490SJason Beloro * Hypervisor SDIO ERR services information for the px nexus driver. 74fc256490SJason Beloro */ 75fc256490SJason Beloro static uint64_t px_sdio_err_min_ver; /* Negotiated SDIO ERR API */ 76fc256490SJason Beloro /* minor version */ 77fc256490SJason Beloro static uint_t px_sdio_err_users = 0; /* SDIO ERR API users */ 78fc256490SJason Beloro static hsvc_info_t px_hsvc_sdio_err = { 79fc256490SJason Beloro HSVC_REV_1, NULL, HSVC_GROUP_SDIO_ERR, PX_SDIO_ERR_MAJOR_VER, 80fc256490SJason Beloro PX_SDIO_ERR_MINOR_VER, "PX" 81fc256490SJason Beloro }; 82fc256490SJason Beloro 83fc256490SJason Beloro #define CHILD_LOANED "child_loaned" 84fc256490SJason Beloro static int px_lib_count_waiting_dev(dev_info_t *); 85fc256490SJason Beloro 867c478bd9Sstevel@tonic-gate int 877c478bd9Sstevel@tonic-gate px_lib_dev_init(dev_info_t *dip, devhandle_t *dev_hdl) 887c478bd9Sstevel@tonic-gate { 897c478bd9Sstevel@tonic-gate px_nexus_regspec_t *rp; 90c9f965e3Set142600 uint_t reglen; 91c9f965e3Set142600 int ret; 92fc256490SJason Beloro px_t *px_p = DIP_TO_STATE(dip); 93d66f8315Sjb145095 uint64_t mjrnum; 94d66f8315Sjb145095 uint64_t mnrnum; 95d66f8315Sjb145095 967c478bd9Sstevel@tonic-gate DBG(DBG_ATTACH, dip, "px_lib_dev_init: dip 0x%p\n", dip); 977c478bd9Sstevel@tonic-gate 98d66f8315Sjb145095 /* 99d66f8315Sjb145095 * Check HV intr group api versioning. 100d66f8315Sjb145095 * This driver uses the old interrupt routines which are supported 101d66f8315Sjb145095 * in old firmware in the CORE API group and in newer firmware in 102d66f8315Sjb145095 * the INTR API group. Support for these calls will be dropped 103d66f8315Sjb145095 * once the INTR API group major goes to 2. 104d66f8315Sjb145095 */ 105d66f8315Sjb145095 if ((hsvc_version(HSVC_GROUP_INTR, &mjrnum, &mnrnum) == 0) && 106d66f8315Sjb145095 (mjrnum > 1)) { 107350effc1SZach Kissel cmn_err(CE_WARN, "px: unsupported intr api group: " 108d66f8315Sjb145095 "maj:0x%lx, min:0x%lx", mjrnum, mnrnum); 109d66f8315Sjb145095 return (ENOTSUP); 110d66f8315Sjb145095 } 111d66f8315Sjb145095 112c9f965e3Set142600 ret = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 113c9f965e3Set142600 "reg", (uchar_t **)&rp, ®len); 114c9f965e3Set142600 if (ret != DDI_PROP_SUCCESS) { 115c9f965e3Set142600 DBG(DBG_ATTACH, dip, "px_lib_dev_init failed ret=%d\n", ret); 1167c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate /* 1207c478bd9Sstevel@tonic-gate * Initilize device handle. The device handle uniquely identifies 1217c478bd9Sstevel@tonic-gate * a SUN4V device. It consists of the lower 28-bits of the hi-cell 1227c478bd9Sstevel@tonic-gate * of the first entry of the SUN4V device's "reg" property as 1237c478bd9Sstevel@tonic-gate * defined by the SUN4V Bus Binding to Open Firmware. 1247c478bd9Sstevel@tonic-gate */ 1257c478bd9Sstevel@tonic-gate *dev_hdl = (devhandle_t)((rp->phys_addr >> 32) & DEVHDLE_MASK); 126c9f965e3Set142600 ddi_prop_free(rp); 127c9f965e3Set142600 128b65731f1Skini /* 129b65731f1Skini * hotplug implementation requires this property to be associated with 130b65731f1Skini * any indirect PCI config access services 131b65731f1Skini */ 132b65731f1Skini (void) ddi_prop_update_int(makedevice(ddi_driver_major(dip), 13326947304SEvan Yan PCI_MINOR_NUM(ddi_get_instance(dip), PCI_DEVCTL_MINOR)), dip, 134b65731f1Skini PCI_BUS_CONF_MAP_PROP, 1); 135b65731f1Skini 1367c478bd9Sstevel@tonic-gate DBG(DBG_ATTACH, dip, "px_lib_dev_init: dev_hdl 0x%llx\n", *dev_hdl); 1377c478bd9Sstevel@tonic-gate 13844bb982bSgovinda /* 139fc256490SJason Beloro * If a /pci node has a pci-intx-not-supported property, this property 140fc256490SJason Beloro * represents that the fabric doesn't support fixed interrupt. 14144bb982bSgovinda */ 142fc256490SJason Beloro if (!ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 143fc256490SJason Beloro "pci-intx-not-supported")) { 144fc256490SJason Beloro DBG(DBG_ATTACH, dip, "px_lib_dev_init: " 145fc256490SJason Beloro "pci-intx-not-supported is not found, dip=0x%p\n", dip); 146fc256490SJason Beloro px_p->px_supp_intr_types |= DDI_INTR_TYPE_FIXED; 14744bb982bSgovinda } 14844bb982bSgovinda 149fc256490SJason Beloro /* 150fc256490SJason Beloro * Negotiate the API version for VPCI hypervisor services. 151fc256490SJason Beloro */ 1523d78e6abSAlan Adamson, SD OSSD if (px_vpci_users == 0) { 1533d78e6abSAlan Adamson, SD OSSD if ((ret = hsvc_register(&px_hsvc_vpci, &px_vpci_min_ver)) 1543d78e6abSAlan Adamson, SD OSSD == 0) { 1553d78e6abSAlan Adamson, SD OSSD px_vpci_maj_ver = px_hsvc_vpci.hsvc_major; 1563d78e6abSAlan Adamson, SD OSSD goto hv_negotiation_complete; 1573d78e6abSAlan Adamson, SD OSSD } 1583d78e6abSAlan Adamson, SD OSSD /* 1593d78e6abSAlan Adamson, SD OSSD * Negotiation with the latest known VPCI hypervisor services 1603d78e6abSAlan Adamson, SD OSSD * failed. Fallback to version 1.0. 1613d78e6abSAlan Adamson, SD OSSD */ 1623d78e6abSAlan Adamson, SD OSSD px_hsvc_vpci.hsvc_major = PX_HSVC_MAJOR_VER_1; 1633d78e6abSAlan Adamson, SD OSSD px_hsvc_vpci.hsvc_minor = PX_HSVC_MINOR_VER_0; 1643d78e6abSAlan Adamson, SD OSSD 1653d78e6abSAlan Adamson, SD OSSD if ((ret = hsvc_register(&px_hsvc_vpci, &px_vpci_min_ver)) 1663d78e6abSAlan Adamson, SD OSSD == 0) { 1673d78e6abSAlan Adamson, SD OSSD px_vpci_maj_ver = px_hsvc_vpci.hsvc_major; 1683d78e6abSAlan Adamson, SD OSSD goto hv_negotiation_complete; 1693d78e6abSAlan Adamson, SD OSSD } 1703d78e6abSAlan Adamson, SD OSSD 171fc256490SJason Beloro cmn_err(CE_WARN, "%s: cannot negotiate hypervisor services " 172fc256490SJason Beloro "group: 0x%lx major: 0x%lx minor: 0x%lx errno: %d\n", 173fc256490SJason Beloro px_hsvc_vpci.hsvc_modname, px_hsvc_vpci.hsvc_group, 174fc256490SJason Beloro px_hsvc_vpci.hsvc_major, px_hsvc_vpci.hsvc_minor, ret); 1753d78e6abSAlan Adamson, SD OSSD 176fc256490SJason Beloro return (DDI_FAILURE); 177fc256490SJason Beloro } 1783d78e6abSAlan Adamson, SD OSSD hv_negotiation_complete: 1793d78e6abSAlan Adamson, SD OSSD 180fc256490SJason Beloro px_vpci_users++; 1813d78e6abSAlan Adamson, SD OSSD 18244bb982bSgovinda DBG(DBG_ATTACH, dip, "px_lib_dev_init: negotiated VPCI API version, " 1833d78e6abSAlan Adamson, SD OSSD "major 0x%lx minor 0x%lx\n", px_vpci_maj_ver, 184fc256490SJason Beloro px_vpci_min_ver); 18544bb982bSgovinda 186fc256490SJason Beloro /* 187fc256490SJason Beloro * Negotiate the API version for SDIO hypervisor services. 188fc256490SJason Beloro */ 189fc256490SJason Beloro if ((px_sdio_users == 0) && 190fc256490SJason Beloro ((ret = hsvc_register(&px_hsvc_sdio, &px_sdio_min_ver)) != 0)) { 191fc256490SJason Beloro DBG(DBG_ATTACH, dip, "%s: cannot negotiate hypervisor " 192fc256490SJason Beloro "services group: 0x%lx major: 0x%lx minor: 0x%lx " 193fc256490SJason Beloro "errno: %d\n", px_hsvc_sdio.hsvc_modname, 194fc256490SJason Beloro px_hsvc_sdio.hsvc_group, px_hsvc_sdio.hsvc_major, 195fc256490SJason Beloro px_hsvc_sdio.hsvc_minor, ret); 196fc256490SJason Beloro } else { 197fc256490SJason Beloro px_sdio_users++; 198fc256490SJason Beloro DBG(DBG_ATTACH, dip, "px_lib_dev_init: negotiated SDIO API" 199fc256490SJason Beloro "version, major 0x%lx minor 0x%lx\n", 200fc256490SJason Beloro px_hsvc_sdio.hsvc_major, px_sdio_min_ver); 201fc256490SJason Beloro } 202fc256490SJason Beloro 203fc256490SJason Beloro /* 204fc256490SJason Beloro * Negotiate the API version for SDIO ERR hypervisor services. 205fc256490SJason Beloro */ 206fc256490SJason Beloro if ((px_sdio_err_users == 0) && 207fc256490SJason Beloro ((ret = hsvc_register(&px_hsvc_sdio_err, 208fc256490SJason Beloro &px_sdio_err_min_ver)) != 0)) { 209fc256490SJason Beloro DBG(DBG_ATTACH, dip, "%s: cannot negotiate SDIO ERR hypervisor " 210fc256490SJason Beloro "services group: 0x%lx major: 0x%lx minor: 0x%lx " 211fc256490SJason Beloro "errno: %d\n", px_hsvc_sdio_err.hsvc_modname, 212fc256490SJason Beloro px_hsvc_sdio_err.hsvc_group, px_hsvc_sdio_err.hsvc_major, 213fc256490SJason Beloro px_hsvc_sdio_err.hsvc_minor, ret); 214fc256490SJason Beloro } else { 215fc256490SJason Beloro px_sdio_err_users++; 216fc256490SJason Beloro DBG(DBG_ATTACH, dip, "px_lib_dev_init: negotiated SDIO ERR API " 217fc256490SJason Beloro "version, major 0x%lx minor 0x%lx\n", 218fc256490SJason Beloro px_hsvc_sdio_err.hsvc_major, px_sdio_err_min_ver); 219fc256490SJason Beloro } 220fc256490SJason Beloro 221fc256490SJason Beloro /* 222fc256490SJason Beloro * Find out the number of dev we need to wait under this RC 223fc256490SJason Beloro * before we issue fabric sync hypercall 224fc256490SJason Beloro */ 225fc256490SJason Beloro px_p->px_plat_p = (void *)(uintptr_t)px_lib_count_waiting_dev(dip); 226fc256490SJason Beloro DBG(DBG_ATTACH, dip, "Found %d bridges need waiting under RC %p", 227fc256490SJason Beloro (int)(uintptr_t)px_p->px_plat_p, dip); 2287c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2327c478bd9Sstevel@tonic-gate int 2337c478bd9Sstevel@tonic-gate px_lib_dev_fini(dev_info_t *dip) 2347c478bd9Sstevel@tonic-gate { 2357c478bd9Sstevel@tonic-gate DBG(DBG_DETACH, dip, "px_lib_dev_fini: dip 0x%p\n", dip); 2367c478bd9Sstevel@tonic-gate 237b65731f1Skini (void) ddi_prop_remove(makedevice(ddi_driver_major(dip), 23826947304SEvan Yan PCI_MINOR_NUM(ddi_get_instance(dip), PCI_DEVCTL_MINOR)), dip, 239b65731f1Skini PCI_BUS_CONF_MAP_PROP); 240b65731f1Skini 24144bb982bSgovinda if (--px_vpci_users == 0) 242fc256490SJason Beloro (void) hsvc_unregister(&px_hsvc_vpci); 243fc256490SJason Beloro 244fc256490SJason Beloro if (--px_sdio_users == 0) 245fc256490SJason Beloro (void) hsvc_unregister(&px_hsvc_sdio); 246fc256490SJason Beloro 247fc256490SJason Beloro if (--px_sdio_err_users == 0) 248fc256490SJason Beloro (void) hsvc_unregister(&px_hsvc_sdio_err); 24944bb982bSgovinda 2507c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2547c478bd9Sstevel@tonic-gate int 2557c478bd9Sstevel@tonic-gate px_lib_intr_devino_to_sysino(dev_info_t *dip, devino_t devino, 2567c478bd9Sstevel@tonic-gate sysino_t *sysino) 2577c478bd9Sstevel@tonic-gate { 2587c478bd9Sstevel@tonic-gate uint64_t ret; 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_devino_to_sysino: dip 0x%p " 2617c478bd9Sstevel@tonic-gate "devino 0x%x\n", dip, devino); 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate if ((ret = hvio_intr_devino_to_sysino(DIP_TO_HANDLE(dip), 2647c478bd9Sstevel@tonic-gate devino, sysino)) != H_EOK) { 2657c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, 2667c478bd9Sstevel@tonic-gate "hvio_intr_devino_to_sysino failed, ret 0x%lx\n", ret); 2677c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_devino_to_sysino: sysino 0x%llx\n", 2717c478bd9Sstevel@tonic-gate *sysino); 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2777c478bd9Sstevel@tonic-gate int 2787c478bd9Sstevel@tonic-gate px_lib_intr_getvalid(dev_info_t *dip, sysino_t sysino, 2797c478bd9Sstevel@tonic-gate intr_valid_state_t *intr_valid_state) 2807c478bd9Sstevel@tonic-gate { 2817c478bd9Sstevel@tonic-gate uint64_t ret; 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_getvalid: dip 0x%p sysino 0x%llx\n", 2847c478bd9Sstevel@tonic-gate dip, sysino); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate if ((ret = hvio_intr_getvalid(sysino, 2877c478bd9Sstevel@tonic-gate (int *)intr_valid_state)) != H_EOK) { 2887c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "hvio_intr_getvalid failed, ret 0x%lx\n", 2897c478bd9Sstevel@tonic-gate ret); 2907c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_getvalid: intr_valid_state 0x%x\n", 2947c478bd9Sstevel@tonic-gate *intr_valid_state); 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3007c478bd9Sstevel@tonic-gate int 3017c478bd9Sstevel@tonic-gate px_lib_intr_setvalid(dev_info_t *dip, sysino_t sysino, 3027c478bd9Sstevel@tonic-gate intr_valid_state_t intr_valid_state) 3037c478bd9Sstevel@tonic-gate { 3047c478bd9Sstevel@tonic-gate uint64_t ret; 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_setvalid: dip 0x%p sysino 0x%llx " 3077c478bd9Sstevel@tonic-gate "intr_valid_state 0x%x\n", dip, sysino, intr_valid_state); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate if ((ret = hvio_intr_setvalid(sysino, intr_valid_state)) != H_EOK) { 3107c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "hvio_intr_setvalid failed, ret 0x%lx\n", 3117c478bd9Sstevel@tonic-gate ret); 3127c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3197c478bd9Sstevel@tonic-gate int 3207c478bd9Sstevel@tonic-gate px_lib_intr_getstate(dev_info_t *dip, sysino_t sysino, 3217c478bd9Sstevel@tonic-gate intr_state_t *intr_state) 3227c478bd9Sstevel@tonic-gate { 3237c478bd9Sstevel@tonic-gate uint64_t ret; 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_getstate: dip 0x%p sysino 0x%llx\n", 3267c478bd9Sstevel@tonic-gate dip, sysino); 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate if ((ret = hvio_intr_getstate(sysino, (int *)intr_state)) != H_EOK) { 3297c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "hvio_intr_getstate failed, ret 0x%lx\n", 3307c478bd9Sstevel@tonic-gate ret); 3317c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_getstate: intr_state 0x%x\n", 3357c478bd9Sstevel@tonic-gate *intr_state); 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3417c478bd9Sstevel@tonic-gate int 3427c478bd9Sstevel@tonic-gate px_lib_intr_setstate(dev_info_t *dip, sysino_t sysino, 3437c478bd9Sstevel@tonic-gate intr_state_t intr_state) 3447c478bd9Sstevel@tonic-gate { 3457c478bd9Sstevel@tonic-gate uint64_t ret; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_setstate: dip 0x%p sysino 0x%llx " 3487c478bd9Sstevel@tonic-gate "intr_state 0x%x\n", dip, sysino, intr_state); 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate if ((ret = hvio_intr_setstate(sysino, intr_state)) != H_EOK) { 3517c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "hvio_intr_setstate failed, ret 0x%lx\n", 3527c478bd9Sstevel@tonic-gate ret); 3537c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 3547c478bd9Sstevel@tonic-gate } 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3607c478bd9Sstevel@tonic-gate int 3617c478bd9Sstevel@tonic-gate px_lib_intr_gettarget(dev_info_t *dip, sysino_t sysino, cpuid_t *cpuid) 3627c478bd9Sstevel@tonic-gate { 3637c478bd9Sstevel@tonic-gate uint64_t ret; 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_gettarget: dip 0x%p sysino 0x%llx\n", 3667c478bd9Sstevel@tonic-gate dip, sysino); 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate if ((ret = hvio_intr_gettarget(sysino, cpuid)) != H_EOK) { 3697c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, 3707c478bd9Sstevel@tonic-gate "hvio_intr_gettarget failed, ret 0x%lx\n", ret); 3717c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate 37409b1eac2SEvan Yan DBG(DBG_LIB_INT, dip, "px_lib_intr_gettarget: cpuid 0x%x\n", *cpuid); 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3807c478bd9Sstevel@tonic-gate int 3817c478bd9Sstevel@tonic-gate px_lib_intr_settarget(dev_info_t *dip, sysino_t sysino, cpuid_t cpuid) 3827c478bd9Sstevel@tonic-gate { 3837c478bd9Sstevel@tonic-gate uint64_t ret; 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_settarget: dip 0x%p sysino 0x%llx " 3867c478bd9Sstevel@tonic-gate "cpuid 0x%x\n", dip, sysino, cpuid); 3877c478bd9Sstevel@tonic-gate 388d8d130aeSanbui ret = hvio_intr_settarget(sysino, cpuid); 389d8d130aeSanbui if (ret == H_ECPUERROR) { 390d8d130aeSanbui cmn_err(CE_PANIC, 391d8d130aeSanbui "px_lib_intr_settarget: hvio_intr_settarget failed, " 392d8d130aeSanbui "ret = 0x%lx, cpuid = 0x%x, sysino = 0x%lx\n", ret, 393d8d130aeSanbui cpuid, sysino); 394d8d130aeSanbui } else if (ret != H_EOK) { 3957c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, 3967c478bd9Sstevel@tonic-gate "hvio_intr_settarget failed, ret 0x%lx\n", ret); 3977c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 4047c478bd9Sstevel@tonic-gate int 4057c478bd9Sstevel@tonic-gate px_lib_intr_reset(dev_info_t *dip) 4067c478bd9Sstevel@tonic-gate { 4079c75c6bfSgovinda px_t *px_p = DIP_TO_STATE(dip); 4089c75c6bfSgovinda px_ib_t *ib_p = px_p->px_ib_p; 409b0fc0e77Sgovinda px_ino_t *ino_p; 4109c75c6bfSgovinda 4117c478bd9Sstevel@tonic-gate DBG(DBG_LIB_INT, dip, "px_lib_intr_reset: dip 0x%p\n", dip); 4127c478bd9Sstevel@tonic-gate 4139c75c6bfSgovinda mutex_enter(&ib_p->ib_ino_lst_mutex); 4149c75c6bfSgovinda 4159c75c6bfSgovinda /* Reset all Interrupts */ 416b0fc0e77Sgovinda for (ino_p = ib_p->ib_ino_lst; ino_p; ino_p = ino_p->ino_next_p) { 4179c75c6bfSgovinda if (px_lib_intr_setstate(dip, ino_p->ino_sysino, 4189c75c6bfSgovinda INTR_IDLE_STATE) != DDI_SUCCESS) 4199c75c6bfSgovinda return (BF_FATAL); 4209c75c6bfSgovinda } 4219c75c6bfSgovinda 4229c75c6bfSgovinda mutex_exit(&ib_p->ib_ino_lst_mutex); 4239c75c6bfSgovinda 4249c75c6bfSgovinda return (BF_NONE); 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 4287c478bd9Sstevel@tonic-gate int 4297c478bd9Sstevel@tonic-gate px_lib_iommu_map(dev_info_t *dip, tsbid_t tsbid, pages_t pages, 43044bb982bSgovinda io_attributes_t attr, void *addr, size_t pfn_index, int flags) 4317c478bd9Sstevel@tonic-gate { 4327c478bd9Sstevel@tonic-gate tsbnum_t tsb_num = PCI_TSBID_TO_TSBNUM(tsbid); 4335bc7e870Sgovinda tsbindex_t tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid); 4345bc7e870Sgovinda io_page_list_t *pfns, *pfn_p; 4355bc7e870Sgovinda pages_t ttes_mapped = 0; 4367c478bd9Sstevel@tonic-gate int i, err = DDI_SUCCESS; 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, "px_lib_iommu_map: dip 0x%p tsbid 0x%llx " 439ef2504f2SDaniel Ice "pages 0x%x attr 0x%llx addr 0x%p pfn_index 0x%llx flags 0x%x\n", 44044bb982bSgovinda dip, tsbid, pages, attr, addr, pfn_index, flags); 4417c478bd9Sstevel@tonic-gate 4425bc7e870Sgovinda if ((pfns = pfn_p = kmem_zalloc((pages * sizeof (io_page_list_t)), 4437c478bd9Sstevel@tonic-gate KM_NOSLEEP)) == NULL) { 4447c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, "px_lib_iommu_map: kmem_zalloc failed\n"); 4457c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4485bc7e870Sgovinda for (i = 0; i < pages; i++) 44944bb982bSgovinda pfns[i] = MMU_PTOB(PX_ADDR2PFN(addr, pfn_index, flags, i)); 4507c478bd9Sstevel@tonic-gate 4515a40150bSam139583 /* 4523d78e6abSAlan Adamson, SD OSSD * If HV VPCI version is 2.0 and higher, pass BDF, phantom function, 45344961713Sgirish * and relaxed ordering attributes. Otherwise, pass only read or write 45444961713Sgirish * attribute. 4555a40150bSam139583 */ 4563d78e6abSAlan Adamson, SD OSSD if ((px_vpci_maj_ver == PX_HSVC_MAJOR_VER_1) && 4573d78e6abSAlan Adamson, SD OSSD (px_vpci_min_ver == PX_HSVC_MINOR_VER_0)) 4585a40150bSam139583 attr = attr & (PCI_MAP_ATTR_READ | PCI_MAP_ATTR_WRITE); 4595a40150bSam139583 4605bc7e870Sgovinda while ((ttes_mapped = pfn_p - pfns) < pages) { 4615bc7e870Sgovinda uintptr_t ra = va_to_pa(pfn_p); 4625bc7e870Sgovinda pages_t ttes2map; 4635bc7e870Sgovinda uint64_t ret; 4647c478bd9Sstevel@tonic-gate 4655bc7e870Sgovinda ttes2map = (MMU_PAGE_SIZE - P2PHASE(ra, MMU_PAGE_SIZE)) >> 3; 4665bc7e870Sgovinda ra = MMU_PTOB(MMU_BTOP(ra)); 4677c478bd9Sstevel@tonic-gate 4685bc7e870Sgovinda for (ttes2map = MIN(ttes2map, pages - ttes_mapped); ttes2map; 4695bc7e870Sgovinda ttes2map -= ttes_mapped, pfn_p += ttes_mapped) { 4707c478bd9Sstevel@tonic-gate 4715bc7e870Sgovinda ttes_mapped = 0; 4727c478bd9Sstevel@tonic-gate if ((ret = hvio_iommu_map(DIP_TO_HANDLE(dip), 4735bc7e870Sgovinda PCI_TSBID(tsb_num, tsb_index + (pfn_p - pfns)), 47444bb982bSgovinda ttes2map, attr, (io_page_list_t *)(ra | 4755bc7e870Sgovinda ((uintptr_t)pfn_p & MMU_PAGE_OFFSET)), 4765bc7e870Sgovinda &ttes_mapped)) != H_EOK) { 4775bc7e870Sgovinda DBG(DBG_LIB_DMA, dip, "hvio_iommu_map failed " 4785bc7e870Sgovinda "ret 0x%lx\n", ret); 4795bc7e870Sgovinda 4805bc7e870Sgovinda ttes_mapped = pfn_p - pfns; 4817c478bd9Sstevel@tonic-gate err = DDI_FAILURE; 4825bc7e870Sgovinda goto cleanup; 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4855bc7e870Sgovinda DBG(DBG_LIB_DMA, dip, "px_lib_iommu_map: tsb_num 0x%x " 486ef2504f2SDaniel Ice "tsb_index 0x%lx ttes_to_map 0x%lx attr 0x%llx " 4875bc7e870Sgovinda "ra 0x%p ttes_mapped 0x%x\n", tsb_num, 48844bb982bSgovinda tsb_index + (pfn_p - pfns), ttes2map, attr, 4895bc7e870Sgovinda ra | ((uintptr_t)pfn_p & MMU_PAGE_OFFSET), 4905bc7e870Sgovinda ttes_mapped); 4915bc7e870Sgovinda } 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4945bc7e870Sgovinda cleanup: 4955bc7e870Sgovinda if ((err == DDI_FAILURE) && ttes_mapped) 4965bc7e870Sgovinda (void) px_lib_iommu_demap(dip, tsbid, ttes_mapped); 4977c478bd9Sstevel@tonic-gate 4985bc7e870Sgovinda kmem_free(pfns, pages * sizeof (io_page_list_t)); 4997c478bd9Sstevel@tonic-gate return (err); 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5037c478bd9Sstevel@tonic-gate int 5047c478bd9Sstevel@tonic-gate px_lib_iommu_demap(dev_info_t *dip, tsbid_t tsbid, pages_t pages) 5057c478bd9Sstevel@tonic-gate { 5067c478bd9Sstevel@tonic-gate tsbnum_t tsb_num = PCI_TSBID_TO_TSBNUM(tsbid); 5075bc7e870Sgovinda tsbindex_t tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid); 5085bc7e870Sgovinda pages_t ttes2demap, ttes_demapped = 0; 5097c478bd9Sstevel@tonic-gate uint64_t ret; 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, "px_lib_iommu_demap: dip 0x%p tsbid 0x%llx " 5127c478bd9Sstevel@tonic-gate "pages 0x%x\n", dip, tsbid, pages); 5137c478bd9Sstevel@tonic-gate 5145bc7e870Sgovinda for (ttes2demap = pages; ttes2demap; 5155bc7e870Sgovinda ttes2demap -= ttes_demapped, tsb_index += ttes_demapped) { 5167c478bd9Sstevel@tonic-gate if ((ret = hvio_iommu_demap(DIP_TO_HANDLE(dip), 5175bc7e870Sgovinda PCI_TSBID(tsb_num, tsb_index), ttes2demap, 5185bc7e870Sgovinda &ttes_demapped)) != H_EOK) { 5195bc7e870Sgovinda DBG(DBG_LIB_DMA, dip, "hvio_iommu_demap failed, " 5205bc7e870Sgovinda "ret 0x%lx\n", ret); 5215bc7e870Sgovinda 5227c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate 5255bc7e870Sgovinda DBG(DBG_LIB_DMA, dip, "px_lib_iommu_demap: tsb_num 0x%x " 5265bc7e870Sgovinda "tsb_index 0x%lx ttes_to_demap 0x%lx ttes_demapped 0x%x\n", 5275bc7e870Sgovinda tsb_num, tsb_index, ttes2demap, ttes_demapped); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5347c478bd9Sstevel@tonic-gate int 53544bb982bSgovinda px_lib_iommu_getmap(dev_info_t *dip, tsbid_t tsbid, io_attributes_t *attr_p, 53644bb982bSgovinda r_addr_t *r_addr_p) 5377c478bd9Sstevel@tonic-gate { 5387c478bd9Sstevel@tonic-gate uint64_t ret; 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getmap: dip 0x%p tsbid 0x%llx\n", 5417c478bd9Sstevel@tonic-gate dip, tsbid); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate if ((ret = hvio_iommu_getmap(DIP_TO_HANDLE(dip), tsbid, 54444bb982bSgovinda attr_p, r_addr_p)) != H_EOK) { 5457c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, 5467c478bd9Sstevel@tonic-gate "hvio_iommu_getmap failed, ret 0x%lx\n", ret); 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate return ((ret == H_ENOMAP) ? DDI_DMA_NOMAPPING:DDI_FAILURE); 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate 551ef2504f2SDaniel Ice DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getmap: attr 0x%llx " 552ef2504f2SDaniel Ice "r_addr 0x%llx\n", *attr_p, *r_addr_p); 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate 55725cf1a30Sjl139090 /*ARGSUSED*/ 558*89b42a21Sandrew.rutz@sun.com int 559*89b42a21Sandrew.rutz@sun.com px_lib_iommu_detach(px_t *px_p) 560*89b42a21Sandrew.rutz@sun.com { 561*89b42a21Sandrew.rutz@sun.com return (DDI_SUCCESS); 562*89b42a21Sandrew.rutz@sun.com } 563*89b42a21Sandrew.rutz@sun.com 564*89b42a21Sandrew.rutz@sun.com /*ARGSUSED*/ 56525cf1a30Sjl139090 uint64_t 566d3533785Sschwartz px_get_rng_parent_hi_mask(px_t *px_p) 56725cf1a30Sjl139090 { 568d3533785Sschwartz return (PX_RANGE_PROP_MASK); 56925cf1a30Sjl139090 } 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate /* 5727c478bd9Sstevel@tonic-gate * Checks dma attributes against system bypass ranges 5737c478bd9Sstevel@tonic-gate * A sun4v device must be capable of generating the entire 64-bit 5747c478bd9Sstevel@tonic-gate * address in order to perform bypass DMA. 5757c478bd9Sstevel@tonic-gate */ 5767c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5777c478bd9Sstevel@tonic-gate int 57825cf1a30Sjl139090 px_lib_dma_bypass_rngchk(dev_info_t *dip, ddi_dma_attr_t *attr_p, 57925cf1a30Sjl139090 uint64_t *lo_p, uint64_t *hi_p) 5807c478bd9Sstevel@tonic-gate { 58144bb982bSgovinda if ((attr_p->dma_attr_addr_lo != 0ull) || 58244bb982bSgovinda (attr_p->dma_attr_addr_hi != UINT64_MAX)) { 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate return (DDI_DMA_BADATTR); 5857c478bd9Sstevel@tonic-gate } 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate *lo_p = 0ull; 5887c478bd9Sstevel@tonic-gate *hi_p = UINT64_MAX; 5897c478bd9Sstevel@tonic-gate 5907c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 5917c478bd9Sstevel@tonic-gate } 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5957c478bd9Sstevel@tonic-gate int 59644bb982bSgovinda px_lib_iommu_getbypass(dev_info_t *dip, r_addr_t ra, io_attributes_t attr, 59744bb982bSgovinda io_addr_t *io_addr_p) 5987c478bd9Sstevel@tonic-gate { 5997c478bd9Sstevel@tonic-gate uint64_t ret; 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getbypass: dip 0x%p ra 0x%llx " 602ef2504f2SDaniel Ice "attr 0x%llx\n", dip, ra, attr); 6036142aa70Sandrew.rutz@sun.com /* 6043d78e6abSAlan Adamson, SD OSSD * If HV VPCI version is 2.0 and higher, pass BDF, phantom function, 6056142aa70Sandrew.rutz@sun.com * and relaxed ordering attributes. Otherwise, pass only read or write 6066142aa70Sandrew.rutz@sun.com * attribute. 6076142aa70Sandrew.rutz@sun.com */ 6083d78e6abSAlan Adamson, SD OSSD if ((px_vpci_maj_ver == PX_HSVC_MAJOR_VER_1) && 6093d78e6abSAlan Adamson, SD OSSD (px_vpci_min_ver == PX_HSVC_MINOR_VER_0)) 6106142aa70Sandrew.rutz@sun.com attr &= PCI_MAP_ATTR_READ | PCI_MAP_ATTR_WRITE; 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate if ((ret = hvio_iommu_getbypass(DIP_TO_HANDLE(dip), ra, 61344bb982bSgovinda attr, io_addr_p)) != H_EOK) { 6147c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, 6157c478bd9Sstevel@tonic-gate "hvio_iommu_getbypass failed, ret 0x%lx\n", ret); 6167c478bd9Sstevel@tonic-gate return (ret == H_ENOTSUPPORTED ? DDI_ENOTSUP : DDI_FAILURE); 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getbypass: io_addr 0x%llx\n", 6207c478bd9Sstevel@tonic-gate *io_addr_p); 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 6237c478bd9Sstevel@tonic-gate } 6247c478bd9Sstevel@tonic-gate 625a616a11eSLida.Horn /* 626a616a11eSLida.Horn * Returns any needed IO address bit(s) for relaxed ordering in IOMMU 627a616a11eSLida.Horn * bypass mode. 628a616a11eSLida.Horn */ 629a616a11eSLida.Horn /* ARGSUSED */ 630a616a11eSLida.Horn uint64_t 631a616a11eSLida.Horn px_lib_ro_bypass(dev_info_t *dip, io_attributes_t attr, uint64_t ioaddr) 632a616a11eSLida.Horn { 633a616a11eSLida.Horn return (ioaddr); 634a616a11eSLida.Horn } 635a616a11eSLida.Horn 6367c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 6377c478bd9Sstevel@tonic-gate int 6387c478bd9Sstevel@tonic-gate px_lib_dma_sync(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle, 6397c478bd9Sstevel@tonic-gate off_t off, size_t len, uint_t cache_flags) 6407c478bd9Sstevel@tonic-gate { 6417c478bd9Sstevel@tonic-gate ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle; 6427c478bd9Sstevel@tonic-gate uint64_t sync_dir; 64322bbbd20Saa72041 size_t bytes_synced; 64422bbbd20Saa72041 int end, idx; 64522bbbd20Saa72041 off_t pg_off; 64622bbbd20Saa72041 devhandle_t hdl = DIP_TO_HANDLE(dip); /* need to cache hdl */ 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate DBG(DBG_LIB_DMA, dip, "px_lib_dma_sync: dip 0x%p rdip 0x%p " 6497c478bd9Sstevel@tonic-gate "handle 0x%llx off 0x%x len 0x%x flags 0x%x\n", 6507c478bd9Sstevel@tonic-gate dip, rdip, handle, off, len, cache_flags); 6517c478bd9Sstevel@tonic-gate 65236fe4a92Segillett if (!(mp->dmai_flags & PX_DMAI_FLAGS_INUSE)) { 653f8d2de6bSjchu cmn_err(CE_WARN, "%s%d: Unbound dma handle %p.", 654f8d2de6bSjchu ddi_driver_name(rdip), ddi_get_instance(rdip), (void *)mp); 6557c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate 65836fe4a92Segillett if (mp->dmai_flags & PX_DMAI_FLAGS_NOSYNC) 6597c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate if (!len) 6627c478bd9Sstevel@tonic-gate len = mp->dmai_size; 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate if (mp->dmai_rflags & DDI_DMA_READ) 6657c478bd9Sstevel@tonic-gate sync_dir = HVIO_DMA_SYNC_DIR_FROM_DEV; 6667c478bd9Sstevel@tonic-gate else 6677c478bd9Sstevel@tonic-gate sync_dir = HVIO_DMA_SYNC_DIR_TO_DEV; 6687c478bd9Sstevel@tonic-gate 66922bbbd20Saa72041 off += mp->dmai_offset; 67022bbbd20Saa72041 pg_off = off & MMU_PAGEOFFSET; 67122bbbd20Saa72041 67222bbbd20Saa72041 DBG(DBG_LIB_DMA, dip, "px_lib_dma_sync: page offset %x size %x\n", 67322bbbd20Saa72041 pg_off, len); 67422bbbd20Saa72041 67522bbbd20Saa72041 /* sync on page basis */ 67622bbbd20Saa72041 end = MMU_BTOPR(off + len - 1); 67722bbbd20Saa72041 for (idx = MMU_BTOP(off); idx < end; idx++, 67822bbbd20Saa72041 len -= bytes_synced, pg_off = 0) { 6799d0d62adSJason Beloro size_t bytes_to_sync = bytes_to_sync = 6809d0d62adSJason Beloro MIN(len, MMU_PAGESIZE - pg_off); 68122bbbd20Saa72041 6829d0d62adSJason Beloro if (hvio_dma_sync(hdl, MMU_PTOB(PX_GET_MP_PFN(mp, idx)) + 6839d0d62adSJason Beloro pg_off, bytes_to_sync, sync_dir, &bytes_synced) != H_EOK) 68422bbbd20Saa72041 break; 68522bbbd20Saa72041 68622bbbd20Saa72041 DBG(DBG_LIB_DMA, dip, "px_lib_dma_sync: Called hvio_dma_sync " 68722bbbd20Saa72041 "ra = %p bytes to sync = %x bytes synced %x\n", 68822bbbd20Saa72041 MMU_PTOB(PX_GET_MP_PFN(mp, idx)) + pg_off, bytes_to_sync, 68922bbbd20Saa72041 bytes_synced); 69022bbbd20Saa72041 69122bbbd20Saa72041 if (bytes_to_sync != bytes_synced) 69222bbbd20Saa72041 break; 6937c478bd9Sstevel@tonic-gate } 6947c478bd9Sstevel@tonic-gate 69522bbbd20Saa72041 return (len ? DDI_FAILURE : DDI_SUCCESS); 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate /* 7007c478bd9Sstevel@tonic-gate * MSIQ Functions: 7017c478bd9Sstevel@tonic-gate */ 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 7047c478bd9Sstevel@tonic-gate int 7057c478bd9Sstevel@tonic-gate px_lib_msiq_init(dev_info_t *dip) 7067c478bd9Sstevel@tonic-gate { 7077c478bd9Sstevel@tonic-gate px_t *px_p = DIP_TO_STATE(dip); 7087c478bd9Sstevel@tonic-gate px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 70995003185Segillett r_addr_t ra; 7107c478bd9Sstevel@tonic-gate size_t msiq_size; 7117c478bd9Sstevel@tonic-gate uint_t rec_cnt; 7127c478bd9Sstevel@tonic-gate int i, err = DDI_SUCCESS; 7137c478bd9Sstevel@tonic-gate uint64_t ret; 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_init: dip 0x%p\n", dip); 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate msiq_size = msiq_state_p->msiq_rec_cnt * sizeof (msiq_rec_t); 7187c478bd9Sstevel@tonic-gate 719348fdf9eSAlan Adamson, SD OSSD /* sun4v requires all EQ allocation to be on q size boundary */ 720348fdf9eSAlan Adamson, SD OSSD if ((msiq_state_p->msiq_buf_p = contig_mem_alloc_align( 721348fdf9eSAlan Adamson, SD OSSD msiq_state_p->msiq_cnt * msiq_size, msiq_size)) == NULL) { 722348fdf9eSAlan Adamson, SD OSSD DBG(DBG_LIB_MSIQ, dip, 723348fdf9eSAlan Adamson, SD OSSD "px_lib_msiq_init: Contig alloc failed\n"); 724348fdf9eSAlan Adamson, SD OSSD 725348fdf9eSAlan Adamson, SD OSSD return (DDI_FAILURE); 726348fdf9eSAlan Adamson, SD OSSD } 727348fdf9eSAlan Adamson, SD OSSD 7287c478bd9Sstevel@tonic-gate for (i = 0; i < msiq_state_p->msiq_cnt; i++) { 729348fdf9eSAlan Adamson, SD OSSD msiq_state_p->msiq_p[i].msiq_base_p = (msiqhead_t *) 730348fdf9eSAlan Adamson, SD OSSD ((caddr_t)msiq_state_p->msiq_buf_p + (i * msiq_size)); 731348fdf9eSAlan Adamson, SD OSSD 73295003185Segillett ra = (r_addr_t)va_to_pa((caddr_t)msiq_state_p->msiq_buf_p + 73395003185Segillett (i * msiq_size)); 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_conf(DIP_TO_HANDLE(dip), 7367c478bd9Sstevel@tonic-gate (i + msiq_state_p->msiq_1st_msiq_id), 7377c478bd9Sstevel@tonic-gate ra, msiq_state_p->msiq_rec_cnt)) != H_EOK) { 7387c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 7397c478bd9Sstevel@tonic-gate "hvio_msiq_conf failed, ret 0x%lx\n", ret); 7407c478bd9Sstevel@tonic-gate err = DDI_FAILURE; 7417c478bd9Sstevel@tonic-gate break; 7427c478bd9Sstevel@tonic-gate } 7437c478bd9Sstevel@tonic-gate 7447c478bd9Sstevel@tonic-gate if ((err = px_lib_msiq_info(dip, 7457c478bd9Sstevel@tonic-gate (i + msiq_state_p->msiq_1st_msiq_id), 7467c478bd9Sstevel@tonic-gate &ra, &rec_cnt)) != DDI_SUCCESS) { 7477c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 7487c478bd9Sstevel@tonic-gate "px_lib_msiq_info failed, ret 0x%x\n", err); 7497c478bd9Sstevel@tonic-gate err = DDI_FAILURE; 7507c478bd9Sstevel@tonic-gate break; 7517c478bd9Sstevel@tonic-gate } 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 7547c478bd9Sstevel@tonic-gate "px_lib_msiq_init: ra 0x%p rec_cnt 0x%x\n", ra, rec_cnt); 7557c478bd9Sstevel@tonic-gate } 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate return (err); 7587c478bd9Sstevel@tonic-gate } 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 7617c478bd9Sstevel@tonic-gate int 7627c478bd9Sstevel@tonic-gate px_lib_msiq_fini(dev_info_t *dip) 7637c478bd9Sstevel@tonic-gate { 764348fdf9eSAlan Adamson, SD OSSD px_t *px_p = DIP_TO_STATE(dip); 765348fdf9eSAlan Adamson, SD OSSD px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 766348fdf9eSAlan Adamson, SD OSSD size_t msiq_size; 767348fdf9eSAlan Adamson, SD OSSD 7687c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_fini: dip 0x%p\n", dip); 769348fdf9eSAlan Adamson, SD OSSD msiq_size = msiq_state_p->msiq_rec_cnt * sizeof (msiq_rec_t); 770348fdf9eSAlan Adamson, SD OSSD 771348fdf9eSAlan Adamson, SD OSSD if (msiq_state_p->msiq_buf_p != NULL) 772348fdf9eSAlan Adamson, SD OSSD contig_mem_free(msiq_state_p->msiq_buf_p, 773348fdf9eSAlan Adamson, SD OSSD msiq_state_p->msiq_cnt * msiq_size); 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 7767c478bd9Sstevel@tonic-gate } 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 7797c478bd9Sstevel@tonic-gate int 7807c478bd9Sstevel@tonic-gate px_lib_msiq_info(dev_info_t *dip, msiqid_t msiq_id, r_addr_t *ra_p, 7817c478bd9Sstevel@tonic-gate uint_t *msiq_rec_cnt_p) 7827c478bd9Sstevel@tonic-gate { 7837c478bd9Sstevel@tonic-gate uint64_t ret; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_msiq_info: dip 0x%p msiq_id 0x%x\n", 7867c478bd9Sstevel@tonic-gate dip, msiq_id); 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_info(DIP_TO_HANDLE(dip), 7897c478bd9Sstevel@tonic-gate msiq_id, ra_p, msiq_rec_cnt_p)) != H_EOK) { 7907c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 7917c478bd9Sstevel@tonic-gate "hvio_msiq_info failed, ret 0x%lx\n", ret); 7927c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 7937c478bd9Sstevel@tonic-gate } 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_msiq_info: ra_p 0x%p msiq_rec_cnt 0x%x\n", 7967c478bd9Sstevel@tonic-gate ra_p, *msiq_rec_cnt_p); 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8027c478bd9Sstevel@tonic-gate int 8037c478bd9Sstevel@tonic-gate px_lib_msiq_getvalid(dev_info_t *dip, msiqid_t msiq_id, 8047c478bd9Sstevel@tonic-gate pci_msiq_valid_state_t *msiq_valid_state) 8057c478bd9Sstevel@tonic-gate { 8067c478bd9Sstevel@tonic-gate uint64_t ret; 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_getvalid: dip 0x%p msiq_id 0x%x\n", 8097c478bd9Sstevel@tonic-gate dip, msiq_id); 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_getvalid(DIP_TO_HANDLE(dip), 8127c478bd9Sstevel@tonic-gate msiq_id, msiq_valid_state)) != H_EOK) { 8137c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 8147c478bd9Sstevel@tonic-gate "hvio_msiq_getvalid failed, ret 0x%lx\n", ret); 8157c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_getvalid: msiq_valid_state 0x%x\n", 8197c478bd9Sstevel@tonic-gate *msiq_valid_state); 8207c478bd9Sstevel@tonic-gate 8217c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 8227c478bd9Sstevel@tonic-gate } 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8257c478bd9Sstevel@tonic-gate int 8267c478bd9Sstevel@tonic-gate px_lib_msiq_setvalid(dev_info_t *dip, msiqid_t msiq_id, 8277c478bd9Sstevel@tonic-gate pci_msiq_valid_state_t msiq_valid_state) 8287c478bd9Sstevel@tonic-gate { 8297c478bd9Sstevel@tonic-gate uint64_t ret; 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_setvalid: dip 0x%p msiq_id 0x%x " 8327c478bd9Sstevel@tonic-gate "msiq_valid_state 0x%x\n", dip, msiq_id, msiq_valid_state); 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_setvalid(DIP_TO_HANDLE(dip), 8357c478bd9Sstevel@tonic-gate msiq_id, msiq_valid_state)) != H_EOK) { 8367c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 8377c478bd9Sstevel@tonic-gate "hvio_msiq_setvalid failed, ret 0x%lx\n", ret); 8387c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 8397c478bd9Sstevel@tonic-gate } 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8457c478bd9Sstevel@tonic-gate int 8467c478bd9Sstevel@tonic-gate px_lib_msiq_getstate(dev_info_t *dip, msiqid_t msiq_id, 8477c478bd9Sstevel@tonic-gate pci_msiq_state_t *msiq_state) 8487c478bd9Sstevel@tonic-gate { 8497c478bd9Sstevel@tonic-gate uint64_t ret; 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_getstate: dip 0x%p msiq_id 0x%x\n", 8527c478bd9Sstevel@tonic-gate dip, msiq_id); 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_getstate(DIP_TO_HANDLE(dip), 8557c478bd9Sstevel@tonic-gate msiq_id, msiq_state)) != H_EOK) { 8567c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 8577c478bd9Sstevel@tonic-gate "hvio_msiq_getstate failed, ret 0x%lx\n", ret); 8587c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 8597c478bd9Sstevel@tonic-gate } 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_getstate: msiq_state 0x%x\n", 8627c478bd9Sstevel@tonic-gate *msiq_state); 8637c478bd9Sstevel@tonic-gate 8647c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 8657c478bd9Sstevel@tonic-gate } 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8687c478bd9Sstevel@tonic-gate int 8697c478bd9Sstevel@tonic-gate px_lib_msiq_setstate(dev_info_t *dip, msiqid_t msiq_id, 8707c478bd9Sstevel@tonic-gate pci_msiq_state_t msiq_state) 8717c478bd9Sstevel@tonic-gate { 8727c478bd9Sstevel@tonic-gate uint64_t ret; 8737c478bd9Sstevel@tonic-gate 8747c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_setstate: dip 0x%p msiq_id 0x%x " 8757c478bd9Sstevel@tonic-gate "msiq_state 0x%x\n", dip, msiq_id, msiq_state); 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_setstate(DIP_TO_HANDLE(dip), 8787c478bd9Sstevel@tonic-gate msiq_id, msiq_state)) != H_EOK) { 8797c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 8807c478bd9Sstevel@tonic-gate "hvio_msiq_setstate failed, ret 0x%lx\n", ret); 8817c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 8827c478bd9Sstevel@tonic-gate } 8837c478bd9Sstevel@tonic-gate 8847c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 8857c478bd9Sstevel@tonic-gate } 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8887c478bd9Sstevel@tonic-gate int 8897c478bd9Sstevel@tonic-gate px_lib_msiq_gethead(dev_info_t *dip, msiqid_t msiq_id, 8907c478bd9Sstevel@tonic-gate msiqhead_t *msiq_head_p) 8917c478bd9Sstevel@tonic-gate { 8927c478bd9Sstevel@tonic-gate uint64_t ret; 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_gethead: dip 0x%p msiq_id 0x%x\n", 8957c478bd9Sstevel@tonic-gate dip, msiq_id); 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_gethead(DIP_TO_HANDLE(dip), 8987c478bd9Sstevel@tonic-gate msiq_id, msiq_head_p)) != H_EOK) { 8997c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 9007c478bd9Sstevel@tonic-gate "hvio_msiq_gethead failed, ret 0x%lx\n", ret); 9017c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate *msiq_head_p = (*msiq_head_p / sizeof (msiq_rec_t)); 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_msiq_gethead: msiq_head 0x%x\n", 9077c478bd9Sstevel@tonic-gate *msiq_head_p); 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 9137c478bd9Sstevel@tonic-gate int 9147c478bd9Sstevel@tonic-gate px_lib_msiq_sethead(dev_info_t *dip, msiqid_t msiq_id, 9157c478bd9Sstevel@tonic-gate msiqhead_t msiq_head) 9167c478bd9Sstevel@tonic-gate { 9177c478bd9Sstevel@tonic-gate uint64_t ret; 9187c478bd9Sstevel@tonic-gate 9197c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_sethead: dip 0x%p msiq_id 0x%x " 9207c478bd9Sstevel@tonic-gate "msiq_head 0x%x\n", dip, msiq_id, msiq_head); 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_sethead(DIP_TO_HANDLE(dip), 9237c478bd9Sstevel@tonic-gate msiq_id, msiq_head * sizeof (msiq_rec_t))) != H_EOK) { 9247c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 9257c478bd9Sstevel@tonic-gate "hvio_msiq_sethead failed, ret 0x%lx\n", ret); 9267c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 9277c478bd9Sstevel@tonic-gate } 9287c478bd9Sstevel@tonic-gate 9297c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 9307c478bd9Sstevel@tonic-gate } 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 9337c478bd9Sstevel@tonic-gate int 9347c478bd9Sstevel@tonic-gate px_lib_msiq_gettail(dev_info_t *dip, msiqid_t msiq_id, 9357c478bd9Sstevel@tonic-gate msiqtail_t *msiq_tail_p) 9367c478bd9Sstevel@tonic-gate { 9377c478bd9Sstevel@tonic-gate uint64_t ret; 9387c478bd9Sstevel@tonic-gate 9397c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_gettail: dip 0x%p msiq_id 0x%x\n", 9407c478bd9Sstevel@tonic-gate dip, msiq_id); 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate if ((ret = hvio_msiq_gettail(DIP_TO_HANDLE(dip), 9437c478bd9Sstevel@tonic-gate msiq_id, msiq_tail_p)) != H_EOK) { 9447c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, 9457c478bd9Sstevel@tonic-gate "hvio_msiq_gettail failed, ret 0x%lx\n", ret); 9467c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 9477c478bd9Sstevel@tonic-gate } 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate *msiq_tail_p = (*msiq_tail_p / sizeof (msiq_rec_t)); 9507c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_gettail: msiq_tail 0x%x\n", 9517c478bd9Sstevel@tonic-gate *msiq_tail_p); 9527c478bd9Sstevel@tonic-gate 9537c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 9547c478bd9Sstevel@tonic-gate } 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 9577c478bd9Sstevel@tonic-gate void 958023ccc1eSegillett px_lib_get_msiq_rec(dev_info_t *dip, msiqhead_t *msiq_head_p, 959023ccc1eSegillett msiq_rec_t *msiq_rec_p) 9607c478bd9Sstevel@tonic-gate { 961023ccc1eSegillett msiq_rec_t *curr_msiq_rec_p = (msiq_rec_t *)msiq_head_p; 9627c478bd9Sstevel@tonic-gate 9637c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSIQ, dip, "px_lib_get_msiq_rec: dip 0x%p\n", dip); 9647c478bd9Sstevel@tonic-gate 965b0fc0e77Sgovinda if (!curr_msiq_rec_p->msiq_rec_type) { 966b0fc0e77Sgovinda /* Set msiq_rec_type to zero */ 967b0fc0e77Sgovinda msiq_rec_p->msiq_rec_type = 0; 968b0fc0e77Sgovinda 9697c478bd9Sstevel@tonic-gate return; 970b0fc0e77Sgovinda } 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate *msiq_rec_p = *curr_msiq_rec_p; 973b0fc0e77Sgovinda } 974b0fc0e77Sgovinda 975b0fc0e77Sgovinda /*ARGSUSED*/ 976b0fc0e77Sgovinda void 977b0fc0e77Sgovinda px_lib_clr_msiq_rec(dev_info_t *dip, msiqhead_t *msiq_head_p) 978b0fc0e77Sgovinda { 979b0fc0e77Sgovinda msiq_rec_t *curr_msiq_rec_p = (msiq_rec_t *)msiq_head_p; 980b0fc0e77Sgovinda 981b0fc0e77Sgovinda DBG(DBG_LIB_MSIQ, dip, "px_lib_clr_msiq_rec: dip 0x%p\n", dip); 9827c478bd9Sstevel@tonic-gate 9833ee8f295Smg140465 /* Zero out msiq_rec_type field */ 9843ee8f295Smg140465 curr_msiq_rec_p->msiq_rec_type = 0; 9857c478bd9Sstevel@tonic-gate } 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate /* 9887c478bd9Sstevel@tonic-gate * MSI Functions: 9897c478bd9Sstevel@tonic-gate */ 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 9927c478bd9Sstevel@tonic-gate int 9937c478bd9Sstevel@tonic-gate px_lib_msi_init(dev_info_t *dip) 9947c478bd9Sstevel@tonic-gate { 9957c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_init: dip 0x%p\n", dip); 9967c478bd9Sstevel@tonic-gate 9977c478bd9Sstevel@tonic-gate /* Noop */ 9987c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 9997c478bd9Sstevel@tonic-gate } 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 10027c478bd9Sstevel@tonic-gate int 10037c478bd9Sstevel@tonic-gate px_lib_msi_getmsiq(dev_info_t *dip, msinum_t msi_num, 10047c478bd9Sstevel@tonic-gate msiqid_t *msiq_id) 10057c478bd9Sstevel@tonic-gate { 10067c478bd9Sstevel@tonic-gate uint64_t ret; 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_getmsiq: dip 0x%p msi_num 0x%x\n", 10097c478bd9Sstevel@tonic-gate dip, msi_num); 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate if ((ret = hvio_msi_getmsiq(DIP_TO_HANDLE(dip), 10127c478bd9Sstevel@tonic-gate msi_num, msiq_id)) != H_EOK) { 10137c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, 10147c478bd9Sstevel@tonic-gate "hvio_msi_getmsiq failed, ret 0x%lx\n", ret); 10157c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_getmsiq: msiq_id 0x%x\n", 10197c478bd9Sstevel@tonic-gate *msiq_id); 10207c478bd9Sstevel@tonic-gate 10217c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 10227c478bd9Sstevel@tonic-gate } 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 10257c478bd9Sstevel@tonic-gate int 10267c478bd9Sstevel@tonic-gate px_lib_msi_setmsiq(dev_info_t *dip, msinum_t msi_num, 10277c478bd9Sstevel@tonic-gate msiqid_t msiq_id, msi_type_t msitype) 10287c478bd9Sstevel@tonic-gate { 10297c478bd9Sstevel@tonic-gate uint64_t ret; 10307c478bd9Sstevel@tonic-gate 10317c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_setmsiq: dip 0x%p msi_num 0x%x " 10327c478bd9Sstevel@tonic-gate "msq_id 0x%x\n", dip, msi_num, msiq_id); 10337c478bd9Sstevel@tonic-gate 10347c478bd9Sstevel@tonic-gate if ((ret = hvio_msi_setmsiq(DIP_TO_HANDLE(dip), 10357c478bd9Sstevel@tonic-gate msi_num, msiq_id, msitype)) != H_EOK) { 10367c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, 10377c478bd9Sstevel@tonic-gate "hvio_msi_setmsiq failed, ret 0x%lx\n", ret); 10387c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 10397c478bd9Sstevel@tonic-gate } 10407c478bd9Sstevel@tonic-gate 10417c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 10427c478bd9Sstevel@tonic-gate } 10437c478bd9Sstevel@tonic-gate 10447c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 10457c478bd9Sstevel@tonic-gate int 10467c478bd9Sstevel@tonic-gate px_lib_msi_getvalid(dev_info_t *dip, msinum_t msi_num, 10477c478bd9Sstevel@tonic-gate pci_msi_valid_state_t *msi_valid_state) 10487c478bd9Sstevel@tonic-gate { 10497c478bd9Sstevel@tonic-gate uint64_t ret; 10507c478bd9Sstevel@tonic-gate 10517c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_getvalid: dip 0x%p msi_num 0x%x\n", 10527c478bd9Sstevel@tonic-gate dip, msi_num); 10537c478bd9Sstevel@tonic-gate 10547c478bd9Sstevel@tonic-gate if ((ret = hvio_msi_getvalid(DIP_TO_HANDLE(dip), 10557c478bd9Sstevel@tonic-gate msi_num, msi_valid_state)) != H_EOK) { 10567c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, 10577c478bd9Sstevel@tonic-gate "hvio_msi_getvalid failed, ret 0x%lx\n", ret); 10587c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 10597c478bd9Sstevel@tonic-gate } 10607c478bd9Sstevel@tonic-gate 10617c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_getvalid: msiq_id 0x%x\n", 10627c478bd9Sstevel@tonic-gate *msi_valid_state); 10637c478bd9Sstevel@tonic-gate 10647c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate 10677c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 10687c478bd9Sstevel@tonic-gate int 10697c478bd9Sstevel@tonic-gate px_lib_msi_setvalid(dev_info_t *dip, msinum_t msi_num, 10707c478bd9Sstevel@tonic-gate pci_msi_valid_state_t msi_valid_state) 10717c478bd9Sstevel@tonic-gate { 10727c478bd9Sstevel@tonic-gate uint64_t ret; 10737c478bd9Sstevel@tonic-gate 10747c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_setvalid: dip 0x%p msi_num 0x%x " 10757c478bd9Sstevel@tonic-gate "msi_valid_state 0x%x\n", dip, msi_num, msi_valid_state); 10767c478bd9Sstevel@tonic-gate 10777c478bd9Sstevel@tonic-gate if ((ret = hvio_msi_setvalid(DIP_TO_HANDLE(dip), 10787c478bd9Sstevel@tonic-gate msi_num, msi_valid_state)) != H_EOK) { 10797c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, 10807c478bd9Sstevel@tonic-gate "hvio_msi_setvalid failed, ret 0x%lx\n", ret); 10817c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 10827c478bd9Sstevel@tonic-gate } 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 10857c478bd9Sstevel@tonic-gate } 10867c478bd9Sstevel@tonic-gate 10877c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 10887c478bd9Sstevel@tonic-gate int 10897c478bd9Sstevel@tonic-gate px_lib_msi_getstate(dev_info_t *dip, msinum_t msi_num, 10907c478bd9Sstevel@tonic-gate pci_msi_state_t *msi_state) 10917c478bd9Sstevel@tonic-gate { 10927c478bd9Sstevel@tonic-gate uint64_t ret; 10937c478bd9Sstevel@tonic-gate 10947c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_getstate: dip 0x%p msi_num 0x%x\n", 10957c478bd9Sstevel@tonic-gate dip, msi_num); 10967c478bd9Sstevel@tonic-gate 10977c478bd9Sstevel@tonic-gate if ((ret = hvio_msi_getstate(DIP_TO_HANDLE(dip), 10987c478bd9Sstevel@tonic-gate msi_num, msi_state)) != H_EOK) { 10997c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, 11007c478bd9Sstevel@tonic-gate "hvio_msi_getstate failed, ret 0x%lx\n", ret); 11017c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 11027c478bd9Sstevel@tonic-gate } 11037c478bd9Sstevel@tonic-gate 11047c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_getstate: msi_state 0x%x\n", 11057c478bd9Sstevel@tonic-gate *msi_state); 11067c478bd9Sstevel@tonic-gate 11077c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 11087c478bd9Sstevel@tonic-gate } 11097c478bd9Sstevel@tonic-gate 11107c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 11117c478bd9Sstevel@tonic-gate int 11127c478bd9Sstevel@tonic-gate px_lib_msi_setstate(dev_info_t *dip, msinum_t msi_num, 11137c478bd9Sstevel@tonic-gate pci_msi_state_t msi_state) 11147c478bd9Sstevel@tonic-gate { 11157c478bd9Sstevel@tonic-gate uint64_t ret; 11167c478bd9Sstevel@tonic-gate 11177c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msi_setstate: dip 0x%p msi_num 0x%x " 11187c478bd9Sstevel@tonic-gate "msi_state 0x%x\n", dip, msi_num, msi_state); 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate if ((ret = hvio_msi_setstate(DIP_TO_HANDLE(dip), 11217c478bd9Sstevel@tonic-gate msi_num, msi_state)) != H_EOK) { 11227c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, 11237c478bd9Sstevel@tonic-gate "hvio_msi_setstate failed, ret 0x%lx\n", ret); 11247c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 11257c478bd9Sstevel@tonic-gate } 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 11287c478bd9Sstevel@tonic-gate } 11297c478bd9Sstevel@tonic-gate 11307c478bd9Sstevel@tonic-gate /* 11317c478bd9Sstevel@tonic-gate * MSG Functions: 11327c478bd9Sstevel@tonic-gate */ 11337c478bd9Sstevel@tonic-gate 11347c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 11357c478bd9Sstevel@tonic-gate int 11367c478bd9Sstevel@tonic-gate px_lib_msg_getmsiq(dev_info_t *dip, pcie_msg_type_t msg_type, 11377c478bd9Sstevel@tonic-gate msiqid_t *msiq_id) 11387c478bd9Sstevel@tonic-gate { 11397c478bd9Sstevel@tonic-gate uint64_t ret; 11407c478bd9Sstevel@tonic-gate 11417c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSG, dip, "px_lib_msg_getmsiq: dip 0x%p msg_type 0x%x\n", 11427c478bd9Sstevel@tonic-gate dip, msg_type); 11437c478bd9Sstevel@tonic-gate 11447c478bd9Sstevel@tonic-gate if ((ret = hvio_msg_getmsiq(DIP_TO_HANDLE(dip), 11457c478bd9Sstevel@tonic-gate msg_type, msiq_id)) != H_EOK) { 11467c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSG, dip, 11477c478bd9Sstevel@tonic-gate "hvio_msg_getmsiq failed, ret 0x%lx\n", ret); 11487c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 11497c478bd9Sstevel@tonic-gate } 11507c478bd9Sstevel@tonic-gate 11517c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msg_getmsiq: msiq_id 0x%x\n", 11527c478bd9Sstevel@tonic-gate *msiq_id); 11537c478bd9Sstevel@tonic-gate 11547c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 11557c478bd9Sstevel@tonic-gate } 11567c478bd9Sstevel@tonic-gate 11577c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 11587c478bd9Sstevel@tonic-gate int 11597c478bd9Sstevel@tonic-gate px_lib_msg_setmsiq(dev_info_t *dip, pcie_msg_type_t msg_type, 11607c478bd9Sstevel@tonic-gate msiqid_t msiq_id) 11617c478bd9Sstevel@tonic-gate { 11627c478bd9Sstevel@tonic-gate uint64_t ret; 11637c478bd9Sstevel@tonic-gate 11647c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSG, dip, "px_lib_msg_setmsiq: dip 0x%p msg_type 0x%x " 11657c478bd9Sstevel@tonic-gate "msq_id 0x%x\n", dip, msg_type, msiq_id); 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate if ((ret = hvio_msg_setmsiq(DIP_TO_HANDLE(dip), 11687c478bd9Sstevel@tonic-gate msg_type, msiq_id)) != H_EOK) { 11697c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSG, dip, 11707c478bd9Sstevel@tonic-gate "hvio_msg_setmsiq failed, ret 0x%lx\n", ret); 11717c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 11727c478bd9Sstevel@tonic-gate } 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 11757c478bd9Sstevel@tonic-gate } 11767c478bd9Sstevel@tonic-gate 11777c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 11787c478bd9Sstevel@tonic-gate int 11797c478bd9Sstevel@tonic-gate px_lib_msg_getvalid(dev_info_t *dip, pcie_msg_type_t msg_type, 11807c478bd9Sstevel@tonic-gate pcie_msg_valid_state_t *msg_valid_state) 11817c478bd9Sstevel@tonic-gate { 11827c478bd9Sstevel@tonic-gate uint64_t ret; 11837c478bd9Sstevel@tonic-gate 11847c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSG, dip, "px_lib_msg_getvalid: dip 0x%p msg_type 0x%x\n", 11857c478bd9Sstevel@tonic-gate dip, msg_type); 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate if ((ret = hvio_msg_getvalid(DIP_TO_HANDLE(dip), msg_type, 11887c478bd9Sstevel@tonic-gate msg_valid_state)) != H_EOK) { 11897c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSG, dip, 11907c478bd9Sstevel@tonic-gate "hvio_msg_getvalid failed, ret 0x%lx\n", ret); 11917c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 11927c478bd9Sstevel@tonic-gate } 11937c478bd9Sstevel@tonic-gate 11947c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSI, dip, "px_lib_msg_getvalid: msg_valid_state 0x%x\n", 11957c478bd9Sstevel@tonic-gate *msg_valid_state); 11967c478bd9Sstevel@tonic-gate 11977c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 11987c478bd9Sstevel@tonic-gate } 11997c478bd9Sstevel@tonic-gate 12007c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 12017c478bd9Sstevel@tonic-gate int 12027c478bd9Sstevel@tonic-gate px_lib_msg_setvalid(dev_info_t *dip, pcie_msg_type_t msg_type, 12037c478bd9Sstevel@tonic-gate pcie_msg_valid_state_t msg_valid_state) 12047c478bd9Sstevel@tonic-gate { 12057c478bd9Sstevel@tonic-gate uint64_t ret; 12067c478bd9Sstevel@tonic-gate 12077c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSG, dip, "px_lib_msg_setvalid: dip 0x%p msg_type 0x%x " 12087c478bd9Sstevel@tonic-gate "msg_valid_state 0x%x\n", dip, msg_type, msg_valid_state); 12097c478bd9Sstevel@tonic-gate 12107c478bd9Sstevel@tonic-gate if ((ret = hvio_msg_setvalid(DIP_TO_HANDLE(dip), msg_type, 12117c478bd9Sstevel@tonic-gate msg_valid_state)) != H_EOK) { 12127c478bd9Sstevel@tonic-gate DBG(DBG_LIB_MSG, dip, 12137c478bd9Sstevel@tonic-gate "hvio_msg_setvalid failed, ret 0x%lx\n", ret); 12147c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 12157c478bd9Sstevel@tonic-gate } 12167c478bd9Sstevel@tonic-gate 12177c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 12187c478bd9Sstevel@tonic-gate } 12197c478bd9Sstevel@tonic-gate 12207c478bd9Sstevel@tonic-gate /* 12217c478bd9Sstevel@tonic-gate * Suspend/Resume Functions: 12227c478bd9Sstevel@tonic-gate * Currently unsupported by hypervisor and all functions are noops. 12237c478bd9Sstevel@tonic-gate */ 12247c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 12257c478bd9Sstevel@tonic-gate int 12267c478bd9Sstevel@tonic-gate px_lib_suspend(dev_info_t *dip) 12277c478bd9Sstevel@tonic-gate { 12287c478bd9Sstevel@tonic-gate DBG(DBG_ATTACH, dip, "px_lib_suspend: Not supported\n"); 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate /* Not supported */ 12317c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 12327c478bd9Sstevel@tonic-gate } 12337c478bd9Sstevel@tonic-gate 12347c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 12357c478bd9Sstevel@tonic-gate void 12367c478bd9Sstevel@tonic-gate px_lib_resume(dev_info_t *dip) 12377c478bd9Sstevel@tonic-gate { 12387c478bd9Sstevel@tonic-gate DBG(DBG_ATTACH, dip, "px_lib_resume: Not supported\n"); 12397c478bd9Sstevel@tonic-gate 12407c478bd9Sstevel@tonic-gate /* Noop */ 12417c478bd9Sstevel@tonic-gate } 12427c478bd9Sstevel@tonic-gate 12437c478bd9Sstevel@tonic-gate /* 12447c478bd9Sstevel@tonic-gate * Misc Functions: 12457c478bd9Sstevel@tonic-gate * Currently unsupported by hypervisor and all functions are noops. 12467c478bd9Sstevel@tonic-gate */ 12477c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 12487c478bd9Sstevel@tonic-gate static int 12497c478bd9Sstevel@tonic-gate px_lib_config_get(dev_info_t *dip, pci_device_t bdf, pci_config_offset_t off, 12507c478bd9Sstevel@tonic-gate uint8_t size, pci_cfg_data_t *data_p) 12517c478bd9Sstevel@tonic-gate { 12527c478bd9Sstevel@tonic-gate uint64_t ret; 12537c478bd9Sstevel@tonic-gate 12547c478bd9Sstevel@tonic-gate DBG(DBG_LIB_CFG, dip, "px_lib_config_get: dip 0x%p, bdf 0x%llx " 12557c478bd9Sstevel@tonic-gate "off 0x%x size 0x%x\n", dip, bdf, off, size); 12567c478bd9Sstevel@tonic-gate 12577c478bd9Sstevel@tonic-gate if ((ret = hvio_config_get(DIP_TO_HANDLE(dip), bdf, off, 12587c478bd9Sstevel@tonic-gate size, data_p)) != H_EOK) { 12597c478bd9Sstevel@tonic-gate DBG(DBG_LIB_CFG, dip, 12607c478bd9Sstevel@tonic-gate "hvio_config_get failed, ret 0x%lx\n", ret); 12617c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 12627c478bd9Sstevel@tonic-gate } 12637c478bd9Sstevel@tonic-gate DBG(DBG_LIB_CFG, dip, "px_config_get: data 0x%x\n", data_p->dw); 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 12667c478bd9Sstevel@tonic-gate } 12677c478bd9Sstevel@tonic-gate 12687c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 12697c478bd9Sstevel@tonic-gate static int 12707c478bd9Sstevel@tonic-gate px_lib_config_put(dev_info_t *dip, pci_device_t bdf, pci_config_offset_t off, 12717c478bd9Sstevel@tonic-gate uint8_t size, pci_cfg_data_t data) 12727c478bd9Sstevel@tonic-gate { 12737c478bd9Sstevel@tonic-gate uint64_t ret; 12747c478bd9Sstevel@tonic-gate 12757c478bd9Sstevel@tonic-gate DBG(DBG_LIB_CFG, dip, "px_lib_config_put: dip 0x%p, bdf 0x%llx " 12767c478bd9Sstevel@tonic-gate "off 0x%x size 0x%x data 0x%llx\n", dip, bdf, off, size, data.qw); 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate if ((ret = hvio_config_put(DIP_TO_HANDLE(dip), bdf, off, 12797c478bd9Sstevel@tonic-gate size, data)) != H_EOK) { 12807c478bd9Sstevel@tonic-gate DBG(DBG_LIB_CFG, dip, 12817c478bd9Sstevel@tonic-gate "hvio_config_put failed, ret 0x%lx\n", ret); 12827c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 12837c478bd9Sstevel@tonic-gate } 12847c478bd9Sstevel@tonic-gate 12857c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 12867c478bd9Sstevel@tonic-gate } 12877c478bd9Sstevel@tonic-gate 12887c478bd9Sstevel@tonic-gate static uint32_t 12897c478bd9Sstevel@tonic-gate px_pci_config_get(ddi_acc_impl_t *handle, uint32_t *addr, int size) 12907c478bd9Sstevel@tonic-gate { 12917c478bd9Sstevel@tonic-gate px_config_acc_pvt_t *px_pvt = (px_config_acc_pvt_t *) 12927c478bd9Sstevel@tonic-gate handle->ahi_common.ah_bus_private; 1293fc256490SJason Beloro pcie_bus_t *busp = NULL; 1294fc256490SJason Beloro dev_info_t *cdip = NULL; 12957c478bd9Sstevel@tonic-gate uint32_t pci_dev_addr = px_pvt->raddr; 12967c478bd9Sstevel@tonic-gate uint32_t vaddr = px_pvt->vaddr; 1297b40cec45Skrishnae uint16_t off = (uint16_t)(uintptr_t)(addr - vaddr) & 0xfff; 1298abdf5d9aSShesha Sreenivasamurthy uint64_t rdata = 0; 12997c478bd9Sstevel@tonic-gate 13007c478bd9Sstevel@tonic-gate if (px_lib_config_get(px_pvt->dip, pci_dev_addr, off, 13017c478bd9Sstevel@tonic-gate size, (pci_cfg_data_t *)&rdata) != DDI_SUCCESS) 13027c478bd9Sstevel@tonic-gate /* XXX update error kstats */ 13037c478bd9Sstevel@tonic-gate return (0xffffffff); 1304fc256490SJason Beloro 1305fc256490SJason Beloro if (cdip = pcie_find_dip_by_bdf(px_pvt->dip, pci_dev_addr >> 8)) 1306fc256490SJason Beloro busp = PCIE_DIP2BUS(cdip); 1307fc256490SJason Beloro /* 1308fc256490SJason Beloro * This can be called early, before busp or busp->bus_dom has 1309fc256490SJason Beloro * been initialized, so check both before invoking 1310fc256490SJason Beloro * PCIE_IS_ASSIGNED. 1311fc256490SJason Beloro */ 1312fc256490SJason Beloro if (busp && PCIE_BUS2DOM(busp) && PCIE_IS_ASSIGNED(busp)) { 1313fc256490SJason Beloro if (off == PCI_CONF_VENID && size == 2) 1314fc256490SJason Beloro rdata = busp->bus_dev_ven_id & 0xffff; 1315fc256490SJason Beloro else if (off == PCI_CONF_DEVID && size == 2) 1316fc256490SJason Beloro rdata = busp->bus_dev_ven_id >> 16; 1317fc256490SJason Beloro else if (off == PCI_CONF_VENID && size == 4) 1318fc256490SJason Beloro rdata = busp->bus_dev_ven_id; 1319fc256490SJason Beloro } 1320abdf5d9aSShesha Sreenivasamurthy return ((uint32_t)rdata); 13217c478bd9Sstevel@tonic-gate } 13227c478bd9Sstevel@tonic-gate 13237c478bd9Sstevel@tonic-gate static void 13247c478bd9Sstevel@tonic-gate px_pci_config_put(ddi_acc_impl_t *handle, uint32_t *addr, 13257c478bd9Sstevel@tonic-gate int size, pci_cfg_data_t wdata) 13267c478bd9Sstevel@tonic-gate { 13277c478bd9Sstevel@tonic-gate px_config_acc_pvt_t *px_pvt = (px_config_acc_pvt_t *) 13287c478bd9Sstevel@tonic-gate handle->ahi_common.ah_bus_private; 13297c478bd9Sstevel@tonic-gate uint32_t pci_dev_addr = px_pvt->raddr; 13307c478bd9Sstevel@tonic-gate uint32_t vaddr = px_pvt->vaddr; 1331b40cec45Skrishnae uint16_t off = (uint16_t)(uintptr_t)(addr - vaddr) & 0xfff; 13327c478bd9Sstevel@tonic-gate 13337c478bd9Sstevel@tonic-gate if (px_lib_config_put(px_pvt->dip, pci_dev_addr, off, 13347c478bd9Sstevel@tonic-gate size, wdata) != DDI_SUCCESS) { 13357c478bd9Sstevel@tonic-gate /*EMPTY*/ 13367c478bd9Sstevel@tonic-gate /* XXX update error kstats */ 13377c478bd9Sstevel@tonic-gate } 13387c478bd9Sstevel@tonic-gate } 13397c478bd9Sstevel@tonic-gate 13407c478bd9Sstevel@tonic-gate static uint8_t 13417c478bd9Sstevel@tonic-gate px_pci_config_get8(ddi_acc_impl_t *handle, uint8_t *addr) 13427c478bd9Sstevel@tonic-gate { 13437c478bd9Sstevel@tonic-gate return ((uint8_t)px_pci_config_get(handle, (uint32_t *)addr, 1)); 13447c478bd9Sstevel@tonic-gate } 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate static uint16_t 13477c478bd9Sstevel@tonic-gate px_pci_config_get16(ddi_acc_impl_t *handle, uint16_t *addr) 13487c478bd9Sstevel@tonic-gate { 13497c478bd9Sstevel@tonic-gate return ((uint16_t)px_pci_config_get(handle, (uint32_t *)addr, 2)); 13507c478bd9Sstevel@tonic-gate } 13517c478bd9Sstevel@tonic-gate 13527c478bd9Sstevel@tonic-gate static uint32_t 13537c478bd9Sstevel@tonic-gate px_pci_config_get32(ddi_acc_impl_t *handle, uint32_t *addr) 13547c478bd9Sstevel@tonic-gate { 13557c478bd9Sstevel@tonic-gate return ((uint32_t)px_pci_config_get(handle, (uint32_t *)addr, 4)); 13567c478bd9Sstevel@tonic-gate } 13577c478bd9Sstevel@tonic-gate 13587c478bd9Sstevel@tonic-gate static uint64_t 13597c478bd9Sstevel@tonic-gate px_pci_config_get64(ddi_acc_impl_t *handle, uint64_t *addr) 13607c478bd9Sstevel@tonic-gate { 13617c478bd9Sstevel@tonic-gate uint32_t rdatah, rdatal; 13627c478bd9Sstevel@tonic-gate 13637c478bd9Sstevel@tonic-gate rdatal = (uint32_t)px_pci_config_get(handle, (uint32_t *)addr, 4); 13647c478bd9Sstevel@tonic-gate rdatah = (uint32_t)px_pci_config_get(handle, 13657c478bd9Sstevel@tonic-gate (uint32_t *)((char *)addr+4), 4); 13667c478bd9Sstevel@tonic-gate return (((uint64_t)rdatah << 32) | rdatal); 13677c478bd9Sstevel@tonic-gate } 13687c478bd9Sstevel@tonic-gate 13697c478bd9Sstevel@tonic-gate static void 13707c478bd9Sstevel@tonic-gate px_pci_config_put8(ddi_acc_impl_t *handle, uint8_t *addr, uint8_t data) 13717c478bd9Sstevel@tonic-gate { 13727c478bd9Sstevel@tonic-gate pci_cfg_data_t wdata = { 0 }; 13737c478bd9Sstevel@tonic-gate 13747c478bd9Sstevel@tonic-gate wdata.qw = (uint8_t)data; 13757c478bd9Sstevel@tonic-gate px_pci_config_put(handle, (uint32_t *)addr, 1, wdata); 13767c478bd9Sstevel@tonic-gate } 13777c478bd9Sstevel@tonic-gate 13787c478bd9Sstevel@tonic-gate static void 13797c478bd9Sstevel@tonic-gate px_pci_config_put16(ddi_acc_impl_t *handle, uint16_t *addr, uint16_t data) 13807c478bd9Sstevel@tonic-gate { 13817c478bd9Sstevel@tonic-gate pci_cfg_data_t wdata = { 0 }; 13827c478bd9Sstevel@tonic-gate 13837c478bd9Sstevel@tonic-gate wdata.qw = (uint16_t)data; 13847c478bd9Sstevel@tonic-gate px_pci_config_put(handle, (uint32_t *)addr, 2, wdata); 13857c478bd9Sstevel@tonic-gate } 13867c478bd9Sstevel@tonic-gate 13877c478bd9Sstevel@tonic-gate static void 13887c478bd9Sstevel@tonic-gate px_pci_config_put32(ddi_acc_impl_t *handle, uint32_t *addr, uint32_t data) 13897c478bd9Sstevel@tonic-gate { 13907c478bd9Sstevel@tonic-gate pci_cfg_data_t wdata = { 0 }; 13917c478bd9Sstevel@tonic-gate 13927c478bd9Sstevel@tonic-gate wdata.qw = (uint32_t)data; 13937c478bd9Sstevel@tonic-gate px_pci_config_put(handle, (uint32_t *)addr, 4, wdata); 13947c478bd9Sstevel@tonic-gate } 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate static void 13977c478bd9Sstevel@tonic-gate px_pci_config_put64(ddi_acc_impl_t *handle, uint64_t *addr, uint64_t data) 13987c478bd9Sstevel@tonic-gate { 13997c478bd9Sstevel@tonic-gate pci_cfg_data_t wdata = { 0 }; 14007c478bd9Sstevel@tonic-gate 14017c478bd9Sstevel@tonic-gate wdata.qw = (uint32_t)(data & 0xffffffff); 14027c478bd9Sstevel@tonic-gate px_pci_config_put(handle, (uint32_t *)addr, 4, wdata); 14037c478bd9Sstevel@tonic-gate wdata.qw = (uint32_t)((data >> 32) & 0xffffffff); 14047c478bd9Sstevel@tonic-gate px_pci_config_put(handle, (uint32_t *)((char *)addr+4), 4, wdata); 14057c478bd9Sstevel@tonic-gate } 14067c478bd9Sstevel@tonic-gate 14077c478bd9Sstevel@tonic-gate static void 14087c478bd9Sstevel@tonic-gate px_pci_config_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr, 14097c478bd9Sstevel@tonic-gate uint8_t *dev_addr, size_t repcount, uint_t flags) 14107c478bd9Sstevel@tonic-gate { 14117c478bd9Sstevel@tonic-gate if (flags == DDI_DEV_AUTOINCR) 14127c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14137c478bd9Sstevel@tonic-gate *host_addr++ = px_pci_config_get8(handle, dev_addr++); 14147c478bd9Sstevel@tonic-gate else 14157c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14167c478bd9Sstevel@tonic-gate *host_addr++ = px_pci_config_get8(handle, dev_addr); 14177c478bd9Sstevel@tonic-gate } 14187c478bd9Sstevel@tonic-gate 14197c478bd9Sstevel@tonic-gate /* 14207c478bd9Sstevel@tonic-gate * Function to rep read 16 bit data off the PCI configuration space behind 14217c478bd9Sstevel@tonic-gate * the 21554's host interface. 14227c478bd9Sstevel@tonic-gate */ 14237c478bd9Sstevel@tonic-gate static void 14247c478bd9Sstevel@tonic-gate px_pci_config_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr, 14257c478bd9Sstevel@tonic-gate uint16_t *dev_addr, size_t repcount, uint_t flags) 14267c478bd9Sstevel@tonic-gate { 14277c478bd9Sstevel@tonic-gate if (flags == DDI_DEV_AUTOINCR) 14287c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14297c478bd9Sstevel@tonic-gate *host_addr++ = px_pci_config_get16(handle, dev_addr++); 14307c478bd9Sstevel@tonic-gate else 14317c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14327c478bd9Sstevel@tonic-gate *host_addr++ = px_pci_config_get16(handle, dev_addr); 14337c478bd9Sstevel@tonic-gate } 14347c478bd9Sstevel@tonic-gate 14357c478bd9Sstevel@tonic-gate /* 14367c478bd9Sstevel@tonic-gate * Function to rep read 32 bit data off the PCI configuration space behind 14377c478bd9Sstevel@tonic-gate * the 21554's host interface. 14387c478bd9Sstevel@tonic-gate */ 14397c478bd9Sstevel@tonic-gate static void 14407c478bd9Sstevel@tonic-gate px_pci_config_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr, 14417c478bd9Sstevel@tonic-gate uint32_t *dev_addr, size_t repcount, uint_t flags) 14427c478bd9Sstevel@tonic-gate { 14437c478bd9Sstevel@tonic-gate if (flags == DDI_DEV_AUTOINCR) 14447c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14457c478bd9Sstevel@tonic-gate *host_addr++ = px_pci_config_get32(handle, dev_addr++); 14467c478bd9Sstevel@tonic-gate else 14477c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14487c478bd9Sstevel@tonic-gate *host_addr++ = px_pci_config_get32(handle, dev_addr); 14497c478bd9Sstevel@tonic-gate } 14507c478bd9Sstevel@tonic-gate 14517c478bd9Sstevel@tonic-gate /* 14527c478bd9Sstevel@tonic-gate * Function to rep read 64 bit data off the PCI configuration space behind 14537c478bd9Sstevel@tonic-gate * the 21554's host interface. 14547c478bd9Sstevel@tonic-gate */ 14557c478bd9Sstevel@tonic-gate static void 14567c478bd9Sstevel@tonic-gate px_pci_config_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr, 14577c478bd9Sstevel@tonic-gate uint64_t *dev_addr, size_t repcount, uint_t flags) 14587c478bd9Sstevel@tonic-gate { 14597c478bd9Sstevel@tonic-gate if (flags == DDI_DEV_AUTOINCR) 14607c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14617c478bd9Sstevel@tonic-gate *host_addr++ = px_pci_config_get64(handle, dev_addr++); 14627c478bd9Sstevel@tonic-gate else 14637c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14647c478bd9Sstevel@tonic-gate *host_addr++ = px_pci_config_get64(handle, dev_addr); 14657c478bd9Sstevel@tonic-gate } 14667c478bd9Sstevel@tonic-gate 14677c478bd9Sstevel@tonic-gate /* 14687c478bd9Sstevel@tonic-gate * Function to rep write 8 bit data into the PCI configuration space behind 14697c478bd9Sstevel@tonic-gate * the 21554's host interface. 14707c478bd9Sstevel@tonic-gate */ 14717c478bd9Sstevel@tonic-gate static void 14727c478bd9Sstevel@tonic-gate px_pci_config_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr, 14737c478bd9Sstevel@tonic-gate uint8_t *dev_addr, size_t repcount, uint_t flags) 14747c478bd9Sstevel@tonic-gate { 14757c478bd9Sstevel@tonic-gate if (flags == DDI_DEV_AUTOINCR) 14767c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14777c478bd9Sstevel@tonic-gate px_pci_config_put8(handle, dev_addr++, *host_addr++); 14787c478bd9Sstevel@tonic-gate else 14797c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14807c478bd9Sstevel@tonic-gate px_pci_config_put8(handle, dev_addr, *host_addr++); 14817c478bd9Sstevel@tonic-gate } 14827c478bd9Sstevel@tonic-gate 14837c478bd9Sstevel@tonic-gate /* 14847c478bd9Sstevel@tonic-gate * Function to rep write 16 bit data into the PCI configuration space behind 14857c478bd9Sstevel@tonic-gate * the 21554's host interface. 14867c478bd9Sstevel@tonic-gate */ 14877c478bd9Sstevel@tonic-gate static void 14887c478bd9Sstevel@tonic-gate px_pci_config_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr, 14897c478bd9Sstevel@tonic-gate uint16_t *dev_addr, size_t repcount, uint_t flags) 14907c478bd9Sstevel@tonic-gate { 14917c478bd9Sstevel@tonic-gate if (flags == DDI_DEV_AUTOINCR) 14927c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14937c478bd9Sstevel@tonic-gate px_pci_config_put16(handle, dev_addr++, *host_addr++); 14947c478bd9Sstevel@tonic-gate else 14957c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 14967c478bd9Sstevel@tonic-gate px_pci_config_put16(handle, dev_addr, *host_addr++); 14977c478bd9Sstevel@tonic-gate } 14987c478bd9Sstevel@tonic-gate 14997c478bd9Sstevel@tonic-gate /* 15007c478bd9Sstevel@tonic-gate * Function to rep write 32 bit data into the PCI configuration space behind 15017c478bd9Sstevel@tonic-gate * the 21554's host interface. 15027c478bd9Sstevel@tonic-gate */ 15037c478bd9Sstevel@tonic-gate static void 15047c478bd9Sstevel@tonic-gate px_pci_config_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr, 15057c478bd9Sstevel@tonic-gate uint32_t *dev_addr, size_t repcount, uint_t flags) 15067c478bd9Sstevel@tonic-gate { 15077c478bd9Sstevel@tonic-gate if (flags == DDI_DEV_AUTOINCR) 15087c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 15097c478bd9Sstevel@tonic-gate px_pci_config_put32(handle, dev_addr++, *host_addr++); 15107c478bd9Sstevel@tonic-gate else 15117c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 15127c478bd9Sstevel@tonic-gate px_pci_config_put32(handle, dev_addr, *host_addr++); 15137c478bd9Sstevel@tonic-gate } 15147c478bd9Sstevel@tonic-gate 15157c478bd9Sstevel@tonic-gate /* 15167c478bd9Sstevel@tonic-gate * Function to rep write 64 bit data into the PCI configuration space behind 15177c478bd9Sstevel@tonic-gate * the 21554's host interface. 15187c478bd9Sstevel@tonic-gate */ 15197c478bd9Sstevel@tonic-gate static void 15207c478bd9Sstevel@tonic-gate px_pci_config_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr, 15217c478bd9Sstevel@tonic-gate uint64_t *dev_addr, size_t repcount, uint_t flags) 15227c478bd9Sstevel@tonic-gate { 15237c478bd9Sstevel@tonic-gate if (flags == DDI_DEV_AUTOINCR) 15247c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 15257c478bd9Sstevel@tonic-gate px_pci_config_put64(handle, dev_addr++, *host_addr++); 15267c478bd9Sstevel@tonic-gate else 15277c478bd9Sstevel@tonic-gate for (; repcount; repcount--) 15287c478bd9Sstevel@tonic-gate px_pci_config_put64(handle, dev_addr, *host_addr++); 15297c478bd9Sstevel@tonic-gate } 15307c478bd9Sstevel@tonic-gate 15317c478bd9Sstevel@tonic-gate /* 15327c478bd9Sstevel@tonic-gate * Provide a private access handle to route config access calls to Hypervisor. 15337c478bd9Sstevel@tonic-gate * Beware: Do all error checking for config space accesses before calling 15347c478bd9Sstevel@tonic-gate * this function. ie. do error checking from the calling function. 15357c478bd9Sstevel@tonic-gate * Due to a lack of meaningful error code in DDI, the gauranteed return of 15367c478bd9Sstevel@tonic-gate * DDI_SUCCESS from here makes the code organization readable/easier from 15377c478bd9Sstevel@tonic-gate * the generic code. 15387c478bd9Sstevel@tonic-gate */ 15397c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 15407c478bd9Sstevel@tonic-gate int 15417c478bd9Sstevel@tonic-gate px_lib_map_vconfig(dev_info_t *dip, 15427c478bd9Sstevel@tonic-gate ddi_map_req_t *mp, pci_config_offset_t off, 15437c478bd9Sstevel@tonic-gate pci_regspec_t *rp, caddr_t *addrp) 15447c478bd9Sstevel@tonic-gate { 1545eae2e508Skrishnae int fmcap; 1546eae2e508Skrishnae ndi_err_t *errp; 1547eae2e508Skrishnae on_trap_data_t *otp; 15487c478bd9Sstevel@tonic-gate ddi_acc_hdl_t *hp; 15497c478bd9Sstevel@tonic-gate ddi_acc_impl_t *ap; 15507c478bd9Sstevel@tonic-gate uchar_t busnum; /* bus number */ 15517c478bd9Sstevel@tonic-gate uchar_t devnum; /* device number */ 15527c478bd9Sstevel@tonic-gate uchar_t funcnum; /* function number */ 15537c478bd9Sstevel@tonic-gate px_config_acc_pvt_t *px_pvt; 15547c478bd9Sstevel@tonic-gate 15557c478bd9Sstevel@tonic-gate hp = (ddi_acc_hdl_t *)mp->map_handlep; 15567c478bd9Sstevel@tonic-gate ap = (ddi_acc_impl_t *)hp->ah_platform_private; 15577c478bd9Sstevel@tonic-gate 15587c478bd9Sstevel@tonic-gate /* Check for mapping teardown operation */ 15597c478bd9Sstevel@tonic-gate if ((mp->map_op == DDI_MO_UNMAP) || 15607c478bd9Sstevel@tonic-gate (mp->map_op == DDI_MO_UNLOCK)) { 15617c478bd9Sstevel@tonic-gate /* free up memory allocated for the private access handle. */ 15627c478bd9Sstevel@tonic-gate px_pvt = (px_config_acc_pvt_t *)hp->ah_bus_private; 15637c478bd9Sstevel@tonic-gate kmem_free((void *)px_pvt, sizeof (px_config_acc_pvt_t)); 15647c478bd9Sstevel@tonic-gate 15657c478bd9Sstevel@tonic-gate /* unmap operation of PCI IO/config space. */ 15667c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 15677c478bd9Sstevel@tonic-gate } 15687c478bd9Sstevel@tonic-gate 1569eae2e508Skrishnae fmcap = ddi_fm_capable(dip); 1570eae2e508Skrishnae if (DDI_FM_ACC_ERR_CAP(fmcap)) { 1571eae2e508Skrishnae errp = ((ddi_acc_impl_t *)hp)->ahi_err; 1572eae2e508Skrishnae otp = (on_trap_data_t *)errp->err_ontrap; 1573eae2e508Skrishnae otp->ot_handle = (void *)(hp); 1574eae2e508Skrishnae otp->ot_prot = OT_DATA_ACCESS; 1575eae2e508Skrishnae errp->err_status = DDI_FM_OK; 1576eae2e508Skrishnae errp->err_expected = DDI_FM_ERR_UNEXPECTED; 1577eae2e508Skrishnae errp->err_cf = px_err_cfg_hdl_check; 1578eae2e508Skrishnae } 1579eae2e508Skrishnae 15807c478bd9Sstevel@tonic-gate ap->ahi_get8 = px_pci_config_get8; 15817c478bd9Sstevel@tonic-gate ap->ahi_get16 = px_pci_config_get16; 15827c478bd9Sstevel@tonic-gate ap->ahi_get32 = px_pci_config_get32; 15837c478bd9Sstevel@tonic-gate ap->ahi_get64 = px_pci_config_get64; 15847c478bd9Sstevel@tonic-gate ap->ahi_put8 = px_pci_config_put8; 15857c478bd9Sstevel@tonic-gate ap->ahi_put16 = px_pci_config_put16; 15867c478bd9Sstevel@tonic-gate ap->ahi_put32 = px_pci_config_put32; 15877c478bd9Sstevel@tonic-gate ap->ahi_put64 = px_pci_config_put64; 15887c478bd9Sstevel@tonic-gate ap->ahi_rep_get8 = px_pci_config_rep_get8; 15897c478bd9Sstevel@tonic-gate ap->ahi_rep_get16 = px_pci_config_rep_get16; 15907c478bd9Sstevel@tonic-gate ap->ahi_rep_get32 = px_pci_config_rep_get32; 15917c478bd9Sstevel@tonic-gate ap->ahi_rep_get64 = px_pci_config_rep_get64; 15927c478bd9Sstevel@tonic-gate ap->ahi_rep_put8 = px_pci_config_rep_put8; 15937c478bd9Sstevel@tonic-gate ap->ahi_rep_put16 = px_pci_config_rep_put16; 15947c478bd9Sstevel@tonic-gate ap->ahi_rep_put32 = px_pci_config_rep_put32; 15957c478bd9Sstevel@tonic-gate ap->ahi_rep_put64 = px_pci_config_rep_put64; 15967c478bd9Sstevel@tonic-gate 15977c478bd9Sstevel@tonic-gate /* Initialize to default check/notify functions */ 15987c478bd9Sstevel@tonic-gate ap->ahi_fault = 0; 15997c478bd9Sstevel@tonic-gate ap->ahi_fault_check = i_ddi_acc_fault_check; 16007c478bd9Sstevel@tonic-gate ap->ahi_fault_notify = i_ddi_acc_fault_notify; 16017c478bd9Sstevel@tonic-gate 16027c478bd9Sstevel@tonic-gate /* allocate memory for our private handle */ 16037c478bd9Sstevel@tonic-gate px_pvt = (px_config_acc_pvt_t *) 16047c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (px_config_acc_pvt_t), KM_SLEEP); 16057c478bd9Sstevel@tonic-gate hp->ah_bus_private = (void *)px_pvt; 16067c478bd9Sstevel@tonic-gate 16077c478bd9Sstevel@tonic-gate busnum = PCI_REG_BUS_G(rp->pci_phys_hi); 16087c478bd9Sstevel@tonic-gate devnum = PCI_REG_DEV_G(rp->pci_phys_hi); 16097c478bd9Sstevel@tonic-gate funcnum = PCI_REG_FUNC_G(rp->pci_phys_hi); 16107c478bd9Sstevel@tonic-gate 16117c478bd9Sstevel@tonic-gate /* set up private data for use during IO routines */ 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate /* addr needed by the HV APIs */ 16147c478bd9Sstevel@tonic-gate px_pvt->raddr = busnum << 16 | devnum << 11 | funcnum << 8; 16157c478bd9Sstevel@tonic-gate /* 16167c478bd9Sstevel@tonic-gate * Address that specifies the actual offset into the 256MB 16177c478bd9Sstevel@tonic-gate * memory mapped configuration space, 4K per device. 16187c478bd9Sstevel@tonic-gate * First 12bits form the offset into 4K config space. 16197c478bd9Sstevel@tonic-gate * This address is only used during the IO routines to calculate 16207c478bd9Sstevel@tonic-gate * the offset at which the transaction must be performed. 16217c478bd9Sstevel@tonic-gate * Drivers bypassing DDI functions to access PCI config space will 16227c478bd9Sstevel@tonic-gate * panic the system since the following is a bogus virtual address. 16237c478bd9Sstevel@tonic-gate */ 16247c478bd9Sstevel@tonic-gate px_pvt->vaddr = busnum << 20 | devnum << 15 | funcnum << 12 | off; 16257c478bd9Sstevel@tonic-gate px_pvt->dip = dip; 16267c478bd9Sstevel@tonic-gate 16277c478bd9Sstevel@tonic-gate DBG(DBG_LIB_CFG, dip, "px_config_setup: raddr 0x%x, vaddr 0x%x\n", 16287c478bd9Sstevel@tonic-gate px_pvt->raddr, px_pvt->vaddr); 1629b40cec45Skrishnae *addrp = (caddr_t)(uintptr_t)px_pvt->vaddr; 16307c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 16317c478bd9Sstevel@tonic-gate } 16327c478bd9Sstevel@tonic-gate 16334fbb58f6Sjchu /*ARGSUSED*/ 16344fbb58f6Sjchu void 16354fbb58f6Sjchu px_lib_map_attr_check(ddi_map_req_t *mp) 16364fbb58f6Sjchu { 16374fbb58f6Sjchu } 16384fbb58f6Sjchu 1639f8d2de6bSjchu /* 1640f8d2de6bSjchu * px_lib_log_safeacc_err: 1641f8d2de6bSjchu * Imitate a cpu/mem trap call when a peek/poke fails. 1642f8d2de6bSjchu * This will initiate something similar to px_fm_callback. 1643f8d2de6bSjchu */ 16447c478bd9Sstevel@tonic-gate static void 1645bf8fc234Set142600 px_lib_log_safeacc_err(px_t *px_p, ddi_acc_handle_t handle, int fme_flag, 1646bf8fc234Set142600 r_addr_t addr) 16477c478bd9Sstevel@tonic-gate { 1648bf8fc234Set142600 uint32_t addr_high, addr_low; 1649c85864d8SKrishna Elango pcie_req_id_t bdf = PCIE_INVALID_BDF; 165026947304SEvan Yan pci_ranges_t *ranges_p; 1651bf8fc234Set142600 int range_len, i; 16527c478bd9Sstevel@tonic-gate ddi_acc_impl_t *hp = (ddi_acc_impl_t *)handle; 16537c478bd9Sstevel@tonic-gate ddi_fm_error_t derr; 16547c478bd9Sstevel@tonic-gate 1655fc256490SJason Beloro if (px_fm_enter(px_p) != DDI_SUCCESS) 1656fc256490SJason Beloro return; 1657fc256490SJason Beloro 16587c478bd9Sstevel@tonic-gate derr.fme_status = DDI_FM_NONFATAL; 16597c478bd9Sstevel@tonic-gate derr.fme_version = DDI_FME_VERSION; 16607c478bd9Sstevel@tonic-gate derr.fme_flag = fme_flag; 16617c478bd9Sstevel@tonic-gate derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 16627c478bd9Sstevel@tonic-gate derr.fme_acc_handle = handle; 16637c478bd9Sstevel@tonic-gate if (hp) 16647c478bd9Sstevel@tonic-gate hp->ahi_err->err_expected = DDI_FM_ERR_EXPECTED; 16657c478bd9Sstevel@tonic-gate 1666bf8fc234Set142600 addr_high = (uint32_t)(addr >> 32); 1667bf8fc234Set142600 addr_low = (uint32_t)addr; 1668bf8fc234Set142600 1669bf8fc234Set142600 /* 1670bf8fc234Set142600 * Make sure this failed load came from this PCIe port. Check by 1671bf8fc234Set142600 * matching the upper 32 bits of the address with the ranges property. 1672bf8fc234Set142600 */ 167326947304SEvan Yan range_len = px_p->px_ranges_length / sizeof (pci_ranges_t); 1674bf8fc234Set142600 i = 0; 1675bf8fc234Set142600 for (ranges_p = px_p->px_ranges_p; i < range_len; i++, ranges_p++) { 1676bf8fc234Set142600 if (ranges_p->parent_high == addr_high) { 1677bf8fc234Set142600 switch (ranges_p->child_high & PCI_ADDR_MASK) { 1678bf8fc234Set142600 case PCI_ADDR_CONFIG: 1679bf8fc234Set142600 bdf = (pcie_req_id_t)(addr_low >> 12); 1680bf8fc234Set142600 break; 1681bf8fc234Set142600 default: 1682c85864d8SKrishna Elango bdf = PCIE_INVALID_BDF; 1683bf8fc234Set142600 break; 1684bf8fc234Set142600 } 1685bf8fc234Set142600 break; 1686bf8fc234Set142600 } 1687bf8fc234Set142600 } 1688bf8fc234Set142600 1689fc256490SJason Beloro (void) px_rp_en_q(px_p, bdf, addr, NULL); 1690eae2e508Skrishnae (void) px_scan_fabric(px_p, px_p->px_dip, &derr); 1691eae2e508Skrishnae px_fm_exit(px_p); 1692bf8fc234Set142600 } 16937c478bd9Sstevel@tonic-gate 16947c478bd9Sstevel@tonic-gate 16957c478bd9Sstevel@tonic-gate #ifdef DEBUG 16967c478bd9Sstevel@tonic-gate int px_peekfault_cnt = 0; 16977c478bd9Sstevel@tonic-gate int px_pokefault_cnt = 0; 16987c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 16997c478bd9Sstevel@tonic-gate 17007c478bd9Sstevel@tonic-gate /* 17017c478bd9Sstevel@tonic-gate * Do a safe write to a device. 17027c478bd9Sstevel@tonic-gate * 17037c478bd9Sstevel@tonic-gate * When this function is given a handle (cautious access), all errors are 17047c478bd9Sstevel@tonic-gate * suppressed. 17057c478bd9Sstevel@tonic-gate * 17067c478bd9Sstevel@tonic-gate * When this function is not given a handle (poke), only Unsupported Request 17077c478bd9Sstevel@tonic-gate * and Completer Abort errors are suppressed. 17087c478bd9Sstevel@tonic-gate * 17097c478bd9Sstevel@tonic-gate * In all cases, all errors are returned in the function return status. 17107c478bd9Sstevel@tonic-gate */ 17117c478bd9Sstevel@tonic-gate 17127c478bd9Sstevel@tonic-gate int 17137c478bd9Sstevel@tonic-gate px_lib_ctlops_poke(dev_info_t *dip, dev_info_t *rdip, 17147c478bd9Sstevel@tonic-gate peekpoke_ctlops_t *in_args) 17157c478bd9Sstevel@tonic-gate { 17167c478bd9Sstevel@tonic-gate px_t *px_p = DIP_TO_STATE(dip); 17177c478bd9Sstevel@tonic-gate px_pec_t *pec_p = px_p->px_pec_p; 1718f8d2de6bSjchu ddi_acc_impl_t *hp = (ddi_acc_impl_t *)in_args->handle; 17197c478bd9Sstevel@tonic-gate 17207c478bd9Sstevel@tonic-gate size_t repcount = in_args->repcount; 17217c478bd9Sstevel@tonic-gate size_t size = in_args->size; 17227c478bd9Sstevel@tonic-gate uintptr_t dev_addr = in_args->dev_addr; 17237c478bd9Sstevel@tonic-gate uintptr_t host_addr = in_args->host_addr; 17247c478bd9Sstevel@tonic-gate 17257c478bd9Sstevel@tonic-gate int err = DDI_SUCCESS; 17267c478bd9Sstevel@tonic-gate uint64_t hvio_poke_status; 17277c478bd9Sstevel@tonic-gate uint32_t wrt_stat; 17287c478bd9Sstevel@tonic-gate 17297c478bd9Sstevel@tonic-gate r_addr_t ra; 17307c478bd9Sstevel@tonic-gate uint64_t pokeval; 1731939f5b68Saa72041 pcie_req_id_t bdf; 1732f8d2de6bSjchu 17337c478bd9Sstevel@tonic-gate ra = (r_addr_t)va_to_pa((void *)dev_addr); 17347c478bd9Sstevel@tonic-gate for (; repcount; repcount--) { 17357c478bd9Sstevel@tonic-gate 17367c478bd9Sstevel@tonic-gate switch (size) { 17377c478bd9Sstevel@tonic-gate case sizeof (uint8_t): 17387c478bd9Sstevel@tonic-gate pokeval = *(uint8_t *)host_addr; 17397c478bd9Sstevel@tonic-gate break; 17407c478bd9Sstevel@tonic-gate case sizeof (uint16_t): 17417c478bd9Sstevel@tonic-gate pokeval = *(uint16_t *)host_addr; 17427c478bd9Sstevel@tonic-gate break; 17437c478bd9Sstevel@tonic-gate case sizeof (uint32_t): 17447c478bd9Sstevel@tonic-gate pokeval = *(uint32_t *)host_addr; 17457c478bd9Sstevel@tonic-gate break; 17467c478bd9Sstevel@tonic-gate case sizeof (uint64_t): 17477c478bd9Sstevel@tonic-gate pokeval = *(uint64_t *)host_addr; 17487c478bd9Sstevel@tonic-gate break; 17497c478bd9Sstevel@tonic-gate default: 17507c478bd9Sstevel@tonic-gate DBG(DBG_MAP, px_p->px_dip, 17517c478bd9Sstevel@tonic-gate "poke: invalid size %d passed\n", size); 17527c478bd9Sstevel@tonic-gate err = DDI_FAILURE; 17537c478bd9Sstevel@tonic-gate goto done; 17547c478bd9Sstevel@tonic-gate } 17557c478bd9Sstevel@tonic-gate 17567c478bd9Sstevel@tonic-gate /* 1757f8d2de6bSjchu * Grab pokefault mutex since hypervisor does not guarantee 1758f8d2de6bSjchu * poke serialization. 17597c478bd9Sstevel@tonic-gate */ 1760f8d2de6bSjchu if (hp) { 1761f8d2de6bSjchu i_ndi_busop_access_enter(hp->ahi_common.ah_dip, 1762f8d2de6bSjchu (ddi_acc_handle_t)hp); 1763f8d2de6bSjchu pec_p->pec_safeacc_type = DDI_FM_ERR_EXPECTED; 1764f8d2de6bSjchu } else { 1765f8d2de6bSjchu mutex_enter(&pec_p->pec_pokefault_mutex); 1766f8d2de6bSjchu pec_p->pec_safeacc_type = DDI_FM_ERR_POKE; 1767f8d2de6bSjchu } 1768939f5b68Saa72041 1769939f5b68Saa72041 if (pcie_get_bdf_from_dip(rdip, &bdf) != DDI_SUCCESS) { 1770939f5b68Saa72041 err = DDI_FAILURE; 1771939f5b68Saa72041 goto done; 1772939f5b68Saa72041 } 1773f8d2de6bSjchu 17747c478bd9Sstevel@tonic-gate hvio_poke_status = hvio_poke(px_p->px_dev_hdl, ra, size, 1775939f5b68Saa72041 pokeval, bdf << 8, &wrt_stat); 17767c478bd9Sstevel@tonic-gate 17777c478bd9Sstevel@tonic-gate if ((hvio_poke_status != H_EOK) || (wrt_stat != H_EOK)) { 17787c478bd9Sstevel@tonic-gate err = DDI_FAILURE; 17797c478bd9Sstevel@tonic-gate #ifdef DEBUG 17807c478bd9Sstevel@tonic-gate px_pokefault_cnt++; 17817c478bd9Sstevel@tonic-gate #endif 17827c478bd9Sstevel@tonic-gate /* 17837c478bd9Sstevel@tonic-gate * For CAUTIOUS and POKE access, notify FMA to 1784f8d2de6bSjchu * cleanup. Imitate a cpu/mem trap call like in sun4u. 17857c478bd9Sstevel@tonic-gate */ 1786f8d2de6bSjchu px_lib_log_safeacc_err(px_p, (ddi_acc_handle_t)hp, 1787f8d2de6bSjchu (hp ? DDI_FM_ERR_EXPECTED : 1788bf8fc234Set142600 DDI_FM_ERR_POKE), ra); 17897c478bd9Sstevel@tonic-gate 1790f8d2de6bSjchu pec_p->pec_ontrap_data = NULL; 1791f8d2de6bSjchu pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; 1792f8d2de6bSjchu if (hp) { 1793f8d2de6bSjchu i_ndi_busop_access_exit(hp->ahi_common.ah_dip, 1794f8d2de6bSjchu (ddi_acc_handle_t)hp); 1795f8d2de6bSjchu } else { 1796f8d2de6bSjchu mutex_exit(&pec_p->pec_pokefault_mutex); 1797f8d2de6bSjchu } 17987c478bd9Sstevel@tonic-gate goto done; 17997c478bd9Sstevel@tonic-gate } 18007c478bd9Sstevel@tonic-gate 1801f8d2de6bSjchu pec_p->pec_ontrap_data = NULL; 1802f8d2de6bSjchu pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; 1803f8d2de6bSjchu if (hp) { 1804f8d2de6bSjchu i_ndi_busop_access_exit(hp->ahi_common.ah_dip, 1805f8d2de6bSjchu (ddi_acc_handle_t)hp); 1806f8d2de6bSjchu } else { 1807f8d2de6bSjchu mutex_exit(&pec_p->pec_pokefault_mutex); 1808f8d2de6bSjchu } 1809f8d2de6bSjchu 18107c478bd9Sstevel@tonic-gate host_addr += size; 18117c478bd9Sstevel@tonic-gate 18127c478bd9Sstevel@tonic-gate if (in_args->flags == DDI_DEV_AUTOINCR) { 18137c478bd9Sstevel@tonic-gate dev_addr += size; 18147c478bd9Sstevel@tonic-gate ra = (r_addr_t)va_to_pa((void *)dev_addr); 18157c478bd9Sstevel@tonic-gate } 18167c478bd9Sstevel@tonic-gate } 18177c478bd9Sstevel@tonic-gate 18187c478bd9Sstevel@tonic-gate done: 18197c478bd9Sstevel@tonic-gate return (err); 18207c478bd9Sstevel@tonic-gate } 18217c478bd9Sstevel@tonic-gate 18227c478bd9Sstevel@tonic-gate 18237c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 18247c478bd9Sstevel@tonic-gate int 18257c478bd9Sstevel@tonic-gate px_lib_ctlops_peek(dev_info_t *dip, dev_info_t *rdip, 18267c478bd9Sstevel@tonic-gate peekpoke_ctlops_t *in_args, void *result) 18277c478bd9Sstevel@tonic-gate { 18287c478bd9Sstevel@tonic-gate px_t *px_p = DIP_TO_STATE(dip); 18297c478bd9Sstevel@tonic-gate px_pec_t *pec_p = px_p->px_pec_p; 1830f8d2de6bSjchu ddi_acc_impl_t *hp = (ddi_acc_impl_t *)in_args->handle; 18317c478bd9Sstevel@tonic-gate 18327c478bd9Sstevel@tonic-gate size_t repcount = in_args->repcount; 18337c478bd9Sstevel@tonic-gate uintptr_t dev_addr = in_args->dev_addr; 18347c478bd9Sstevel@tonic-gate uintptr_t host_addr = in_args->host_addr; 18357c478bd9Sstevel@tonic-gate 18367c478bd9Sstevel@tonic-gate r_addr_t ra; 18377c478bd9Sstevel@tonic-gate uint32_t read_status; 18387c478bd9Sstevel@tonic-gate uint64_t hvio_peek_status; 18397c478bd9Sstevel@tonic-gate uint64_t peekval; 18407c478bd9Sstevel@tonic-gate int err = DDI_SUCCESS; 18417c478bd9Sstevel@tonic-gate 18427c478bd9Sstevel@tonic-gate result = (void *)in_args->host_addr; 18437c478bd9Sstevel@tonic-gate 18447c478bd9Sstevel@tonic-gate ra = (r_addr_t)va_to_pa((void *)dev_addr); 18457c478bd9Sstevel@tonic-gate for (; repcount; repcount--) { 18467c478bd9Sstevel@tonic-gate 18477c478bd9Sstevel@tonic-gate /* Lock pokefault mutex so read doesn't mask a poke fault. */ 1848f8d2de6bSjchu if (hp) { 1849f8d2de6bSjchu i_ndi_busop_access_enter(hp->ahi_common.ah_dip, 1850f8d2de6bSjchu (ddi_acc_handle_t)hp); 1851f8d2de6bSjchu pec_p->pec_safeacc_type = DDI_FM_ERR_EXPECTED; 1852f8d2de6bSjchu } else { 18537c478bd9Sstevel@tonic-gate mutex_enter(&pec_p->pec_pokefault_mutex); 1854f8d2de6bSjchu pec_p->pec_safeacc_type = DDI_FM_ERR_PEEK; 1855f8d2de6bSjchu } 18567c478bd9Sstevel@tonic-gate 18577c478bd9Sstevel@tonic-gate hvio_peek_status = hvio_peek(px_p->px_dev_hdl, ra, 18587c478bd9Sstevel@tonic-gate in_args->size, &read_status, &peekval); 18597c478bd9Sstevel@tonic-gate 18607c478bd9Sstevel@tonic-gate if ((hvio_peek_status != H_EOK) || (read_status != H_EOK)) { 18617c478bd9Sstevel@tonic-gate err = DDI_FAILURE; 18627c478bd9Sstevel@tonic-gate 18637c478bd9Sstevel@tonic-gate /* 18647c478bd9Sstevel@tonic-gate * For CAUTIOUS and PEEK access, notify FMA to 1865f8d2de6bSjchu * cleanup. Imitate a cpu/mem trap call like in sun4u. 18667c478bd9Sstevel@tonic-gate */ 1867f8d2de6bSjchu px_lib_log_safeacc_err(px_p, (ddi_acc_handle_t)hp, 1868f8d2de6bSjchu (hp ? DDI_FM_ERR_EXPECTED : 1869bf8fc234Set142600 DDI_FM_ERR_PEEK), ra); 18707c478bd9Sstevel@tonic-gate 18717c478bd9Sstevel@tonic-gate /* Stuff FFs in host addr if peek. */ 1872f8d2de6bSjchu if (hp == NULL) { 18737c478bd9Sstevel@tonic-gate int i; 18747c478bd9Sstevel@tonic-gate uint8_t *ff_addr = (uint8_t *)host_addr; 18757c478bd9Sstevel@tonic-gate for (i = 0; i < in_args->size; i++) 18767c478bd9Sstevel@tonic-gate *ff_addr++ = 0xff; 18777c478bd9Sstevel@tonic-gate } 18787c478bd9Sstevel@tonic-gate #ifdef DEBUG 18797c478bd9Sstevel@tonic-gate px_peekfault_cnt++; 18807c478bd9Sstevel@tonic-gate #endif 1881f8d2de6bSjchu pec_p->pec_ontrap_data = NULL; 1882f8d2de6bSjchu pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; 1883f8d2de6bSjchu if (hp) { 1884f8d2de6bSjchu i_ndi_busop_access_exit(hp->ahi_common.ah_dip, 1885f8d2de6bSjchu (ddi_acc_handle_t)hp); 1886f8d2de6bSjchu } else { 1887f8d2de6bSjchu mutex_exit(&pec_p->pec_pokefault_mutex); 1888f8d2de6bSjchu } 18897c478bd9Sstevel@tonic-gate goto done; 18907c478bd9Sstevel@tonic-gate 1891f8d2de6bSjchu } 1892f8d2de6bSjchu pec_p->pec_ontrap_data = NULL; 1893f8d2de6bSjchu pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; 1894f8d2de6bSjchu if (hp) { 1895f8d2de6bSjchu i_ndi_busop_access_exit(hp->ahi_common.ah_dip, 1896f8d2de6bSjchu (ddi_acc_handle_t)hp); 18977c478bd9Sstevel@tonic-gate } else { 1898f8d2de6bSjchu mutex_exit(&pec_p->pec_pokefault_mutex); 1899f8d2de6bSjchu } 19007c478bd9Sstevel@tonic-gate 19017c478bd9Sstevel@tonic-gate switch (in_args->size) { 19027c478bd9Sstevel@tonic-gate case sizeof (uint8_t): 19037c478bd9Sstevel@tonic-gate *(uint8_t *)host_addr = (uint8_t)peekval; 19047c478bd9Sstevel@tonic-gate break; 19057c478bd9Sstevel@tonic-gate case sizeof (uint16_t): 19067c478bd9Sstevel@tonic-gate *(uint16_t *)host_addr = (uint16_t)peekval; 19077c478bd9Sstevel@tonic-gate break; 19087c478bd9Sstevel@tonic-gate case sizeof (uint32_t): 19097c478bd9Sstevel@tonic-gate *(uint32_t *)host_addr = (uint32_t)peekval; 19107c478bd9Sstevel@tonic-gate break; 19117c478bd9Sstevel@tonic-gate case sizeof (uint64_t): 19127c478bd9Sstevel@tonic-gate *(uint64_t *)host_addr = (uint64_t)peekval; 19137c478bd9Sstevel@tonic-gate break; 19147c478bd9Sstevel@tonic-gate default: 19157c478bd9Sstevel@tonic-gate DBG(DBG_MAP, px_p->px_dip, 19167c478bd9Sstevel@tonic-gate "peek: invalid size %d passed\n", 19177c478bd9Sstevel@tonic-gate in_args->size); 19187c478bd9Sstevel@tonic-gate err = DDI_FAILURE; 19197c478bd9Sstevel@tonic-gate goto done; 19207c478bd9Sstevel@tonic-gate } 19217c478bd9Sstevel@tonic-gate 19227c478bd9Sstevel@tonic-gate host_addr += in_args->size; 19237c478bd9Sstevel@tonic-gate 19247c478bd9Sstevel@tonic-gate if (in_args->flags == DDI_DEV_AUTOINCR) { 19257c478bd9Sstevel@tonic-gate dev_addr += in_args->size; 19267c478bd9Sstevel@tonic-gate ra = (r_addr_t)va_to_pa((void *)dev_addr); 19277c478bd9Sstevel@tonic-gate } 19287c478bd9Sstevel@tonic-gate } 19297c478bd9Sstevel@tonic-gate done: 19307c478bd9Sstevel@tonic-gate return (err); 19317c478bd9Sstevel@tonic-gate } 19327c478bd9Sstevel@tonic-gate 1933f8d2de6bSjchu 1934f8d2de6bSjchu /* add interrupt vector */ 1935f8d2de6bSjchu int 1936f8d2de6bSjchu px_err_add_intr(px_fault_t *px_fault_p) 1937f8d2de6bSjchu { 1938f8d2de6bSjchu px_t *px_p = DIP_TO_STATE(px_fault_p->px_fh_dip); 1939f8d2de6bSjchu 1940f8d2de6bSjchu DBG(DBG_LIB_INT, px_p->px_dip, 1941f8d2de6bSjchu "px_err_add_intr: calling add_ivintr"); 1942f8d2de6bSjchu 1943b0fc0e77Sgovinda VERIFY(add_ivintr(px_fault_p->px_fh_sysino, PX_ERR_PIL, 1944b0fc0e77Sgovinda (intrfunc)px_fault_p->px_err_func, (caddr_t)px_fault_p, NULL, 1945b0fc0e77Sgovinda (caddr_t)&px_fault_p->px_intr_payload[0]) == 0); 1946f8d2de6bSjchu 1947f8d2de6bSjchu DBG(DBG_LIB_INT, px_p->px_dip, 1948f8d2de6bSjchu "px_err_add_intr: ib_intr_enable "); 1949f8d2de6bSjchu 1950f8d2de6bSjchu px_ib_intr_enable(px_p, intr_dist_cpuid(), px_fault_p->px_intr_ino); 1951f8d2de6bSjchu 1952b0fc0e77Sgovinda return (DDI_SUCCESS); 1953f8d2de6bSjchu } 1954f8d2de6bSjchu 1955f8d2de6bSjchu /* remove interrupt vector */ 1956f8d2de6bSjchu void 1957f8d2de6bSjchu px_err_rem_intr(px_fault_t *px_fault_p) 1958f8d2de6bSjchu { 1959f8d2de6bSjchu px_t *px_p = DIP_TO_STATE(px_fault_p->px_fh_dip); 1960f8d2de6bSjchu 1961f8d2de6bSjchu px_ib_intr_disable(px_p->px_ib_p, px_fault_p->px_intr_ino, 1962f8d2de6bSjchu IB_INTR_WAIT); 19639c75c6bfSgovinda 1964b0fc0e77Sgovinda VERIFY(rem_ivintr(px_fault_p->px_fh_sysino, PX_ERR_PIL) == 0); 1965f8d2de6bSjchu } 1966f8d2de6bSjchu 1967a3c68edcSjchu void 1968a3c68edcSjchu px_cb_intr_redist(void *arg) 1969a3c68edcSjchu { 1970a3c68edcSjchu px_t *px_p = (px_t *)arg; 1971a3c68edcSjchu px_ib_intr_dist_en(px_p->px_dip, intr_dist_cpuid(), 1972a3c68edcSjchu px_p->px_inos[PX_INTR_XBC], B_FALSE); 1973a3c68edcSjchu } 1974a3c68edcSjchu 197501689544Sjchu int 197601689544Sjchu px_cb_add_intr(px_fault_t *f_p) 197701689544Sjchu { 1978a3c68edcSjchu px_t *px_p = DIP_TO_STATE(f_p->px_fh_dip); 1979a3c68edcSjchu 1980a3c68edcSjchu DBG(DBG_LIB_INT, px_p->px_dip, 1981a3c68edcSjchu "px_err_add_intr: calling add_ivintr"); 1982a3c68edcSjchu 1983a3c68edcSjchu VERIFY(add_ivintr(f_p->px_fh_sysino, PX_ERR_PIL, 1984a3c68edcSjchu (intrfunc)f_p->px_err_func, (caddr_t)f_p, NULL, 1985a3c68edcSjchu (caddr_t)&f_p->px_intr_payload[0]) == 0); 1986a3c68edcSjchu 1987a3c68edcSjchu intr_dist_add(px_cb_intr_redist, px_p); 1988a3c68edcSjchu 1989a3c68edcSjchu DBG(DBG_LIB_INT, px_p->px_dip, 1990a3c68edcSjchu "px_err_add_intr: ib_intr_enable "); 1991a3c68edcSjchu 1992a3c68edcSjchu px_ib_intr_enable(px_p, intr_dist_cpuid(), f_p->px_intr_ino); 1993a3c68edcSjchu 1994a3c68edcSjchu return (DDI_SUCCESS); 199501689544Sjchu } 199601689544Sjchu 199701689544Sjchu void 199801689544Sjchu px_cb_rem_intr(px_fault_t *f_p) 199901689544Sjchu { 2000a3c68edcSjchu intr_dist_rem(px_cb_intr_redist, DIP_TO_STATE(f_p->px_fh_dip)); 200101689544Sjchu px_err_rem_intr(f_p); 200201689544Sjchu } 200301689544Sjchu 2004f8d2de6bSjchu #ifdef FMA 2005f8d2de6bSjchu void 2006f8d2de6bSjchu px_fill_rc_status(px_fault_t *px_fault_p, pciex_rc_error_regs_t *rc_status) 2007f8d2de6bSjchu { 2008f8d2de6bSjchu px_pec_err_t *err_pkt; 2009f8d2de6bSjchu 2010f8d2de6bSjchu err_pkt = (px_pec_err_t *)px_fault_p->px_intr_payload; 2011f8d2de6bSjchu 2012f8d2de6bSjchu /* initialise all the structure members */ 2013f8d2de6bSjchu rc_status->status_valid = 0; 2014f8d2de6bSjchu 2015f8d2de6bSjchu if (err_pkt->pec_descr.P) { 2016f8d2de6bSjchu /* PCI Status Register */ 2017f8d2de6bSjchu rc_status->pci_err_status = err_pkt->pci_err_status; 2018f8d2de6bSjchu rc_status->status_valid |= PCI_ERR_STATUS_VALID; 2019f8d2de6bSjchu } 2020f8d2de6bSjchu 2021f8d2de6bSjchu if (err_pkt->pec_descr.E) { 2022f8d2de6bSjchu /* PCIe Status Register */ 2023f8d2de6bSjchu rc_status->pcie_err_status = err_pkt->pcie_err_status; 2024f8d2de6bSjchu rc_status->status_valid |= PCIE_ERR_STATUS_VALID; 2025f8d2de6bSjchu } 2026f8d2de6bSjchu 2027f8d2de6bSjchu if (err_pkt->pec_descr.U) { 2028f8d2de6bSjchu rc_status->ue_status = err_pkt->ue_reg_status; 2029f8d2de6bSjchu rc_status->status_valid |= UE_STATUS_VALID; 2030f8d2de6bSjchu } 2031f8d2de6bSjchu 2032f8d2de6bSjchu if (err_pkt->pec_descr.H) { 2033f8d2de6bSjchu rc_status->ue_hdr1 = err_pkt->hdr[0]; 2034f8d2de6bSjchu rc_status->status_valid |= UE_HDR1_VALID; 2035f8d2de6bSjchu } 2036f8d2de6bSjchu 2037f8d2de6bSjchu if (err_pkt->pec_descr.I) { 2038f8d2de6bSjchu rc_status->ue_hdr2 = err_pkt->hdr[1]; 2039f8d2de6bSjchu rc_status->status_valid |= UE_HDR2_VALID; 2040f8d2de6bSjchu } 2041f8d2de6bSjchu 2042f8d2de6bSjchu /* ue_fst_err_ptr - not available for sun4v?? */ 2043f8d2de6bSjchu 2044f8d2de6bSjchu 2045f8d2de6bSjchu if (err_pkt->pec_descr.S) { 2046f8d2de6bSjchu rc_status->source_id = err_pkt->err_src_reg; 2047f8d2de6bSjchu rc_status->status_valid |= SOURCE_ID_VALID; 2048f8d2de6bSjchu } 2049f8d2de6bSjchu 2050f8d2de6bSjchu if (err_pkt->pec_descr.R) { 2051f8d2de6bSjchu rc_status->root_err_status = err_pkt->root_err_status; 2052f8d2de6bSjchu rc_status->status_valid |= CE_STATUS_VALID; 2053f8d2de6bSjchu } 2054f8d2de6bSjchu } 2055f8d2de6bSjchu #endif 2056f8d2de6bSjchu 20577c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 20587c478bd9Sstevel@tonic-gate int 20597c478bd9Sstevel@tonic-gate px_lib_pmctl(int cmd, px_t *px_p) 20607c478bd9Sstevel@tonic-gate { 20617c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 20627c478bd9Sstevel@tonic-gate } 20631a887b2eSjchu 20641a887b2eSjchu /*ARGSUSED*/ 20651a887b2eSjchu uint_t 20661a887b2eSjchu px_pmeq_intr(caddr_t arg) 20671a887b2eSjchu { 20681a887b2eSjchu return (DDI_INTR_CLAIMED); 20691a887b2eSjchu } 20708bc7d88aSet142600 20718bc7d88aSet142600 /* 2072c0da6274SZhi-Jun Robin Fu * fetch the config space base addr of the root complex 2073c0da6274SZhi-Jun Robin Fu * note this depends on px structure being initialized 20748bc7d88aSet142600 */ 2075c0da6274SZhi-Jun Robin Fu uint64_t 2076c0da6274SZhi-Jun Robin Fu px_lib_get_cfgacc_base(dev_info_t *dip) 2077c0da6274SZhi-Jun Robin Fu { 2078c0da6274SZhi-Jun Robin Fu int instance = DIP_TO_INST(dip); 2079c0da6274SZhi-Jun Robin Fu px_t *px_p = INST_TO_STATE(instance); 20808bc7d88aSet142600 2081c0da6274SZhi-Jun Robin Fu return (px_p->px_dev_hdl); 20828bc7d88aSet142600 } 2083817a6df8Sjchu 2084fc256490SJason Beloro void 2085fc256490SJason Beloro px_panic_domain(px_t *px_p, pcie_req_id_t bdf) 2086fc256490SJason Beloro { 2087fc256490SJason Beloro uint64_t ret; 2088fc256490SJason Beloro dev_info_t *dip = px_p->px_dip; 2089fc256490SJason Beloro 2090fc256490SJason Beloro DBG(DBG_ERR_INTR, dip, "px_panic_domain: handle 0x%lx, ino %d, " 2091fc256490SJason Beloro "bdf<<8 0x%lx\n", 2092fc256490SJason Beloro (uint64_t)DIP_TO_HANDLE(dip), px_p->px_cb_fault.px_intr_ino, 2093fc256490SJason Beloro (pci_device_t)bdf << 8); 2094fc256490SJason Beloro if ((ret = pci_error_send(DIP_TO_HANDLE(dip), 2095fc256490SJason Beloro px_p->px_cb_fault.px_intr_ino, (pci_device_t)bdf << 8)) != H_EOK) { 2096fc256490SJason Beloro DBG(DBG_ERR_INTR, dip, "pci_error_send failed, ret 0x%lx\n", 2097fc256490SJason Beloro ret); 2098fc256490SJason Beloro } else 2099fc256490SJason Beloro DBG(DBG_ERR_INTR, dip, "pci_error_send worked\n"); 2100fc256490SJason Beloro } 2101fc256490SJason Beloro 2102b65731f1Skini /*ARGSUSED*/ 2103b65731f1Skini int 2104b65731f1Skini px_lib_hotplug_init(dev_info_t *dip, void *arg) 2105b65731f1Skini { 2106b65731f1Skini return (DDI_ENOTSUP); 2107b65731f1Skini } 2108b65731f1Skini 2109b65731f1Skini /*ARGSUSED*/ 2110b65731f1Skini void 2111b65731f1Skini px_lib_hotplug_uninit(dev_info_t *dip) 2112b65731f1Skini { 2113b65731f1Skini } 2114b65731f1Skini 2115ab4471cdSscarter /*ARGSUSED*/ 2116ab4471cdSscarter void 2117ab4471cdSscarter px_hp_intr_redist(px_t *px_p) 2118ab4471cdSscarter { 2119ab4471cdSscarter } 2120ab4471cdSscarter 2121817a6df8Sjchu /* Dummy cpr add callback */ 2122817a6df8Sjchu /*ARGSUSED*/ 2123817a6df8Sjchu void 2124817a6df8Sjchu px_cpr_add_callb(px_t *px_p) 2125817a6df8Sjchu { 2126817a6df8Sjchu } 2127817a6df8Sjchu 2128817a6df8Sjchu /* Dummy cpr rem callback */ 2129817a6df8Sjchu /*ARGSUSED*/ 2130817a6df8Sjchu void 2131817a6df8Sjchu px_cpr_rem_callb(px_t *px_p) 2132817a6df8Sjchu { 2133817a6df8Sjchu } 2134d60bae31Sdwoods 2135d60bae31Sdwoods /*ARGSUSED*/ 2136d60bae31Sdwoods boolean_t 2137d60bae31Sdwoods px_lib_is_in_drain_state(px_t *px_p) 2138d60bae31Sdwoods { 2139d60bae31Sdwoods return (B_FALSE); 2140d60bae31Sdwoods } 21417ea9b230Set142600 21427ea9b230Set142600 /* 21437ea9b230Set142600 * There is no IOAPI to get the BDF of the pcie root port nexus at this moment. 21447ea9b230Set142600 * Assume it is 0x0000, until otherwise noted. For now, all sun4v platforms 21457ea9b230Set142600 * have programmed the BDF to be 0x0000. 21467ea9b230Set142600 */ 21477ea9b230Set142600 /*ARGSUSED*/ 21487ea9b230Set142600 pcie_req_id_t 21497ea9b230Set142600 px_lib_get_bdf(px_t *px_p) 21507ea9b230Set142600 { 21517ea9b230Set142600 return (0x0000); 21527ea9b230Set142600 } 21530114761dSAlan Adamson, SD OSSD 21540114761dSAlan Adamson, SD OSSD int 21550114761dSAlan Adamson, SD OSSD px_lib_get_root_complex_mps(px_t *px_p, dev_info_t *dip, int *mps) 21560114761dSAlan Adamson, SD OSSD { 21570114761dSAlan Adamson, SD OSSD pci_device_t bdf = px_lib_get_bdf(px_p); 21580114761dSAlan Adamson, SD OSSD 21590114761dSAlan Adamson, SD OSSD if (hvio_get_rp_mps_cap(DIP_TO_HANDLE(dip), bdf, mps) == H_EOK) 21600114761dSAlan Adamson, SD OSSD return (DDI_SUCCESS); 21610114761dSAlan Adamson, SD OSSD else 21620114761dSAlan Adamson, SD OSSD return (DDI_FAILURE); 21630114761dSAlan Adamson, SD OSSD } 21640114761dSAlan Adamson, SD OSSD 21650114761dSAlan Adamson, SD OSSD int 21660114761dSAlan Adamson, SD OSSD px_lib_set_root_complex_mps(px_t *px_p, dev_info_t *dip, int mps) 21670114761dSAlan Adamson, SD OSSD { 21680114761dSAlan Adamson, SD OSSD pci_device_t bdf = px_lib_get_bdf(px_p); 21690114761dSAlan Adamson, SD OSSD 21700114761dSAlan Adamson, SD OSSD if (hvio_set_rp_mps(DIP_TO_HANDLE(dip), bdf, mps) == H_EOK) 21710114761dSAlan Adamson, SD OSSD return (DDI_SUCCESS); 21720114761dSAlan Adamson, SD OSSD else 21730114761dSAlan Adamson, SD OSSD return (DDI_FAILURE); 21740114761dSAlan Adamson, SD OSSD } 2175fc256490SJason Beloro 2176fc256490SJason Beloro static int 2177fc256490SJason Beloro px_lib_do_count_waiting_dev(dev_info_t *dip, void *arg) 2178fc256490SJason Beloro { 2179fc256490SJason Beloro int *count = (int *)arg; 2180fc256490SJason Beloro dev_info_t *cdip = ddi_get_child(dip); 2181fc256490SJason Beloro 2182fc256490SJason Beloro while (cdip != NULL) { 2183fc256490SJason Beloro /* check if this is an assigned device */ 2184fc256490SJason Beloro if (ddi_prop_exists(DDI_DEV_T_NONE, cdip, DDI_PROP_DONTPASS, 2185fc256490SJason Beloro "ddi-assigned")) { 2186fc256490SJason Beloro DBG(DBG_ATTACH, dip, "px_lib_do_count_waiting_dev: " 2187fc256490SJason Beloro "Found an assigned dev %p, under bridge %p", 2188fc256490SJason Beloro cdip, dip); 2189fc256490SJason Beloro 2190fc256490SJason Beloro /* 2191fc256490SJason Beloro * Mark this bridge as needing waiting for 2192fc256490SJason Beloro * CHILD_LOANED will be removed after bridge reports 2193fc256490SJason Beloro * its readyness back to px driver 2194fc256490SJason Beloro */ 2195fc256490SJason Beloro if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 2196fc256490SJason Beloro CHILD_LOANED, 1) == DDI_PROP_SUCCESS) 2197fc256490SJason Beloro (*count)++; 2198fc256490SJason Beloro break; 2199fc256490SJason Beloro } 2200fc256490SJason Beloro cdip = ddi_get_next_sibling(cdip); 2201fc256490SJason Beloro } 2202fc256490SJason Beloro 2203fc256490SJason Beloro return (DDI_WALK_CONTINUE); 2204fc256490SJason Beloro } 2205fc256490SJason Beloro 2206fc256490SJason Beloro static int 2207fc256490SJason Beloro px_lib_count_waiting_dev(dev_info_t *dip) 2208fc256490SJason Beloro { 2209fc256490SJason Beloro int circular_count; 2210fc256490SJason Beloro int count = 0; 2211fc256490SJason Beloro 2212fc256490SJason Beloro /* No need to continue if this system is not SDIO capable */ 2213fc256490SJason Beloro if (px_sdio_users == 0) 2214fc256490SJason Beloro return (0); 2215fc256490SJason Beloro 2216fc256490SJason Beloro /* see if px iteslf has assigned children */ 2217fc256490SJason Beloro (void) px_lib_do_count_waiting_dev(dip, &count); 2218fc256490SJason Beloro 2219fc256490SJason Beloro /* scan dev under this px */ 2220fc256490SJason Beloro ndi_devi_enter(dip, &circular_count); 2221fc256490SJason Beloro ddi_walk_devs(ddi_get_child(dip), px_lib_do_count_waiting_dev, &count); 2222fc256490SJason Beloro ndi_devi_exit(dip, circular_count); 2223fc256490SJason Beloro return (count); 2224fc256490SJason Beloro } 2225fc256490SJason Beloro 2226fc256490SJason Beloro /* Called from px/bridge driver directly to report its readyness */ 2227fc256490SJason Beloro int 2228fc256490SJason Beloro px_lib_fabric_sync(dev_info_t *dip) 2229fc256490SJason Beloro { 2230fc256490SJason Beloro px_t *px; 2231fc256490SJason Beloro dev_info_t *rcdip; 2232fc256490SJason Beloro int waitdev; 2233fc256490SJason Beloro 2234fc256490SJason Beloro /* No need to continue if this system is not SDIO capable */ 2235fc256490SJason Beloro if (px_sdio_users == 0) 2236fc256490SJason Beloro return (DDI_SUCCESS); 2237fc256490SJason Beloro 2238fc256490SJason Beloro /* a valid bridge w/ assigned dev under it? */ 2239fc256490SJason Beloro if (ddi_prop_remove(DDI_DEV_T_NONE, dip, CHILD_LOANED) != 2240fc256490SJason Beloro DDI_PROP_SUCCESS) 2241fc256490SJason Beloro return (DDI_FAILURE); 2242fc256490SJason Beloro 2243fc256490SJason Beloro /* find out RC dip */ 2244fc256490SJason Beloro for (rcdip = dip; rcdip != NULL; rcdip = ddi_get_parent(rcdip)) { 2245fc256490SJason Beloro if (PCIE_DIP2BUS(rcdip) && PCIE_IS_RC(PCIE_DIP2BUS(rcdip))) 2246fc256490SJason Beloro break; 2247fc256490SJason Beloro } 2248fc256490SJason Beloro if ((rcdip == NULL) || ((px = (px_t *)DIP_TO_STATE(rcdip)) == NULL)) 2249fc256490SJason Beloro return (DDI_FAILURE); 2250fc256490SJason Beloro 2251fc256490SJason Beloro /* are we ready? */ 2252fc256490SJason Beloro waitdev = (int)(uintptr_t)px->px_plat_p; 2253fc256490SJason Beloro ASSERT(waitdev); 2254fc256490SJason Beloro DBG(DBG_CTLOPS, rcdip, "px_lib_fabric_sync: " 2255fc256490SJason Beloro "Px/bridge %p is ready, %d left", rcdip, waitdev - 1); 2256fc256490SJason Beloro --waitdev; 2257fc256490SJason Beloro px->px_plat_p = (void *)(uintptr_t)waitdev; 2258fc256490SJason Beloro if (waitdev != 0) 2259fc256490SJason Beloro return (DDI_SUCCESS); 2260fc256490SJason Beloro 2261fc256490SJason Beloro /* notify hpyervisor */ 2262fc256490SJason Beloro DBG(DBG_CTLOPS, rcdip, "px_lib_fabric_sync: " 2263fc256490SJason Beloro "Notifying HV that RC %p is ready users=%d", rcdip, px_sdio_users); 2264fc256490SJason Beloro 2265fc256490SJason Beloro if (pci_iov_root_configured(px->px_dev_hdl) != H_EOK) 2266fc256490SJason Beloro return (DDI_FAILURE); 2267fc256490SJason Beloro 2268fc256490SJason Beloro return (DDI_SUCCESS); 2269fc256490SJason Beloro } 2270