12336Snarayan /*
22336Snarayan * CDDL HEADER START
32336Snarayan *
42336Snarayan * The contents of this file are subject to the terms of the
52336Snarayan * Common Development and Distribution License (the "License").
62336Snarayan * You may not use this file except in compliance with the License.
72336Snarayan *
82336Snarayan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92336Snarayan * or http://www.opensolaris.org/os/licensing.
102336Snarayan * See the License for the specific language governing permissions
112336Snarayan * and limitations under the License.
122336Snarayan *
132336Snarayan * When distributing Covered Code, include this CDDL HEADER in each
142336Snarayan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152336Snarayan * If applicable, add the following below this CDDL HEADER, with the
162336Snarayan * fields enclosed by brackets "[]" replaced with your own identifying
172336Snarayan * information: Portions Copyright [yyyy] [name of copyright owner]
182336Snarayan *
192336Snarayan * CDDL HEADER END
202336Snarayan */
212336Snarayan
222336Snarayan /*
23*12139SSriharsha.Basavapatna@Sun.COM * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
242336Snarayan */
252336Snarayan
262336Snarayan #include <sys/types.h>
272336Snarayan #include <sys/sysmacros.h>
282336Snarayan #include <sys/errno.h>
292336Snarayan #include <sys/kmem.h>
302336Snarayan #include <sys/ksynch.h>
312336Snarayan #include <sys/stream.h>
322336Snarayan #include <sys/ddi.h>
332336Snarayan #include <sys/sunddi.h>
342336Snarayan #include <sys/vio_util.h>
352336Snarayan
369217SWentao.Yang@Sun.COM static int vio_pool_cleanup_retries = 10; /* Max retries to free pool */
379217SWentao.Yang@Sun.COM static int vio_pool_cleanup_delay = 10000; /* 10ms */
389217SWentao.Yang@Sun.COM
392336Snarayan /*
402336Snarayan * Create a pool of mblks from which future vio_allocb() requests
412336Snarayan * will be serviced.
422336Snarayan *
432336Snarayan * NOTE: num_mblks has to non-zero and a power-of-2
442336Snarayan *
459217SWentao.Yang@Sun.COM * Returns
469217SWentao.Yang@Sun.COM * 0 on success
479217SWentao.Yang@Sun.COM * EINVAL if num_mblks is zero or not a power of 2.
489217SWentao.Yang@Sun.COM * ENOSPC if the pool could not be created due to alloc failures.
492336Snarayan */
502336Snarayan int
vio_create_mblks(uint64_t num_mblks,size_t mblk_size,uint8_t * mblk_datap,vio_mblk_pool_t ** poolp)5112011SSriharsha.Basavapatna@Sun.COM vio_create_mblks(uint64_t num_mblks, size_t mblk_size, uint8_t *mblk_datap,
5212011SSriharsha.Basavapatna@Sun.COM vio_mblk_pool_t **poolp)
532336Snarayan {
542336Snarayan vio_mblk_pool_t *vmplp;
552336Snarayan vio_mblk_t *vmp;
562336Snarayan uint8_t *datap;
572336Snarayan int i;
589235SWentao.Yang@Sun.COM int rv;
592336Snarayan
602336Snarayan if (!(num_mblks) || (!ISP2(num_mblks))) {
612336Snarayan *poolp = 0;
622336Snarayan return (EINVAL);
632336Snarayan }
642336Snarayan
652336Snarayan vmplp = kmem_zalloc(sizeof (*vmplp), KM_SLEEP);
662336Snarayan vmplp->quelen = num_mblks;
672336Snarayan vmplp->quemask = num_mblks - 1; /* expects quelen is power-of-2 */
682336Snarayan vmplp->mblk_size = mblk_size;
692336Snarayan
702336Snarayan mutex_init(&vmplp->hlock, NULL, MUTEX_DRIVER,
714650Sraghuram DDI_INTR_PRI(DDI_INTR_SOFTPRI_DEFAULT));
722336Snarayan mutex_init(&vmplp->tlock, NULL, MUTEX_DRIVER,
734650Sraghuram DDI_INTR_PRI(DDI_INTR_SOFTPRI_DEFAULT));
742336Snarayan
752336Snarayan vmplp->basep = kmem_zalloc(num_mblks * sizeof (vio_mblk_t), KM_SLEEP);
7612011SSriharsha.Basavapatna@Sun.COM if (mblk_datap == NULL) {
7712011SSriharsha.Basavapatna@Sun.COM vmplp->datap = kmem_zalloc(num_mblks * mblk_size, KM_SLEEP);
7812011SSriharsha.Basavapatna@Sun.COM } else {
7912011SSriharsha.Basavapatna@Sun.COM vmplp->datap = mblk_datap;
8012011SSriharsha.Basavapatna@Sun.COM vmplp->flag |= VMPL_FLAG_CLIENT_DATA;
8112011SSriharsha.Basavapatna@Sun.COM }
822336Snarayan vmplp->nextp = NULL;
832336Snarayan
842336Snarayan /* create a queue of pointers to free vio_mblk_t's */
854647Sraghuram vmplp->quep = kmem_zalloc(vmplp->quelen *
864650Sraghuram sizeof (vio_mblk_t *), KM_SLEEP);
872336Snarayan vmplp->head = 0;
882336Snarayan vmplp->tail = 0;
892336Snarayan
902336Snarayan for (i = 0, datap = vmplp->datap; i < num_mblks; i++) {
912336Snarayan
922336Snarayan vmp = &(vmplp->basep[i]);
932336Snarayan vmp->vmplp = vmplp;
942336Snarayan vmp->datap = datap;
952336Snarayan vmp->reclaim.free_func = vio_freeb;
962336Snarayan vmp->reclaim.free_arg = (caddr_t)vmp;
972336Snarayan vmp->mp = desballoc(vmp->datap, mblk_size, BPRI_MED,
982336Snarayan &vmp->reclaim);
992336Snarayan
1009217SWentao.Yang@Sun.COM if (vmp->mp == NULL) {
1019217SWentao.Yang@Sun.COM /* reset tail */
1029217SWentao.Yang@Sun.COM vmplp->tail = vmplp->head;
1039217SWentao.Yang@Sun.COM
1049217SWentao.Yang@Sun.COM /*
1059217SWentao.Yang@Sun.COM * vio_destroy_mblks() frees mblks that have been
1069217SWentao.Yang@Sun.COM * allocated so far and then destroys the pool.
1079217SWentao.Yang@Sun.COM */
1089235SWentao.Yang@Sun.COM rv = vio_destroy_mblks(vmplp);
1099235SWentao.Yang@Sun.COM ASSERT(rv == 0);
1109217SWentao.Yang@Sun.COM
1119217SWentao.Yang@Sun.COM *poolp = NULL;
1129217SWentao.Yang@Sun.COM return (ENOSPC);
1139217SWentao.Yang@Sun.COM }
1142336Snarayan
115*12139SSriharsha.Basavapatna@Sun.COM vmp->index = i;
116*12139SSriharsha.Basavapatna@Sun.COM vmp->state = VIO_MBLK_FREE;
11712011SSriharsha.Basavapatna@Sun.COM
1182336Snarayan /* put this vmp on the free stack */
1192336Snarayan vmplp->quep[vmplp->tail] = vmp;
1202336Snarayan vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
1212336Snarayan
1222336Snarayan datap += mblk_size;
1232336Snarayan }
1242336Snarayan
1252336Snarayan *poolp = vmplp;
1262336Snarayan return (0);
1272336Snarayan }
1282336Snarayan
1292336Snarayan /*
1302336Snarayan * Destroy the pool of mblks. This can only succeed when
1312336Snarayan * all allocated mblks have been returned to the pool.
1322336Snarayan *
1332336Snarayan * It is up to the caller to ensure that no further mblks are
1342336Snarayan * requested from the pool after destroy has been invoked.
1352336Snarayan *
1362336Snarayan * Returns 0 on success, EINVAL if handle is invalid, or
1372336Snarayan * EBUSY if not all mblks reclaimed yet.
1382336Snarayan */
1392336Snarayan int
vio_destroy_mblks(vio_mblk_pool_t * vmplp)1402336Snarayan vio_destroy_mblks(vio_mblk_pool_t *vmplp)
1412336Snarayan {
1429217SWentao.Yang@Sun.COM uint64_t i;
1439217SWentao.Yang@Sun.COM uint64_t num_mblks;
1449217SWentao.Yang@Sun.COM vio_mblk_t *vmp;
1459217SWentao.Yang@Sun.COM int pool_cleanup_retries = 0;
1469217SWentao.Yang@Sun.COM
1472793Slm66018
1482336Snarayan if (vmplp == NULL)
1492336Snarayan return (EINVAL);
1502336Snarayan
1512336Snarayan /*
1522336Snarayan * We can only destroy the pool once all the mblks have
1532336Snarayan * been reclaimed.
1542336Snarayan */
1559217SWentao.Yang@Sun.COM do {
1569217SWentao.Yang@Sun.COM if (vmplp->head == vmplp->tail) {
1579217SWentao.Yang@Sun.COM break;
1589217SWentao.Yang@Sun.COM }
1599217SWentao.Yang@Sun.COM
1609217SWentao.Yang@Sun.COM /* some mblks still in use */
1619217SWentao.Yang@Sun.COM drv_usecwait(vio_pool_cleanup_delay);
1629217SWentao.Yang@Sun.COM } while (++pool_cleanup_retries < vio_pool_cleanup_retries);
1639217SWentao.Yang@Sun.COM
1642336Snarayan if (vmplp->head != vmplp->tail) {
1652336Snarayan return (EBUSY);
1662336Snarayan }
1672336Snarayan
1682793Slm66018 num_mblks = vmplp->quelen;
1692793Slm66018
1702793Slm66018 /*
1712793Slm66018 * Set pool flag to tell vio_freeb() which is invoked from freeb(),
1722793Slm66018 * that it is being called in the context of vio_destroy_mblks().
1732793Slm66018 * This results in freeing only mblk_t and dblk_t structures for
1742793Slm66018 * each mp. The associated data buffers are freed below as one big
1752793Slm66018 * chunk through kmem_free(vmplp->datap).
1762793Slm66018 */
1772793Slm66018 vmplp->flag |= VMPL_FLAG_DESTROYING;
1782793Slm66018 for (i = 0; i < num_mblks; i++) {
1792793Slm66018 vmp = &(vmplp->basep[i]);
1809217SWentao.Yang@Sun.COM /*
1819217SWentao.Yang@Sun.COM * It is possible that mblks have been allocated only upto
1829217SWentao.Yang@Sun.COM * a certain index and the entire quelen has not been
1839217SWentao.Yang@Sun.COM * initialized. This might happen due to desballoc() failure
1849217SWentao.Yang@Sun.COM * while creating the pool. The below check handles this
1859217SWentao.Yang@Sun.COM * condition.
1869217SWentao.Yang@Sun.COM */
1879217SWentao.Yang@Sun.COM if (vmp->mp != NULL)
1882793Slm66018 freeb(vmp->mp);
1892793Slm66018 }
1902793Slm66018 vmplp->flag &= ~(VMPL_FLAG_DESTROYING);
1912793Slm66018
1922793Slm66018 kmem_free(vmplp->basep, num_mblks * sizeof (vio_mblk_t));
19312011SSriharsha.Basavapatna@Sun.COM if ((vmplp->flag & VMPL_FLAG_CLIENT_DATA) == 0) {
19412011SSriharsha.Basavapatna@Sun.COM kmem_free(vmplp->datap, num_mblks * vmplp->mblk_size);
19512011SSriharsha.Basavapatna@Sun.COM }
1962793Slm66018 kmem_free(vmplp->quep, num_mblks * sizeof (vio_mblk_t *));
1972336Snarayan
1982336Snarayan mutex_destroy(&vmplp->hlock);
1992336Snarayan mutex_destroy(&vmplp->tlock);
2002336Snarayan
2012336Snarayan kmem_free(vmplp, sizeof (*vmplp));
2022336Snarayan
2032336Snarayan return (0);
2042336Snarayan }
2052336Snarayan
2062336Snarayan /*
20712011SSriharsha.Basavapatna@Sun.COM * Allocate a vio_mblk from the free pool if one is available.
2082336Snarayan * Otherwise returns NULL.
2092336Snarayan */
21012011SSriharsha.Basavapatna@Sun.COM vio_mblk_t *
vio_allocb(vio_mblk_pool_t * vmplp)2112336Snarayan vio_allocb(vio_mblk_pool_t *vmplp)
2122336Snarayan {
2132336Snarayan vio_mblk_t *vmp = NULL;
2142336Snarayan uint32_t head;
2152336Snarayan
2162336Snarayan mutex_enter(&vmplp->hlock);
2172336Snarayan head = (vmplp->head + 1) & vmplp->quemask;
2182336Snarayan if (head != vmplp->tail) {
2192336Snarayan /* we have free mblks */
2202336Snarayan vmp = vmplp->quep[vmplp->head];
2212336Snarayan vmplp->head = head;
22212011SSriharsha.Basavapatna@Sun.COM ASSERT(vmp->state == VIO_MBLK_FREE);
22312011SSriharsha.Basavapatna@Sun.COM vmp->state = VIO_MBLK_BOUND;
2242336Snarayan }
2252336Snarayan mutex_exit(&vmplp->hlock);
2262336Snarayan
22712011SSriharsha.Basavapatna@Sun.COM return (vmp);
2282336Snarayan }
2292336Snarayan
2302336Snarayan /*
2312336Snarayan * Return a mblk to the free pool. Invoked when the upper IP
2322336Snarayan * layers do freemsg() etc on the mblk they were passed.
2332336Snarayan */
2342336Snarayan void
vio_freeb(void * arg)2352336Snarayan vio_freeb(void *arg)
2362336Snarayan {
2372336Snarayan vio_mblk_t *vmp = (vio_mblk_t *)arg;
2382336Snarayan vio_mblk_pool_t *vmplp = vmp->vmplp;
2392336Snarayan
2402793Slm66018 if (vmplp->flag & VMPL_FLAG_DESTROYING) {
2412793Slm66018 /*
2422793Slm66018 * This flag indicates that freeb() is being called from
2432793Slm66018 * vio_destroy_mblks().
2442793Slm66018 * We don't need to alloc a new mblk_t/dblk_t pair for
2452793Slm66018 * this data buffer, return from here and the data buffer
2462793Slm66018 * itself will be freed in vio_destroy_mblks().
2472793Slm66018 */
2482793Slm66018 return;
2492793Slm66018 }
2502793Slm66018
2512336Snarayan vmp->mp = desballoc(vmp->datap, vmplp->mblk_size,
2524650Sraghuram BPRI_MED, &vmp->reclaim);
25312011SSriharsha.Basavapatna@Sun.COM vmp->state = VIO_MBLK_FREE;
2542336Snarayan
2552336Snarayan mutex_enter(&vmplp->tlock);
2562336Snarayan vmplp->quep[vmplp->tail] = vmp;
2572336Snarayan vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
2582336Snarayan mutex_exit(&vmplp->tlock);
2592336Snarayan }
2604647Sraghuram
26112011SSriharsha.Basavapatna@Sun.COM
26212011SSriharsha.Basavapatna@Sun.COM /*
26312011SSriharsha.Basavapatna@Sun.COM * This function searches the given mblk pool for mblks that are in the
26412011SSriharsha.Basavapatna@Sun.COM * BOUND state and moves them to the FREE state. Note that only clients that
26512011SSriharsha.Basavapatna@Sun.COM * are operating in RxDringData mode use this function. This allows such
26612011SSriharsha.Basavapatna@Sun.COM * clients to reclaim buffers that are provided to the peer as shared memory,
26712011SSriharsha.Basavapatna@Sun.COM * before calling vio_destroy_mblks(). We don't need this in other cases
26812011SSriharsha.Basavapatna@Sun.COM * as the buffer is locally managed.
26912011SSriharsha.Basavapatna@Sun.COM */
27012011SSriharsha.Basavapatna@Sun.COM void
vio_clobber_pool(vio_mblk_pool_t * vmplp)27112011SSriharsha.Basavapatna@Sun.COM vio_clobber_pool(vio_mblk_pool_t *vmplp)
27212011SSriharsha.Basavapatna@Sun.COM {
27312011SSriharsha.Basavapatna@Sun.COM uint64_t num_mblks = vmplp->quelen;
27412011SSriharsha.Basavapatna@Sun.COM uint64_t i;
27512011SSriharsha.Basavapatna@Sun.COM vio_mblk_t *vmp;
27612011SSriharsha.Basavapatna@Sun.COM
27712011SSriharsha.Basavapatna@Sun.COM mutex_enter(&vmplp->hlock);
27812011SSriharsha.Basavapatna@Sun.COM mutex_enter(&vmplp->tlock);
27912011SSriharsha.Basavapatna@Sun.COM for (i = 0; i < num_mblks; i++) {
28012011SSriharsha.Basavapatna@Sun.COM vmp = &(vmplp->basep[i]);
28112011SSriharsha.Basavapatna@Sun.COM if ((vmp->state & VIO_MBLK_BOUND) != 0) {
28212011SSriharsha.Basavapatna@Sun.COM /* put this vmp on the free stack */
28312011SSriharsha.Basavapatna@Sun.COM vmp->state = VIO_MBLK_FREE;
28412011SSriharsha.Basavapatna@Sun.COM ASSERT(vmplp->tail != vmplp->head);
28512011SSriharsha.Basavapatna@Sun.COM vmplp->quep[vmplp->tail] = vmp;
28612011SSriharsha.Basavapatna@Sun.COM vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
28712011SSriharsha.Basavapatna@Sun.COM }
28812011SSriharsha.Basavapatna@Sun.COM }
28912011SSriharsha.Basavapatna@Sun.COM mutex_exit(&vmplp->tlock);
29012011SSriharsha.Basavapatna@Sun.COM mutex_exit(&vmplp->hlock);
29112011SSriharsha.Basavapatna@Sun.COM }
29212011SSriharsha.Basavapatna@Sun.COM
2934647Sraghuram /*
2944647Sraghuram * Create a multiple pools of mblks from which future vio_allocb()
2954647Sraghuram * or vio_multipool_allocb() requests will be serviced.
2964647Sraghuram *
2974647Sraghuram * Arguments:
2984647Sraghuram * vmultip -- A pointer to vio_multi_pool_t structure.
2994647Sraghuram * num_pools -- Number of the pools.
3004647Sraghuram * ... -- Variable arguments consisting a list of buffer sizes for
3014647Sraghuram * each pool and list of number of buffers for each pool.
3024647Sraghuram *
3034647Sraghuram * NOTE: The restrictions of vio_create_mblks() apply to this interface also.
3044647Sraghuram *
3054647Sraghuram * Returns 0 on success or an error returned by vio_create_mblks().
3064647Sraghuram */
3074647Sraghuram int
vio_init_multipools(vio_multi_pool_t * vmultip,int num_pools,...)3084647Sraghuram vio_init_multipools(vio_multi_pool_t *vmultip, int num_pools, ...)
3094647Sraghuram {
3104647Sraghuram int i;
3114647Sraghuram int status;
3124647Sraghuram char *tbuf;
3134647Sraghuram va_list vap;
3144647Sraghuram vio_mblk_pool_t *fvmp = NULL;
3154647Sraghuram
3164647Sraghuram /*
3174647Sraghuram * Allocate memory for all of the following in one allocation.
3184647Sraghuram * bufsz_tbl -- sizeof (uint32_t) * num_pools
3194647Sraghuram * nbuf_tbl -- sizeof (uint32_t) * num_pools
3204647Sraghuram * vmpp -- sizeof (vio_mblk_pool_t *) * numpools
3214647Sraghuram */
3224647Sraghuram vmultip->tbsz = (sizeof (uint32_t) * num_pools) +
3234650Sraghuram (sizeof (uint32_t) * num_pools) +
3244650Sraghuram (sizeof (vio_mblk_pool_t *) * num_pools);
3254647Sraghuram tbuf = kmem_zalloc(vmultip->tbsz, KM_SLEEP);
3264647Sraghuram vmultip->bufsz_tbl = (uint32_t *)tbuf;
3274647Sraghuram vmultip->nbuf_tbl = (uint32_t *)(tbuf +
3284650Sraghuram (sizeof (uint32_t) * num_pools));
3294647Sraghuram vmultip->vmpp = (vio_mblk_pool_t **)(tbuf +
3304650Sraghuram (sizeof (uint32_t) * num_pools * 2));
3314647Sraghuram vmultip->num_pools = num_pools;
3324647Sraghuram
3334647Sraghuram /* initialize the array first */
3344647Sraghuram va_start(vap, num_pools);
3354647Sraghuram for (i = 0; i < num_pools; i++) {
3364647Sraghuram vmultip->bufsz_tbl[i] = va_arg(vap, uint32_t);
3374647Sraghuram }
3384647Sraghuram for (i = 0; i < num_pools; i++) {
3394647Sraghuram vmultip->nbuf_tbl[i] = va_arg(vap, uint32_t);
3404647Sraghuram }
3414647Sraghuram va_end(vap);
3424647Sraghuram
3434647Sraghuram for (i = 0; i < vmultip->num_pools; i++) {
3444647Sraghuram status = vio_create_mblks(vmultip->nbuf_tbl[i],
34512011SSriharsha.Basavapatna@Sun.COM vmultip->bufsz_tbl[i], NULL, &vmultip->vmpp[i]);
3464647Sraghuram if (status != 0) {
3474647Sraghuram vio_destroy_multipools(vmultip, &fvmp);
3484647Sraghuram /* We expect to free the pools without failure here */
3494647Sraghuram ASSERT(fvmp == NULL);
3504647Sraghuram return (status);
3514647Sraghuram }
3524647Sraghuram }
3534647Sraghuram return (0);
3544647Sraghuram }
3554647Sraghuram
3564647Sraghuram /*
3574647Sraghuram * Destroy the multiple pools of mblks. This can only succeed when
3584647Sraghuram * all allocated mblks have been returned to the pool.
3594647Sraghuram *
3604647Sraghuram * If a pool of mblks couldn't be destroyed, then the failed vio_mblk_pool_t
3614647Sraghuram * pointers are returned via th fvmp list. Its the caller's
3624647Sraghuram * responsibility to check this list and free them later at an appropriate
3634647Sraghuram * time with vio_destroy_mblks().
3644647Sraghuram *
3654647Sraghuram * Arguments:
3664647Sraghuram * vmultip -- A pointer to vio_multi_pool_t structure.
3674647Sraghuram * fvmp -- A list in which the pools that couldn't be destroyed are
3684647Sraghuram * returned.
3694647Sraghuram */
3704647Sraghuram void
vio_destroy_multipools(vio_multi_pool_t * vmultip,vio_mblk_pool_t ** fvmp)3714647Sraghuram vio_destroy_multipools(vio_multi_pool_t *vmultip, vio_mblk_pool_t **fvmp)
3724647Sraghuram {
3734647Sraghuram int i;
3744647Sraghuram vio_mblk_pool_t *vmp;
3754647Sraghuram
3764647Sraghuram for (i = 0; i < vmultip->num_pools; i++) {
3774647Sraghuram if ((vmp = vmultip->vmpp[i]) != NULL) {
3784647Sraghuram if (vio_destroy_mblks(vmp)) {
3794647Sraghuram /*
3804647Sraghuram * if we cannot reclaim all mblks, then
3814647Sraghuram * return the pool in the failed vmp
3824647Sraghuram * list(fvmp).
3834647Sraghuram */
3844647Sraghuram vmp->nextp = *fvmp;
3854647Sraghuram *fvmp = vmp;
3864647Sraghuram }
3874647Sraghuram }
3884647Sraghuram }
3899217SWentao.Yang@Sun.COM if (vmultip->tbsz != 0)
3909217SWentao.Yang@Sun.COM kmem_free(vmultip->bufsz_tbl, vmultip->tbsz);
3914647Sraghuram vmultip->bufsz_tbl = NULL;
3924647Sraghuram vmultip->nbuf_tbl = NULL;
3934647Sraghuram vmultip->vmpp = NULL;
3947529SSriharsha.Basavapatna@Sun.COM vmultip->num_pools = 0;
3957529SSriharsha.Basavapatna@Sun.COM vmultip->tbsz = 0;
3964647Sraghuram }
3974647Sraghuram
3984647Sraghuram
3994647Sraghuram /*
40012011SSriharsha.Basavapatna@Sun.COM * Allocate an vio_mblk from one of the free pools, but tries the pool that
4014647Sraghuram * best fits size requested first.
4024647Sraghuram */
40312011SSriharsha.Basavapatna@Sun.COM vio_mblk_t *
vio_multipool_allocb(vio_multi_pool_t * vmultip,size_t size)4044647Sraghuram vio_multipool_allocb(vio_multi_pool_t *vmultip, size_t size)
4054647Sraghuram {
4064647Sraghuram int i;
40712011SSriharsha.Basavapatna@Sun.COM vio_mblk_t *vmp = NULL;
4084647Sraghuram
4094647Sraghuram /* Try allocating any size that fits */
4104647Sraghuram for (i = 0; i < vmultip->num_pools; i++) {
4114647Sraghuram if (size > vmultip->bufsz_tbl[i]) {
4124647Sraghuram continue;
4134647Sraghuram }
41412011SSriharsha.Basavapatna@Sun.COM vmp = vio_allocb(vmultip->vmpp[i]);
41512011SSriharsha.Basavapatna@Sun.COM if (vmp != NULL) {
4164647Sraghuram break;
4174647Sraghuram }
4184647Sraghuram }
41912011SSriharsha.Basavapatna@Sun.COM return (vmp);
4204647Sraghuram }
4215365Slm66018
4225365Slm66018 /*
4235365Slm66018 * -----------------------------------------------------------------------------
4245365Slm66018 * LDoms versioning functions
4255365Slm66018 *
4265365Slm66018 * Future work: the version negotiating code in the various VIO drivers
4275365Slm66018 * could be made common and placed here.
4285365Slm66018 */
4295365Slm66018
4305365Slm66018 /*
4315365Slm66018 * Description:
4325365Slm66018 * This function checks to see if the supplied version tuple (major,minor)
4335365Slm66018 * is supported by the version 'ver', negotiated during the handshake
4345365Slm66018 * between the client and the server (ver).
4355365Slm66018 *
4365365Slm66018 * Assumption:
4375365Slm66018 * This function assumes that backward compatability is not broken in
4385365Slm66018 * newer minor versions of the protocol (e.g. v1.5 & v1.1 support v1.0)
4395365Slm66018 *
4405365Slm66018 * Return Value:
4415365Slm66018 * B_TRUE - The (major,minor) version is supported
4425365Slm66018 * B_FALSE - not supported
4435365Slm66018 */
4445365Slm66018 boolean_t
vio_ver_is_supported(vio_ver_t ver,uint16_t major,uint16_t minor)4455365Slm66018 vio_ver_is_supported(vio_ver_t ver, uint16_t major, uint16_t minor)
4465365Slm66018 {
4475365Slm66018 if ((ver.major == major) && (ver.minor >= minor))
4485365Slm66018 return (B_TRUE);
4495365Slm66018
4505365Slm66018 return (B_FALSE);
4515365Slm66018 }
452