1d10e4ef2Snarayan /*
2d10e4ef2Snarayan * CDDL HEADER START
3d10e4ef2Snarayan *
4d10e4ef2Snarayan * The contents of this file are subject to the terms of the
5d10e4ef2Snarayan * Common Development and Distribution License (the "License").
6d10e4ef2Snarayan * You may not use this file except in compliance with the License.
7d10e4ef2Snarayan *
8d10e4ef2Snarayan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d10e4ef2Snarayan * or http://www.opensolaris.org/os/licensing.
10d10e4ef2Snarayan * See the License for the specific language governing permissions
11d10e4ef2Snarayan * and limitations under the License.
12d10e4ef2Snarayan *
13d10e4ef2Snarayan * When distributing Covered Code, include this CDDL HEADER in each
14d10e4ef2Snarayan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d10e4ef2Snarayan * If applicable, add the following below this CDDL HEADER, with the
16d10e4ef2Snarayan * fields enclosed by brackets "[]" replaced with your own identifying
17d10e4ef2Snarayan * information: Portions Copyright [yyyy] [name of copyright owner]
18d10e4ef2Snarayan *
19d10e4ef2Snarayan * CDDL HEADER END
20d10e4ef2Snarayan */
21d10e4ef2Snarayan
22d10e4ef2Snarayan /*
23*046cfe5cSSriharsha Basavapatna * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24d10e4ef2Snarayan */
25d10e4ef2Snarayan
26d10e4ef2Snarayan #include <sys/types.h>
27d10e4ef2Snarayan #include <sys/sysmacros.h>
28d10e4ef2Snarayan #include <sys/errno.h>
29d10e4ef2Snarayan #include <sys/kmem.h>
30d10e4ef2Snarayan #include <sys/ksynch.h>
31d10e4ef2Snarayan #include <sys/stream.h>
32d10e4ef2Snarayan #include <sys/ddi.h>
33d10e4ef2Snarayan #include <sys/sunddi.h>
34d10e4ef2Snarayan #include <sys/vio_util.h>
35d10e4ef2Snarayan
366f09f0feSWENTAO YANG static int vio_pool_cleanup_retries = 10; /* Max retries to free pool */
376f09f0feSWENTAO YANG static int vio_pool_cleanup_delay = 10000; /* 10ms */
386f09f0feSWENTAO YANG
39d10e4ef2Snarayan /*
40d10e4ef2Snarayan * Create a pool of mblks from which future vio_allocb() requests
41d10e4ef2Snarayan * will be serviced.
42d10e4ef2Snarayan *
43d10e4ef2Snarayan * NOTE: num_mblks has to non-zero and a power-of-2
44d10e4ef2Snarayan *
456f09f0feSWENTAO YANG * Returns
466f09f0feSWENTAO YANG * 0 on success
476f09f0feSWENTAO YANG * EINVAL if num_mblks is zero or not a power of 2.
486f09f0feSWENTAO YANG * ENOSPC if the pool could not be created due to alloc failures.
49d10e4ef2Snarayan */
50d10e4ef2Snarayan int
vio_create_mblks(uint64_t num_mblks,size_t mblk_size,uint8_t * mblk_datap,vio_mblk_pool_t ** poolp)517bd3a2e2SSriharsha Basavapatna vio_create_mblks(uint64_t num_mblks, size_t mblk_size, uint8_t *mblk_datap,
527bd3a2e2SSriharsha Basavapatna vio_mblk_pool_t **poolp)
53d10e4ef2Snarayan {
54d10e4ef2Snarayan vio_mblk_pool_t *vmplp;
55d10e4ef2Snarayan vio_mblk_t *vmp;
56d10e4ef2Snarayan uint8_t *datap;
57d10e4ef2Snarayan int i;
583ab636deSWENTAO YANG int rv;
59d10e4ef2Snarayan
60d10e4ef2Snarayan if (!(num_mblks) || (!ISP2(num_mblks))) {
61d10e4ef2Snarayan *poolp = 0;
62d10e4ef2Snarayan return (EINVAL);
63d10e4ef2Snarayan }
64d10e4ef2Snarayan
65d10e4ef2Snarayan vmplp = kmem_zalloc(sizeof (*vmplp), KM_SLEEP);
66d10e4ef2Snarayan vmplp->quelen = num_mblks;
67d10e4ef2Snarayan vmplp->quemask = num_mblks - 1; /* expects quelen is power-of-2 */
68d10e4ef2Snarayan vmplp->mblk_size = mblk_size;
69d10e4ef2Snarayan
70d10e4ef2Snarayan mutex_init(&vmplp->hlock, NULL, MUTEX_DRIVER,
71b4d0458eSraghuram DDI_INTR_PRI(DDI_INTR_SOFTPRI_DEFAULT));
72d10e4ef2Snarayan mutex_init(&vmplp->tlock, NULL, MUTEX_DRIVER,
73b4d0458eSraghuram DDI_INTR_PRI(DDI_INTR_SOFTPRI_DEFAULT));
74d10e4ef2Snarayan
75d10e4ef2Snarayan vmplp->basep = kmem_zalloc(num_mblks * sizeof (vio_mblk_t), KM_SLEEP);
767bd3a2e2SSriharsha Basavapatna if (mblk_datap == NULL) {
777bd3a2e2SSriharsha Basavapatna vmplp->datap = kmem_zalloc(num_mblks * mblk_size, KM_SLEEP);
787bd3a2e2SSriharsha Basavapatna } else {
797bd3a2e2SSriharsha Basavapatna vmplp->datap = mblk_datap;
807bd3a2e2SSriharsha Basavapatna vmplp->flag |= VMPL_FLAG_CLIENT_DATA;
817bd3a2e2SSriharsha Basavapatna }
82d10e4ef2Snarayan vmplp->nextp = NULL;
83d10e4ef2Snarayan
84d10e4ef2Snarayan /* create a queue of pointers to free vio_mblk_t's */
85844e62a3Sraghuram vmplp->quep = kmem_zalloc(vmplp->quelen *
86b4d0458eSraghuram sizeof (vio_mblk_t *), KM_SLEEP);
87d10e4ef2Snarayan vmplp->head = 0;
88d10e4ef2Snarayan vmplp->tail = 0;
89d10e4ef2Snarayan
90d10e4ef2Snarayan for (i = 0, datap = vmplp->datap; i < num_mblks; i++) {
91d10e4ef2Snarayan
92d10e4ef2Snarayan vmp = &(vmplp->basep[i]);
93d10e4ef2Snarayan vmp->vmplp = vmplp;
94d10e4ef2Snarayan vmp->datap = datap;
95d10e4ef2Snarayan vmp->reclaim.free_func = vio_freeb;
96d10e4ef2Snarayan vmp->reclaim.free_arg = (caddr_t)vmp;
97d10e4ef2Snarayan vmp->mp = desballoc(vmp->datap, mblk_size, BPRI_MED,
98d10e4ef2Snarayan &vmp->reclaim);
99d10e4ef2Snarayan
1006f09f0feSWENTAO YANG if (vmp->mp == NULL) {
1016f09f0feSWENTAO YANG /* reset tail */
1026f09f0feSWENTAO YANG vmplp->tail = vmplp->head;
1036f09f0feSWENTAO YANG
1046f09f0feSWENTAO YANG /*
1056f09f0feSWENTAO YANG * vio_destroy_mblks() frees mblks that have been
1066f09f0feSWENTAO YANG * allocated so far and then destroys the pool.
1076f09f0feSWENTAO YANG */
1083ab636deSWENTAO YANG rv = vio_destroy_mblks(vmplp);
1093ab636deSWENTAO YANG ASSERT(rv == 0);
1106f09f0feSWENTAO YANG
1116f09f0feSWENTAO YANG *poolp = NULL;
1126f09f0feSWENTAO YANG return (ENOSPC);
1136f09f0feSWENTAO YANG }
114d10e4ef2Snarayan
115*046cfe5cSSriharsha Basavapatna vmp->index = i;
116*046cfe5cSSriharsha Basavapatna vmp->state = VIO_MBLK_FREE;
1177bd3a2e2SSriharsha Basavapatna
118d10e4ef2Snarayan /* put this vmp on the free stack */
119d10e4ef2Snarayan vmplp->quep[vmplp->tail] = vmp;
120d10e4ef2Snarayan vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
121d10e4ef2Snarayan
122d10e4ef2Snarayan datap += mblk_size;
123d10e4ef2Snarayan }
124d10e4ef2Snarayan
125d10e4ef2Snarayan *poolp = vmplp;
126d10e4ef2Snarayan return (0);
127d10e4ef2Snarayan }
128d10e4ef2Snarayan
129d10e4ef2Snarayan /*
130d10e4ef2Snarayan * Destroy the pool of mblks. This can only succeed when
131d10e4ef2Snarayan * all allocated mblks have been returned to the pool.
132d10e4ef2Snarayan *
133d10e4ef2Snarayan * It is up to the caller to ensure that no further mblks are
134d10e4ef2Snarayan * requested from the pool after destroy has been invoked.
135d10e4ef2Snarayan *
136d10e4ef2Snarayan * Returns 0 on success, EINVAL if handle is invalid, or
137d10e4ef2Snarayan * EBUSY if not all mblks reclaimed yet.
138d10e4ef2Snarayan */
139d10e4ef2Snarayan int
vio_destroy_mblks(vio_mblk_pool_t * vmplp)140d10e4ef2Snarayan vio_destroy_mblks(vio_mblk_pool_t *vmplp)
141d10e4ef2Snarayan {
1426f09f0feSWENTAO YANG uint64_t i;
1436f09f0feSWENTAO YANG uint64_t num_mblks;
1446f09f0feSWENTAO YANG vio_mblk_t *vmp;
1456f09f0feSWENTAO YANG int pool_cleanup_retries = 0;
1466f09f0feSWENTAO YANG
1473af08d82Slm
148d10e4ef2Snarayan if (vmplp == NULL)
149d10e4ef2Snarayan return (EINVAL);
150d10e4ef2Snarayan
151d10e4ef2Snarayan /*
152d10e4ef2Snarayan * We can only destroy the pool once all the mblks have
153d10e4ef2Snarayan * been reclaimed.
154d10e4ef2Snarayan */
1556f09f0feSWENTAO YANG do {
1566f09f0feSWENTAO YANG if (vmplp->head == vmplp->tail) {
1576f09f0feSWENTAO YANG break;
1586f09f0feSWENTAO YANG }
1596f09f0feSWENTAO YANG
160d10e4ef2Snarayan /* some mblks still in use */
1616f09f0feSWENTAO YANG drv_usecwait(vio_pool_cleanup_delay);
1626f09f0feSWENTAO YANG } while (++pool_cleanup_retries < vio_pool_cleanup_retries);
1636f09f0feSWENTAO YANG
1646f09f0feSWENTAO YANG if (vmplp->head != vmplp->tail) {
165d10e4ef2Snarayan return (EBUSY);
166d10e4ef2Snarayan }
167d10e4ef2Snarayan
1683af08d82Slm num_mblks = vmplp->quelen;
1693af08d82Slm
1703af08d82Slm /*
1713af08d82Slm * Set pool flag to tell vio_freeb() which is invoked from freeb(),
1723af08d82Slm * that it is being called in the context of vio_destroy_mblks().
1733af08d82Slm * This results in freeing only mblk_t and dblk_t structures for
1743af08d82Slm * each mp. The associated data buffers are freed below as one big
1753af08d82Slm * chunk through kmem_free(vmplp->datap).
1763af08d82Slm */
1773af08d82Slm vmplp->flag |= VMPL_FLAG_DESTROYING;
1783af08d82Slm for (i = 0; i < num_mblks; i++) {
1793af08d82Slm vmp = &(vmplp->basep[i]);
1806f09f0feSWENTAO YANG /*
1816f09f0feSWENTAO YANG * It is possible that mblks have been allocated only upto
1826f09f0feSWENTAO YANG * a certain index and the entire quelen has not been
1836f09f0feSWENTAO YANG * initialized. This might happen due to desballoc() failure
1846f09f0feSWENTAO YANG * while creating the pool. The below check handles this
1856f09f0feSWENTAO YANG * condition.
1866f09f0feSWENTAO YANG */
1876f09f0feSWENTAO YANG if (vmp->mp != NULL)
1883af08d82Slm freeb(vmp->mp);
1893af08d82Slm }
1903af08d82Slm vmplp->flag &= ~(VMPL_FLAG_DESTROYING);
1913af08d82Slm
1923af08d82Slm kmem_free(vmplp->basep, num_mblks * sizeof (vio_mblk_t));
1937bd3a2e2SSriharsha Basavapatna if ((vmplp->flag & VMPL_FLAG_CLIENT_DATA) == 0) {
1947bd3a2e2SSriharsha Basavapatna kmem_free(vmplp->datap, num_mblks * vmplp->mblk_size);
1957bd3a2e2SSriharsha Basavapatna }
1963af08d82Slm kmem_free(vmplp->quep, num_mblks * sizeof (vio_mblk_t *));
197d10e4ef2Snarayan
198d10e4ef2Snarayan mutex_destroy(&vmplp->hlock);
199d10e4ef2Snarayan mutex_destroy(&vmplp->tlock);
200d10e4ef2Snarayan
201d10e4ef2Snarayan kmem_free(vmplp, sizeof (*vmplp));
202d10e4ef2Snarayan
203d10e4ef2Snarayan return (0);
204d10e4ef2Snarayan }
205d10e4ef2Snarayan
206d10e4ef2Snarayan /*
2077bd3a2e2SSriharsha Basavapatna * Allocate a vio_mblk from the free pool if one is available.
208d10e4ef2Snarayan * Otherwise returns NULL.
209d10e4ef2Snarayan */
2107bd3a2e2SSriharsha Basavapatna vio_mblk_t *
vio_allocb(vio_mblk_pool_t * vmplp)211d10e4ef2Snarayan vio_allocb(vio_mblk_pool_t *vmplp)
212d10e4ef2Snarayan {
213d10e4ef2Snarayan vio_mblk_t *vmp = NULL;
214d10e4ef2Snarayan uint32_t head;
215d10e4ef2Snarayan
216d10e4ef2Snarayan mutex_enter(&vmplp->hlock);
217d10e4ef2Snarayan head = (vmplp->head + 1) & vmplp->quemask;
218d10e4ef2Snarayan if (head != vmplp->tail) {
219d10e4ef2Snarayan /* we have free mblks */
220d10e4ef2Snarayan vmp = vmplp->quep[vmplp->head];
221d10e4ef2Snarayan vmplp->head = head;
2227bd3a2e2SSriharsha Basavapatna ASSERT(vmp->state == VIO_MBLK_FREE);
2237bd3a2e2SSriharsha Basavapatna vmp->state = VIO_MBLK_BOUND;
224d10e4ef2Snarayan }
225d10e4ef2Snarayan mutex_exit(&vmplp->hlock);
226d10e4ef2Snarayan
2277bd3a2e2SSriharsha Basavapatna return (vmp);
228d10e4ef2Snarayan }
229d10e4ef2Snarayan
230d10e4ef2Snarayan /*
231d10e4ef2Snarayan * Return a mblk to the free pool. Invoked when the upper IP
232d10e4ef2Snarayan * layers do freemsg() etc on the mblk they were passed.
233d10e4ef2Snarayan */
234d10e4ef2Snarayan void
vio_freeb(void * arg)235d10e4ef2Snarayan vio_freeb(void *arg)
236d10e4ef2Snarayan {
237d10e4ef2Snarayan vio_mblk_t *vmp = (vio_mblk_t *)arg;
238d10e4ef2Snarayan vio_mblk_pool_t *vmplp = vmp->vmplp;
239d10e4ef2Snarayan
2403af08d82Slm if (vmplp->flag & VMPL_FLAG_DESTROYING) {
2413af08d82Slm /*
2423af08d82Slm * This flag indicates that freeb() is being called from
2433af08d82Slm * vio_destroy_mblks().
2443af08d82Slm * We don't need to alloc a new mblk_t/dblk_t pair for
2453af08d82Slm * this data buffer, return from here and the data buffer
2463af08d82Slm * itself will be freed in vio_destroy_mblks().
2473af08d82Slm */
2483af08d82Slm return;
2493af08d82Slm }
2503af08d82Slm
251d10e4ef2Snarayan vmp->mp = desballoc(vmp->datap, vmplp->mblk_size,
252b4d0458eSraghuram BPRI_MED, &vmp->reclaim);
2537bd3a2e2SSriharsha Basavapatna vmp->state = VIO_MBLK_FREE;
254d10e4ef2Snarayan
255d10e4ef2Snarayan mutex_enter(&vmplp->tlock);
256d10e4ef2Snarayan vmplp->quep[vmplp->tail] = vmp;
257d10e4ef2Snarayan vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
258d10e4ef2Snarayan mutex_exit(&vmplp->tlock);
259d10e4ef2Snarayan }
260844e62a3Sraghuram
2617bd3a2e2SSriharsha Basavapatna
2627bd3a2e2SSriharsha Basavapatna /*
2637bd3a2e2SSriharsha Basavapatna * This function searches the given mblk pool for mblks that are in the
2647bd3a2e2SSriharsha Basavapatna * BOUND state and moves them to the FREE state. Note that only clients that
2657bd3a2e2SSriharsha Basavapatna * are operating in RxDringData mode use this function. This allows such
2667bd3a2e2SSriharsha Basavapatna * clients to reclaim buffers that are provided to the peer as shared memory,
2677bd3a2e2SSriharsha Basavapatna * before calling vio_destroy_mblks(). We don't need this in other cases
2687bd3a2e2SSriharsha Basavapatna * as the buffer is locally managed.
2697bd3a2e2SSriharsha Basavapatna */
2707bd3a2e2SSriharsha Basavapatna void
vio_clobber_pool(vio_mblk_pool_t * vmplp)2717bd3a2e2SSriharsha Basavapatna vio_clobber_pool(vio_mblk_pool_t *vmplp)
2727bd3a2e2SSriharsha Basavapatna {
2737bd3a2e2SSriharsha Basavapatna uint64_t num_mblks = vmplp->quelen;
2747bd3a2e2SSriharsha Basavapatna uint64_t i;
2757bd3a2e2SSriharsha Basavapatna vio_mblk_t *vmp;
2767bd3a2e2SSriharsha Basavapatna
2777bd3a2e2SSriharsha Basavapatna mutex_enter(&vmplp->hlock);
2787bd3a2e2SSriharsha Basavapatna mutex_enter(&vmplp->tlock);
2797bd3a2e2SSriharsha Basavapatna for (i = 0; i < num_mblks; i++) {
2807bd3a2e2SSriharsha Basavapatna vmp = &(vmplp->basep[i]);
2817bd3a2e2SSriharsha Basavapatna if ((vmp->state & VIO_MBLK_BOUND) != 0) {
2827bd3a2e2SSriharsha Basavapatna /* put this vmp on the free stack */
2837bd3a2e2SSriharsha Basavapatna vmp->state = VIO_MBLK_FREE;
2847bd3a2e2SSriharsha Basavapatna ASSERT(vmplp->tail != vmplp->head);
2857bd3a2e2SSriharsha Basavapatna vmplp->quep[vmplp->tail] = vmp;
2867bd3a2e2SSriharsha Basavapatna vmplp->tail = (vmplp->tail + 1) & vmplp->quemask;
2877bd3a2e2SSriharsha Basavapatna }
2887bd3a2e2SSriharsha Basavapatna }
2897bd3a2e2SSriharsha Basavapatna mutex_exit(&vmplp->tlock);
2907bd3a2e2SSriharsha Basavapatna mutex_exit(&vmplp->hlock);
2917bd3a2e2SSriharsha Basavapatna }
2927bd3a2e2SSriharsha Basavapatna
293844e62a3Sraghuram /*
294844e62a3Sraghuram * Create a multiple pools of mblks from which future vio_allocb()
295844e62a3Sraghuram * or vio_multipool_allocb() requests will be serviced.
296844e62a3Sraghuram *
297844e62a3Sraghuram * Arguments:
298844e62a3Sraghuram * vmultip -- A pointer to vio_multi_pool_t structure.
299844e62a3Sraghuram * num_pools -- Number of the pools.
300844e62a3Sraghuram * ... -- Variable arguments consisting a list of buffer sizes for
301844e62a3Sraghuram * each pool and list of number of buffers for each pool.
302844e62a3Sraghuram *
303844e62a3Sraghuram * NOTE: The restrictions of vio_create_mblks() apply to this interface also.
304844e62a3Sraghuram *
305844e62a3Sraghuram * Returns 0 on success or an error returned by vio_create_mblks().
306844e62a3Sraghuram */
307844e62a3Sraghuram int
vio_init_multipools(vio_multi_pool_t * vmultip,int num_pools,...)308844e62a3Sraghuram vio_init_multipools(vio_multi_pool_t *vmultip, int num_pools, ...)
309844e62a3Sraghuram {
310844e62a3Sraghuram int i;
311844e62a3Sraghuram int status;
312844e62a3Sraghuram char *tbuf;
313844e62a3Sraghuram va_list vap;
314844e62a3Sraghuram vio_mblk_pool_t *fvmp = NULL;
315844e62a3Sraghuram
316844e62a3Sraghuram /*
317844e62a3Sraghuram * Allocate memory for all of the following in one allocation.
318844e62a3Sraghuram * bufsz_tbl -- sizeof (uint32_t) * num_pools
319844e62a3Sraghuram * nbuf_tbl -- sizeof (uint32_t) * num_pools
320844e62a3Sraghuram * vmpp -- sizeof (vio_mblk_pool_t *) * numpools
321844e62a3Sraghuram */
322844e62a3Sraghuram vmultip->tbsz = (sizeof (uint32_t) * num_pools) +
323b4d0458eSraghuram (sizeof (uint32_t) * num_pools) +
324b4d0458eSraghuram (sizeof (vio_mblk_pool_t *) * num_pools);
325844e62a3Sraghuram tbuf = kmem_zalloc(vmultip->tbsz, KM_SLEEP);
326844e62a3Sraghuram vmultip->bufsz_tbl = (uint32_t *)tbuf;
327844e62a3Sraghuram vmultip->nbuf_tbl = (uint32_t *)(tbuf +
328b4d0458eSraghuram (sizeof (uint32_t) * num_pools));
329844e62a3Sraghuram vmultip->vmpp = (vio_mblk_pool_t **)(tbuf +
330b4d0458eSraghuram (sizeof (uint32_t) * num_pools * 2));
331844e62a3Sraghuram vmultip->num_pools = num_pools;
332844e62a3Sraghuram
333844e62a3Sraghuram /* initialize the array first */
334844e62a3Sraghuram va_start(vap, num_pools);
335844e62a3Sraghuram for (i = 0; i < num_pools; i++) {
336844e62a3Sraghuram vmultip->bufsz_tbl[i] = va_arg(vap, uint32_t);
337844e62a3Sraghuram }
338844e62a3Sraghuram for (i = 0; i < num_pools; i++) {
339844e62a3Sraghuram vmultip->nbuf_tbl[i] = va_arg(vap, uint32_t);
340844e62a3Sraghuram }
341844e62a3Sraghuram va_end(vap);
342844e62a3Sraghuram
343844e62a3Sraghuram for (i = 0; i < vmultip->num_pools; i++) {
344844e62a3Sraghuram status = vio_create_mblks(vmultip->nbuf_tbl[i],
3457bd3a2e2SSriharsha Basavapatna vmultip->bufsz_tbl[i], NULL, &vmultip->vmpp[i]);
346844e62a3Sraghuram if (status != 0) {
347844e62a3Sraghuram vio_destroy_multipools(vmultip, &fvmp);
348844e62a3Sraghuram /* We expect to free the pools without failure here */
349844e62a3Sraghuram ASSERT(fvmp == NULL);
350844e62a3Sraghuram return (status);
351844e62a3Sraghuram }
352844e62a3Sraghuram }
353844e62a3Sraghuram return (0);
354844e62a3Sraghuram }
355844e62a3Sraghuram
356844e62a3Sraghuram /*
357844e62a3Sraghuram * Destroy the multiple pools of mblks. This can only succeed when
358844e62a3Sraghuram * all allocated mblks have been returned to the pool.
359844e62a3Sraghuram *
360844e62a3Sraghuram * If a pool of mblks couldn't be destroyed, then the failed vio_mblk_pool_t
361844e62a3Sraghuram * pointers are returned via th fvmp list. Its the caller's
362844e62a3Sraghuram * responsibility to check this list and free them later at an appropriate
363844e62a3Sraghuram * time with vio_destroy_mblks().
364844e62a3Sraghuram *
365844e62a3Sraghuram * Arguments:
366844e62a3Sraghuram * vmultip -- A pointer to vio_multi_pool_t structure.
367844e62a3Sraghuram * fvmp -- A list in which the pools that couldn't be destroyed are
368844e62a3Sraghuram * returned.
369844e62a3Sraghuram */
370844e62a3Sraghuram void
vio_destroy_multipools(vio_multi_pool_t * vmultip,vio_mblk_pool_t ** fvmp)371844e62a3Sraghuram vio_destroy_multipools(vio_multi_pool_t *vmultip, vio_mblk_pool_t **fvmp)
372844e62a3Sraghuram {
373844e62a3Sraghuram int i;
374844e62a3Sraghuram vio_mblk_pool_t *vmp;
375844e62a3Sraghuram
376844e62a3Sraghuram for (i = 0; i < vmultip->num_pools; i++) {
377844e62a3Sraghuram if ((vmp = vmultip->vmpp[i]) != NULL) {
378844e62a3Sraghuram if (vio_destroy_mblks(vmp)) {
379844e62a3Sraghuram /*
380844e62a3Sraghuram * if we cannot reclaim all mblks, then
381844e62a3Sraghuram * return the pool in the failed vmp
382844e62a3Sraghuram * list(fvmp).
383844e62a3Sraghuram */
384844e62a3Sraghuram vmp->nextp = *fvmp;
385844e62a3Sraghuram *fvmp = vmp;
386844e62a3Sraghuram }
387844e62a3Sraghuram }
388844e62a3Sraghuram }
3896f09f0feSWENTAO YANG if (vmultip->tbsz != 0)
3906f09f0feSWENTAO YANG kmem_free(vmultip->bufsz_tbl, vmultip->tbsz);
391844e62a3Sraghuram vmultip->bufsz_tbl = NULL;
392844e62a3Sraghuram vmultip->nbuf_tbl = NULL;
393844e62a3Sraghuram vmultip->vmpp = NULL;
3947b1f684aSSriharsha Basavapatna vmultip->num_pools = 0;
3957b1f684aSSriharsha Basavapatna vmultip->tbsz = 0;
396844e62a3Sraghuram }
397844e62a3Sraghuram
398844e62a3Sraghuram
399844e62a3Sraghuram /*
4007bd3a2e2SSriharsha Basavapatna * Allocate an vio_mblk from one of the free pools, but tries the pool that
401844e62a3Sraghuram * best fits size requested first.
402844e62a3Sraghuram */
4037bd3a2e2SSriharsha Basavapatna vio_mblk_t *
vio_multipool_allocb(vio_multi_pool_t * vmultip,size_t size)404844e62a3Sraghuram vio_multipool_allocb(vio_multi_pool_t *vmultip, size_t size)
405844e62a3Sraghuram {
406844e62a3Sraghuram int i;
4077bd3a2e2SSriharsha Basavapatna vio_mblk_t *vmp = NULL;
408844e62a3Sraghuram
409844e62a3Sraghuram /* Try allocating any size that fits */
410844e62a3Sraghuram for (i = 0; i < vmultip->num_pools; i++) {
411844e62a3Sraghuram if (size > vmultip->bufsz_tbl[i]) {
412844e62a3Sraghuram continue;
413844e62a3Sraghuram }
4147bd3a2e2SSriharsha Basavapatna vmp = vio_allocb(vmultip->vmpp[i]);
4157bd3a2e2SSriharsha Basavapatna if (vmp != NULL) {
416844e62a3Sraghuram break;
417844e62a3Sraghuram }
418844e62a3Sraghuram }
4197bd3a2e2SSriharsha Basavapatna return (vmp);
420844e62a3Sraghuram }
42117cadca8Slm
42217cadca8Slm /*
42317cadca8Slm * -----------------------------------------------------------------------------
42417cadca8Slm * LDoms versioning functions
42517cadca8Slm *
42617cadca8Slm * Future work: the version negotiating code in the various VIO drivers
42717cadca8Slm * could be made common and placed here.
42817cadca8Slm */
42917cadca8Slm
43017cadca8Slm /*
43117cadca8Slm * Description:
43217cadca8Slm * This function checks to see if the supplied version tuple (major,minor)
43317cadca8Slm * is supported by the version 'ver', negotiated during the handshake
43417cadca8Slm * between the client and the server (ver).
43517cadca8Slm *
43617cadca8Slm * Assumption:
43717cadca8Slm * This function assumes that backward compatability is not broken in
43817cadca8Slm * newer minor versions of the protocol (e.g. v1.5 & v1.1 support v1.0)
43917cadca8Slm *
44017cadca8Slm * Return Value:
44117cadca8Slm * B_TRUE - The (major,minor) version is supported
44217cadca8Slm * B_FALSE - not supported
44317cadca8Slm */
44417cadca8Slm boolean_t
vio_ver_is_supported(vio_ver_t ver,uint16_t major,uint16_t minor)44517cadca8Slm vio_ver_is_supported(vio_ver_t ver, uint16_t major, uint16_t minor)
44617cadca8Slm {
44717cadca8Slm if ((ver.major == major) && (ver.minor >= minor))
44817cadca8Slm return (B_TRUE);
44917cadca8Slm
45017cadca8Slm return (B_FALSE);
45117cadca8Slm }
452