d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan/*
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * CDDL HEADER START
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * The contents of this file are subject to the terms of the
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * Common Development and Distribution License (the "License").
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * You may not use this file except in compliance with the License.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * or http://www.opensolaris.org/os/licensing.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * See the License for the specific language governing permissions
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * and limitations under the License.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * When distributing Covered Code, include this CDDL HEADER in each
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * If applicable, add the following below this CDDL HEADER, with the
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * fields enclosed by brackets "[]" replaced with your own identifying
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * information: Portions Copyright [yyyy] [name of copyright owner]
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * CDDL HEADER END
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan/*
046cfe5c17cdf5694e6d0d26efdc0e95ad2a1fbcSriharsha Basavapatna * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/types.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/sysmacros.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/errno.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/kmem.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/ksynch.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/stream.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/ddi.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/sunddi.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#include <sys/vio_util.h>
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGstatic int vio_pool_cleanup_retries = 10; /* Max retries to free pool */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGstatic int vio_pool_cleanup_delay = 10000; /* 10ms */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan/*
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * Create a pool of mblks from which future vio_allocb() requests
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * will be serviced.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * NOTE: num_mblks has to non-zero and a power-of-2
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * Returns
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * 0 on success
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * EINVAL if num_mblks is zero or not a power of 2.
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * ENOSPC if the pool could not be created due to alloc failures.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayanint
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavio_create_mblks(uint64_t num_mblks, size_t mblk_size, uint8_t *mblk_datap,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_pool_t **poolp)
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan{
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vio_mblk_pool_t *vmplp;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vio_mblk_t *vmp;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan uint8_t *datap;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan int i;
3ab636deaa8cd06b5153d9eb3eaf79808afb491cWENTAO YANG int rv;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan if (!(num_mblks) || (!ISP2(num_mblks))) {
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *poolp = 0;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan return (EINVAL);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan }
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp = kmem_zalloc(sizeof (*vmplp), KM_SLEEP);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->quelen = num_mblks;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->quemask = num_mblks - 1; /* expects quelen is power-of-2 */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->mblk_size = mblk_size;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan mutex_init(&vmplp->hlock, NULL, MUTEX_DRIVER,
b4d0458e18abef7b5e036915e96807c219ec1d58raghuram DDI_INTR_PRI(DDI_INTR_SOFTPRI_DEFAULT));
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan mutex_init(&vmplp->tlock, NULL, MUTEX_DRIVER,
b4d0458e18abef7b5e036915e96807c219ec1d58raghuram DDI_INTR_PRI(DDI_INTR_SOFTPRI_DEFAULT));
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->basep = kmem_zalloc(num_mblks * sizeof (vio_mblk_t), KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (mblk_datap == NULL) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmplp->datap = kmem_zalloc(num_mblks * mblk_size, KM_SLEEP);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna } else {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmplp->datap = mblk_datap;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmplp->flag |= VMPL_FLAG_CLIENT_DATA;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->nextp = NULL;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan /* create a queue of pointers to free vio_mblk_t's */
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmplp->quep = kmem_zalloc(vmplp->quelen *
b4d0458e18abef7b5e036915e96807c219ec1d58raghuram sizeof (vio_mblk_t *), KM_SLEEP);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->head = 0;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->tail = 0;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan for (i = 0, datap = vmplp->datap; i < num_mblks; i++) {
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmp = &(vmplp->basep[i]);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmp->vmplp = vmplp;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmp->datap = datap;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmp->reclaim.free_func = vio_freeb;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmp->reclaim.free_arg = (caddr_t)vmp;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmp->mp = desballoc(vmp->datap, mblk_size, BPRI_MED,
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan &vmp->reclaim);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (vmp->mp == NULL) {
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* reset tail */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG vmplp->tail = vmplp->head;
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /*
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * vio_destroy_mblks() frees mblks that have been
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * allocated so far and then destroys the pool.
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG */
3ab636deaa8cd06b5153d9eb3eaf79808afb491cWENTAO YANG rv = vio_destroy_mblks(vmplp);
3ab636deaa8cd06b5153d9eb3eaf79808afb491cWENTAO YANG ASSERT(rv == 0);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG *poolp = NULL;
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG return (ENOSPC);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG }
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
046cfe5c17cdf5694e6d0d26efdc0e95ad2a1fbcSriharsha Basavapatna vmp->index = i;
046cfe5c17cdf5694e6d0d26efdc0e95ad2a1fbcSriharsha Basavapatna vmp->state = VIO_MBLK_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan /* put this vmp on the free stack */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->quep[vmplp->tail] = vmp;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan datap += mblk_size;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan }
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *poolp = vmplp;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan return (0);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan}
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan/*
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * Destroy the pool of mblks. This can only succeed when
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * all allocated mblks have been returned to the pool.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * It is up to the caller to ensure that no further mblks are
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * requested from the pool after destroy has been invoked.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan *
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * Returns 0 on success, EINVAL if handle is invalid, or
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * EBUSY if not all mblks reclaimed yet.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayanint
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayanvio_destroy_mblks(vio_mblk_pool_t *vmplp)
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan{
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG uint64_t i;
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG uint64_t num_mblks;
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG vio_mblk_t *vmp;
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG int pool_cleanup_retries = 0;
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG
3af08d828975d7e2581b6829e0eecff14d87a483lm
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan if (vmplp == NULL)
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan return (EINVAL);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan /*
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * We can only destroy the pool once all the mblks have
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * been reclaimed.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG do {
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (vmplp->head == vmplp->tail) {
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG break;
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG }
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan /* some mblks still in use */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG drv_usecwait(vio_pool_cleanup_delay);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG } while (++pool_cleanup_retries < vio_pool_cleanup_retries);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (vmplp->head != vmplp->tail) {
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan return (EBUSY);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan }
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
3af08d828975d7e2581b6829e0eecff14d87a483lm num_mblks = vmplp->quelen;
3af08d828975d7e2581b6829e0eecff14d87a483lm
3af08d828975d7e2581b6829e0eecff14d87a483lm /*
3af08d828975d7e2581b6829e0eecff14d87a483lm * Set pool flag to tell vio_freeb() which is invoked from freeb(),
3af08d828975d7e2581b6829e0eecff14d87a483lm * that it is being called in the context of vio_destroy_mblks().
3af08d828975d7e2581b6829e0eecff14d87a483lm * This results in freeing only mblk_t and dblk_t structures for
3af08d828975d7e2581b6829e0eecff14d87a483lm * each mp. The associated data buffers are freed below as one big
3af08d828975d7e2581b6829e0eecff14d87a483lm * chunk through kmem_free(vmplp->datap).
3af08d828975d7e2581b6829e0eecff14d87a483lm */
3af08d828975d7e2581b6829e0eecff14d87a483lm vmplp->flag |= VMPL_FLAG_DESTROYING;
3af08d828975d7e2581b6829e0eecff14d87a483lm for (i = 0; i < num_mblks; i++) {
3af08d828975d7e2581b6829e0eecff14d87a483lm vmp = &(vmplp->basep[i]);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /*
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * It is possible that mblks have been allocated only upto
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * a certain index and the entire quelen has not been
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * initialized. This might happen due to desballoc() failure
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * while creating the pool. The below check handles this
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * condition.
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (vmp->mp != NULL)
3af08d828975d7e2581b6829e0eecff14d87a483lm freeb(vmp->mp);
3af08d828975d7e2581b6829e0eecff14d87a483lm }
3af08d828975d7e2581b6829e0eecff14d87a483lm vmplp->flag &= ~(VMPL_FLAG_DESTROYING);
3af08d828975d7e2581b6829e0eecff14d87a483lm
3af08d828975d7e2581b6829e0eecff14d87a483lm kmem_free(vmplp->basep, num_mblks * sizeof (vio_mblk_t));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((vmplp->flag & VMPL_FLAG_CLIENT_DATA) == 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna kmem_free(vmplp->datap, num_mblks * vmplp->mblk_size);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
3af08d828975d7e2581b6829e0eecff14d87a483lm kmem_free(vmplp->quep, num_mblks * sizeof (vio_mblk_t *));
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan mutex_destroy(&vmplp->hlock);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan mutex_destroy(&vmplp->tlock);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan kmem_free(vmplp, sizeof (*vmplp));
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan return (0);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan}
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Allocate a vio_mblk from the free pool if one is available.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * Otherwise returns NULL.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavio_mblk_t *
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayanvio_allocb(vio_mblk_pool_t *vmplp)
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan{
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vio_mblk_t *vmp = NULL;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan uint32_t head;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan mutex_enter(&vmplp->hlock);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan head = (vmplp->head + 1) & vmplp->quemask;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan if (head != vmplp->tail) {
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan /* we have free mblks */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmp = vmplp->quep[vmplp->head];
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->head = head;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(vmp->state == VIO_MBLK_FREE);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp->state = VIO_MBLK_BOUND;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan }
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan mutex_exit(&vmplp->hlock);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (vmp);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan}
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan/*
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * Return a mblk to the free pool. Invoked when the upper IP
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan * layers do freemsg() etc on the mblk they were passed.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayanvoid
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayanvio_freeb(void *arg)
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan{
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vio_mblk_t *vmp = (vio_mblk_t *)arg;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vio_mblk_pool_t *vmplp = vmp->vmplp;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
3af08d828975d7e2581b6829e0eecff14d87a483lm if (vmplp->flag & VMPL_FLAG_DESTROYING) {
3af08d828975d7e2581b6829e0eecff14d87a483lm /*
3af08d828975d7e2581b6829e0eecff14d87a483lm * This flag indicates that freeb() is being called from
3af08d828975d7e2581b6829e0eecff14d87a483lm * vio_destroy_mblks().
3af08d828975d7e2581b6829e0eecff14d87a483lm * We don't need to alloc a new mblk_t/dblk_t pair for
3af08d828975d7e2581b6829e0eecff14d87a483lm * this data buffer, return from here and the data buffer
3af08d828975d7e2581b6829e0eecff14d87a483lm * itself will be freed in vio_destroy_mblks().
3af08d828975d7e2581b6829e0eecff14d87a483lm */
3af08d828975d7e2581b6829e0eecff14d87a483lm return;
3af08d828975d7e2581b6829e0eecff14d87a483lm }
3af08d828975d7e2581b6829e0eecff14d87a483lm
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmp->mp = desballoc(vmp->datap, vmplp->mblk_size,
b4d0458e18abef7b5e036915e96807c219ec1d58raghuram BPRI_MED, &vmp->reclaim);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp->state = VIO_MBLK_FREE;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan mutex_enter(&vmplp->tlock);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->quep[vmplp->tail] = vmp;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan mutex_exit(&vmplp->tlock);
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan}
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * This function searches the given mblk pool for mblks that are in the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * BOUND state and moves them to the FREE state. Note that only clients that
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * are operating in RxDringData mode use this function. This allows such
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * clients to reclaim buffers that are provided to the peer as shared memory,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * before calling vio_destroy_mblks(). We don't need this in other cases
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * as the buffer is locally managed.
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavoid
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavio_clobber_pool(vio_mblk_pool_t *vmplp)
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna{
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint64_t num_mblks = vmplp->quelen;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint64_t i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_t *vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&vmplp->hlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_enter(&vmplp->tlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (i = 0; i < num_mblks; i++) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp = &(vmplp->basep[i]);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((vmp->state & VIO_MBLK_BOUND) != 0) {
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* put this vmp on the free stack */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp->state = VIO_MBLK_FREE;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ASSERT(vmplp->tail != vmplp->head);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmplp->quep[vmplp->tail] = vmp;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&vmplp->tlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna mutex_exit(&vmplp->hlock);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna}
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram/*
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * Create a multiple pools of mblks from which future vio_allocb()
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * or vio_multipool_allocb() requests will be serviced.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram *
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * Arguments:
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * vmultip -- A pointer to vio_multi_pool_t structure.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * num_pools -- Number of the pools.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * ... -- Variable arguments consisting a list of buffer sizes for
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * each pool and list of number of buffers for each pool.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram *
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * NOTE: The restrictions of vio_create_mblks() apply to this interface also.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram *
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * Returns 0 on success or an error returned by vio_create_mblks().
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram */
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuramint
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuramvio_init_multipools(vio_multi_pool_t *vmultip, int num_pools, ...)
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram{
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram int i;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram int status;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram char *tbuf;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram va_list vap;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vio_mblk_pool_t *fvmp = NULL;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram /*
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * Allocate memory for all of the following in one allocation.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * bufsz_tbl -- sizeof (uint32_t) * num_pools
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * nbuf_tbl -- sizeof (uint32_t) * num_pools
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * vmpp -- sizeof (vio_mblk_pool_t *) * numpools
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram */
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->tbsz = (sizeof (uint32_t) * num_pools) +
b4d0458e18abef7b5e036915e96807c219ec1d58raghuram (sizeof (uint32_t) * num_pools) +
b4d0458e18abef7b5e036915e96807c219ec1d58raghuram (sizeof (vio_mblk_pool_t *) * num_pools);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram tbuf = kmem_zalloc(vmultip->tbsz, KM_SLEEP);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->bufsz_tbl = (uint32_t *)tbuf;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->nbuf_tbl = (uint32_t *)(tbuf +
b4d0458e18abef7b5e036915e96807c219ec1d58raghuram (sizeof (uint32_t) * num_pools));
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->vmpp = (vio_mblk_pool_t **)(tbuf +
b4d0458e18abef7b5e036915e96807c219ec1d58raghuram (sizeof (uint32_t) * num_pools * 2));
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->num_pools = num_pools;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram /* initialize the array first */
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram va_start(vap, num_pools);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram for (i = 0; i < num_pools; i++) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->bufsz_tbl[i] = va_arg(vap, uint32_t);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram for (i = 0; i < num_pools; i++) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->nbuf_tbl[i] = va_arg(vap, uint32_t);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram va_end(vap);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram for (i = 0; i < vmultip->num_pools; i++) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram status = vio_create_mblks(vmultip->nbuf_tbl[i],
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmultip->bufsz_tbl[i], NULL, &vmultip->vmpp[i]);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram if (status != 0) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vio_destroy_multipools(vmultip, &fvmp);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram /* We expect to free the pools without failure here */
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram ASSERT(fvmp == NULL);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram return (status);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram return (0);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram}
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram/*
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * Destroy the multiple pools of mblks. This can only succeed when
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * all allocated mblks have been returned to the pool.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram *
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * If a pool of mblks couldn't be destroyed, then the failed vio_mblk_pool_t
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * pointers are returned via th fvmp list. Its the caller's
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * responsibility to check this list and free them later at an appropriate
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * time with vio_destroy_mblks().
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram *
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * Arguments:
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * vmultip -- A pointer to vio_multi_pool_t structure.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * fvmp -- A list in which the pools that couldn't be destroyed are
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * returned.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram */
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuramvoid
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuramvio_destroy_multipools(vio_multi_pool_t *vmultip, vio_mblk_pool_t **fvmp)
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram{
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram int i;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vio_mblk_pool_t *vmp;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram for (i = 0; i < vmultip->num_pools; i++) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram if ((vmp = vmultip->vmpp[i]) != NULL) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram if (vio_destroy_mblks(vmp)) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram /*
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * if we cannot reclaim all mblks, then
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * return the pool in the failed vmp
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * list(fvmp).
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram */
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmp->nextp = *fvmp;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram *fvmp = vmp;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (vmultip->tbsz != 0)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG kmem_free(vmultip->bufsz_tbl, vmultip->tbsz);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->bufsz_tbl = NULL;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->nbuf_tbl = NULL;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram vmultip->vmpp = NULL;
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna vmultip->num_pools = 0;
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna vmultip->tbsz = 0;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram}
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram/*
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna * Allocate an vio_mblk from one of the free pools, but tries the pool that
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram * best fits size requested first.
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatnavio_mblk_t *
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuramvio_multipool_allocb(vio_multi_pool_t *vmultip, size_t size)
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram{
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram int i;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vio_mblk_t *vmp = NULL;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram /* Try allocating any size that fits */
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram for (i = 0; i < vmultip->num_pools; i++) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram if (size > vmultip->bufsz_tbl[i]) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram continue;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna vmp = vio_allocb(vmultip->vmpp[i]);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if (vmp != NULL) {
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram break;
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram }
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna return (vmp);
844e62a3ec8c8ff5175bb35d1c38446e060730f6raghuram}
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm/*
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * -----------------------------------------------------------------------------
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * LDoms versioning functions
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm *
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * Future work: the version negotiating code in the various VIO drivers
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * could be made common and placed here.
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm */
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm/*
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * Description:
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * This function checks to see if the supplied version tuple (major,minor)
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * is supported by the version 'ver', negotiated during the handshake
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * between the client and the server (ver).
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm *
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * Assumption:
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * This function assumes that backward compatability is not broken in
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * newer minor versions of the protocol (e.g. v1.5 & v1.1 support v1.0)
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm *
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * Return Value:
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * B_TRUE - The (major,minor) version is supported
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm * B_FALSE - not supported
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm */
17cadca83cc82e37ff517ea2783eb4bfcc07b950lmboolean_t
17cadca83cc82e37ff517ea2783eb4bfcc07b950lmvio_ver_is_supported(vio_ver_t ver, uint16_t major, uint16_t minor)
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm{
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm if ((ver.major == major) && (ver.minor >= minor))
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm return (B_TRUE);
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm return (B_FALSE);
17cadca83cc82e37ff517ea2783eb4bfcc07b950lm}