1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _VIO_UTIL_H 28 #define _VIO_UTIL_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/stream.h> 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /* 39 * A message is composed of three structures. A message block (mblk_t), a 40 * data block to which it points and a data buffer. desballoc(9F) allows 41 * the caller to specify the data buffer and a free function which will 42 * be invoked when freeb(9F) is called to free the message. This allows 43 * the user to reclaim and reuse the data buffer, as opposed to using 44 * allocb(9F) where the message block, data block and data buffer are 45 * all destroyed by freeb(). 46 * 47 * Note that even with desballoc the message and data blocks are destroyed 48 * by freeb() and must be recreated. It is only the data buffer which is 49 * preserved. 50 * 51 * The caller first creates a pool of vio_mblk_t's by invoking 52 * vio_create_mblks() and specifying the number of mblks and the size of the 53 * associated data buffers. Each vio_mblk_t contains a pointer to the 54 * mblk_t, a pointer to the data buffer and a function pointer to the 55 * reclaim function. The caller is returned a pointer to the pool which is 56 * used in subsequent allocation/destroy requests. 57 * 58 * The pool is managed as a circular queue with a head and tail pointer. 59 * Allocation requests result in the head index being incremented, mblks 60 * being returned to the pool result in the tail pointer being incremented. 61 * 62 * The pool can only be destroyed when all the mblks have been returned. It 63 * is the responsibility of the caller to ensure that all vio_allocb() 64 * requests have been completed before the pool is destroyed. 65 * 66 * 67 * vio_mblk_pool_t 68 * +-------------+ 69 * | tail |--------------------------------+ 70 * +-------------+ | 71 * | head |--------+ | 72 * +-------------+ | | 73 * ............... V V 74 * +-------------+ +-------+-------+-------+-------+ 75 * | quep |---->| vmp_t | vmp_t | vmp_t | vmp_t | 76 * +-------------+ +-------+-------+-------+-------+ 77 * | | | | | | 78 * ... | | | | +------------+ 79 * | | | +-->| data block | 80 * | | | +------------+ 81 * | | | +------------+ 82 * | | +-->| data block | 83 * | | +------------+ 84 * | | +------------+ 85 * | +-->| data block | 86 * | +------------+ 87 * | +------------+ 88 * +-->| data block | 89 * +------------+ 90 * 91 */ 92 93 struct vio_mblk_pool; 94 95 typedef struct vio_mblk { 96 uint8_t *datap; /* data buffer */ 97 mblk_t *mp; /* mblk using datap */ 98 frtn_t reclaim; /* mblk reclaim routine */ 99 struct vio_mblk_pool *vmplp; /* pointer to parent pool */ 100 } vio_mblk_t; 101 102 typedef struct vio_mblk_pool { 103 struct vio_mblk_pool *nextp; /* next in a list */ 104 kmutex_t hlock; /* sync access to head */ 105 kmutex_t tlock; /* sync access to tail */ 106 vio_mblk_t *basep; /* base pointer to pool of vio_mblks */ 107 vio_mblk_t **quep; /* queue of free vio_mblks */ 108 uint8_t *datap; /* rx data buffer area */ 109 uint32_t head; /* queue head */ 110 uint32_t tail; /* queue tail */ 111 uint64_t quelen; /* queue len (# mblks) */ 112 uint64_t quemask; /* quelen - 1 */ 113 size_t mblk_size; /* data buf size of each mblk */ 114 } vio_mblk_pool_t; 115 116 int vio_create_mblks(uint64_t num_mblks, 117 size_t mblk_size, vio_mblk_pool_t **); 118 int vio_destroy_mblks(vio_mblk_pool_t *); 119 mblk_t *vio_allocb(vio_mblk_pool_t *); 120 void vio_freeb(void *arg); 121 122 123 #ifdef __cplusplus 124 } 125 #endif 126 127 #endif /* _VIO_UTIL_H */ 128