17613SVikram.Hegde@Sun.COM /*
27613SVikram.Hegde@Sun.COM * CDDL HEADER START
37613SVikram.Hegde@Sun.COM *
47613SVikram.Hegde@Sun.COM * The contents of this file are subject to the terms of the
57613SVikram.Hegde@Sun.COM * Common Development and Distribution License (the "License").
67613SVikram.Hegde@Sun.COM * You may not use this file except in compliance with the License.
77613SVikram.Hegde@Sun.COM *
87613SVikram.Hegde@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97613SVikram.Hegde@Sun.COM * or http://www.opensolaris.org/os/licensing.
107613SVikram.Hegde@Sun.COM * See the License for the specific language governing permissions
117613SVikram.Hegde@Sun.COM * and limitations under the License.
127613SVikram.Hegde@Sun.COM *
137613SVikram.Hegde@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147613SVikram.Hegde@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157613SVikram.Hegde@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167613SVikram.Hegde@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177613SVikram.Hegde@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187613SVikram.Hegde@Sun.COM *
197613SVikram.Hegde@Sun.COM * CDDL HEADER END
207613SVikram.Hegde@Sun.COM */
217613SVikram.Hegde@Sun.COM /*
22*13050Sfrank.van.der.linden@oracle.com * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
237613SVikram.Hegde@Sun.COM */
247613SVikram.Hegde@Sun.COM
257613SVikram.Hegde@Sun.COM #pragma ident "@(#)iommulib.c 1.6 08/09/07 SMI"
267613SVikram.Hegde@Sun.COM
277613SVikram.Hegde@Sun.COM #include <sys/sunddi.h>
287613SVikram.Hegde@Sun.COM #include <sys/sunndi.h>
297613SVikram.Hegde@Sun.COM #include <sys/errno.h>
307613SVikram.Hegde@Sun.COM #include <sys/modctl.h>
317613SVikram.Hegde@Sun.COM #include <sys/iommulib.h>
327613SVikram.Hegde@Sun.COM
337613SVikram.Hegde@Sun.COM /* ******** Type definitions private to this file ********************** */
347613SVikram.Hegde@Sun.COM
357613SVikram.Hegde@Sun.COM /* 1 per IOMMU unit. There may be more than one per dip */
367613SVikram.Hegde@Sun.COM typedef struct iommulib_unit {
377613SVikram.Hegde@Sun.COM kmutex_t ilu_lock;
387613SVikram.Hegde@Sun.COM uint64_t ilu_ref;
397613SVikram.Hegde@Sun.COM uint32_t ilu_unitid;
407613SVikram.Hegde@Sun.COM dev_info_t *ilu_dip;
417613SVikram.Hegde@Sun.COM iommulib_ops_t *ilu_ops;
427613SVikram.Hegde@Sun.COM void* ilu_data;
437613SVikram.Hegde@Sun.COM struct iommulib_unit *ilu_next;
447613SVikram.Hegde@Sun.COM struct iommulib_unit *ilu_prev;
45*13050Sfrank.van.der.linden@oracle.com iommulib_nexhandle_t ilu_nex;
467613SVikram.Hegde@Sun.COM } iommulib_unit_t;
477613SVikram.Hegde@Sun.COM
487613SVikram.Hegde@Sun.COM typedef struct iommulib_nex {
497613SVikram.Hegde@Sun.COM dev_info_t *nex_dip;
507613SVikram.Hegde@Sun.COM iommulib_nexops_t nex_ops;
517613SVikram.Hegde@Sun.COM struct iommulib_nex *nex_next;
527613SVikram.Hegde@Sun.COM struct iommulib_nex *nex_prev;
53*13050Sfrank.van.der.linden@oracle.com uint_t nex_ref;
547613SVikram.Hegde@Sun.COM } iommulib_nex_t;
557613SVikram.Hegde@Sun.COM
567613SVikram.Hegde@Sun.COM /* ********* Globals ************************ */
577613SVikram.Hegde@Sun.COM
588371SVikram.Hegde@Sun.COM /* For IOMMU drivers */
598371SVikram.Hegde@Sun.COM smbios_hdl_t *iommulib_smbios;
608371SVikram.Hegde@Sun.COM
617613SVikram.Hegde@Sun.COM /* IOMMU side: Following data protected by lock */
627613SVikram.Hegde@Sun.COM static kmutex_t iommulib_lock;
637613SVikram.Hegde@Sun.COM static iommulib_unit_t *iommulib_list;
647613SVikram.Hegde@Sun.COM static uint64_t iommulib_unit_ids = 0;
657613SVikram.Hegde@Sun.COM static uint64_t iommulib_num_units = 0;
667613SVikram.Hegde@Sun.COM
677613SVikram.Hegde@Sun.COM /* rootnex side data */
687613SVikram.Hegde@Sun.COM
697613SVikram.Hegde@Sun.COM static kmutex_t iommulib_nexus_lock;
707613SVikram.Hegde@Sun.COM static iommulib_nex_t *iommulib_nexus_list;
717613SVikram.Hegde@Sun.COM
727613SVikram.Hegde@Sun.COM /* can be set atomically without lock */
737613SVikram.Hegde@Sun.COM static volatile uint32_t iommulib_fini;
747613SVikram.Hegde@Sun.COM
757613SVikram.Hegde@Sun.COM /* debug flag */
767613SVikram.Hegde@Sun.COM static int iommulib_debug;
777613SVikram.Hegde@Sun.COM
787613SVikram.Hegde@Sun.COM /*
797613SVikram.Hegde@Sun.COM * Module linkage information for the kernel.
807613SVikram.Hegde@Sun.COM */
817613SVikram.Hegde@Sun.COM static struct modlmisc modlmisc = {
827613SVikram.Hegde@Sun.COM &mod_miscops, "IOMMU library module"
837613SVikram.Hegde@Sun.COM };
847613SVikram.Hegde@Sun.COM
857613SVikram.Hegde@Sun.COM static struct modlinkage modlinkage = {
867613SVikram.Hegde@Sun.COM MODREV_1, (void *)&modlmisc, NULL
877613SVikram.Hegde@Sun.COM };
887613SVikram.Hegde@Sun.COM
897613SVikram.Hegde@Sun.COM int
_init(void)907613SVikram.Hegde@Sun.COM _init(void)
917613SVikram.Hegde@Sun.COM {
927613SVikram.Hegde@Sun.COM return (mod_install(&modlinkage));
937613SVikram.Hegde@Sun.COM }
947613SVikram.Hegde@Sun.COM
957613SVikram.Hegde@Sun.COM int
_fini(void)967613SVikram.Hegde@Sun.COM _fini(void)
977613SVikram.Hegde@Sun.COM {
987613SVikram.Hegde@Sun.COM mutex_enter(&iommulib_lock);
997613SVikram.Hegde@Sun.COM if (iommulib_list != NULL || iommulib_nexus_list != NULL) {
1007613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
1017613SVikram.Hegde@Sun.COM return (EBUSY);
1027613SVikram.Hegde@Sun.COM }
1037613SVikram.Hegde@Sun.COM iommulib_fini = 1;
1047613SVikram.Hegde@Sun.COM
1057613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
1067613SVikram.Hegde@Sun.COM return (mod_remove(&modlinkage));
1077613SVikram.Hegde@Sun.COM }
1087613SVikram.Hegde@Sun.COM
1097613SVikram.Hegde@Sun.COM int
_info(struct modinfo * modinfop)1107613SVikram.Hegde@Sun.COM _info(struct modinfo *modinfop)
1117613SVikram.Hegde@Sun.COM {
1127613SVikram.Hegde@Sun.COM return (mod_info(&modlinkage, modinfop));
1137613SVikram.Hegde@Sun.COM }
1147613SVikram.Hegde@Sun.COM
1157613SVikram.Hegde@Sun.COM /*
1167613SVikram.Hegde@Sun.COM * Routines with iommulib_iommu_* are invoked from the
1177613SVikram.Hegde@Sun.COM * IOMMU driver.
1187613SVikram.Hegde@Sun.COM * Routines with iommulib_nex* are invoked from the
1197613SVikram.Hegde@Sun.COM * nexus driver (typically rootnex)
1207613SVikram.Hegde@Sun.COM */
1217613SVikram.Hegde@Sun.COM
1227613SVikram.Hegde@Sun.COM int
iommulib_nexus_register(dev_info_t * dip,iommulib_nexops_t * nexops,iommulib_nexhandle_t * handle)1237613SVikram.Hegde@Sun.COM iommulib_nexus_register(dev_info_t *dip, iommulib_nexops_t *nexops,
1247613SVikram.Hegde@Sun.COM iommulib_nexhandle_t *handle)
1257613SVikram.Hegde@Sun.COM {
1267613SVikram.Hegde@Sun.COM iommulib_nex_t *nexp;
1277613SVikram.Hegde@Sun.COM int instance = ddi_get_instance(dip);
1287613SVikram.Hegde@Sun.COM const char *driver = ddi_driver_name(dip);
1297613SVikram.Hegde@Sun.COM dev_info_t *pdip = ddi_get_parent(dip);
1307613SVikram.Hegde@Sun.COM const char *f = "iommulib_nexus_register";
1317613SVikram.Hegde@Sun.COM
1327613SVikram.Hegde@Sun.COM ASSERT(nexops);
1337613SVikram.Hegde@Sun.COM ASSERT(handle);
1347613SVikram.Hegde@Sun.COM
1357613SVikram.Hegde@Sun.COM *handle = NULL;
1367613SVikram.Hegde@Sun.COM
1377613SVikram.Hegde@Sun.COM /*
1387613SVikram.Hegde@Sun.COM * Root node is never busy held
1397613SVikram.Hegde@Sun.COM */
1407613SVikram.Hegde@Sun.COM if (dip != ddi_root_node() && (i_ddi_node_state(dip) < DS_PROBED ||
1417613SVikram.Hegde@Sun.COM !DEVI_BUSY_OWNED(pdip))) {
1427613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: NEXUS devinfo node not in DS_PROBED "
1437613SVikram.Hegde@Sun.COM "or busy held for nexops vector (%p). Failing registration",
1447613SVikram.Hegde@Sun.COM f, (void *)nexops);
1457613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
1467613SVikram.Hegde@Sun.COM }
1477613SVikram.Hegde@Sun.COM
1487613SVikram.Hegde@Sun.COM if (nexops->nops_vers != IOMMU_NEXOPS_VERSION) {
1497613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: Invalid IOMMULIB nexops version "
1507613SVikram.Hegde@Sun.COM "in nexops vector (%p). Failing NEXUS registration",
1517613SVikram.Hegde@Sun.COM f, driver, instance, (void *)nexops);
1527613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
1537613SVikram.Hegde@Sun.COM }
1547613SVikram.Hegde@Sun.COM
1557613SVikram.Hegde@Sun.COM ASSERT(nexops->nops_data == NULL);
1567613SVikram.Hegde@Sun.COM
1577613SVikram.Hegde@Sun.COM if (nexops->nops_id == NULL) {
1587613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL ID field. "
1597613SVikram.Hegde@Sun.COM "Failing registration for nexops vector: %p",
1607613SVikram.Hegde@Sun.COM f, driver, instance, (void *)nexops);
1617613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
1627613SVikram.Hegde@Sun.COM }
1637613SVikram.Hegde@Sun.COM
1647613SVikram.Hegde@Sun.COM if (nexops->nops_dma_allochdl == NULL) {
1657613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_allochdl op. "
1667613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
1677613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
1687613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
1697613SVikram.Hegde@Sun.COM }
1707613SVikram.Hegde@Sun.COM
1717613SVikram.Hegde@Sun.COM if (nexops->nops_dma_freehdl == NULL) {
1727613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_freehdl op. "
1737613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
1747613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
1757613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
1767613SVikram.Hegde@Sun.COM }
1777613SVikram.Hegde@Sun.COM
1787613SVikram.Hegde@Sun.COM if (nexops->nops_dma_bindhdl == NULL) {
1797613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_bindhdl op. "
1807613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
1817613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
1827613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
1837613SVikram.Hegde@Sun.COM }
1847613SVikram.Hegde@Sun.COM
1857613SVikram.Hegde@Sun.COM if (nexops->nops_dma_sync == NULL) {
1867613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_sync op. "
1877613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
1887613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
1897613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
1907613SVikram.Hegde@Sun.COM }
1917613SVikram.Hegde@Sun.COM
1927613SVikram.Hegde@Sun.COM if (nexops->nops_dma_reset_cookies == NULL) {
1937613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_reset_cookies op. "
1947613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
1957613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
1967613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
1977613SVikram.Hegde@Sun.COM }
1987613SVikram.Hegde@Sun.COM
1997613SVikram.Hegde@Sun.COM if (nexops->nops_dma_get_cookies == NULL) {
2007613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_get_cookies op. "
2017613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
2027613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
2037613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
2047613SVikram.Hegde@Sun.COM }
2057613SVikram.Hegde@Sun.COM
2068215SVikram.Hegde@Sun.COM if (nexops->nops_dma_set_cookies == NULL) {
2078215SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_set_cookies op. "
2088215SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
2098215SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
2108215SVikram.Hegde@Sun.COM return (DDI_FAILURE);
2118215SVikram.Hegde@Sun.COM }
2128215SVikram.Hegde@Sun.COM
2138215SVikram.Hegde@Sun.COM if (nexops->nops_dma_clear_cookies == NULL) {
2148215SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_clear_cookies op. "
2158215SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
2168215SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
2178215SVikram.Hegde@Sun.COM return (DDI_FAILURE);
2188215SVikram.Hegde@Sun.COM }
2198215SVikram.Hegde@Sun.COM
2208215SVikram.Hegde@Sun.COM if (nexops->nops_dma_get_sleep_flags == NULL) {
2218215SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_get_sleep_flags op. "
2228215SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
2238215SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
2248215SVikram.Hegde@Sun.COM return (DDI_FAILURE);
2258215SVikram.Hegde@Sun.COM }
2268215SVikram.Hegde@Sun.COM
2277613SVikram.Hegde@Sun.COM if (nexops->nops_dma_win == NULL) {
2287613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL nops_dma_win op. "
2297613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
2307613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
2317613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
2327613SVikram.Hegde@Sun.COM }
2337613SVikram.Hegde@Sun.COM
234*13050Sfrank.van.der.linden@oracle.com if (nexops->nops_dmahdl_setprivate == NULL) {
235*13050Sfrank.van.der.linden@oracle.com cmn_err(CE_WARN, "%s: %s%d: NULL nops_dmahdl_setprivate op. "
236*13050Sfrank.van.der.linden@oracle.com "Failing registration for ops vector: %p", f,
237*13050Sfrank.van.der.linden@oracle.com driver, instance, (void *)nexops);
238*13050Sfrank.van.der.linden@oracle.com return (DDI_FAILURE);
239*13050Sfrank.van.der.linden@oracle.com }
240*13050Sfrank.van.der.linden@oracle.com
241*13050Sfrank.van.der.linden@oracle.com if (nexops->nops_dmahdl_getprivate == NULL) {
242*13050Sfrank.van.der.linden@oracle.com cmn_err(CE_WARN, "%s: %s%d: NULL nops_dmahdl_getprivate op. "
243*13050Sfrank.van.der.linden@oracle.com "Failing registration for ops vector: %p", f,
244*13050Sfrank.van.der.linden@oracle.com driver, instance, (void *)nexops);
245*13050Sfrank.van.der.linden@oracle.com return (DDI_FAILURE);
246*13050Sfrank.van.der.linden@oracle.com }
247*13050Sfrank.van.der.linden@oracle.com
2487613SVikram.Hegde@Sun.COM /* Check for legacy ops */
2497613SVikram.Hegde@Sun.COM if (nexops->nops_dma_map == NULL) {
2507613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL legacy nops_dma_map op. "
2517613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
2527613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
2537613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
2547613SVikram.Hegde@Sun.COM }
2557613SVikram.Hegde@Sun.COM
2567613SVikram.Hegde@Sun.COM if (nexops->nops_dma_mctl == NULL) {
2577613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL legacy nops_dma_mctl op. "
2587613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
2597613SVikram.Hegde@Sun.COM driver, instance, (void *)nexops);
2607613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
2617613SVikram.Hegde@Sun.COM }
2627613SVikram.Hegde@Sun.COM
2637613SVikram.Hegde@Sun.COM nexp = kmem_zalloc(sizeof (iommulib_nex_t), KM_SLEEP);
2647613SVikram.Hegde@Sun.COM
2657613SVikram.Hegde@Sun.COM mutex_enter(&iommulib_lock);
2667613SVikram.Hegde@Sun.COM if (iommulib_fini == 1) {
2677613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
2687613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: IOMMULIB unloading. "
2697613SVikram.Hegde@Sun.COM "Failing NEXUS register.", f);
2707613SVikram.Hegde@Sun.COM kmem_free(nexp, sizeof (iommulib_nex_t));
2717613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
2727613SVikram.Hegde@Sun.COM }
2737613SVikram.Hegde@Sun.COM
2747613SVikram.Hegde@Sun.COM /*
2757613SVikram.Hegde@Sun.COM * fini/register race conditions have been handled. Now create the
2767613SVikram.Hegde@Sun.COM * nexus struct
2777613SVikram.Hegde@Sun.COM */
2787613SVikram.Hegde@Sun.COM ndi_hold_devi(dip);
2797613SVikram.Hegde@Sun.COM nexp->nex_dip = dip;
2807613SVikram.Hegde@Sun.COM nexp->nex_ops = *nexops;
2817613SVikram.Hegde@Sun.COM
2827613SVikram.Hegde@Sun.COM mutex_enter(&iommulib_nexus_lock);
2837613SVikram.Hegde@Sun.COM nexp->nex_next = iommulib_nexus_list;
2847613SVikram.Hegde@Sun.COM iommulib_nexus_list = nexp;
2857613SVikram.Hegde@Sun.COM nexp->nex_prev = NULL;
2867613SVikram.Hegde@Sun.COM
2877613SVikram.Hegde@Sun.COM if (nexp->nex_next != NULL)
2887613SVikram.Hegde@Sun.COM nexp->nex_next->nex_prev = nexp;
2897613SVikram.Hegde@Sun.COM
290*13050Sfrank.van.der.linden@oracle.com nexp->nex_ref = 0;
291*13050Sfrank.van.der.linden@oracle.com
292*13050Sfrank.van.der.linden@oracle.com /*
293*13050Sfrank.van.der.linden@oracle.com * The nexus device won't be controlled by an IOMMU.
294*13050Sfrank.van.der.linden@oracle.com */
295*13050Sfrank.van.der.linden@oracle.com DEVI(dip)->devi_iommulib_handle = IOMMU_HANDLE_UNUSED;
296*13050Sfrank.van.der.linden@oracle.com
297*13050Sfrank.van.der.linden@oracle.com DEVI(dip)->devi_iommulib_nex_handle = nexp;
298*13050Sfrank.van.der.linden@oracle.com
2997613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_nexus_lock);
3007613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
3017613SVikram.Hegde@Sun.COM
3027613SVikram.Hegde@Sun.COM cmn_err(CE_NOTE, "!%s: %s%d: Succesfully registered NEXUS %s "
3037613SVikram.Hegde@Sun.COM "nexops=%p", f, driver, instance, ddi_node_name(dip),
3047613SVikram.Hegde@Sun.COM (void *)nexops);
3057613SVikram.Hegde@Sun.COM
3067613SVikram.Hegde@Sun.COM *handle = nexp;
3077613SVikram.Hegde@Sun.COM
3087613SVikram.Hegde@Sun.COM return (DDI_SUCCESS);
3097613SVikram.Hegde@Sun.COM }
3107613SVikram.Hegde@Sun.COM
3117613SVikram.Hegde@Sun.COM int
iommulib_nexus_unregister(iommulib_nexhandle_t handle)3127613SVikram.Hegde@Sun.COM iommulib_nexus_unregister(iommulib_nexhandle_t handle)
3137613SVikram.Hegde@Sun.COM {
3147613SVikram.Hegde@Sun.COM dev_info_t *dip;
3157613SVikram.Hegde@Sun.COM int instance;
3167613SVikram.Hegde@Sun.COM const char *driver;
3177613SVikram.Hegde@Sun.COM iommulib_nex_t *nexp = (iommulib_nex_t *)handle;
3187613SVikram.Hegde@Sun.COM const char *f = "iommulib_nexus_unregister";
3197613SVikram.Hegde@Sun.COM
3207613SVikram.Hegde@Sun.COM ASSERT(nexp);
3217613SVikram.Hegde@Sun.COM
322*13050Sfrank.van.der.linden@oracle.com if (nexp->nex_ref != 0)
323*13050Sfrank.van.der.linden@oracle.com return (DDI_FAILURE);
324*13050Sfrank.van.der.linden@oracle.com
3257613SVikram.Hegde@Sun.COM mutex_enter(&iommulib_nexus_lock);
3267613SVikram.Hegde@Sun.COM
3277613SVikram.Hegde@Sun.COM dip = nexp->nex_dip;
3287613SVikram.Hegde@Sun.COM driver = ddi_driver_name(dip);
3297613SVikram.Hegde@Sun.COM instance = ddi_get_instance(dip);
3307613SVikram.Hegde@Sun.COM
3317613SVikram.Hegde@Sun.COM /* A future enhancement would be to add ref-counts */
3327613SVikram.Hegde@Sun.COM
3337613SVikram.Hegde@Sun.COM if (nexp->nex_prev == NULL) {
3347613SVikram.Hegde@Sun.COM iommulib_nexus_list = nexp->nex_next;
3357613SVikram.Hegde@Sun.COM } else {
3367613SVikram.Hegde@Sun.COM nexp->nex_prev->nex_next = nexp->nex_next;
3377613SVikram.Hegde@Sun.COM }
3387613SVikram.Hegde@Sun.COM
3397613SVikram.Hegde@Sun.COM if (nexp->nex_next != NULL)
3407613SVikram.Hegde@Sun.COM nexp->nex_next->nex_prev = nexp->nex_prev;
3417613SVikram.Hegde@Sun.COM
3427613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_nexus_lock);
3437613SVikram.Hegde@Sun.COM
3447613SVikram.Hegde@Sun.COM kmem_free(nexp, sizeof (iommulib_nex_t));
3457613SVikram.Hegde@Sun.COM
3468215SVikram.Hegde@Sun.COM cmn_err(CE_NOTE, "!%s: %s%d: NEXUS (%s) handle successfully "
3477613SVikram.Hegde@Sun.COM "unregistered from IOMMULIB", f, driver, instance,
3487613SVikram.Hegde@Sun.COM ddi_node_name(dip));
3497613SVikram.Hegde@Sun.COM
3507613SVikram.Hegde@Sun.COM ndi_rele_devi(dip);
3517613SVikram.Hegde@Sun.COM
3527613SVikram.Hegde@Sun.COM return (DDI_SUCCESS);
3537613SVikram.Hegde@Sun.COM }
3547613SVikram.Hegde@Sun.COM
3557613SVikram.Hegde@Sun.COM int
iommulib_iommu_register(dev_info_t * dip,iommulib_ops_t * ops,iommulib_handle_t * handle)3567613SVikram.Hegde@Sun.COM iommulib_iommu_register(dev_info_t *dip, iommulib_ops_t *ops,
3577613SVikram.Hegde@Sun.COM iommulib_handle_t *handle)
3587613SVikram.Hegde@Sun.COM {
3597613SVikram.Hegde@Sun.COM const char *vendor;
3607613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp;
3617613SVikram.Hegde@Sun.COM int instance = ddi_get_instance(dip);
3627613SVikram.Hegde@Sun.COM const char *driver = ddi_driver_name(dip);
3637613SVikram.Hegde@Sun.COM const char *f = "iommulib_register";
3647613SVikram.Hegde@Sun.COM
3657613SVikram.Hegde@Sun.COM ASSERT(ops);
3667613SVikram.Hegde@Sun.COM ASSERT(handle);
3677613SVikram.Hegde@Sun.COM
3687613SVikram.Hegde@Sun.COM if (ops->ilops_vers != IOMMU_OPS_VERSION) {
3697613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: Invalid IOMMULIB ops version "
3707613SVikram.Hegde@Sun.COM "in ops vector (%p). Failing registration", f, driver,
3717613SVikram.Hegde@Sun.COM instance, (void *)ops);
3727613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
3737613SVikram.Hegde@Sun.COM }
3747613SVikram.Hegde@Sun.COM
3757613SVikram.Hegde@Sun.COM switch (ops->ilops_vendor) {
3767613SVikram.Hegde@Sun.COM case AMD_IOMMU:
3777613SVikram.Hegde@Sun.COM vendor = "AMD";
3787613SVikram.Hegde@Sun.COM break;
3797613SVikram.Hegde@Sun.COM case INTEL_IOMMU:
3807613SVikram.Hegde@Sun.COM vendor = "Intel";
3817613SVikram.Hegde@Sun.COM break;
3827613SVikram.Hegde@Sun.COM case INVALID_VENDOR:
3837613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: vendor field (%x) not initialized. "
3847613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
3857613SVikram.Hegde@Sun.COM driver, instance, ops->ilops_vendor, (void *)ops);
3867613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
3877613SVikram.Hegde@Sun.COM default:
3887613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: Invalid vendor field (%x). "
3897613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
3907613SVikram.Hegde@Sun.COM driver, instance, ops->ilops_vendor, (void *)ops);
3917613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
3927613SVikram.Hegde@Sun.COM }
3937613SVikram.Hegde@Sun.COM
3948215SVikram.Hegde@Sun.COM cmn_err(CE_NOTE, "!%s: %s%d: Detected IOMMU registration from vendor"
3958215SVikram.Hegde@Sun.COM " %s", f, driver, instance, vendor);
3967613SVikram.Hegde@Sun.COM
3977613SVikram.Hegde@Sun.COM if (ops->ilops_data == NULL) {
3987613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL IOMMU data field. "
3997613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4007613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4017613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4027613SVikram.Hegde@Sun.COM }
4037613SVikram.Hegde@Sun.COM
4047613SVikram.Hegde@Sun.COM if (ops->ilops_id == NULL) {
4057613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL ID field. "
4067613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4077613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4087613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4097613SVikram.Hegde@Sun.COM }
4107613SVikram.Hegde@Sun.COM
4117613SVikram.Hegde@Sun.COM if (ops->ilops_probe == NULL) {
4127613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL probe op. "
4137613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4147613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4157613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4167613SVikram.Hegde@Sun.COM }
4177613SVikram.Hegde@Sun.COM
4187613SVikram.Hegde@Sun.COM if (ops->ilops_dma_allochdl == NULL) {
4197613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL dma_allochdl op. "
4207613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4217613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4227613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4237613SVikram.Hegde@Sun.COM }
4247613SVikram.Hegde@Sun.COM
4257613SVikram.Hegde@Sun.COM if (ops->ilops_dma_freehdl == NULL) {
4267613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL dma_freehdl op. "
4277613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4287613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4297613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4307613SVikram.Hegde@Sun.COM }
4317613SVikram.Hegde@Sun.COM
4327613SVikram.Hegde@Sun.COM if (ops->ilops_dma_bindhdl == NULL) {
4337613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL dma_bindhdl op. "
4347613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4357613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4367613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4377613SVikram.Hegde@Sun.COM }
4387613SVikram.Hegde@Sun.COM
4397613SVikram.Hegde@Sun.COM if (ops->ilops_dma_sync == NULL) {
4407613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL dma_sync op. "
4417613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4427613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4437613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4447613SVikram.Hegde@Sun.COM }
4457613SVikram.Hegde@Sun.COM
4467613SVikram.Hegde@Sun.COM if (ops->ilops_dma_win == NULL) {
4477613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL dma_win op. "
4487613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4497613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4507613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4517613SVikram.Hegde@Sun.COM }
4527613SVikram.Hegde@Sun.COM
4537613SVikram.Hegde@Sun.COM /* Check for legacy ops */
4547613SVikram.Hegde@Sun.COM if (ops->ilops_dma_map == NULL) {
4557613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL legacy dma_map op. "
4567613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4577613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4587613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4597613SVikram.Hegde@Sun.COM }
4607613SVikram.Hegde@Sun.COM
4617613SVikram.Hegde@Sun.COM if (ops->ilops_dma_mctl == NULL) {
4627613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: NULL legacy dma_mctl op. "
4637613SVikram.Hegde@Sun.COM "Failing registration for ops vector: %p", f,
4647613SVikram.Hegde@Sun.COM driver, instance, (void *)ops);
4657613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4667613SVikram.Hegde@Sun.COM }
4677613SVikram.Hegde@Sun.COM
4687613SVikram.Hegde@Sun.COM unitp = kmem_zalloc(sizeof (iommulib_unit_t), KM_SLEEP);
4697613SVikram.Hegde@Sun.COM mutex_enter(&iommulib_lock);
4707613SVikram.Hegde@Sun.COM if (iommulib_fini == 1) {
4717613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
4727613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: IOMMULIB unloading. Failing register.",
4737613SVikram.Hegde@Sun.COM f);
4747613SVikram.Hegde@Sun.COM kmem_free(unitp, sizeof (iommulib_unit_t));
4757613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
4767613SVikram.Hegde@Sun.COM }
4777613SVikram.Hegde@Sun.COM
4787613SVikram.Hegde@Sun.COM /*
4797613SVikram.Hegde@Sun.COM * fini/register race conditions have been handled. Now create the
4807613SVikram.Hegde@Sun.COM * IOMMU unit
4817613SVikram.Hegde@Sun.COM */
4827613SVikram.Hegde@Sun.COM mutex_init(&unitp->ilu_lock, NULL, MUTEX_DEFAULT, NULL);
4837613SVikram.Hegde@Sun.COM
4847613SVikram.Hegde@Sun.COM mutex_enter(&unitp->ilu_lock);
4857613SVikram.Hegde@Sun.COM unitp->ilu_unitid = ++iommulib_unit_ids;
4867613SVikram.Hegde@Sun.COM unitp->ilu_ref = 0;
4877613SVikram.Hegde@Sun.COM ndi_hold_devi(dip);
4887613SVikram.Hegde@Sun.COM unitp->ilu_dip = dip;
4897613SVikram.Hegde@Sun.COM unitp->ilu_ops = ops;
4907613SVikram.Hegde@Sun.COM unitp->ilu_data = ops->ilops_data;
4917613SVikram.Hegde@Sun.COM
4927613SVikram.Hegde@Sun.COM unitp->ilu_next = iommulib_list;
4938215SVikram.Hegde@Sun.COM iommulib_list = unitp;
4947613SVikram.Hegde@Sun.COM unitp->ilu_prev = NULL;
4958215SVikram.Hegde@Sun.COM if (unitp->ilu_next)
4968215SVikram.Hegde@Sun.COM unitp->ilu_next->ilu_prev = unitp;
4977613SVikram.Hegde@Sun.COM
498*13050Sfrank.van.der.linden@oracle.com /*
499*13050Sfrank.van.der.linden@oracle.com * The IOMMU device itself is not controlled by an IOMMU.
500*13050Sfrank.van.der.linden@oracle.com */
501*13050Sfrank.van.der.linden@oracle.com DEVI(dip)->devi_iommulib_handle = IOMMU_HANDLE_UNUSED;
502*13050Sfrank.van.der.linden@oracle.com
5037613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
5047613SVikram.Hegde@Sun.COM
5057613SVikram.Hegde@Sun.COM iommulib_num_units++;
5067613SVikram.Hegde@Sun.COM
5077613SVikram.Hegde@Sun.COM *handle = unitp;
5087613SVikram.Hegde@Sun.COM
5097613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
5107613SVikram.Hegde@Sun.COM
5118215SVikram.Hegde@Sun.COM cmn_err(CE_NOTE, "!%s: %s%d: Succesfully registered IOMMU unit "
5127613SVikram.Hegde@Sun.COM "from vendor=%s, ops=%p, data=%p, IOMMULIB unitid=%u",
5137613SVikram.Hegde@Sun.COM f, driver, instance, vendor, (void *)ops, (void *)unitp->ilu_data,
5147613SVikram.Hegde@Sun.COM unitp->ilu_unitid);
5157613SVikram.Hegde@Sun.COM
5167613SVikram.Hegde@Sun.COM return (DDI_SUCCESS);
5177613SVikram.Hegde@Sun.COM }
5187613SVikram.Hegde@Sun.COM
5197613SVikram.Hegde@Sun.COM int
iommulib_iommu_unregister(iommulib_handle_t handle)5207613SVikram.Hegde@Sun.COM iommulib_iommu_unregister(iommulib_handle_t handle)
5217613SVikram.Hegde@Sun.COM {
5227613SVikram.Hegde@Sun.COM uint32_t unitid;
5237613SVikram.Hegde@Sun.COM dev_info_t *dip;
5247613SVikram.Hegde@Sun.COM int instance;
5257613SVikram.Hegde@Sun.COM const char *driver;
5267613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
5277613SVikram.Hegde@Sun.COM const char *f = "iommulib_unregister";
5287613SVikram.Hegde@Sun.COM
5297613SVikram.Hegde@Sun.COM ASSERT(unitp);
5307613SVikram.Hegde@Sun.COM
5317613SVikram.Hegde@Sun.COM mutex_enter(&iommulib_lock);
5327613SVikram.Hegde@Sun.COM mutex_enter(&unitp->ilu_lock);
5337613SVikram.Hegde@Sun.COM
5347613SVikram.Hegde@Sun.COM unitid = unitp->ilu_unitid;
5357613SVikram.Hegde@Sun.COM dip = unitp->ilu_dip;
5367613SVikram.Hegde@Sun.COM driver = ddi_driver_name(dip);
5377613SVikram.Hegde@Sun.COM instance = ddi_get_instance(dip);
5387613SVikram.Hegde@Sun.COM
5397613SVikram.Hegde@Sun.COM if (unitp->ilu_ref != 0) {
5407613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
5417613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
5427613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: IOMMULIB handle is busy. Cannot "
5437613SVikram.Hegde@Sun.COM "unregister IOMMULIB unitid %u",
5447613SVikram.Hegde@Sun.COM f, driver, instance, unitid);
5457613SVikram.Hegde@Sun.COM return (DDI_FAILURE);
5467613SVikram.Hegde@Sun.COM }
5477613SVikram.Hegde@Sun.COM unitp->ilu_unitid = 0;
5487613SVikram.Hegde@Sun.COM ASSERT(unitp->ilu_ref == 0);
5497613SVikram.Hegde@Sun.COM
5507613SVikram.Hegde@Sun.COM if (unitp->ilu_prev == NULL) {
5517613SVikram.Hegde@Sun.COM iommulib_list = unitp->ilu_next;
5527613SVikram.Hegde@Sun.COM unitp->ilu_next->ilu_prev = NULL;
5537613SVikram.Hegde@Sun.COM } else {
5547613SVikram.Hegde@Sun.COM unitp->ilu_prev->ilu_next = unitp->ilu_next;
5557613SVikram.Hegde@Sun.COM unitp->ilu_next->ilu_prev = unitp->ilu_prev;
5567613SVikram.Hegde@Sun.COM }
5577613SVikram.Hegde@Sun.COM
5587613SVikram.Hegde@Sun.COM iommulib_num_units--;
5597613SVikram.Hegde@Sun.COM
5607613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
5617613SVikram.Hegde@Sun.COM
5627613SVikram.Hegde@Sun.COM mutex_destroy(&unitp->ilu_lock);
5637613SVikram.Hegde@Sun.COM kmem_free(unitp, sizeof (iommulib_unit_t));
5647613SVikram.Hegde@Sun.COM
5657613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
5667613SVikram.Hegde@Sun.COM
5677613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: IOMMULIB handle (unitid=%u) successfully "
5687613SVikram.Hegde@Sun.COM "unregistered", f, driver, instance, unitid);
5697613SVikram.Hegde@Sun.COM
5707613SVikram.Hegde@Sun.COM ndi_rele_devi(dip);
5717613SVikram.Hegde@Sun.COM
5727613SVikram.Hegde@Sun.COM return (DDI_SUCCESS);
5737613SVikram.Hegde@Sun.COM }
5747613SVikram.Hegde@Sun.COM
5757613SVikram.Hegde@Sun.COM int
iommulib_nex_open(dev_info_t * dip,dev_info_t * rdip)576*13050Sfrank.van.der.linden@oracle.com iommulib_nex_open(dev_info_t *dip, dev_info_t *rdip)
5777613SVikram.Hegde@Sun.COM {
5787613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp;
5797613SVikram.Hegde@Sun.COM int instance = ddi_get_instance(rdip);
5807613SVikram.Hegde@Sun.COM const char *driver = ddi_driver_name(rdip);
5817613SVikram.Hegde@Sun.COM const char *f = "iommulib_nex_open";
5827613SVikram.Hegde@Sun.COM
583*13050Sfrank.van.der.linden@oracle.com ASSERT(DEVI(dip)->devi_iommulib_nex_handle != NULL);
5848215SVikram.Hegde@Sun.COM ASSERT(DEVI(rdip)->devi_iommulib_handle == NULL);
5857613SVikram.Hegde@Sun.COM
5867613SVikram.Hegde@Sun.COM /* prevent use of IOMMU for AMD IOMMU's DMA */
5877613SVikram.Hegde@Sun.COM if (strcmp(driver, "amd_iommu") == 0) {
588*13050Sfrank.van.der.linden@oracle.com DEVI(rdip)->devi_iommulib_handle = IOMMU_HANDLE_UNUSED;
589*13050Sfrank.van.der.linden@oracle.com return (DDI_ENOTSUP);
5907613SVikram.Hegde@Sun.COM }
5917613SVikram.Hegde@Sun.COM
5927613SVikram.Hegde@Sun.COM /*
5938215SVikram.Hegde@Sun.COM * Use the probe entry point to determine in a hardware specific
5948215SVikram.Hegde@Sun.COM * manner whether this dip is controlled by an IOMMU. If yes,
5958215SVikram.Hegde@Sun.COM * return the handle corresponding to the IOMMU unit.
5967613SVikram.Hegde@Sun.COM */
5977613SVikram.Hegde@Sun.COM
5987613SVikram.Hegde@Sun.COM mutex_enter(&iommulib_lock);
5997613SVikram.Hegde@Sun.COM for (unitp = iommulib_list; unitp; unitp = unitp->ilu_next) {
6008215SVikram.Hegde@Sun.COM if (unitp->ilu_ops->ilops_probe(unitp, rdip) == DDI_SUCCESS)
6017613SVikram.Hegde@Sun.COM break;
6027613SVikram.Hegde@Sun.COM }
6037613SVikram.Hegde@Sun.COM
6047613SVikram.Hegde@Sun.COM if (unitp == NULL) {
6057613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
6067613SVikram.Hegde@Sun.COM if (iommulib_debug) {
6077717SVikram.Hegde@Sun.COM char *buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
6087613SVikram.Hegde@Sun.COM cmn_err(CE_WARN, "%s: %s%d: devinfo node (%p): is not "
6097613SVikram.Hegde@Sun.COM "controlled by an IOMMU: path=%s", f, driver,
6107613SVikram.Hegde@Sun.COM instance, (void *)rdip, ddi_pathname(rdip, buf));
6117717SVikram.Hegde@Sun.COM kmem_free(buf, MAXPATHLEN);
6127613SVikram.Hegde@Sun.COM }
613*13050Sfrank.van.der.linden@oracle.com DEVI(rdip)->devi_iommulib_handle = IOMMU_HANDLE_UNUSED;
614*13050Sfrank.van.der.linden@oracle.com return (DDI_ENOTSUP);
6157613SVikram.Hegde@Sun.COM }
6167613SVikram.Hegde@Sun.COM
6177613SVikram.Hegde@Sun.COM mutex_enter(&unitp->ilu_lock);
618*13050Sfrank.van.der.linden@oracle.com unitp->ilu_nex = DEVI(dip)->devi_iommulib_nex_handle;
6197613SVikram.Hegde@Sun.COM unitp->ilu_ref++;
620*13050Sfrank.van.der.linden@oracle.com DEVI(rdip)->devi_iommulib_handle = unitp;
6217613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
6227613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
6237613SVikram.Hegde@Sun.COM
624*13050Sfrank.van.der.linden@oracle.com atomic_inc_uint(&DEVI(dip)->devi_iommulib_nex_handle->nex_ref);
6257613SVikram.Hegde@Sun.COM
6267613SVikram.Hegde@Sun.COM return (DDI_SUCCESS);
6277613SVikram.Hegde@Sun.COM }
6287613SVikram.Hegde@Sun.COM
6297613SVikram.Hegde@Sun.COM void
iommulib_nex_close(dev_info_t * rdip)6307613SVikram.Hegde@Sun.COM iommulib_nex_close(dev_info_t *rdip)
6317613SVikram.Hegde@Sun.COM {
6327613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp;
6337613SVikram.Hegde@Sun.COM const char *driver;
6347613SVikram.Hegde@Sun.COM int instance;
6357613SVikram.Hegde@Sun.COM uint32_t unitid;
636*13050Sfrank.van.der.linden@oracle.com iommulib_nex_t *nexp;
6377613SVikram.Hegde@Sun.COM const char *f = "iommulib_nex_close";
6387613SVikram.Hegde@Sun.COM
639*13050Sfrank.van.der.linden@oracle.com ASSERT(IOMMU_USED(rdip));
6407613SVikram.Hegde@Sun.COM
641*13050Sfrank.van.der.linden@oracle.com unitp = DEVI(rdip)->devi_iommulib_handle;
6427613SVikram.Hegde@Sun.COM
6437613SVikram.Hegde@Sun.COM mutex_enter(&iommulib_lock);
6447613SVikram.Hegde@Sun.COM mutex_enter(&unitp->ilu_lock);
645*13050Sfrank.van.der.linden@oracle.com
646*13050Sfrank.van.der.linden@oracle.com nexp = (iommulib_nex_t *)unitp->ilu_nex;
647*13050Sfrank.van.der.linden@oracle.com DEVI(rdip)->devi_iommulib_handle = NULL;
648*13050Sfrank.van.der.linden@oracle.com
6497613SVikram.Hegde@Sun.COM unitid = unitp->ilu_unitid;
6507613SVikram.Hegde@Sun.COM driver = ddi_driver_name(unitp->ilu_dip);
6517613SVikram.Hegde@Sun.COM instance = ddi_get_instance(unitp->ilu_dip);
652*13050Sfrank.van.der.linden@oracle.com
6537613SVikram.Hegde@Sun.COM unitp->ilu_ref--;
6547613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
6557613SVikram.Hegde@Sun.COM mutex_exit(&iommulib_lock);
6567613SVikram.Hegde@Sun.COM
657*13050Sfrank.van.der.linden@oracle.com atomic_dec_uint(&nexp->nex_ref);
658*13050Sfrank.van.der.linden@oracle.com
6597613SVikram.Hegde@Sun.COM if (iommulib_debug) {
6607717SVikram.Hegde@Sun.COM char *buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
6617717SVikram.Hegde@Sun.COM (void) ddi_pathname(rdip, buf);
6627613SVikram.Hegde@Sun.COM cmn_err(CE_NOTE, "%s: %s%d: closing IOMMU for dip (%p), "
6637613SVikram.Hegde@Sun.COM "unitid=%u rdip path = %s", f, driver, instance,
6647613SVikram.Hegde@Sun.COM (void *)rdip, unitid, buf);
6657717SVikram.Hegde@Sun.COM kmem_free(buf, MAXPATHLEN);
6667613SVikram.Hegde@Sun.COM }
6677613SVikram.Hegde@Sun.COM }
6687613SVikram.Hegde@Sun.COM
6697613SVikram.Hegde@Sun.COM int
iommulib_nexdma_allochdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_attr_t * attr,int (* waitfp)(caddr_t),caddr_t arg,ddi_dma_handle_t * dma_handlep)6707613SVikram.Hegde@Sun.COM iommulib_nexdma_allochdl(dev_info_t *dip, dev_info_t *rdip,
6717613SVikram.Hegde@Sun.COM ddi_dma_attr_t *attr, int (*waitfp)(caddr_t),
6727613SVikram.Hegde@Sun.COM caddr_t arg, ddi_dma_handle_t *dma_handlep)
6737613SVikram.Hegde@Sun.COM {
6747613SVikram.Hegde@Sun.COM iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
6757613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
6767613SVikram.Hegde@Sun.COM
6777613SVikram.Hegde@Sun.COM ASSERT(unitp);
6787613SVikram.Hegde@Sun.COM
6797613SVikram.Hegde@Sun.COM /* No need to grab lock - the handle is reference counted */
6807613SVikram.Hegde@Sun.COM return (unitp->ilu_ops->ilops_dma_allochdl(handle, dip, rdip,
6817613SVikram.Hegde@Sun.COM attr, waitfp, arg, dma_handlep));
6827613SVikram.Hegde@Sun.COM }
6837613SVikram.Hegde@Sun.COM
6847613SVikram.Hegde@Sun.COM int
iommulib_nexdma_freehdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t dma_handle)6857613SVikram.Hegde@Sun.COM iommulib_nexdma_freehdl(dev_info_t *dip, dev_info_t *rdip,
6867613SVikram.Hegde@Sun.COM ddi_dma_handle_t dma_handle)
6877613SVikram.Hegde@Sun.COM {
6887613SVikram.Hegde@Sun.COM int error;
6897613SVikram.Hegde@Sun.COM iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
6907613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
6917613SVikram.Hegde@Sun.COM
6927613SVikram.Hegde@Sun.COM ASSERT(unitp);
6937613SVikram.Hegde@Sun.COM
6947613SVikram.Hegde@Sun.COM /* No need to grab lock - the handle is reference counted */
6957613SVikram.Hegde@Sun.COM error = unitp->ilu_ops->ilops_dma_freehdl(handle, dip,
6967613SVikram.Hegde@Sun.COM rdip, dma_handle);
6977613SVikram.Hegde@Sun.COM
6987613SVikram.Hegde@Sun.COM return (error);
6997613SVikram.Hegde@Sun.COM }
7007613SVikram.Hegde@Sun.COM
7017613SVikram.Hegde@Sun.COM int
iommulib_nexdma_bindhdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t dma_handle,struct ddi_dma_req * dmareq,ddi_dma_cookie_t * cookiep,uint_t * ccountp)7027613SVikram.Hegde@Sun.COM iommulib_nexdma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
7037613SVikram.Hegde@Sun.COM ddi_dma_handle_t dma_handle, struct ddi_dma_req *dmareq,
7047613SVikram.Hegde@Sun.COM ddi_dma_cookie_t *cookiep, uint_t *ccountp)
7057613SVikram.Hegde@Sun.COM {
7067613SVikram.Hegde@Sun.COM iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
7077613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
7087613SVikram.Hegde@Sun.COM
7097613SVikram.Hegde@Sun.COM ASSERT(unitp);
7107613SVikram.Hegde@Sun.COM
7117613SVikram.Hegde@Sun.COM /* No need to grab lock - the handle is reference counted */
7127613SVikram.Hegde@Sun.COM return (unitp->ilu_ops->ilops_dma_bindhdl(handle, dip, rdip, dma_handle,
7137613SVikram.Hegde@Sun.COM dmareq, cookiep, ccountp));
7147613SVikram.Hegde@Sun.COM }
7157613SVikram.Hegde@Sun.COM
7167613SVikram.Hegde@Sun.COM int
iommulib_nexdma_unbindhdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t dma_handle)7177613SVikram.Hegde@Sun.COM iommulib_nexdma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
7187613SVikram.Hegde@Sun.COM ddi_dma_handle_t dma_handle)
7197613SVikram.Hegde@Sun.COM {
7207613SVikram.Hegde@Sun.COM iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
7217613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
7227613SVikram.Hegde@Sun.COM
7237613SVikram.Hegde@Sun.COM ASSERT(unitp);
7247613SVikram.Hegde@Sun.COM
7257613SVikram.Hegde@Sun.COM /* No need to grab lock - the handle is reference counted */
7267613SVikram.Hegde@Sun.COM return (unitp->ilu_ops->ilops_dma_unbindhdl(handle, dip, rdip,
7277613SVikram.Hegde@Sun.COM dma_handle));
7287613SVikram.Hegde@Sun.COM }
7297613SVikram.Hegde@Sun.COM
7307613SVikram.Hegde@Sun.COM int
iommulib_nexdma_sync(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t dma_handle,off_t off,size_t len,uint_t cache_flags)7317613SVikram.Hegde@Sun.COM iommulib_nexdma_sync(dev_info_t *dip, dev_info_t *rdip,
7327613SVikram.Hegde@Sun.COM ddi_dma_handle_t dma_handle, off_t off, size_t len,
7337613SVikram.Hegde@Sun.COM uint_t cache_flags)
7347613SVikram.Hegde@Sun.COM {
7357613SVikram.Hegde@Sun.COM iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
7367613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
7377613SVikram.Hegde@Sun.COM
7387613SVikram.Hegde@Sun.COM ASSERT(unitp);
7397613SVikram.Hegde@Sun.COM
7407613SVikram.Hegde@Sun.COM /* No need to grab lock - the handle is reference counted */
7417613SVikram.Hegde@Sun.COM return (unitp->ilu_ops->ilops_dma_sync(handle, dip, rdip, dma_handle,
7427613SVikram.Hegde@Sun.COM off, len, cache_flags));
7437613SVikram.Hegde@Sun.COM }
7447613SVikram.Hegde@Sun.COM
7457613SVikram.Hegde@Sun.COM int
iommulib_nexdma_win(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t dma_handle,uint_t win,off_t * offp,size_t * lenp,ddi_dma_cookie_t * cookiep,uint_t * ccountp)7467613SVikram.Hegde@Sun.COM iommulib_nexdma_win(dev_info_t *dip, dev_info_t *rdip,
7477613SVikram.Hegde@Sun.COM ddi_dma_handle_t dma_handle, uint_t win, off_t *offp, size_t *lenp,
7487613SVikram.Hegde@Sun.COM ddi_dma_cookie_t *cookiep, uint_t *ccountp)
7497613SVikram.Hegde@Sun.COM {
7507613SVikram.Hegde@Sun.COM iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
7517613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
7527613SVikram.Hegde@Sun.COM
7537613SVikram.Hegde@Sun.COM ASSERT(unitp);
7547613SVikram.Hegde@Sun.COM
7557613SVikram.Hegde@Sun.COM /* No need to grab lock - the handle is reference counted */
7567613SVikram.Hegde@Sun.COM return (unitp->ilu_ops->ilops_dma_win(handle, dip, rdip, dma_handle,
7577613SVikram.Hegde@Sun.COM win, offp, lenp, cookiep, ccountp));
7587613SVikram.Hegde@Sun.COM }
7597613SVikram.Hegde@Sun.COM
7607613SVikram.Hegde@Sun.COM /* Obsolete DMA routines */
7617613SVikram.Hegde@Sun.COM
7627613SVikram.Hegde@Sun.COM int
iommulib_nexdma_map(dev_info_t * dip,dev_info_t * rdip,struct ddi_dma_req * dmareq,ddi_dma_handle_t * dma_handle)7637613SVikram.Hegde@Sun.COM iommulib_nexdma_map(dev_info_t *dip, dev_info_t *rdip,
7647613SVikram.Hegde@Sun.COM struct ddi_dma_req *dmareq, ddi_dma_handle_t *dma_handle)
7657613SVikram.Hegde@Sun.COM {
7667613SVikram.Hegde@Sun.COM iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
7677613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = handle;
7687613SVikram.Hegde@Sun.COM
7697613SVikram.Hegde@Sun.COM ASSERT(unitp);
7707613SVikram.Hegde@Sun.COM
7717613SVikram.Hegde@Sun.COM /* No need to grab lock - the handle is reference counted */
7727613SVikram.Hegde@Sun.COM return (unitp->ilu_ops->ilops_dma_map(handle, dip, rdip, dmareq,
7737613SVikram.Hegde@Sun.COM dma_handle));
7747613SVikram.Hegde@Sun.COM }
7757613SVikram.Hegde@Sun.COM
7767613SVikram.Hegde@Sun.COM int
iommulib_nexdma_mctl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t dma_handle,enum ddi_dma_ctlops request,off_t * offp,size_t * lenp,caddr_t * objpp,uint_t cache_flags)7777613SVikram.Hegde@Sun.COM iommulib_nexdma_mctl(dev_info_t *dip, dev_info_t *rdip,
7787613SVikram.Hegde@Sun.COM ddi_dma_handle_t dma_handle, enum ddi_dma_ctlops request,
7797613SVikram.Hegde@Sun.COM off_t *offp, size_t *lenp, caddr_t *objpp, uint_t cache_flags)
7807613SVikram.Hegde@Sun.COM {
7817613SVikram.Hegde@Sun.COM iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
7827613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
7837613SVikram.Hegde@Sun.COM
7847613SVikram.Hegde@Sun.COM ASSERT(unitp);
7857613SVikram.Hegde@Sun.COM
7867613SVikram.Hegde@Sun.COM /* No need to grab lock - the handle is reference counted */
7877613SVikram.Hegde@Sun.COM return (unitp->ilu_ops->ilops_dma_mctl(handle, dip, rdip, dma_handle,
7887613SVikram.Hegde@Sun.COM request, offp, lenp, objpp, cache_flags));
7897613SVikram.Hegde@Sun.COM }
7907613SVikram.Hegde@Sun.COM
791*13050Sfrank.van.der.linden@oracle.com int
iommulib_nexdma_mapobject(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t dma_handle,struct ddi_dma_req * dmareq,ddi_dma_obj_t * dmao)792*13050Sfrank.van.der.linden@oracle.com iommulib_nexdma_mapobject(dev_info_t *dip, dev_info_t *rdip,
793*13050Sfrank.van.der.linden@oracle.com ddi_dma_handle_t dma_handle, struct ddi_dma_req *dmareq,
794*13050Sfrank.van.der.linden@oracle.com ddi_dma_obj_t *dmao)
795*13050Sfrank.van.der.linden@oracle.com {
796*13050Sfrank.van.der.linden@oracle.com iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
797*13050Sfrank.van.der.linden@oracle.com iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
798*13050Sfrank.van.der.linden@oracle.com
799*13050Sfrank.van.der.linden@oracle.com return (unitp->ilu_ops->ilops_dma_mapobject(handle, dip, rdip,
800*13050Sfrank.van.der.linden@oracle.com dma_handle, dmareq, dmao));
801*13050Sfrank.van.der.linden@oracle.com }
802*13050Sfrank.van.der.linden@oracle.com
803*13050Sfrank.van.der.linden@oracle.com int
iommulib_nexdma_unmapobject(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t dma_handle,ddi_dma_obj_t * dmao)804*13050Sfrank.van.der.linden@oracle.com iommulib_nexdma_unmapobject(dev_info_t *dip, dev_info_t *rdip,
805*13050Sfrank.van.der.linden@oracle.com ddi_dma_handle_t dma_handle, ddi_dma_obj_t *dmao)
806*13050Sfrank.van.der.linden@oracle.com {
807*13050Sfrank.van.der.linden@oracle.com iommulib_handle_t handle = DEVI(rdip)->devi_iommulib_handle;
808*13050Sfrank.van.der.linden@oracle.com iommulib_unit_t *unitp = (iommulib_unit_t *)handle;
809*13050Sfrank.van.der.linden@oracle.com
810*13050Sfrank.van.der.linden@oracle.com return (unitp->ilu_ops->ilops_dma_unmapobject(handle, dip, rdip,
811*13050Sfrank.van.der.linden@oracle.com dma_handle, dmao));
812*13050Sfrank.van.der.linden@oracle.com }
813*13050Sfrank.van.der.linden@oracle.com
8147613SVikram.Hegde@Sun.COM /* Utility routines invoked by IOMMU drivers */
8157613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_allochdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_attr_t * attr,int (* waitfp)(caddr_t),caddr_t arg,ddi_dma_handle_t * handlep)8167613SVikram.Hegde@Sun.COM iommulib_iommu_dma_allochdl(dev_info_t *dip, dev_info_t *rdip,
8177613SVikram.Hegde@Sun.COM ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg,
8187613SVikram.Hegde@Sun.COM ddi_dma_handle_t *handlep)
8197613SVikram.Hegde@Sun.COM {
820*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
821*13050Sfrank.van.der.linden@oracle.com
822*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
8237613SVikram.Hegde@Sun.COM return (nexops->nops_dma_allochdl(dip, rdip, attr, waitfp, arg,
8247613SVikram.Hegde@Sun.COM handlep));
8257613SVikram.Hegde@Sun.COM }
8267613SVikram.Hegde@Sun.COM
8277613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_freehdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t handle)8287613SVikram.Hegde@Sun.COM iommulib_iommu_dma_freehdl(dev_info_t *dip, dev_info_t *rdip,
8297613SVikram.Hegde@Sun.COM ddi_dma_handle_t handle)
8307613SVikram.Hegde@Sun.COM {
831*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
832*13050Sfrank.van.der.linden@oracle.com
833*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
834*13050Sfrank.van.der.linden@oracle.com ASSERT(nexops);
8357613SVikram.Hegde@Sun.COM return (nexops->nops_dma_freehdl(dip, rdip, handle));
8367613SVikram.Hegde@Sun.COM }
8377613SVikram.Hegde@Sun.COM
8387613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_bindhdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t handle,struct ddi_dma_req * dmareq,ddi_dma_cookie_t * cookiep,uint_t * ccountp)8397613SVikram.Hegde@Sun.COM iommulib_iommu_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
8407613SVikram.Hegde@Sun.COM ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
8417613SVikram.Hegde@Sun.COM ddi_dma_cookie_t *cookiep, uint_t *ccountp)
8427613SVikram.Hegde@Sun.COM {
843*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
844*13050Sfrank.van.der.linden@oracle.com
845*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
8467613SVikram.Hegde@Sun.COM return (nexops->nops_dma_bindhdl(dip, rdip, handle, dmareq,
8477613SVikram.Hegde@Sun.COM cookiep, ccountp));
8487613SVikram.Hegde@Sun.COM }
8497613SVikram.Hegde@Sun.COM
8507613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_unbindhdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t handle)8517613SVikram.Hegde@Sun.COM iommulib_iommu_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
8527613SVikram.Hegde@Sun.COM ddi_dma_handle_t handle)
8537613SVikram.Hegde@Sun.COM {
854*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
855*13050Sfrank.van.der.linden@oracle.com
856*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
8577613SVikram.Hegde@Sun.COM return (nexops->nops_dma_unbindhdl(dip, rdip, handle));
8587613SVikram.Hegde@Sun.COM }
8597613SVikram.Hegde@Sun.COM
8607613SVikram.Hegde@Sun.COM void
iommulib_iommu_dma_reset_cookies(dev_info_t * dip,ddi_dma_handle_t handle)8617613SVikram.Hegde@Sun.COM iommulib_iommu_dma_reset_cookies(dev_info_t *dip, ddi_dma_handle_t handle)
8627613SVikram.Hegde@Sun.COM {
863*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
864*13050Sfrank.van.der.linden@oracle.com
865*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
8667613SVikram.Hegde@Sun.COM nexops->nops_dma_reset_cookies(dip, handle);
8677613SVikram.Hegde@Sun.COM }
8687613SVikram.Hegde@Sun.COM
8697613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_get_cookies(dev_info_t * dip,ddi_dma_handle_t handle,ddi_dma_cookie_t ** cookiepp,uint_t * ccountp)8707613SVikram.Hegde@Sun.COM iommulib_iommu_dma_get_cookies(dev_info_t *dip, ddi_dma_handle_t handle,
8718215SVikram.Hegde@Sun.COM ddi_dma_cookie_t **cookiepp, uint_t *ccountp)
8728215SVikram.Hegde@Sun.COM {
873*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
874*13050Sfrank.van.der.linden@oracle.com
875*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
8768215SVikram.Hegde@Sun.COM return (nexops->nops_dma_get_cookies(dip, handle, cookiepp, ccountp));
8778215SVikram.Hegde@Sun.COM }
8788215SVikram.Hegde@Sun.COM
8798215SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_set_cookies(dev_info_t * dip,ddi_dma_handle_t handle,ddi_dma_cookie_t * cookiep,uint_t ccount)8808215SVikram.Hegde@Sun.COM iommulib_iommu_dma_set_cookies(dev_info_t *dip, ddi_dma_handle_t handle,
8818215SVikram.Hegde@Sun.COM ddi_dma_cookie_t *cookiep, uint_t ccount)
8827613SVikram.Hegde@Sun.COM {
883*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
884*13050Sfrank.van.der.linden@oracle.com
885*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
8868215SVikram.Hegde@Sun.COM return (nexops->nops_dma_set_cookies(dip, handle, cookiep, ccount));
8878215SVikram.Hegde@Sun.COM }
8888215SVikram.Hegde@Sun.COM
8898215SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_clear_cookies(dev_info_t * dip,ddi_dma_handle_t handle)8908215SVikram.Hegde@Sun.COM iommulib_iommu_dma_clear_cookies(dev_info_t *dip, ddi_dma_handle_t handle)
8918215SVikram.Hegde@Sun.COM {
892*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
893*13050Sfrank.van.der.linden@oracle.com
894*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
8958215SVikram.Hegde@Sun.COM return (nexops->nops_dma_clear_cookies(dip, handle));
8968215SVikram.Hegde@Sun.COM }
8978215SVikram.Hegde@Sun.COM
8988215SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_get_sleep_flags(dev_info_t * dip,ddi_dma_handle_t handle)8998215SVikram.Hegde@Sun.COM iommulib_iommu_dma_get_sleep_flags(dev_info_t *dip, ddi_dma_handle_t handle)
9008215SVikram.Hegde@Sun.COM {
901*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
902*13050Sfrank.van.der.linden@oracle.com
903*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
9048215SVikram.Hegde@Sun.COM return (nexops->nops_dma_get_sleep_flags(handle));
9057613SVikram.Hegde@Sun.COM }
9067613SVikram.Hegde@Sun.COM
9077613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_sync(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t handle,off_t off,size_t len,uint_t cache_flags)9087613SVikram.Hegde@Sun.COM iommulib_iommu_dma_sync(dev_info_t *dip, dev_info_t *rdip,
9097613SVikram.Hegde@Sun.COM ddi_dma_handle_t handle, off_t off, size_t len, uint_t cache_flags)
9107613SVikram.Hegde@Sun.COM {
911*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
912*13050Sfrank.van.der.linden@oracle.com
913*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
9147613SVikram.Hegde@Sun.COM return (nexops->nops_dma_sync(dip, rdip, handle, off, len,
9157613SVikram.Hegde@Sun.COM cache_flags));
9167613SVikram.Hegde@Sun.COM }
9177613SVikram.Hegde@Sun.COM
9187613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_win(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t handle,uint_t win,off_t * offp,size_t * lenp,ddi_dma_cookie_t * cookiep,uint_t * ccountp)9197613SVikram.Hegde@Sun.COM iommulib_iommu_dma_win(dev_info_t *dip, dev_info_t *rdip,
9207613SVikram.Hegde@Sun.COM ddi_dma_handle_t handle, uint_t win, off_t *offp, size_t *lenp,
9217613SVikram.Hegde@Sun.COM ddi_dma_cookie_t *cookiep, uint_t *ccountp)
9227613SVikram.Hegde@Sun.COM {
923*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
924*13050Sfrank.van.der.linden@oracle.com
925*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
9267613SVikram.Hegde@Sun.COM return (nexops->nops_dma_win(dip, rdip, handle, win, offp, lenp,
9277613SVikram.Hegde@Sun.COM cookiep, ccountp));
9287613SVikram.Hegde@Sun.COM }
9297613SVikram.Hegde@Sun.COM
9307613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_map(dev_info_t * dip,dev_info_t * rdip,struct ddi_dma_req * dmareq,ddi_dma_handle_t * handlep)9317613SVikram.Hegde@Sun.COM iommulib_iommu_dma_map(dev_info_t *dip, dev_info_t *rdip,
9327613SVikram.Hegde@Sun.COM struct ddi_dma_req *dmareq, ddi_dma_handle_t *handlep)
9337613SVikram.Hegde@Sun.COM {
934*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
935*13050Sfrank.van.der.linden@oracle.com
936*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
9377613SVikram.Hegde@Sun.COM return (nexops->nops_dma_map(dip, rdip, dmareq, handlep));
9387613SVikram.Hegde@Sun.COM }
9397613SVikram.Hegde@Sun.COM
9407613SVikram.Hegde@Sun.COM int
iommulib_iommu_dma_mctl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t handle,enum ddi_dma_ctlops request,off_t * offp,size_t * lenp,caddr_t * objpp,uint_t cache_flags)9417613SVikram.Hegde@Sun.COM iommulib_iommu_dma_mctl(dev_info_t *dip, dev_info_t *rdip,
9427613SVikram.Hegde@Sun.COM ddi_dma_handle_t handle, enum ddi_dma_ctlops request, off_t *offp,
9437613SVikram.Hegde@Sun.COM size_t *lenp, caddr_t *objpp, uint_t cache_flags)
9447613SVikram.Hegde@Sun.COM {
945*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
946*13050Sfrank.van.der.linden@oracle.com
947*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
9487613SVikram.Hegde@Sun.COM return (nexops->nops_dma_mctl(dip, rdip, handle, request, offp, lenp,
9497613SVikram.Hegde@Sun.COM objpp, cache_flags));
9507613SVikram.Hegde@Sun.COM }
9517613SVikram.Hegde@Sun.COM
9527613SVikram.Hegde@Sun.COM int
iommulib_iommu_dmahdl_setprivate(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t handle,void * priv)953*13050Sfrank.van.der.linden@oracle.com iommulib_iommu_dmahdl_setprivate(dev_info_t *dip, dev_info_t *rdip,
954*13050Sfrank.van.der.linden@oracle.com ddi_dma_handle_t handle, void *priv)
955*13050Sfrank.van.der.linden@oracle.com {
956*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
957*13050Sfrank.van.der.linden@oracle.com
958*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
959*13050Sfrank.van.der.linden@oracle.com return (nexops->nops_dmahdl_setprivate(dip, rdip, handle, priv));
960*13050Sfrank.van.der.linden@oracle.com }
961*13050Sfrank.van.der.linden@oracle.com
962*13050Sfrank.van.der.linden@oracle.com void *
iommulib_iommu_dmahdl_getprivate(dev_info_t * dip,dev_info_t * rdip,ddi_dma_handle_t handle)963*13050Sfrank.van.der.linden@oracle.com iommulib_iommu_dmahdl_getprivate(dev_info_t *dip, dev_info_t *rdip,
964*13050Sfrank.van.der.linden@oracle.com ddi_dma_handle_t handle)
965*13050Sfrank.van.der.linden@oracle.com {
966*13050Sfrank.van.der.linden@oracle.com iommulib_nexops_t *nexops;
967*13050Sfrank.van.der.linden@oracle.com
968*13050Sfrank.van.der.linden@oracle.com nexops = &DEVI(dip)->devi_iommulib_nex_handle->nex_ops;
969*13050Sfrank.van.der.linden@oracle.com return (nexops->nops_dmahdl_getprivate(dip, rdip, handle));
970*13050Sfrank.van.der.linden@oracle.com }
971*13050Sfrank.van.der.linden@oracle.com
972*13050Sfrank.van.der.linden@oracle.com int
iommulib_iommu_getunitid(iommulib_handle_t handle,uint64_t * unitidp)9737613SVikram.Hegde@Sun.COM iommulib_iommu_getunitid(iommulib_handle_t handle, uint64_t *unitidp)
9747613SVikram.Hegde@Sun.COM {
9757613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp;
9767613SVikram.Hegde@Sun.COM uint64_t unitid;
9777613SVikram.Hegde@Sun.COM
9787613SVikram.Hegde@Sun.COM unitp = (iommulib_unit_t *)handle;
9797613SVikram.Hegde@Sun.COM
9807613SVikram.Hegde@Sun.COM ASSERT(unitp);
9817613SVikram.Hegde@Sun.COM ASSERT(unitidp);
9827613SVikram.Hegde@Sun.COM
9837613SVikram.Hegde@Sun.COM mutex_enter(&unitp->ilu_lock);
9847613SVikram.Hegde@Sun.COM unitid = unitp->ilu_unitid;
9857613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
9867613SVikram.Hegde@Sun.COM
9877613SVikram.Hegde@Sun.COM ASSERT(unitid > 0);
9887613SVikram.Hegde@Sun.COM *unitidp = (uint64_t)unitid;
9897613SVikram.Hegde@Sun.COM
9907613SVikram.Hegde@Sun.COM return (DDI_SUCCESS);
9917613SVikram.Hegde@Sun.COM }
9927613SVikram.Hegde@Sun.COM
9937613SVikram.Hegde@Sun.COM dev_info_t *
iommulib_iommu_getdip(iommulib_handle_t handle)9947613SVikram.Hegde@Sun.COM iommulib_iommu_getdip(iommulib_handle_t handle)
9957613SVikram.Hegde@Sun.COM {
9967613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp;
9977613SVikram.Hegde@Sun.COM dev_info_t *dip;
9987613SVikram.Hegde@Sun.COM
9997613SVikram.Hegde@Sun.COM unitp = (iommulib_unit_t *)handle;
10007613SVikram.Hegde@Sun.COM
10017613SVikram.Hegde@Sun.COM ASSERT(unitp);
10027613SVikram.Hegde@Sun.COM
10037613SVikram.Hegde@Sun.COM mutex_enter(&unitp->ilu_lock);
10047613SVikram.Hegde@Sun.COM dip = unitp->ilu_dip;
10057613SVikram.Hegde@Sun.COM ASSERT(dip);
10067613SVikram.Hegde@Sun.COM ndi_hold_devi(dip);
10077613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
10087613SVikram.Hegde@Sun.COM
10097613SVikram.Hegde@Sun.COM return (dip);
10107613SVikram.Hegde@Sun.COM }
10117613SVikram.Hegde@Sun.COM
10127613SVikram.Hegde@Sun.COM iommulib_ops_t *
iommulib_iommu_getops(iommulib_handle_t handle)10137613SVikram.Hegde@Sun.COM iommulib_iommu_getops(iommulib_handle_t handle)
10147613SVikram.Hegde@Sun.COM {
10157613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp;
10167613SVikram.Hegde@Sun.COM iommulib_ops_t *ops;
10177613SVikram.Hegde@Sun.COM
10187613SVikram.Hegde@Sun.COM unitp = (iommulib_unit_t *)handle;
10197613SVikram.Hegde@Sun.COM
10207613SVikram.Hegde@Sun.COM ASSERT(unitp);
10217613SVikram.Hegde@Sun.COM
10227613SVikram.Hegde@Sun.COM mutex_enter(&unitp->ilu_lock);
10237613SVikram.Hegde@Sun.COM ops = unitp->ilu_ops;
10247613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
10257613SVikram.Hegde@Sun.COM
10267613SVikram.Hegde@Sun.COM ASSERT(ops);
10277613SVikram.Hegde@Sun.COM
10287613SVikram.Hegde@Sun.COM return (ops);
10297613SVikram.Hegde@Sun.COM }
10307613SVikram.Hegde@Sun.COM
10317613SVikram.Hegde@Sun.COM void *
iommulib_iommu_getdata(iommulib_handle_t handle)10327613SVikram.Hegde@Sun.COM iommulib_iommu_getdata(iommulib_handle_t handle)
10337613SVikram.Hegde@Sun.COM {
10347613SVikram.Hegde@Sun.COM iommulib_unit_t *unitp;
10357613SVikram.Hegde@Sun.COM void *data;
10367613SVikram.Hegde@Sun.COM
10377613SVikram.Hegde@Sun.COM unitp = (iommulib_unit_t *)handle;
10387613SVikram.Hegde@Sun.COM
10397613SVikram.Hegde@Sun.COM ASSERT(unitp);
10407613SVikram.Hegde@Sun.COM
10417613SVikram.Hegde@Sun.COM mutex_enter(&unitp->ilu_lock);
10427613SVikram.Hegde@Sun.COM data = unitp->ilu_data;
10437613SVikram.Hegde@Sun.COM mutex_exit(&unitp->ilu_lock);
10447613SVikram.Hegde@Sun.COM
10457613SVikram.Hegde@Sun.COM ASSERT(data);
10467613SVikram.Hegde@Sun.COM
10477613SVikram.Hegde@Sun.COM return (data);
10487613SVikram.Hegde@Sun.COM }
1049