/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_MULTIDATA_IMPL_H #define _SYS_MULTIDATA_IMPL_H #pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { #endif /* * Multidata: implementation-private data structure and declarations. */ /* * Structure used for insque/remque circular list operations. */ typedef struct ql_s { struct ql_s *ql_next; /* pointer to next list element */ struct ql_s *ql_prev; /* pointer to previous list element */ } ql_t; #define QL_INIT(q) { \ ((ql_t *)(q))->ql_next = (ql_t *)(q); \ ((ql_t *)(q))->ql_prev = (ql_t *)(q); \ } typedef struct pdesc_slab_s pdesc_slab_t; /* * Attribute hash bucket structure. */ typedef struct patbkt_s { kmutex_t pbkt_lock; /* per-bucket lock */ ql_t pbkt_pattr_q; /* list of attributes */ uint_t pbkt_tbl_sz; /* table size (if this is first bucket) */ } patbkt_t; /* * Attribute structure. */ #define PATTR_MAGIC 0x50615472 /* "PaTr" */ struct pattr_s { pattr_t *pat_next; /* pointer to next attribute in bucket */ pattr_t *pat_prev; /* pointer to previous attribute in bucket */ uint_t pat_magic; /* set to PATTR_MAGIC */ kmutex_t *pat_lock; /* pointer to per-bucket lock */ multidata_t *pat_mmd; /* back pointer to Multidata */ uint_t pat_buflen; /* length of this structure + attribute */ uint_t pat_type; /* type of encapsulated attribute */ uint_t pat_flags; /* misc. flags */ }; /* * Values for pat_flags. */ #define PATTR_REM_DEFER 0x1 /* entry is marked unusable but still exists */ #define PATTR_PERSIST 0x2 /* entry can't be removed */ #define Q2PATTR(p) \ ((pattr_t *)((caddr_t)(p) - offsetof(pattr_t, pat_next))) /* * Packet descriptor structure. */ #define PDESC_MAGIC 0x506b5464 /* "PkTd" */ struct pdesc_s { pdesc_t *pd_next; /* pointer to next descriptor */ pdesc_t *pd_prev; /* pointer to previous descriptor */ uint_t pd_magic; /* set to PDESC_MAGIC */ pdesc_slab_t *pd_slab; /* back pointer to descriptor slab */ patbkt_t *pd_pattbl; /* hash table of local attributes */ pdescinfo_t pd_pdi; /* embedded descriptor info structure */ #define pd_flags pd_pdi.flags }; /* * Additional internal flags for pd_flags (see multidata.h for the rest). */ #define PDESC_REM_DEFER 0x1000 /* entry is marked unusable but still exists */ #define PDESC_HAS_REF (PDESC_HBUF_REF | PDESC_PBUF_REF) #define Q2PD(p) \ ((pdesc_t *)((caddr_t)(p) - offsetof(pdesc_t, pd_next))) #define PDI_COPY(pd_src, pd_dst) { \ (pd_dst)->flags = (pd_src)->flags & PDESC_HAS_REF; \ if ((pd_dst)->flags & PDESC_HBUF_REF) { \ (pd_dst)->hdr_base = (pd_src)->hdr_base; \ (pd_dst)->hdr_rptr = (pd_src)->hdr_rptr; \ (pd_dst)->hdr_wptr = (pd_src)->hdr_wptr; \ (pd_dst)->hdr_lim = (pd_src)->hdr_lim; \ } else { \ (pd_dst)->hdr_base = NULL; \ (pd_dst)->hdr_rptr = NULL; \ (pd_dst)->hdr_wptr = NULL; \ (pd_dst)->hdr_lim = NULL; \ } \ \ if ((pd_dst)->flags & PDESC_PBUF_REF) { \ int i; \ \ (pd_dst)->pld_cnt = (pd_src)->pld_cnt; \ for (i = 0; i < (pd_dst)->pld_cnt; i++) { \ (pd_dst)->pld_ary[i].pld_pbuf_idx = \ (pd_src)->pld_ary[i].pld_pbuf_idx; \ (pd_dst)->pld_ary[i].pld_rptr = \ (pd_src)->pld_ary[i].pld_rptr; \ (pd_dst)->pld_ary[i].pld_wptr = \ (pd_src)->pld_ary[i].pld_wptr; \ } \ } else { \ (pd_dst)->pld_cnt = 0; \ } \ } /* * Packet descriptor slab structure. */ struct pdesc_slab_s { pdesc_slab_t *pds_next; /* pointer to next descriptor slab */ pdesc_slab_t *pds_prev; /* pointer to previous descriptor slab */ multidata_t *pds_mmd; /* back pointer to Multidata */ uint_t pds_used; /* always-increasing index to array */ uint_t pds_sz; /* size of descriptor array */ pdesc_t pds_free_desc[1]; /* array of available descriptors */ }; #define Q2PDSLAB(p) \ ((pdesc_slab_t *)((caddr_t)(p) - offsetof(pdesc_slab_t, pds_next))) #define PDESC_SLAB_SIZE(npd) \ ((size_t)(&((pdesc_slab_t *)0)->pds_free_desc[npd])) /* * Multidata metadata structure. */ #define MULTIDATA_MAGIC 0x4d645461 /* "MdTa" */ struct multidata_s { uint_t mmd_magic; /* set to MULTIDATA_MAGIC */ dblk_t *mmd_dp; /* back pointer to wrapper dblk structure */ mblk_t *mmd_hbuf; /* pointer to header buffer mblk */ patbkt_t *mmd_pattbl; /* hash table of global attributes */ kmutex_t mmd_pd_slab_lock; /* lock to protect the following items */ uint_t mmd_pbuf_cnt; /* number of data buffer */ mblk_t *mmd_pbuf[MULTIDATA_MAX_PBUFS]; /* data buffer mblk(s) */ ql_t mmd_pd_slab_q; /* list of packet descriptor slabs */ ql_t mmd_pd_q; /* list of packet descriptors */ uint_t mmd_slab_cnt; /* number of packet descriptor slabs */ uint_t mmd_pd_cnt; /* number of in-use packet desciptors */ uint_t mmd_hbuf_ref; /* descriptors referring to header buffer */ uint_t mmd_pbuf_ref; /* descriptors referring to payload buffer(s) */ }; #ifdef _KERNEL extern void mmd_init(void); extern mblk_t *mmd_copy(mblk_t *, int); #endif /* _KERNEL */ #ifdef __cplusplus } #endif #endif /* _SYS_MULTIDATA_IMPL_H */