fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * CDDL HEADER START
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * The contents of this file are subject to the terms of the
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Common Development and Distribution License (the "License").
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * You may not use this file except in compliance with the License.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * See the License for the specific language governing permissions
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * and limitations under the License.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * When distributing Covered Code, include this CDDL HEADER in each
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * If applicable, add the following below this CDDL HEADER, with the
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * fields enclosed by brackets "[]" replaced with your own identifying
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * information: Portions Copyright [yyyy] [name of copyright owner]
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * CDDL HEADER END
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Use is subject to license terms.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * The below 2 global variables are for PCIe IOV Error Handling. They must only
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * be accessed during error handling under the protection of a error mutex.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Belorostatic pcie_domains_t *pcie_faulty_domains = NULL;
fc256490629fe68815f7e0f23cf9b3545720cfacJason Belorostatic void pcie_domain_list_destroy(pcie_domains_t *domain_ids);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Belorostatic void pcie_bdf_list_add(pcie_req_id_t bdf,
fc256490629fe68815f7e0f23cf9b3545720cfacJason Belorostatic void pcie_bdf_list_remove(pcie_req_id_t bdf,
fc256490629fe68815f7e0f23cf9b3545720cfacJason Belorostatic void pcie_cache_domain_info(pcie_bus_t *bus_p);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Belorostatic void pcie_uncache_domain_info(pcie_bus_t *bus_p);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Belorostatic void pcie_faulty_list_update(pcie_domains_t *pd,
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropcie_find_dip_by_bdf(dev_info_t *rootp, pcie_req_id_t bdf)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Add a device bdf to the bdf list.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropcie_bdf_list_add(pcie_req_id_t bdf, pcie_req_id_list_t **rlist_p)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pcie_req_id_list_t *rl = PCIE_ZALLOC(pcie_req_id_list_t);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Remove a bdf from the bdf list.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropcie_bdf_list_remove(pcie_req_id_t bdf, pcie_req_id_list_t **rlist_p)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro kmem_free(rl_pre, sizeof (pcie_req_id_list_t));
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro kmem_free(rl_next, sizeof (pcie_req_id_list_t));
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Cache IOV domain info in all it's parent's pcie_domain_t
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * The leaf devices's domain info must be set before calling this function.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro boolean_t fma_dom = PCIE_ASSIGNED_TO_FMA_DOM(bus_p);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro for (pdip = ddi_get_parent(PCIE_BUS2DIP(bus_p)); PCIE_DIP2BUS(pdip);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Clear the leaf device's domain info and uncache IOV domain info in all it's
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * parent's pcie_domain_t
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * The leaf devices's domain info is also cleared by calling this function.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro boolean_t fma_dom = PCIE_ASSIGNED_TO_FMA_DOM(bus_p);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pcie_domain_t *dom_p = PCIE_BUS2DOM(bus_p), *pdom_p;
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro ASSERT((dom_p->fmadom_count + dom_p->nfmadom_count +
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro /* Clear the domain information */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro for (pdip = ddi_get_parent(PCIE_BUS2DIP(bus_p)); PCIE_DIP2BUS(pdip);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Initialize private data structure for IOV environments.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * o Allocate memory for iov data
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * o Cache Domain ids.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pcie_domain_t *dom_p = PCIE_ZALLOC(pcie_domain_t);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro /* Only leaf devices are assignable to IO Domains */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * At the time of init_dom in the root domain a device may or may not
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * have been assigned to an IO Domain.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * LDOMS: the property "ddi-assigned" will be set for devices that is
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * assignable to an IO domain and unusable in the root domain. If the
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * property exist assume it has been assigned to a non-fma domain until
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * otherwise notified. The domain id is unknown on LDOMS.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Xen: the "ddi-assigned" property won't be set until Xen store calls
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * pcie_loan_device is called. In this function this will always look
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * like the device is assigned to the root domain. Domain ID caching
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * will occur in pcie_loan_device function.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro if (ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro /* Prevent "assigned" device from detaching */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "ddi-assigned");
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pcie_domain_list_destroy(PCIE_DOMAIN_LIST_GET(bus_p));
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PCIe Severity:
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PF_ERR_NO_ERROR : no IOV Action
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PF_ERR_CE : no IOV Action
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PF_ERR_NO_PANIC : contains error telemetry, log domain info
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PF_ERR_MATCHED_DEVICE: contains error telemetry, log domain info
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PF_ERR_MATCHED_RC : Error already taken care of, no further IOV Action
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PF_ERR_MATCHED_PARENT: Error already taken care of, no further IOV Action
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PF_ERR_PANIC : contains error telemetry, log domain info
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * For NO_PANIC, MATCHED_DEVICE and PANIC, IOV wants to look at the affected
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * devices and find the domains involved.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * If root domain does not own an affected device, IOV EH should change
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * PF_ERR_PANIC to PF_ERR_MATCH_DOM.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pcie_bus_t *a_bus_p; /* Affected device's pcie_bus_t */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * check if all devices under the root device are unassigned.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * this function should quickly return in non-IOV environment.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro } else if (severity & (PF_ERR_NO_PANIC | PF_ERR_MATCHED_DEVICE |
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro dev_affected_flags = PFD_AFFECTED_DEV(pfd_p)->pe_affected_flags;
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro /* adjust affected flags to leverage cached domain ids */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro if (dev_affected_flags & PF_AFFECTED_CHILDREN) {
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * If a leaf device is assigned to the root domain or if
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * a bridge has children assigned to a root domain
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * If a leaf device or a child of a bridge is assigned
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * to NFMA domain mark it for panic. If assigned to FMA
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * domain save the domain id.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Overwrite the severity only if affected device can be
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * identified and root domain does not need to panic.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro/* ARGSUSED */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropciev_eh_exit(pf_data_t *root_pfd_p, uint_t intr_type)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * check if all devices under the root device are unassigned.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * this function should quickly return in non-IOV environment.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropciev_get_affected_dev(pf_impl_t *impl, pf_data_t *pfd_p,
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro uint16_t affected_flag, uint16_t dev_affected_flags)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro uint16_t flag = affected_flag & dev_affected_flags;
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro return (PCIE_DIP2BUS(ddi_get_parent(PCIE_BUS2DIP(bus_p))));
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro case PF_AFFECTED_BDF: /* may only be used for RC */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro a_bdf = PFD_AFFECTED_DEV(pfd_p)->pe_affected_bdf;
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro if (pf_tlp_decode(bus_p, PCIE_ADV_REG(pfd_p)) == DDI_SUCCESS) {
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro if (pf_pci_decode(pfd_p, &cmd) == DDI_SUCCESS) {
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro temp_bus_p = pf_find_busp_by_saer(impl, pfd_p);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro temp_bus_p = pf_find_busp_by_addr(impl, a_addr);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro/* type used for pcie_domain_list_find() function */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Belorotypedef enum {
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Check if a domain id is already in the linked list
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropcie_domain_list_find(uint_t domain_id, pcie_domains_t *pd_list_p,
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Return true if a leaf device is assigned to a domain or a bridge device
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * has children assigned to the domain
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropcie_in_domain(pcie_bus_t *bus_p, uint_t domain_id)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro PCIE_DOMAIN_LIST_GET(bus_p), PCIE_DOM_LIST_TYPE_CACHE);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro return (PCIE_DOMAIN_ID_GET(bus_p) == domain_id);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Add a domain id to a cached domain id list.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * If the domain already exists in the list, increment the reference count.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropcie_domain_list_add(uint_t domain_id, pcie_domains_t **pd_list_p)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pd = pcie_domain_list_find(domain_id, *pd_list_p,
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Remove a domain id from a cached domain id list.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Decrement the reference count.
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropcie_domain_list_remove(uint_t domain_id, pcie_domains_t *pd_list_p)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pd = pcie_domain_list_find(domain_id, pd_list_p,
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro/* destroy cached domain id list */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloropcie_domain_list_destroy(pcie_domains_t *domain_ids)
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro /* unlink all domain structures from the faulty list */
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro /* search domain id in the faulty domain list */