#ifndef _MVEC_H_
#define _MVEC_H_
#include <sys/mbuf.h>
#define mtomv(m) ((struct mbuf_vec *)((m)->m_pktdat))
#define M_IOVEC 0x100000
#define MBUF_IOV_TYPE_MASK ((1<<3)-1)
#define mbuf_vec_set_type(mv, i, type) \
(mv)->mv_vec[(i)].mi_flags = (((mv)->mv_vec[(i)].mi_flags \
& ~MBUF_IOV_TYPE_MASK) | type)
#define mbuf_vec_get_type(mv, i) \
((mv)->mv_vec[(i)].mi_flags & MBUF_IOV_TYPE_MASK)
struct mbuf_iovec {
uint16_t mi_flags;
uint16_t mi_len;
uint32_t mi_offset;
uint8_t *mi_base;
volatile uint32_t *mi_refcnt;
#ifdef __i386__
void *mi_args;
#endif
};
#define MAX_MBUF_IOV ((MHLEN-8)/sizeof(struct mbuf_iovec))
struct mbuf_vec {
uint16_t mv_first;
uint16_t mv_count;
uint32_t mv_flags;
struct mbuf_iovec mv_vec[MAX_MBUF_IOV];
};
int _m_explode(struct mbuf *);
int _m_collapse(struct mbuf *, int maxbufs, struct mbuf **);
void mb_free_vec(struct mbuf *m);
static __inline void
m_iovinit(struct mbuf *m)
{
struct mbuf_vec *mv = mtomv(m);
mv->mv_first = mv->mv_count = 0;
m->m_pkthdr.len = m->m_len = 0;
m->m_flags |= M_IOVEC;
}
static __inline void
m_iovappend(struct mbuf *m, uint8_t *cl, int size, int len, int offset)
{
struct mbuf_vec *mv = mtomv(m);
struct mbuf_iovec *iov;
int idx = mv->mv_first + mv->mv_count;
if ((m->m_flags & M_EXT) != 0)
panic("invalid flags in %s", __func__);
if (mv->mv_count == 0)
m->m_data = cl + offset;
iov = &mv->mv_vec[idx];
iov->mi_base = cl;
iov->mi_len = len;
iov->mi_offset = offset;
m->m_pkthdr.len += len;
m->m_len += len;
mv->mv_count++;
}
static __inline int
m_explode(struct mbuf *m)
{
if ((m->m_flags & M_IOVEC) == 0)
return (0);
return _m_explode(m);
}
static __inline int
m_collapse(struct mbuf *m, int maxbufs, struct mbuf **mnew)
{
#if (!defined(__sparc64__) && !defined(__sun4v__))
if (m->m_next == NULL)
#endif
{
*mnew = m;
return (0);
}
return _m_collapse(m, maxbufs, mnew);
}
static __inline struct mbuf *
m_free_vec(struct mbuf *m)
{
return m_free(m);
}
static __inline void
m_freem_vec(struct mbuf *m)
{
while (m != NULL)
m = m_free_vec(m);
}
#if (!defined(__sparc64__) && !defined(__sun4v__))
int
bus_dmamap_load_mvec_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
bus_dma_segment_t *segs, int *nsegs, int flags);
#else
#define bus_dmamap_load_mvec_sg bus_dmamap_load_mbuf_sg
#endif
#endif